Browse Source

Structured logger can output to a file.

Better support of imports/keys and key manager integration for eth.
cl-refactor
Gav Wood 10 years ago
parent
commit
b3f8518716
  1. 148
      eth/main.cpp
  2. 13
      libdevcore/StructuredLogger.cpp
  3. 14
      libdevcore/StructuredLogger.h
  4. 39
      libethereum/BlockChain.cpp
  5. 2
      libethereum/KeyManager.h
  6. 1
      libethereum/State.cpp
  7. 2
      libethereum/State.h

148
eth/main.cpp

@ -91,10 +91,8 @@ void interactiveHelp()
<< " minestart Starts mining." << endl << " minestart Starts mining." << endl
<< " minestop Stops mining." << endl << " minestop Stops mining." << endl
<< " mineforce <enable> Forces mining, even when there are no transactions." << endl << " mineforce <enable> Forces mining, even when there are no transactions." << endl
<< " address Gives the current address." << endl
<< " secret Gives the current secret" << endl
<< " block Gives the current block height." << endl << " block Gives the current block height." << endl
<< " balance Gives the current balance." << endl << " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl
<< " transact Execute a given transaction." << endl << " transact Execute a given transaction." << endl
<< " send Execute a given transaction with current secret." << endl << " send Execute a given transaction with current secret." << endl
<< " contract Create a new contract with current secret." << endl << " contract Create a new contract with current secret." << endl
@ -103,7 +101,7 @@ void interactiveHelp()
<< " listaccounts List the accounts on the network." << endl << " listaccounts List the accounts on the network." << endl
<< " listcontracts List the contracts on the network." << endl << " listcontracts List the contracts on the network." << endl
#endif #endif
<< " setsecret <secret> Set the secret to the hex secret key." << endl << " setsigningkey <addr> Set the address with which to sign transactions." << endl
<< " setaddress <addr> Set the coinbase (mining payout) address." << endl << " setaddress <addr> Set the coinbase (mining payout) address." << endl
<< " exportconfig <path> Export the config (.RLP) to the path provided." << endl << " exportconfig <path> Export the config (.RLP) to the path provided." << endl
<< " importconfig <path> Import the config (.RLP) from the path provided." << endl << " importconfig <path> Import the config (.RLP) from the path provided." << endl
@ -127,13 +125,18 @@ void help()
#endif #endif
<< " -K,--kill First kill the blockchain." << endl << " -K,--kill First kill the blockchain." << endl
<< " -R,--rebuild Rebuild the blockchain from the existing database." << endl << " -R,--rebuild Rebuild the blockchain from the existing database." << endl
<< " -s,--secret <secretkeyhex> Set the secret key for use with send command (default: auto)." << endl << " -s,--import-secret <secret> Import a secret key into the key store and use as the default." << endl
<< " -S,--session-secret <secretkeyhex> Set the secret key for use with send command, for this session only." << endl << " -S,--import-session-secret <secret> Import a secret key into the key store and use as the default for this session only." << endl
<< " --sign-key <address> Sign all transactions with the key of the given address." << endl
<< " --session-sign-key <address> Sign all transactions with the key of the given address for this session only." << endl
<< " --master <password> Give the master password for the key store." << endl << " --master <password> Give the master password for the key store." << endl
<< " --password <password> Give a password for a private key." << endl
<< endl
<< "Client transacting:" << endl << "Client transacting:" << endl
<< " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl << " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl << " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl
<< " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl << " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl
<< endl
<< "Client mining:" << endl << "Client mining:" << endl
<< " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)" << endl << " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)" << endl
@ -143,6 +146,7 @@ void help()
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl << " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl << " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl << " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
<< endl
<< "Client networking:" << endl << "Client networking:" << endl
<< " --client-name <name> Add a name to your client's version string (default: blank)." << endl << " --client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " -b,--bootstrap Connect to the default Ethereum peerserver." << endl << " -b,--bootstrap Connect to the default Ethereum peerserver." << endl
@ -155,12 +159,15 @@ void help()
<< " --network-id <n> Only connect to other hosts with this network id (default:0)." << endl << " --network-id <n> Only connect to other hosts with this network id (default:0)." << endl
<< " --upnp <on/off> Use UPnP for NAT (default: on)." << endl << " --upnp <on/off> Use UPnP for NAT (default: on)." << endl
#if ETH_JSONRPC || !ETH_TRUE #if ETH_JSONRPC || !ETH_TRUE
<< endl
<< "Work farming mode:" << endl << "Work farming mode:" << endl
<< " -F,--farm <url> Put into mining farm mode with the work server at URL. Use with -G/--opencl." << endl << " -F,--farm <url> Put into mining farm mode with the work server at URL. Use with -G/--opencl." << endl
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl << " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl
#endif #endif
<< endl
<< "Ethash verify mode:" << endl << "Ethash verify mode:" << endl
<< " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl << " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl
<< endl
<< "Benchmarking mode:" << endl << "Benchmarking mode:" << endl
<< " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl << " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl
<< " --benchmark-warmup <seconds> Set the duration of warmup for the benchmark tests (default: 3)." << endl << " --benchmark-warmup <seconds> Set the duration of warmup for the benchmark tests (default: 3)." << endl
@ -169,14 +176,17 @@ void help()
#if ETH_JSONRPC || !ETH_TRUE #if ETH_JSONRPC || !ETH_TRUE
<< " --phone-home <on/off> When benchmarking, publish results (default: on)" << endl << " --phone-home <on/off> When benchmarking, publish results (default: on)" << endl
#endif #endif
<< endl
<< "DAG creation mode:" << endl << "DAG creation mode:" << endl
<< " -D,--create-dag <this/next/number> Create the DAG in preparation for mining on given block and exit." << endl << " -D,--create-dag <this/next/number> Create the DAG in preparation for mining on given block and exit." << endl
<< endl
<< "Import/export modes:" << endl << "Import/export modes:" << endl
<< " -I,--import <file> Import file as a concatenated series of blocks and exit." << endl << " -I,--import <file> Import file as a concatenated series of blocks and exit." << endl
<< " -E,--export <file> Export file as a concatenated series of blocks and exit." << endl << " -E,--export <file> Export file as a concatenated series of blocks and exit." << endl
<< " --from <n> Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl << " --from <n> Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --to <n> Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl << " --to <n> Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --only <n> Equivalent to --export-from n --export-to n." << endl << " --only <n> Equivalent to --export-from n --export-to n." << endl
<< endl
<< "General Options:" << endl << "General Options:" << endl
<< " -d,--db-path <path> Load database from path (default: " << getDataDir() << ")" << endl << " -d,--db-path <path> Load database from path (default: " << getDataDir() << ")" << endl
#if ETH_EVMJIT || !ETH_TRUE #if ETH_EVMJIT || !ETH_TRUE
@ -539,13 +549,14 @@ int main(int argc, char** argv)
/// Mining params /// Mining params
unsigned mining = 0; unsigned mining = 0;
bool forceMining = false; bool forceMining = false;
KeyPair sigKey = KeyPair::create(); Address signingKey;
Secret sessionSecret; Address sessionKey;
Address coinbase = sigKey.address(); Address beneficiary = signingKey;
/// Structured logging params /// Structured logging params
bool structuredLogging = false; bool structuredLogging = false;
string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S";
string structuredLoggingURL;
/// Transaction params /// Transaction params
TransactionPriority priority = TransactionPriority::Medium; TransactionPriority priority = TransactionPriority::Medium;
@ -570,11 +581,20 @@ int main(int argc, char** argv)
string configFile = getDataDir() + "/config.rlp"; string configFile = getDataDir() + "/config.rlp";
bytes b = contents(configFile); bytes b = contents(configFile);
strings passwordsToNote;
Secrets toImport;
if (b.size()) if (b.size())
{ {
RLP config(b); RLP config(b);
sigKey = KeyPair(config[0].toHash<Secret>()); if (config[0].size() == 32) // secret key - import and forget.
coinbase = config[1].toHash<Address>(); {
Secret s = config[0].toHash<Secret>();
toImport.push_back(s);
}
else // new format - just use it as an address.
signingKey = config[0].toHash<Address>();
beneficiary = config[1].toHash<Address>();
} }
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
@ -602,6 +622,8 @@ int main(int argc, char** argv)
cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl; cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl;
remotePort = (short)atoi(argv[++i]); remotePort = (short)atoi(argv[++i]);
} }
else if (arg == "--password" && i + 1 < argc)
passwordsToNote.push_back(argv[++i]);
else if (arg == "--master" && i + 1 < argc) else if (arg == "--master" && i + 1 < argc)
masterPassword = argv[++i]; masterPassword = argv[++i];
else if ((arg == "-I" || arg == "--import") && i + 1 < argc) else if ((arg == "-I" || arg == "--import") && i + 1 < argc)
@ -744,7 +766,7 @@ int main(int argc, char** argv)
} }
else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc)
try { try {
coinbase = h160(fromHex(argv[++i], WhenError::Throw)); beneficiary = h160(fromHex(argv[++i], WhenError::Throw));
} }
catch (BadHexCharacter&) catch (BadHexCharacter&)
{ {
@ -760,14 +782,32 @@ int main(int argc, char** argv)
minerType = MinerType::CPU; minerType = MinerType::CPU;
else if (arg == "-G" || arg == "--opencl") else if (arg == "-G" || arg == "--opencl")
minerType = MinerType::GPU; minerType = MinerType::GPU;
else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) /*<< " -s,--import-secret <secret> Import a secret key into the key store and use as the default." << endl
sigKey = KeyPair(h256(fromHex(argv[++i]))); << " -S,--import-session-secret <secret> Import a secret key into the key store and use as the default for this session only." << endl
else if ((arg == "-S" || arg == "--session-secret") && i + 1 < argc) << " --sign-key <address> Sign all transactions with the key of the given address." << endl
sessionSecret = h256(fromHex(argv[++i])); << " --session-sign-key <address> Sign all transactions with the key of the given address for this session only." << endl*/
else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc)
{
Secret s(fromHex(argv[++i]));
toImport.push_back(s);
signingKey = toAddress(s);
}
else if ((arg == "-S" || arg == "--import-session-secret") && i + 1 < argc)
{
Secret s(fromHex(argv[++i]));
toImport.push_back(s);
sessionKey = toAddress(s);
}
else if ((arg == "--sign-key") && i + 1 < argc)
sessionKey = Address(fromHex(argv[++i]));
else if ((arg == "--session-sign-key") && i + 1 < argc)
sessionKey = Address(fromHex(argv[++i]));
else if (arg == "--structured-logging-format" && i + 1 < argc) else if (arg == "--structured-logging-format" && i + 1 < argc)
structuredLoggingFormat = string(argv[++i]); structuredLoggingFormat = string(argv[++i]);
else if (arg == "--structured-logging") else if (arg == "--structured-logging")
structuredLogging = true; structuredLogging = true;
else if (arg == "--structured-logging-destination" && i + 1 < argc)
structuredLoggingURL = argv[++i];
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc)
dbPath = argv[++i]; dbPath = argv[++i];
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
@ -951,16 +991,24 @@ int main(int argc, char** argv)
} }
} }
KeyManager keyManager;
for (auto const& s: passwordsToNote)
keyManager.notePassword(s);
for (auto const& s: toImport)
{
keyManager.import(s, "Imported key");
if (!signingKey)
signingKey = toAddress(s);
}
{ {
RLPStream config(2); RLPStream config(2);
config << sigKey.secret() << coinbase; config << signingKey << beneficiary;
writeFile(configFile, config.out()); writeFile(configFile, config.out());
} }
if (sessionSecret) if (sessionKey)
sigKey = KeyPair(sessionSecret); signingKey = sessionKey;
if (minerType == MinerType::CPU) if (minerType == MinerType::CPU)
ProofOfWork::CPUMiner::setNumInstances(miningThreads); ProofOfWork::CPUMiner::setNumInstances(miningThreads);
@ -985,7 +1033,7 @@ int main(int argc, char** argv)
if (!clientName.empty()) if (!clientName.empty())
clientName += "/"; clientName += "/";
StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat); StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat, structuredLoggingURL);
VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter);
auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp); auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp);
auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp");
@ -1074,12 +1122,12 @@ int main(int argc, char** argv)
c->setGasPricer(gasPricer); c->setGasPricer(gasPricer);
c->setForceMining(forceMining); c->setForceMining(forceMining);
c->setTurboMining(minerType == MinerType::GPU); c->setTurboMining(minerType == MinerType::GPU);
c->setAddress(coinbase); c->setAddress(beneficiary);
c->setNetworkId(networkId); c->setNetworkId(networkId);
} }
cout << "Transaction Signer: " << sigKey.address() << endl; cout << "Transaction Signer: " << signingKey << endl;
cout << "Mining Benefactor: " << coinbase << endl; cout << "Mining Benefactor: " << beneficiary << endl;
web3.startNetwork(); web3.startNetwork();
cout << "Node ID: " << web3.enode() << endl; cout << "Node ID: " << web3.enode() << endl;
@ -1088,9 +1136,7 @@ int main(int argc, char** argv)
if (remoteHost.size()) if (remoteHost.size())
web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort));
KeyManager keyManager;
if (keyManager.exists()) if (keyManager.exists())
{
while (masterPassword.empty()) while (masterPassword.empty())
{ {
masterPassword = getPassword("Please enter your MASTER password: "); masterPassword = getPassword("Please enter your MASTER password: ");
@ -1100,14 +1146,12 @@ int main(int argc, char** argv)
masterPassword.clear(); masterPassword.clear();
} }
} }
}
else else
{ {
while (masterPassword.empty()) while (masterPassword.empty())
{ {
masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): "); masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): ");
string confirm = getPassword("Please confirm the password by entering it again: "); string confirm = getPassword("Please confirm the password by entering it again: ");
getline(cin, confirm);
if (masterPassword != confirm) if (masterPassword != confirm)
{ {
cout << "Passwords were different. Try again." << endl; cout << "Passwords were different. Try again." << endl;
@ -1123,7 +1167,14 @@ int main(int argc, char** argv)
g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; }; g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; };
// TODO: give hints &c. // TODO: give hints &c.
auto getPassword = [&](Address const& a){ auto s = silence; silence = true; cout << endl; string ret = dev::getPassword("Enter password for address " + a.abridged() + ": "); silence = s; return ret; }; auto getPassword = [&](Address const& a){
auto s = silence;
silence = true;
cout << endl;
string ret = dev::getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): ");
silence = s;
return ret;
};
#if ETH_JSONRPC || !ETH_TRUE #if ETH_JSONRPC || !ETH_TRUE
shared_ptr<WebThreeStubServer> jsonrpcServer; shared_ptr<WebThreeStubServer> jsonrpcServer;
@ -1131,7 +1182,7 @@ int main(int argc, char** argv)
if (jsonrpc > -1) if (jsonrpc > -1)
{ {
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getPassword, keyManager), vector<KeyPair>({sigKey}))); jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getPassword, keyManager), vector<KeyPair>()));
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
} }
#endif #endif
@ -1275,7 +1326,7 @@ int main(int argc, char** argv)
if (jsonrpc < 0) if (jsonrpc < 0)
jsonrpc = SensibleHttpPort; jsonrpc = SensibleHttpPort;
jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getPassword, keyManager), vector<KeyPair>({sigKey}))); jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared<SimpleAccountHolder>([&](){return web3.ethereum();}, getPassword, keyManager), vector<KeyPair>()));
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
} }
else if (cmd == "jsonstop") else if (cmd == "jsonstop")
@ -1287,11 +1338,8 @@ int main(int argc, char** argv)
#endif #endif
else if (cmd == "address") else if (cmd == "address")
{ {
cout << "Current address:" << endl << sigKey.address() << endl; cout << "Current mining beneficiary:" << endl << beneficiary << endl;
} cout << "Current signing account:" << endl << signingKey << endl;
else if (cmd == "secret")
{
cout << "Secret Key: " << sigKey.secret() << endl;
} }
else if (c && cmd == "block") else if (c && cmd == "block")
{ {
@ -1306,7 +1354,15 @@ int main(int argc, char** argv)
} }
else if (c && cmd == "balance") else if (c && cmd == "balance")
{ {
cout << "Current balance: " << formatBalance( c->balanceAt(sigKey.address())) << " = " <<c->balanceAt(sigKey.address()) << " wei" << endl; cout << "Current balance:" << endl;
u256 total = 0;
for (auto const& i: keyManager.accountDetails())
{
auto b = c->balanceAt(i.first);
cout << ((i.first == signingKey) ? "SIGNING " : " ") << ((i.first == beneficiary) ? "COINBASE " : " ") << i.second.first << " (" << i.first << "): " << formatBalance(b) << " = " << b << " wei" << endl;
total += b;
}
cout << "Total: " << formatBalance(total) << " = " << total << " wei" << endl;
} }
else if (c && cmd == "transact") else if (c && cmd == "transact")
{ {
@ -1422,7 +1478,7 @@ int main(int argc, char** argv)
try try
{ {
Address dest = h160(fromHex(hexAddr, WhenError::Throw)); Address dest = h160(fromHex(hexAddr, WhenError::Throw));
c->submitTransaction(sigKey.secret(), amount, dest, bytes(), minGas); c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), amount, dest, bytes(), minGas);
} }
catch (BadHexCharacter& _e) catch (BadHexCharacter& _e)
{ {
@ -1491,7 +1547,7 @@ int main(int argc, char** argv)
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else
c->submitTransaction(sigKey.secret(), endowment, init, gas, gasPrice); c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), endowment, init, gas, gasPrice);
} }
else else
cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX";
@ -1602,13 +1658,13 @@ int main(int argc, char** argv)
} }
} }
} }
else if (cmd == "setsecret") else if (cmd == "setsigningkey")
{ {
if (iss.peek() != -1) if (iss.peek() != -1)
{ {
string hexSec; string hexSec;
iss >> hexSec; iss >> hexSec;
sigKey = KeyPair(h256(fromHex(hexSec))); signingKey = Address(fromHex(hexSec));
} }
else else
cwarn << "Require parameter: setSecret HEXSECRETKEY"; cwarn << "Require parameter: setSecret HEXSECRETKEY";
@ -1625,7 +1681,7 @@ int main(int argc, char** argv)
{ {
try try
{ {
coinbase = h160(fromHex(hexAddr, WhenError::Throw)); beneficiary = h160(fromHex(hexAddr, WhenError::Throw));
} }
catch (BadHexCharacter& _e) catch (BadHexCharacter& _e)
{ {
@ -1648,7 +1704,7 @@ int main(int argc, char** argv)
string path; string path;
iss >> path; iss >> path;
RLPStream config(2); RLPStream config(2);
config << sigKey.secret() << coinbase; config << signingKey << beneficiary;
writeFile(path, config.out()); writeFile(path, config.out());
} }
else else
@ -1664,8 +1720,8 @@ int main(int argc, char** argv)
if (b.size()) if (b.size())
{ {
RLP config(b); RLP config(b);
sigKey = KeyPair(config[0].toHash<Secret>()); signingKey = config[0].toHash<Address>();
coinbase = config[1].toHash<Address>(); beneficiary = config[1].toHash<Address>();
} }
else else
cwarn << path << "has no content!"; cwarn << path << "has no content!";

13
libdevcore/StructuredLogger.cpp

@ -34,6 +34,15 @@ using namespace std;
namespace dev namespace dev
{ {
void StructuredLogger::initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL)
{
m_enabled = _enabled;
m_timeFormat = _timeFormat;
if (_destinationURL.size() > 7 && _destinationURL.substr(0, 7) == "file://")
m_out.open(_destinationURL.substr(7));
// TODO: support tcp://
}
void StructuredLogger::outputJson(Json::Value const& _value, std::string const& _name) const void StructuredLogger::outputJson(Json::Value const& _value, std::string const& _name) const
{ {
Json::Value event; Json::Value event;
@ -41,7 +50,7 @@ void StructuredLogger::outputJson(Json::Value const& _value, std::string const&
Json::FastWriter fastWriter; Json::FastWriter fastWriter;
Guard l(s_lock); Guard l(s_lock);
event[_name] = _value; event[_name] = _value;
cout << fastWriter.write(event) << endl; (m_out.is_open() ? m_out : cout) << fastWriter.write(event) << endl;
} }
void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersion) void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersion)
@ -51,6 +60,7 @@ void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersi
Json::Value event; Json::Value event;
event["client_impl"] = _clientImpl; event["client_impl"] = _clientImpl;
event["eth_version"] = std::string(_ethVersion); event["eth_version"] = std::string(_ethVersion);
// TODO net_version
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
get().outputJson(event, "starting"); get().outputJson(event, "starting");
@ -64,6 +74,7 @@ void StructuredLogger::stopping(string const& _clientImpl, const char* _ethVersi
Json::Value event; Json::Value event;
event["client_impl"] = _clientImpl; event["client_impl"] = _clientImpl;
event["eth_version"] = std::string(_ethVersion); event["eth_version"] = std::string(_ethVersion);
// TODO net_version
event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str());
get().outputJson(event, "stopping"); get().outputJson(event, "stopping");

14
libdevcore/StructuredLogger.h

@ -25,6 +25,7 @@
#pragma once #pragma once
#include <fstream>
#include <string> #include <string>
#include <chrono> #include <chrono>
@ -46,11 +47,7 @@ public:
* http://en.cppreference.com/w/cpp/chrono/c/strftime * http://en.cppreference.com/w/cpp/chrono/c/strftime
* with which to display timestamps * with which to display timestamps
*/ */
void initialize(bool _enabled, std::string const& _timeFormat) void initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL);
{
m_enabled = _enabled;
m_timeFormat = _timeFormat;
}
static StructuredLogger& get() static StructuredLogger& get()
{ {
@ -92,6 +89,11 @@ public:
std::string const& _prevHash std::string const& _prevHash
); );
static void transactionReceived(std::string const& _hash, std::string const& _remoteId); static void transactionReceived(std::string const& _hash, std::string const& _remoteId);
// TODO: static void pendingQueueChanged(std::vector<h256> const& _hashes);
// TODO: static void miningStarted();
// TODO: static void stillMining(unsigned _hashrate);
// TODO: static void miningStopped();
private: private:
// Singleton class. Private default ctor and no copying // Singleton class. Private default ctor and no copying
StructuredLogger() = default; StructuredLogger() = default;
@ -102,6 +104,8 @@ private:
bool m_enabled = false; bool m_enabled = false;
std::string m_timeFormat = "%Y-%m-%dT%H:%M:%S"; std::string m_timeFormat = "%Y-%m-%dT%H:%M:%S";
mutable std::ofstream m_out;
}; };
} }

