From 07f0cde34ff00ad673d8926c7b3f4bfd85b89afa Mon Sep 17 00:00:00 2001 From: caktux Date: Thu, 26 Mar 2015 03:17:31 -0400 Subject: [PATCH] add missing options to neth, support for PeerServer mode --- neth/main.cpp | 341 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 229 insertions(+), 112 deletions(-) diff --git a/neth/main.cpp b/neth/main.cpp index fc4c8c9c6..7af96eb08 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -31,12 +31,15 @@ #include #include +#include +#include +#include #include +#include #if ETH_JSONRPC #include #include #endif -#include #include "BuildInfo.h" #undef KEY_EVENT // from windows.h @@ -68,26 +71,37 @@ void help() << "Usage neth [OPTIONS]" << endl << "Options:" << endl << " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl + << " -b,--bootstrap Connect to the default Ethereum peerserver." << endl + << " -B,--block-fees Set the block fee profit in the reference unit e.g. ¢ (Default: 15)." << endl << " -c,--client-name Add a name to your client's version string (default: blank)." << endl << " -d,--db-path Load database from path (default: ~/.ethereum " << endl << " /Etherum or Library/Application Support/Ethereum)." << endl + << " -e,--ether-price Set the ether price in the reference unit e.g. ¢ (Default: 30.679)." << endl + << " -f,--force-mining Mine even when there are no transaction to mine (Default: off)" << endl << " -h,--help Show this help message and exit." << endl #if ETH_JSONRPC << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: 8080)." << endl #endif + << " -K,--kill-blockchain First kill the blockchain." << endl << " -l,--listen Listen on the given port for incoming connected (default: 30303)." << endl + << " -L,--local-networking Use peers whose addresses are local." << endl << " -m,--mining Enable mining (default: off)" << endl << " -n,--upnp Use upnp for NAT (default: on)." << endl << " -o,--mode Start a full node or a peer node (Default: full)." << endl << " -p,--port Connect to remote port (default: 30303)." << endl + << " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl << " -t,--miners Number of mining threads to start (Default: " << thread::hardware_concurrency() << ")" << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl << " -v,--verbosity <0..9> Set the log verbosity from 0 to 9 (tmp forced to 1)." << endl << " -x,--peers Attempt to connect to given number of peers (default: 5)." << endl - << " -V,--version Show the version and exit." << endl; + << " -V,--version Show the version and exit." << endl +#if ETH_EVMJIT + << " --jit Use EVM JIT (default: off)." << endl +#endif + ; exit(0); } @@ -319,7 +333,14 @@ int main(int argc, char** argv) bool upnp = true; bool useLocal = false; bool forceMining = false; + bool killChain = false; + bool jit = false; + bool structuredLogging = false; + string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; string clientName; + TransactionPriority priority = TransactionPriority::Medium; + double etherPrice = 30.679; + double blockFees = 15.0; // Init defaults Defaults::get(); @@ -367,6 +388,10 @@ int main(int argc, char** argv) return -1; } } + else if (arg == "-L" || arg == "--local-networking") + useLocal = true; + else if (arg == "-K" || arg == "--kill-blockchain") + killChain = true; else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) @@ -389,8 +414,58 @@ int main(int argc, char** argv) } else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) us = KeyPair(h256(fromHex(argv[++i]))); + else if (arg == "--structured-logging-format" && i + 1 < argc) + structuredLoggingFormat = string(argv[++i]); + else if (arg == "--structured-logging") + structuredLogging = true; else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) dbPath = argv[++i]; + else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc) + { + try + { + blockFees = stof(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[++i] << endl; + return -1; + } + } + else if ((arg == "-e" || arg == "--ether-price") && i + 1 < argc) + { + try + { + etherPrice = stof(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[++i] << endl; + return -1; + } + } + else if ((arg == "-P" || arg == "--priority") && i + 1 < argc) + { + string m = boost::to_lower_copy(string(argv[++i])); + if (m == "lowest") + priority = TransactionPriority::Lowest; + else if (m == "low") + priority = TransactionPriority::Low; + else if (m == "medium" || m == "mid" || m == "default" || m == "normal") + priority = TransactionPriority::Medium; + else if (m == "high") + priority = TransactionPriority::High; + else if (m == "highest") + priority = TransactionPriority::Highest; + else + try { + priority = (TransactionPriority)(max(0, min(100, stoi(m))) * 8 / 100); + } + catch (...) { + cerr << "Unknown " << arg << " option: " << m << endl; + return -1; + } + } else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) { string m = argv[++i]; @@ -423,6 +498,28 @@ int main(int argc, char** argv) peers = atoi(argv[++i]); else if ((arg == "-t" || arg == "--miners") && i + 1 < argc) miners = atoi(argv[++i]); + else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) + { + string m = argv[++i]; + if (m == "full") + mode = NodeMode::Full; + else if (m == "peer") + mode = NodeMode::PeerServer; + else + { + cerr << "Unknown mode: " << m << endl; + return -1; + } + } + else if (arg == "--jit") + { +#if ETH_EVMJIT + jit = true; +#else + cerr << "EVM JIT not enabled" << endl; + return -1; +#endif + } else if (arg == "-h" || arg == "--help") help(); else if (arg == "-V" || arg == "--version") @@ -438,35 +535,41 @@ int main(int argc, char** argv) clientName += "/"; cout << credits(); + + StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat); + VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); NetworkPreferences netPrefs(listenPort, publicIP, upnp, useLocal); auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); + std::string clientImplString = "NEthereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : ""); dev::WebThreeDirect web3( - "NEthereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), + clientImplString, dbPath, - false, + killChain, mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, &nodesState, miners ); web3.setIdealPeerCount(peers); + std::shared_ptr gasPricer = make_shared(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000)); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; - + StructuredLogger::starting(clientImplString, dev::Version); if (c) { + c->setGasPricer(gasPricer); c->setForceMining(forceMining); c->setAddress(coinbase); } - cout << "Address: " << endl << toHex(us.address().asArray()) << endl; - + cout << "Transaction Signer: " << us.address() << endl; + cout << "Mining Benefactor: " << coinbase << endl; web3.startNetwork(); if (bootstrap) web3.connect(Host::pocHost()); if (remoteHost.size()) web3.connect(remoteHost, remotePort); - if (mining) + if (c && mining) c->startMining(); #if ETH_JSONRPC @@ -474,11 +577,7 @@ int main(int argc, char** argv) unique_ptr jsonrpcConnector; if (jsonrpc > -1) { -#if ETH_DEBUG - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); -#else - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); -#endif + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); @@ -655,7 +754,7 @@ int main(int argc, char** argv) ccout << "Current secret:" << endl; ccout << toHex(us.secret().asArray()) << endl; } - else if (cmd == "block") + else if (c && cmd == "block") { unsigned n = c->blockChain().details().number; ccout << "Current block # "; @@ -668,13 +767,13 @@ int main(int argc, char** argv) << std::chrono::duration_cast(it.lastPing).count() << "ms" << endl; } - else if (cmd == "balance") + else if (c && cmd == "balance") { u256 balance = c->balanceAt(us.address()); ccout << "Current balance:" << endl; ccout << toString(balance) << endl; } - else if (cmd == "transact") + else if (c && cmd == "transact") { auto const& bc = c->blockChain(); auto h = bc.currentHash(); @@ -761,7 +860,7 @@ int main(int argc, char** argv) } } } - else if (cmd == "send") + else if (c && cmd == "send") { vector s; s.push_back("Address"); @@ -812,7 +911,7 @@ int main(int argc, char** argv) } } } - else if (cmd == "contract") + else if (c && cmd == "contract") { auto const& bc = c->blockChain(); auto h = bc.currentHash(); @@ -895,7 +994,7 @@ int main(int argc, char** argv) } } } - else if (cmd == "inspect") + else if (c && cmd == "inspect") { string rechex; iss >> rechex; @@ -941,111 +1040,119 @@ int main(int argc, char** argv) interactiveHelp(); else if (cmd == "exit") break; + else if (cmd != "") + cwarn << "Unrecognised command. Type 'help' for a list of available commands."; // Clear cmd at each pass cmd = ""; - // Lock to prevent corrupt block-chain errors - auto const& bc = c->blockChain(); - ccout << "Genesis hash: " << bc.genesisHash() << endl; + // Contracts and addresses count / offset + int cc = 1; + int ca = 0; - // Blocks - y = 1; - for (auto h = bc.currentHash(); h != bc.genesisHash(); h = bc.details(h).parent) - { - auto d = bc.details(h); - string s = "# " + std::to_string(d.number) + ' ' + toString(h); // .abridged(); - mvwaddnstr(blockswin, y++, x, s.c_str(), qwidth); + if (c) { + // Lock to prevent corrupt block-chain errors + auto const& bc = c->blockChain(); + ccout << "Genesis hash: " << bc.genesisHash() << endl; - auto b = bc.block(h); - for (auto const& i: RLP(b)[1]) + // Blocks + y = 1; + for (auto h = bc.currentHash(); h != bc.genesisHash(); h = bc.details(h).parent) + { + auto d = bc.details(h); + string s = "# " + std::to_string(d.number) + ' ' + toString(h); // .abridged(); + mvwaddnstr(blockswin, y++, x, s.c_str(), qwidth); + + auto b = bc.block(h); + for (auto const& i: RLP(b)[1]) + { + Transaction t(i.data(), CheckSignature::Sender); + auto s = t.receiveAddress() ? + boost::format(" %1% %2%> %3%: %4% [%5%]") % + toString(t.safeSender()) % + (c->codeAt(t.receiveAddress(), PendingBlock).size() ? '*' : '-') % + toString(t.receiveAddress()) % + toString(formatBalance(t.value())) % + toString((unsigned)t.nonce()) : + boost::format(" %1% +> %2%: %3% [%4%]") % + toString(t.safeSender()) % + toString(right160(sha3(rlpList(t.safeSender(), t.nonce())))) % + toString(formatBalance(t.value())) % + toString((unsigned)t.nonce()); + mvwaddnstr(blockswin, y++, x, s.str().c_str(), qwidth - 2); + if (y > qheight - 2) + break; + } + if (y > qheight - 2) + break; + } + + + // Pending + y = 1; + for (Transaction const& t: c->pending()) { - Transaction t(i.data(), CheckSignature::Sender); auto s = t.receiveAddress() ? - boost::format(" %1% %2%> %3%: %4% [%5%]") % + boost::format("%1% %2%> %3%: %4% [%5%]") % toString(t.safeSender()) % (c->codeAt(t.receiveAddress(), PendingBlock).size() ? '*' : '-') % toString(t.receiveAddress()) % toString(formatBalance(t.value())) % toString((unsigned)t.nonce()) : - boost::format(" %1% +> %2%: %3% [%4%]") % + boost::format("%1% +> %2%: %3% [%4%]") % toString(t.safeSender()) % toString(right160(sha3(rlpList(t.safeSender(), t.nonce())))) % toString(formatBalance(t.value())) % toString((unsigned)t.nonce()); - mvwaddnstr(blockswin, y++, x, s.str().c_str(), qwidth - 2); - if (y > qheight - 2) + mvwaddnstr(pendingwin, y++, x, s.str().c_str(), qwidth); + if (y > height * 1 / 5 - 2) break; } - if (y > qheight - 2) - break; - } - - // Pending - y = 1; - for (Transaction const& t: c->pending()) - { - auto s = t.receiveAddress() ? - boost::format("%1% %2%> %3%: %4% [%5%]") % - toString(t.safeSender()) % - (c->codeAt(t.receiveAddress(), PendingBlock).size() ? '*' : '-') % - toString(t.receiveAddress()) % - toString(formatBalance(t.value())) % - toString((unsigned)t.nonce()) : - boost::format("%1% +> %2%: %3% [%4%]") % - toString(t.safeSender()) % - toString(right160(sha3(rlpList(t.safeSender(), t.nonce())))) % - toString(formatBalance(t.value())) % - toString((unsigned)t.nonce()); - mvwaddnstr(pendingwin, y++, x, s.str().c_str(), qwidth); - if (y > height * 1 / 5 - 2) - break; - } + // Contracts and addresses + y = 1; + auto acs = c->addresses(); + ca = acs.size(); + for (auto const& i: acs) + if (c->codeAt(i, PendingBlock).size()) + { + auto s = boost::format("%1%%2% : %3% [%4%]") % + toString(i) % + pretty(i, c->postState()) % + toString(formatBalance(c->balanceAt(i))) % + toString((unsigned)c->countAt(i, PendingBlock)); + mvwaddnstr(contractswin, cc++, x, s.str().c_str(), qwidth); + if (cc > qheight - 2) + break; + } + for (auto const& i: acs) + if (c->codeAt(i, PendingBlock).empty()) + { + auto s = boost::format("%1%%2% : %3% [%4%]") % + toString(i) % + pretty(i, c->postState()) % + toString(formatBalance(c->balanceAt(i))) % + toString((unsigned)c->countAt(i, PendingBlock)); + mvwaddnstr(addswin, y++, x, s.str().c_str(), width / 2 - 4); + if (y > height * 3 / 5 - 4) + break; + } - // Contracts and addresses - y = 1; - int cc = 1; - auto acs = c->addresses(); - for (auto const& i: acs) - if (c->codeAt(i, PendingBlock).size()) - { - auto s = boost::format("%1%%2% : %3% [%4%]") % - toString(i) % - pretty(i, c->postState()) % - toString(formatBalance(c->balanceAt(i))) % - toString((unsigned)c->countAt(i, PendingBlock)); - mvwaddnstr(contractswin, cc++, x, s.str().c_str(), qwidth); - if (cc > qheight - 2) - break; - } - for (auto const& i: acs) - if (c->codeAt(i, PendingBlock).empty()) + // Peers + y = 1; + for (PeerSessionInfo const& i: web3.peers()) { - auto s = boost::format("%1%%2% : %3% [%4%]") % - toString(i) % - pretty(i, c->postState()) % - toString(formatBalance(c->balanceAt(i))) % - toString((unsigned)c->countAt(i, PendingBlock)); - mvwaddnstr(addswin, y++, x, s.str().c_str(), width / 2 - 4); - if (y > height * 3 / 5 - 4) + auto s = boost::format("%1% ms - %2%:%3% - %4%") % + toString(chrono::duration_cast(i.lastPing).count()) % + i.host % + toString(i.port) % + i.clientVersion; + mvwaddnstr(peerswin, y++, x, s.str().c_str(), qwidth); + if (y > height * 2 / 5 - 4) break; } - - // Peers - y = 1; - for (PeerSessionInfo const& i: web3.peers()) - { - auto s = boost::format("%1% ms - %2%:%3% - %4%") % - toString(chrono::duration_cast(i.lastPing).count()) % - i.host % - toString(i.port) % - i.clientVersion; - mvwaddnstr(peerswin, y++, x, s.str().c_str(), qwidth); - if (y > height * 2 / 5 - 4) - break; } box(consolewin, 0, 0); @@ -1058,31 +1165,41 @@ int main(int argc, char** argv) // Balance stringstream ssb; - u256 balance = c->balanceAt(us.address()); - ssb << "Balance: " << formatBalance(balance); + u256 balance; + if (c) + balance = c->balanceAt(us.address()); + ssb << "Balance: "; + if (c) + ssb << formatBalance(balance); mvwprintw(consolewin, 0, x, ssb.str().c_str()); // Block mvwprintw(blockswin, 0, x, "Block # "); - unsigned n = c->blockChain().details().number; - mvwprintw(blockswin, 0, 10, toString(n).c_str()); + if (c) { + unsigned n = c->blockChain().details().number; + mvwprintw(blockswin, 0, 10, toString(n).c_str()); + } // Pending - string pc; - pc = "Pending: " + toString(c->pending().size()); - mvwprintw(pendingwin, 0, x, pc.c_str()); + stringstream pc; + pc << "Pending: "; + if (c) + pc << toString(c->pending().size()); + else + pc << 0; + mvwprintw(pendingwin, 0, x, pc.str().c_str()); // Contracts - string sc = "Contracts: "; - sc += toString(cc - 1); - mvwprintw(contractswin, 0, x, sc.c_str()); + stringstream sc; + sc << "Contracts: " << cc - 1; + mvwprintw(contractswin, 0, x, sc.str().c_str()); // Peers mvwprintw(peerswin, 0, x, "Peers: "); mvwprintw(peerswin, 0, 9, toString(web3.peers().size()).c_str()); // Mining flag - if (c->isMining()) + if (c && c->isMining()) { mvwprintw(consolewin, qheight - 1, width / 4 - 11, "Mining ON"); dev::eth::MineProgress p = c->miningProgress(); @@ -1095,9 +1212,9 @@ int main(int argc, char** argv) wmove(consolewin, 1, x); // Addresses - string ac; - ac = "Addresses: " + toString(acs.size()); - mvwprintw(addswin, 0, x, ac.c_str()); + stringstream ac; + ac << "Addresses: " << ca; + mvwprintw(addswin, 0, x, ac.str().c_str()); wrefresh(consolewin);