39
libethereum/BlockChain.cpp

@ -456,7 +456,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
{ {
// Check transactions are valid and that they result in a state equivalent to our state_root. // Check transactions are valid and that they result in a state equivalent to our state_root.
// Get total difficulty increase and update state, checking it. // Get total difficulty increase and update state, checking it.
State s(_db); //, bi.coinbaseAddress State s(_db);
auto tdIncrease = s.enactOn(&_block, bi, *this, _ir); auto tdIncrease = s.enactOn(&_block, bi, *this, _ir);
BlockLogBlooms blb; BlockLogBlooms blb;
@ -467,6 +467,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
br.receipts.push_back(s.receipt(i)); br.receipts.push_back(s.receipt(i));
} }
s.cleanup(true); s.cleanup(true);
td = pd.totalDifficulty + tdIncrease; td = pd.totalDifficulty + tdIncrease;
#if ETH_TIMED_IMPORTS #if ETH_TIMED_IMPORTS
@ -603,7 +604,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
{ {
newLastBlockHash = bi.hash(); newLastBlockHash = bi.hash();
newLastBlockNumber = (unsigned)bi.number; newLastBlockNumber = (unsigned)bi.number;
extrasBatch.Put(ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32));
} }
clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route; clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route;
@ -623,12 +623,33 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
m_blocksDB->Write(m_writeOptions, &blocksBatch); m_blocksDB->Write(m_writeOptions, &blocksBatch);
m_extrasDB->Write(m_writeOptions, &extrasBatch); m_extrasDB->Write(m_writeOptions, &extrasBatch);
DEV_WRITE_GUARDED(x_lastBlockHash) if (isKnown(bi.hash()) && !details(bi.hash()))
{ {
m_lastBlockHash = newLastBlockHash; clog(BlockChainDebug) << "Known block just inserted has no details.";
m_lastBlockNumber = newLastBlockNumber; clog(BlockChainDebug) << "Block:" << bi;
clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE";
exit(-1);
} }
try {
State canary(_db, *this, bi.hash());
}
catch (...)
{
clog(BlockChainDebug) << "Failed to initialise State object form imported block.";
clog(BlockChainDebug) << "Block:" << bi;
clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE";
exit(-1);
}
if (m_lastBlockHash != newLastBlockHash)
DEV_WRITE_GUARDED(x_lastBlockHash)
{
m_lastBlockHash = newLastBlockHash;
m_lastBlockNumber = newLastBlockNumber;
m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&m_lastBlockHash, 32));
}
#if ETH_PARANOIA || !ETH_TRUE #if ETH_PARANOIA || !ETH_TRUE
checkConsistency(); checkConsistency();
#endif #endif
@ -646,14 +667,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
if (!route.empty()) if (!route.empty())
noteCanonChanged(); noteCanonChanged();
if (isKnown(bi.hash()) && !details(bi.hash()))
{
clog(BlockChainDebug) << "Known block just inserted has no details.";
clog(BlockChainDebug) << "Block:" << bi;
clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE";
exit(-1);
}
h256s fresh; h256s fresh;
h256s dead; h256s dead;
bool isOld = true; bool isOld = true;

2
libethereum/KeyManager.h

@ -66,6 +66,8 @@ public:
bool load(std::string const& _pass); bool load(std::string const& _pass);
void save(std::string const& _pass) const { write(_pass, m_keysFile); } void save(std::string const& _pass) const { write(_pass, m_keysFile); }
void notePassword(std::string const& _pass) { m_cachedPasswords[hashPassword(_pass)] = _pass; }
AddressHash accounts() const; AddressHash accounts() const;
std::unordered_map<Address, std::pair<std::string, std::string>> accountDetails() const; std::unordered_map<Address, std::pair<std::string, std::string>> accountDetails() const;

1
libethereum/State.cpp

@ -707,6 +707,7 @@ void State::cleanup(bool _fullCommit)
{ {
if (_fullCommit) if (_fullCommit)
{ {
paranoia("immediately before database commit", true); paranoia("immediately before database commit", true);
// Commit the new trie to disk. // Commit the new trie to disk.

2
libethereum/State.h

@ -49,7 +49,7 @@ class BlockChain;
class State; class State;
struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; };
struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 7; }; struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 5; };
struct StateDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; struct StateDetail: public LogChannel { static const char* name(); static const int verbosity = 14; };
struct StateSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; }; struct StateSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; };

Loading…
Cancel
Save