From ec3afa9d713cd30c4fd52a57f379e0428cf6a120 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 7 Jun 2015 09:06:06 +0200 Subject: [PATCH 01/36] eth_newPendingTransactionFilter --- libweb3jsonrpc/WebThreeStubServerBase.cpp | 18 ++++++++---------- libweb3jsonrpc/WebThreeStubServerBase.h | 3 ++- libweb3jsonrpc/abstractwebthreestubserver.h | 14 +++++++++++--- libweb3jsonrpc/spec.json | 3 ++- test/libweb3jsonrpc/webthreestubclient.h | 14 ++++++++++++-- 5 files changed, 35 insertions(+), 17 deletions(-) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index ff7b84dc4..fa07e7dd3 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -781,17 +781,15 @@ string WebThreeStubServerBase::eth_newFilter(Json::Value const& _json) } } -string WebThreeStubServerBase::eth_newBlockFilter(string const& _filter) +string WebThreeStubServerBase::eth_newBlockFilter() { - h256 filter; - - if (_filter.compare("chain") == 0 || _filter.compare("latest") == 0) - filter = dev::eth::ChainChangedFilter; - else if (_filter.compare("pending") == 0) - filter = dev::eth::PendingChangedFilter; - else - BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); - + h256 filter = dev::eth::ChainChangedFilter; + return toJS(client()->installWatch(filter)); +} + +string WebThreeStubServerBase::eth_newPendingTransactionFilter() +{ + h256 filter = dev::eth::PendingChangedFilter; return toJS(client()->installWatch(filter)); } diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index f3f7edfe7..d90df1445 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -107,7 +107,8 @@ public: virtual std::string eth_compileSerpent(std::string const& _s); virtual std::string eth_compileSolidity(std::string const& _code); virtual std::string eth_newFilter(Json::Value const& _json); - virtual std::string eth_newBlockFilter(std::string const& _filter); + virtual std::string eth_newBlockFilter(); + virtual std::string eth_newPendingTransactionFilter(); virtual bool eth_uninstallFilter(std::string const& _filterId); virtual Json::Value eth_getFilterChanges(std::string const& _filterId); virtual Json::Value eth_getFilterLogs(std::string const& _filterId); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 89313df89..6a1a3df10 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -47,7 +47,8 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_compileSerpent", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_compileSerpentI); this->bindAndAddMethod(jsonrpc::Procedure("eth_compileSolidity", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_compileSolidityI); this->bindAndAddMethod(jsonrpc::Procedure("eth_newFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_newFilterI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_newBlockFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_newBlockFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newBlockFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_newBlockFilterI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_newPendingTransactionFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_newPendingTransactionFilterI); this->bindAndAddMethod(jsonrpc::Procedure("eth_uninstallFilter", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_uninstallFilterI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterChanges", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getFilterChangesI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getFilterLogs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getFilterLogsI); @@ -228,7 +229,13 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_newBlockFilter(request[0u].asString()); + (void)request; + response = this->eth_newBlockFilter(); + } + inline virtual void eth_newPendingTransactionFilterI(const Json::Value &request, Json::Value &response) + { + (void)request; + response = this->eth_newPendingTransactionFilter(); } inline virtual void eth_uninstallFilterI(const Json::Value &request, Json::Value &response) { @@ -359,7 +366,8 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_newBlockFilter",p); if (result.isString()) return result.asString(); else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } + std::string eth_newPendingTransactionFilter() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_newPendingTransactionFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } bool eth_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) { Json::Value p; From e655491fe9eac70c1ab2d21257739aeb073abf17 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 8 Jun 2015 11:24:00 +0200 Subject: [PATCH 02/36] add precompiled contracts with prefixed 0's and retune gas limit --- .../stPreCompiledContractsFiller.json | 373 +++++++++++++++++- 1 file changed, 358 insertions(+), 15 deletions(-) diff --git a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json index 1b2d59385..c28c607b7 100644 --- a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json +++ b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json @@ -42,7 +42,50 @@ } }, - "CallEcrecover80": { + "CallEcrecoverH_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa0b29af6a56d6cfef6415cb195ccbe540e006d0a", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallEcrecoverV_prefixed0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -60,6 +103,135 @@ } } }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 0x001c) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallEcrecoverR_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x3f17f1962b36e491b30a40b2405849e597ba5fb5", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallEcrecoverS_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xb4950a7fad428434b11c357fa6d4b4bcd3096a5d", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallEcrecover80": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x3f17f1962b36e491b30a40b2405849e597ba5fb5", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", @@ -214,7 +386,7 @@ } }, - "CallEcrecover0_BonusGas": { + "CallEcrecover0_NoGas": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -224,9 +396,8 @@ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "expect" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "storage" : { - } + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x011248" } }, "pre" : { @@ -266,7 +437,8 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - } + "0x02" : "0x00" + } } }, "pre" : { @@ -671,6 +843,90 @@ } }, + "CallSha256_3_prefix0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallSha256_3_postfix0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x3b745a1c00d035c334f358d007a430e4cf0ae63aa0556fb05529706de546464d", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + "CallSha256_4": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -891,6 +1147,8 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { + "0x00" : "0xdbc100f916bfbc53535573d98cf0cbb3a5b36124", + "0x02" : "0x01" } } }, @@ -898,7 +1156,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 600 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -931,7 +1189,8 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xf34578907f" + "0x00" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca", + "0x02" : "0x01" } } }, @@ -939,7 +1198,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 600 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -960,7 +1219,7 @@ } }, - "CallRipemd160_4": { + "CallRipemd160_3_prefixed0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -972,7 +1231,8 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "0x00" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca", + "0x02" : "0x01" } } }, @@ -980,7 +1240,90 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 120 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallRipemd160_3_postfixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0x7730b4642169b0f16752696da8da830a4b429c9d", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALL 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallRipemd160_4": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3", + "0x02" : "0x01" } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 720 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1001,7 +1344,7 @@ } }, - "CallRipemd160_4_gas99": { + "CallRipemd160_4_gas719": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1021,7 +1364,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 119 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 719 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1062,7 +1405,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 6000 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { From 4205cf79f9cc5c519c1afba66d5be4f05412235f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 8 Jun 2015 12:09:24 +0200 Subject: [PATCH 03/36] Remove pessimising moves. --- libdevcrypto/Common.cpp | 4 ++-- libdevcrypto/CryptoPP.cpp | 2 +- libdevcrypto/CryptoPP.h | 2 +- libdevcrypto/OverlayDB.cpp | 4 ++-- libevmasm/Assembly.cpp | 2 +- libp2p/Common.h | 4 ++-- libp2p/Host.cpp | 4 ++-- libp2p/Network.cpp | 2 +- libp2p/NodeTable.cpp | 10 +++++----- libp2p/RLPxFrameIO.cpp | 4 ++-- libp2p/UDP.cpp | 4 ++-- libp2p/UDP.h | 2 +- libsolidity/CompilerContext.cpp | 2 +- libsolidity/Types.cpp | 12 ++++++------ test/libp2p/net.cpp | 2 +- test/libwhisper/whisperMessage.cpp | 4 ++-- 16 files changed, 32 insertions(+), 32 deletions(-) diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index 814f8309e..5ee73605c 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -54,7 +54,7 @@ Public dev::toPublic(Secret const& _secret) { Public p; s_secp256k1.toPublic(_secret, p); - return std::move(p); + return p; } Address dev::toAddress(Public const& _public) @@ -230,7 +230,7 @@ h256 crypto::kdf(Secret const& _priv, h256 const& _hash) if (!s || !_hash || !_priv) BOOST_THROW_EXCEPTION(InvalidState()); - return std::move(s); + return s; } h256 Nonce::get(bool _commit) diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index b701fed8d..9b550a666 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -61,7 +61,7 @@ bytes Secp256k1::eciesKDF(Secret _z, bytes _s1, unsigned kdByteLen) } k.resize(kdByteLen); - return move(k); + return k; } void Secp256k1::encryptECIES(Public const& _k, bytes& io_cipher) diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h index ca8a2e6b5..377da8754 100644 --- a/libdevcrypto/CryptoPP.h +++ b/libdevcrypto/CryptoPP.h @@ -59,7 +59,7 @@ namespace crypto using namespace CryptoPP; -inline ECP::Point publicToPoint(Public const& _p) { Integer x(_p.data(), 32); Integer y(_p.data() + 32, 32); return std::move(ECP::Point(x,y)); } +inline ECP::Point publicToPoint(Public const& _p) { Integer x(_p.data(), 32); Integer y(_p.data() + 32, 32); return ECP::Point(x,y); } inline Integer secretToExponent(Secret const& _s) { return std::move(Integer(_s.data(), Secret::size)); } diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp index 80c901635..05b9877ad 100644 --- a/libdevcrypto/OverlayDB.cpp +++ b/libdevcrypto/OverlayDB.cpp @@ -95,7 +95,7 @@ bytes OverlayDB::lookupAux(h256 const& _h) const { bytes ret = MemoryDB::lookupAux(_h); if (!ret.empty() || !m_db) - return move(ret); + return ret; std::string v; bytes b = _h.asBytes(); b.push_back(255); // for aux @@ -116,7 +116,7 @@ std::string OverlayDB::lookup(h256 const& _h) const std::string ret = MemoryDB::lookup(_h); if (ret.empty() && m_db) m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); - return move(ret); + return ret; } bool OverlayDB::exists(h256 const& _h) const diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 8642824f6..3557fc0ee 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -109,7 +109,7 @@ string Assembly::getLocationFromSources(StringMap const& _sourceCodes, SourceLoc if (newLinePos != string::npos) cut = cut.substr(0, newLinePos) + "..."; - return move(cut); + return cut; } ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const diff --git a/libp2p/Common.h b/libp2p/Common.h index 8fd330580..4a1b64b70 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -183,8 +183,8 @@ struct NodeIPEndpoint uint16_t udpPort = 0; uint16_t tcpPort = 0; - operator bi::udp::endpoint() const { return std::move(bi::udp::endpoint(address, udpPort)); } - operator bi::tcp::endpoint() const { return std::move(bi::tcp::endpoint(address, tcpPort)); } + operator bi::udp::endpoint() const { return bi::udp::endpoint(address, udpPort); } + operator bi::tcp::endpoint() const { return bi::tcp::endpoint(address, tcpPort); } operator bool() const { return !address.is_unspecified() && udpPort > 0 && tcpPort > 0; } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index b6c9efec9..f47db3c2b 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -834,7 +834,7 @@ KeyPair Host::networkAlias(bytesConstRef _b) { RLP r(_b); if (r.itemCount() == 3 && r[0].isInt() && r[0].toInt() >= 3) - return move(KeyPair(move(Secret(r[1].toBytes())))); + return KeyPair(Secret(r[1].toBytes())); else - return move(KeyPair::create()); + return KeyPair::create(); } diff --git a/libp2p/Network.cpp b/libp2p/Network.cpp index d8ab90a20..2f2f247b6 100644 --- a/libp2p/Network.cpp +++ b/libp2p/Network.cpp @@ -111,7 +111,7 @@ std::set Network::getInterfaceAddresses() #endif - return std::move(addresses); + return addresses; } int Network::tcp4Listen(bi::tcp::acceptor& _acceptor, NetworkPreferences const& _netPrefs) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index bf056c52f..078b4409b 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -88,7 +88,7 @@ shared_ptr NodeTable::addNode(Node const& _node, NodeRelation _relati } if (!_node.endpoint) - return move(shared_ptr()); + return shared_ptr(); // ping address to recover nodeid if nodeid is empty if (!_node.id) @@ -98,7 +98,7 @@ shared_ptr NodeTable::addNode(Node const& _node, NodeRelation _relati DEV_GUARDED(x_pubkDiscoverPings) m_pubkDiscoverPings[_node.endpoint.address] = std::chrono::steady_clock::now(); ping(_node.endpoint); - return move(shared_ptr()); + return shared_ptr(); } DEV_GUARDED(x_nodes) @@ -129,7 +129,7 @@ list NodeTable::nodes() const DEV_GUARDED(x_nodes) for (auto& i: m_nodes) nodes.push_back(i.second->id); - return move(nodes); + return nodes; } list NodeTable::snapshot() const @@ -140,7 +140,7 @@ list NodeTable::snapshot() const for (auto const& np: s.nodes) if (auto n = np.lock()) ret.push_back(*n); - return move(ret); + return ret; } Node NodeTable::node(NodeId const& _id) @@ -282,7 +282,7 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) for (auto const& n: nodes.second) if (ret.size() < s_bucketSize && !!n->endpoint && n->endpoint.isAllowed()) ret.push_back(n); - return move(ret); + return ret; } void NodeTable::ping(NodeIPEndpoint _to) const diff --git a/libp2p/RLPxFrameIO.cpp b/libp2p/RLPxFrameIO.cpp index ac1a27bed..4fa8557ba 100644 --- a/libp2p/RLPxFrameIO.cpp +++ b/libp2p/RLPxFrameIO.cpp @@ -154,7 +154,7 @@ h128 RLPXFrameIO::egressDigest() SHA3_256 h(m_egressMac); h128 digest; h.TruncatedFinal(digest.data(), h128::size); - return move(digest); + return digest; } h128 RLPXFrameIO::ingressDigest() @@ -162,7 +162,7 @@ h128 RLPXFrameIO::ingressDigest() SHA3_256 h(m_ingressMac); h128 digest; h.TruncatedFinal(digest.data(), h128::size); - return move(digest); + return digest; } void RLPXFrameIO::updateEgressMACWithHeader(bytesConstRef _headerCipher) diff --git a/libp2p/UDP.cpp b/libp2p/UDP.cpp index 9f89d9ad0..0b85bae4b 100644 --- a/libp2p/UDP.cpp +++ b/libp2p/UDP.cpp @@ -52,12 +52,12 @@ h256 RLPXDatagramFace::sign(Secret const& _k) bytesConstRef signedRLPx(&data[h256::size], data.size() - h256::size); dev::sha3(signedRLPx).ref().copyTo(rlpxHash); - return std::move(sighash); + return sighash; } Public RLPXDatagramFace::authenticate(bytesConstRef _sig, bytesConstRef _rlp) { Signature const& sig = *(Signature const*)_sig.data(); - return std::move(dev::recover(sig, sha3(_rlp))); + return dev::recover(sig, sha3(_rlp)); } diff --git a/libp2p/UDP.h b/libp2p/UDP.h index 474cb5442..e345ce07f 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -81,7 +81,7 @@ template struct RLPXDatagram: public RLPXDatagramFace { RLPXDatagram(bi::udp::endpoint const& _ep): RLPXDatagramFace(_ep) {} - static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { try { T t(_ep); t.interpretRLP(_bytes); return std::move(t); } catch(...) { T t(_ep); return std::move(t); } } + static T fromBytesConstRef(bi::udp::endpoint const& _ep, bytesConstRef _bytes) { try { T t(_ep); t.interpretRLP(_bytes); return t; } catch(...) { return T{_ep}; } } uint8_t packetType() { return T::type; } }; diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index 2edff82e1..fde6adacc 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -133,7 +133,7 @@ set CompilerContext::getFunctionsWithoutCode() for (auto const& it: m_functionEntryLabels) if (m_functionsWithCode.count(it.first) == 0) functions.insert(it.first); - return move(functions); + return functions; } ModifierDefinition const& CompilerContext::getFunctionModifier(string const& _name) const diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 1316bbc37..e1161c3fb 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -1459,29 +1459,29 @@ MagicType::MagicType(MagicType::Kind _kind): switch (m_kind) { case Kind::Block: - m_members = move(MemberList({ + m_members = MemberList({ {"coinbase", make_shared(0, IntegerType::Modifier::Address)}, {"timestamp", make_shared(256)}, {"blockhash", make_shared(strings{"uint"}, strings{"bytes32"}, FunctionType::Location::BlockHash)}, {"difficulty", make_shared(256)}, {"number", make_shared(256)}, {"gaslimit", make_shared(256)} - })); + }); break; case Kind::Message: - m_members = move(MemberList({ + m_members = MemberList({ {"sender", make_shared(0, IntegerType::Modifier::Address)}, {"gas", make_shared(256)}, {"value", make_shared(256)}, {"data", make_shared(ReferenceType::Location::CallData)}, {"sig", make_shared(4)} - })); + }); break; case Kind::Transaction: - m_members = move(MemberList({ + m_members = MemberList({ {"origin", make_shared(0, IntegerType::Modifier::Address)}, {"gasprice", make_shared(256)} - })); + }); break; default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic.")); diff --git a/test/libp2p/net.cpp b/test/libp2p/net.cpp index 1cd43b13f..a31537b98 100644 --- a/test/libp2p/net.cpp +++ b/test/libp2p/net.cpp @@ -74,7 +74,7 @@ struct TestNodeTable: public NodeTable ret.push_back(make_pair(k,s_basePort+i)); } - return std::move(ret); + return ret; } void pingTestNodes(std::vector> const& _testNodes) diff --git a/test/libwhisper/whisperMessage.cpp b/test/libwhisper/whisperMessage.cpp index 56a763622..343573713 100644 --- a/test/libwhisper/whisperMessage.cpp +++ b/test/libwhisper/whisperMessage.cpp @@ -37,7 +37,7 @@ Topics createRandomTopics(unsigned int i) ret.push_back(t); } - return move(ret); + return ret; } bytes createRandomPayload(unsigned int i) @@ -48,7 +48,7 @@ bytes createRandomPayload(unsigned int i) for (int j = 0; j < sz; ++j) ret.push_back(rand() % 256); - return move(ret); + return ret; } void comparePayloads(Message const& m1, Message const& m2) From eb75d800d838ab47774574b27ffca38e4387c4fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 8 Jun 2015 12:12:36 +0200 Subject: [PATCH 04/36] Remove unused typedef. --- json_spirit/json_spirit_writer_template.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/json_spirit/json_spirit_writer_template.h b/json_spirit/json_spirit_writer_template.h index dbd0f45da..5376ef476 100644 --- a/json_spirit/json_spirit_writer_template.h +++ b/json_spirit/json_spirit_writer_template.h @@ -25,13 +25,9 @@ namespace json_spirit return 'A' - 10 + ch; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-local-typedefs") template< class String_type > String_type non_printable_to_string( unsigned int c ) { - typedef typename String_type::value_type Char_type; - String_type result( 6, '\\' ); result[1] = 'u'; @@ -43,7 +39,6 @@ namespace json_spirit return result; } -#pragma GCC diagnostic pop template< typename Char_type, class String_type > bool add_esc_char( Char_type c, String_type& s ) From a9f3df90b14d882b629920f8c6163dc91b4bbb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 8 Jun 2015 12:13:44 +0200 Subject: [PATCH 05/36] Add missing override specifiers. --- alethzero/MainWin.h | 2 +- alethzero/NatspecHandler.h | 6 +++--- libethereum/Client.h | 4 ++-- libethereum/ClientBase.h | 7 ++----- libsolidity/AST.h | 2 +- libsolidity/LValue.h | 2 +- libsolidity/Types.h | 4 ++-- libtestutils/FixedClient.h | 2 +- libweb3jsonrpc/WebThreeStubServer.h | 2 +- libwhisper/WhisperHost.h | 8 ++++---- mix/CodeModel.cpp | 2 +- mix/MixClient.h | 2 +- 12 files changed, 20 insertions(+), 23 deletions(-) diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 193f8e364..efff89d2b 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -238,7 +238,7 @@ private: void installNameRegWatch(); void installBalancesWatch(); - virtual void timerEvent(QTimerEvent*); + virtual void timerEvent(QTimerEvent*) override; void refreshNetwork(); void refreshMining(); diff --git a/alethzero/NatspecHandler.h b/alethzero/NatspecHandler.h index 7aeafec41..241df4e06 100644 --- a/alethzero/NatspecHandler.h +++ b/alethzero/NatspecHandler.h @@ -39,17 +39,17 @@ class NatspecHandler: public NatSpecFace ~NatspecHandler(); /// Stores locally in a levelDB a key value pair of contract code hash to natspec documentation - void add(dev::h256 const& _contractHash, std::string const& _doc); + virtual void add(dev::h256 const& _contractHash, std::string const& _doc) override; /// Retrieves the natspec documentation as a string given a contract code hash std::string retrieve(dev::h256 const& _contractHash) const override; /// Given a json natspec string and the transaction data return the user notice - std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData); + virtual std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData) override; /// Given a contract code hash and the transaction's data retrieve the natspec documention's /// user notice for that transaction. /// @returns The user notice or an empty string if no natspec for the contract exists /// or if the existing natspec does not document the @c _methodName - std::string getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionDacta); + virtual std::string getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionDacta) override; private: ldb::ReadOptions m_readOptions; diff --git a/libethereum/Client.h b/libethereum/Client.h index 5132b5a30..87209a667 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -143,7 +143,7 @@ public: ExecutionResult call(Address _dest, bytes const& _data = bytes(), u256 _gas = 125000, u256 _value = 0, u256 _gasPrice = 1 * ether, Address const& _from = Address()); /// Get the remaining gas limit in this block. - virtual u256 gasLimitRemaining() const { return m_postMine.gasLimitRemaining(); } + virtual u256 gasLimitRemaining() const override { return m_postMine.gasLimitRemaining(); } // [PRIVATE API - only relevant for base clients, not available in general] dev::eth::State state(unsigned _txi, h256 _block) const; @@ -159,7 +159,7 @@ public: // Mining stuff: - void setAddress(Address _us) { WriteGuard l(x_preMine); m_preMine.setAddress(_us); } + virtual void setAddress(Address _us) override { WriteGuard l(x_preMine); m_preMine.setAddress(_us); } /// Check block validity prior to mining. bool miningParanoia() const { return m_paranoia; } diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 2b271b1df..c55dae96d 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -132,8 +132,8 @@ public: virtual Transactions pending() const override; virtual h256s pendingHashes() const override; - ImportResult injectTransaction(bytes const& _rlp) override { prepareForTransaction(); return m_tq.import(_rlp); } - ImportResult injectBlock(bytes const& _block); + virtual ImportResult injectTransaction(bytes const& _rlp) override { prepareForTransaction(); return m_tq.import(_rlp); } + virtual ImportResult injectBlock(bytes const& _block) override; using Interface::diff; virtual StateDiff diff(unsigned _txi, h256 _block) const override; @@ -143,9 +143,6 @@ public: virtual Addresses addresses(BlockNumber _block) const override; virtual u256 gasLimitRemaining() const override; - /// Set the coinbase address - virtual void setAddress(Address _us) = 0; - /// Get the coinbase address virtual Address address() const override; diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 578709c1e..b3984840f 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -503,7 +503,7 @@ public: /// Returns the declared or inferred type. Can be an empty pointer if no type was explicitly /// declared and there is no assignment to the variable that fixes the type. - TypePointer getType(ContractDefinition const* = nullptr) const { return m_type; } + TypePointer getType(ContractDefinition const* = nullptr) const override { return m_type; } void setType(std::shared_ptr const& _type) { m_type = _type; } virtual bool isLValue() const override; diff --git a/libsolidity/LValue.h b/libsolidity/LValue.h index 1617e8167..726d63328 100644 --- a/libsolidity/LValue.h +++ b/libsolidity/LValue.h @@ -109,7 +109,7 @@ public: StorageItem(CompilerContext& _compilerContext, Declaration const& _declaration); /// Constructs the LValue and assumes that the storage reference is already on the stack. StorageItem(CompilerContext& _compilerContext, Type const& _type); - virtual unsigned sizeOnStack() const { return 2; } + virtual unsigned sizeOnStack() const override { return 2; } virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override; virtual void storeValue( Type const& _sourceType, diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 3ec925395..17d30ea6c 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -407,7 +407,7 @@ public: virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(const Type& _other) const override; virtual unsigned getCalldataEncodedSize(bool _padded) const override; - virtual bool isDynamicallySized() const { return m_hasDynamicLength; } + virtual bool isDynamicallySized() const override { return m_hasDynamicLength; } virtual u256 getStorageSize() const override; virtual unsigned getSizeOnStack() const override; virtual std::string toString() const override; @@ -820,7 +820,7 @@ public: return TypePointer(); } - virtual bool operator==(Type const& _other) const; + virtual bool operator==(Type const& _other) const override; virtual bool canBeStored() const override { return false; } virtual bool canLiveOutsideStorage() const override { return true; } virtual unsigned getSizeOnStack() const override { return 0; } diff --git a/libtestutils/FixedClient.h b/libtestutils/FixedClient.h index 59da9075f..bdec08849 100644 --- a/libtestutils/FixedClient.h +++ b/libtestutils/FixedClient.h @@ -48,7 +48,7 @@ public: virtual eth::State asOf(h256 const& _h) const override; virtual eth::State preMine() const override { ReadGuard l(x_stateDB); return m_state; } virtual eth::State postMine() const override { ReadGuard l(x_stateDB); return m_state; } - virtual void setAddress(Address _us) { WriteGuard l(x_stateDB); m_state.setAddress(_us); } + virtual void setAddress(Address _us) override { WriteGuard l(x_stateDB); m_state.setAddress(_us); } virtual void prepareForTransaction() override {} private: diff --git a/libweb3jsonrpc/WebThreeStubServer.h b/libweb3jsonrpc/WebThreeStubServer.h index 35c35c3f0..1eddc22d4 100644 --- a/libweb3jsonrpc/WebThreeStubServer.h +++ b/libweb3jsonrpc/WebThreeStubServer.h @@ -43,7 +43,7 @@ class WebThreeStubServer: public dev::WebThreeStubServerBase, public dev::WebThr public: WebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::shared_ptr const& _ethAccounts, std::vector const& _shhAccounts); - virtual std::string web3_clientVersion(); + virtual std::string web3_clientVersion() override; private: virtual dev::eth::Interface* client() override; diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h index c5ec5867b..87563d9e8 100644 --- a/libwhisper/WhisperHost.h +++ b/libwhisper/WhisperHost.h @@ -54,7 +54,7 @@ public: virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr) override; - virtual Topics const& fullTopics(unsigned _id) const { try { return m_filters.at(m_watches.at(_id).id).full; } catch (...) { return EmptyTopics; } } + virtual Topics const& fullTopics(unsigned _id) const override { try { return m_filters.at(m_watches.at(_id).id).full; } catch (...) { return EmptyTopics; } } virtual unsigned installWatch(Topics const& _filter) override; virtual unsigned installWatchOnId(h256 _filterId) override; virtual void uninstallWatch(unsigned _watchId) override; @@ -69,11 +69,11 @@ public: void cleanup(); protected: - void doWork(); + virtual void doWork() override; private: - virtual void onStarting() { startWorking(); } - virtual void onStopping() { stopWorking(); } + virtual void onStarting() override { startWorking(); } + virtual void onStopping() override { stopWorking(); } void streamMessage(h256 _m, RLPStream& _s) const; diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 434cf1e7d..1ca5d9160 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -67,7 +67,7 @@ private: return LocationPair(_node.getLocation().start, _node.getLocation().end); } - virtual bool visit(FunctionDefinition const&) + virtual bool visit(FunctionDefinition const&) override { m_functionScope = true; return true; diff --git a/mix/MixClient.h b/mix/MixClient.h index 4c5b51a09..ea6416ac4 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -80,7 +80,7 @@ protected: /// ClientBase methods using ClientBase::asOf; virtual dev::eth::State asOf(h256 const& _block) const override; - virtual dev::eth::BlockChain& bc() { return *m_bc; } + virtual dev::eth::BlockChain& bc() override { return *m_bc; } virtual dev::eth::BlockChain const& bc() const override { return *m_bc; } virtual dev::eth::State preMine() const override { ReadGuard l(x_state); return m_startState; } virtual dev::eth::State postMine() const override { ReadGuard l(x_state); return m_state; } From 2a6f84dc0a5db8129049aa0bbbae5e51198c48e6 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 8 Jun 2015 12:39:07 +0200 Subject: [PATCH 06/36] all precompiled contracts tests as CALLCODE --- .../stPreCompiledContractsFiller.json | 1800 +++++++++++++++++ 1 file changed, 1800 insertions(+) diff --git a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json index c28c607b7..77ed3e0a1 100644 --- a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json +++ b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json @@ -1803,6 +1803,1806 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } + }, + + "CALLCODEEcrecover0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x01" : "0x01", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecoverH_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa0b29af6a56d6cfef6415cb195ccbe540e006d0a", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecoverV_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x01" : "0x01", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 0x001c) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecoverR_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x3f17f1962b36e491b30a40b2405849e597ba5fb5", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecoverS_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xb4950a7fad428434b11c357fa6d4b4bcd3096a5d", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover80": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x3f17f1962b36e491b30a40b2405849e597ba5fb5", + "0x01" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover0_overlappingInputOutput": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x01" : "0x01", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 300000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + + "CALLCODEEcrecover0_completeReturnValue": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 3000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover0_gas3000": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x01" : "0x01", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 3000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover0_NoGas": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0xb0a0" + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 0 1 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover0_Gas2999": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x02" : "0x00" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 2999 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover0_0input": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3652240", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALLCODE 100000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEEcrecover3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xe4319f4b631c6d0fcfc84045dbcb676865fe5e13", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALLCODE 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x600160005260206000602060006000600260fff2600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALLCODE 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_1_nonzeroValue": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "200000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALLCODE 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_3_prefix0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_3_postfix0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x3b745a1c00d035c334f358d007a430e4cf0ae63aa0556fb05529706de546464d", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_4": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_4_gas99": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODESha256_5": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x600160005260206000602060006000600360fff2600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x9c1185a5c5e9fc54612808977ee8f548b2258d31", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALLCODE 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0xdbc100f916bfbc53535573d98cf0cbb3a5b36124", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_3_prefixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_3_postfixed0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0x7730b4642169b0f16752696da8da830a4b429c9d", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_4": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0x1cf4e77f5966e13e109703cd8a0df7ceda7f3dc3", + "0x02" : "0x01" } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 720 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_4_gas719": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 719 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODERipemd160_5": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 6000 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentitiy_0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0000000000000000000000000000000000000000000000000000000000000001" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x600160005260206000602060006000600460fff2600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentitiy_1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALLCODE 500 4 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_1_nonzeroValue": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "200000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALLCODE 200000 4 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x000000000000000000000000000000000000000000000000000000f34578907f", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x000000000000000000000000000000000000000000000000000000f34578907f", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_4": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 100 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_4_gas18": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 18 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_4_gas17": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x02" : "0x00" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 17 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CALLCODEIdentity_5": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 600 4 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } } } From 206e456ba21567593a9b5cdc827da6cd019eae86 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 8 Jun 2015 12:54:11 +0200 Subject: [PATCH 07/36] add sec80 test as provided by sec --- .../stPreCompiledContractsFiller.json | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json index 77ed3e0a1..1c870c543 100644 --- a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json +++ b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json @@ -3603,6 +3603,47 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - } + }, + + "sec80": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x00" : "0xc001f00d" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x601b565b6000555b005b630badf00d6003565b63c001f00d6003565b7319e7e376e7c213b7e7e7e46cc70a5dd086daff2a7f22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda600052601b603f537f16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f6040527f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e40060605260206080607f60006000600161fffff21560075760805114601257600956", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, } From e81fc1e68fd8fe233b1b0a88c64bf58d3677c9aa Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 8 Jun 2015 23:28:46 +0900 Subject: [PATCH 08/36] Minor debug alterations/fixes for blockchain downloading to make it play marginally better with the braindead Go strategy. Import key without address. --- alethzero/MainWin.cpp | 8 +++--- ethkey/KeyAux.h | 39 ++++++++++++++++++++++++++- libdevcore/CommonData.cpp | 52 +++++++++++++++++------------------- libdevcore/CommonData.h | 2 +- libdevcrypto/SecretStore.cpp | 2 +- libethcore/KeyManager.cpp | 23 +++++++++------- libethcore/KeyManager.h | 11 +++++--- libethereum/CommonNet.h | 6 +++-- libethereum/EthereumHost.cpp | 4 ++- libethereum/EthereumPeer.cpp | 4 +-- 10 files changed, 98 insertions(+), 53 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 10038a80e..93054fd67 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -2114,14 +2114,14 @@ void Main::on_reencryptKey_triggered() auto pw = [&](){ auto p = QInputDialog::getText(this, "Re-Encrypt Key", "Enter the original password for this key.\nHint: " + QString::fromStdString(m_keyManager.hint(a)), QLineEdit::Password, QString()).toStdString(); if (p.empty()) - throw UnknownPassword(); + throw PasswordUnknown(); return p; }; while (!(password.empty() ? m_keyManager.recode(a, SemanticPassword::Master, pw, kdf) : m_keyManager.recode(a, password, hint, pw, kdf))) if (QMessageBox::question(this, "Re-Encrypt Key", "Password given is incorrect. Would you like to try again?", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel) return; } - catch (UnknownPassword&) {} + catch (PasswordUnknown&) {} } } @@ -2137,13 +2137,13 @@ void Main::on_reencryptAll_triggered() while (!m_keyManager.recode(a, SemanticPassword::Existing, [&](){ auto p = QInputDialog::getText(nullptr, "Re-Encrypt Key", QString("Enter the original password for key %1.\nHint: %2").arg(QString::fromStdString(pretty(a))).arg(QString::fromStdString(m_keyManager.hint(a))), QLineEdit::Password, QString()).toStdString(); if (p.empty()) - throw UnknownPassword(); + throw PasswordUnknown(); return p; }, (KDF)kdfs.indexOf(kdf))) if (QMessageBox::question(this, "Re-Encrypt Key", "Password given is incorrect. Would you like to try again?", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel) return; } - catch (UnknownPassword&) {} + catch (PasswordUnknown&) {} } void Main::on_go_triggered() diff --git a/ethkey/KeyAux.h b/ethkey/KeyAux.h index 639e1d4f4..d2ec13b2a 100644 --- a/ethkey/KeyAux.h +++ b/ethkey/KeyAux.h @@ -102,6 +102,7 @@ public: List, New, Import, + ImportWithAddress, Export, Recode, Kill @@ -159,6 +160,13 @@ public: m_inputs = strings(1, argv[++i]); m_name = argv[++i]; } + else if ((arg == "-i" || arg == "--import-with-address") && i + 3 < argc) + { + m_mode = OperationMode::ImportWithAddress; + m_inputs = strings(1, argv[++i]); + m_address = Address(argv[++i]); + m_name = argv[++i]; + } else if (arg == "--export") m_mode = OperationMode::Export; else if (arg == "--recode") @@ -314,6 +322,33 @@ public: cout << " ICAP: " << ICAP(k.address()).encoded() << endl; break; } + case OperationMode::ImportWithAddress: + { + string const& i = m_inputs[0]; + h128 u; + bytes b; + b = fromHex(i); + if (b.size() != 32) + { + std::string s = contentsString(i); + b = fromHex(s); + if (b.size() != 32) + u = wallet.store().importKey(i); + } + if (!u && b.size() == 32) + u = wallet.store().importSecret(b, lockPassword(toAddress(Secret(b)).abridged())); + if (!u) + { + cerr << "Cannot import " << i << " not a file or secret." << endl; + break; + } + wallet.importExisting(u, m_name, m_address); + cout << "Successfully imported " << i << ":" << endl; + cout << " Name: " << m_name << endl; + cout << " Address: " << m_address << endl; + cout << " UUID: " << toUUID(u) << endl; + break; + } case OperationMode::List: { vector bare; @@ -369,6 +404,7 @@ public: << " -l,--list List all keys available in wallet." << endl << " -n,--new Create a new key with given name and add it in the wallet." << endl << " -i,--import [||] Import keys from given source and place in wallet." << endl + << " --import-with-address [||]
Import keys from given source with given address and place in wallet." << endl << " -e,--export [
| , ... ] Export given keys." << endl << " -r,--recode [
|| , ... ] Decrypt and re-encrypt given keys." << endl << "Wallet configuration:" << endl @@ -418,8 +454,9 @@ private: string m_lockHint; bool m_icap = true; - /// Creating + /// Creating/importing string m_name; + Address m_address; /// Importing strings m_inputs; diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index f8d8c172f..2d6333f26 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -67,7 +67,7 @@ std::string dev::randomWord() return ret; } -int dev::fromHex(char _i) +int dev::fromHex(char _i, WhenError _throw) { if (_i >= '0' && _i <= '9') return _i - '0'; @@ -75,7 +75,10 @@ int dev::fromHex(char _i) return _i - 'a' + 10; if (_i >= 'A' && _i <= 'F') return _i - 'A' + 10; - BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); + if (_throw == WhenError::Throw) + BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i)); + else + return -1; } bytes dev::fromHex(std::string const& _s, WhenError _throw) @@ -85,33 +88,26 @@ bytes dev::fromHex(std::string const& _s, WhenError _throw) ret.reserve((_s.size() - s + 1) / 2); if (_s.size() % 2) - try - { - ret.push_back(fromHex(_s[s++])); - } - catch (...) - { - ret.push_back(0); - // msvc does not support it -#ifndef BOOST_NO_EXCEPTIONS - cwarn << boost::current_exception_diagnostic_information(); -#endif - if (_throw == WhenError::Throw) - throw; - } + { + int h = fromHex(_s[s++], WhenError::DontThrow); + if (h != -1) + ret.push_back(h); + else if (_throw == WhenError::Throw) + throw BadHexCharacter(); + else + return bytes(); + } for (unsigned i = s; i < _s.size(); i += 2) - try - { - ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1]))); - } - catch (...){ - ret.push_back(0); -#ifndef BOOST_NO_EXCEPTIONS - cwarn << boost::current_exception_diagnostic_information(); -#endif - if (_throw == WhenError::Throw) - throw; - } + { + int h = fromHex(_s[i], WhenError::DontThrow); + int l = fromHex(_s[i + 1], WhenError::DontThrow); + if (h != -1 && l != -1) + ret.push_back((byte)(h * 16 + l)); + else if (_throw == WhenError::Throw) + throw BadHexCharacter(); + else + return bytes(); + } return ret; } diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index e1d8d7bdb..ddc00e09f 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -61,7 +61,7 @@ std::string toHex(_T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::Do /// Converts a (printable) ASCII hex character into the correspnding integer value. /// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5 -int fromHex(char _i); +int fromHex(char _i, WhenError _throw); /// Converts a (printable) ASCII hex string into the corresponding byte stream. /// @example fromHex("41626261") == asBytes("Abba") diff --git a/libdevcrypto/SecretStore.cpp b/libdevcrypto/SecretStore.cpp index 11ff98bf6..b9d4ccfc6 100644 --- a/libdevcrypto/SecretStore.cpp +++ b/libdevcrypto/SecretStore.cpp @@ -164,7 +164,7 @@ void SecretStore::load(std::string const& _keysPath) h128 SecretStore::readKey(std::string const& _file, bool _deleteFile) { - cdebug << "Reading" << _file; + cnote << "Reading" << _file; return readKeyContent(contentsString(_file), _deleteFile ? _file : string()); } diff --git a/libethcore/KeyManager.cpp b/libethcore/KeyManager.cpp index 182201301..4430a588e 100644 --- a/libethcore/KeyManager.cpp +++ b/libethcore/KeyManager.cpp @@ -89,18 +89,18 @@ bool KeyManager::load(std::string const& _pass) for (auto const& i: s[1]) { m_keyInfo[m_addrLookup[(Address)i[0]] = (h128)i[1]] = KeyInfo((h256)i[2], (std::string)i[3]); - cdebug << toString((Address)i[0]) << toString((h128)i[1]) << toString((h256)i[2]) << (std::string)i[3]; +// cdebug << toString((Address)i[0]) << toString((h128)i[1]) << toString((h256)i[2]) << (std::string)i[3]; } for (auto const& i: s[2]) m_passwordInfo[(h256)i[0]] = (std::string)i[1]; m_password = (string)s[3]; } - cdebug << hashPassword(m_password) << toHex(m_password); +// cdebug << hashPassword(m_password) << toHex(m_password); m_cachedPasswords[hashPassword(m_password)] = m_password; - cdebug << hashPassword(asString(m_key.ref())) << m_key.hex(); +// cdebug << hashPassword(asString(m_key.ref())) << m_key.hex(); m_cachedPasswords[hashPassword(asString(m_key.ref()))] = asString(m_key.ref()); - cdebug << hashPassword(_pass) << _pass; +// cdebug << hashPassword(_pass) << _pass; m_cachedPasswords[m_master = hashPassword(_pass)] = _pass; return true; } @@ -141,7 +141,7 @@ std::string KeyManager::getPassword(h256 const& _passHash, function const& _pass = DontKnowThrow) const; Secret secret(h128 const& _uuid, std::function const& _pass = DontKnowThrow) const; diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h index a2f4a2e7c..8cf2647cf 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -38,14 +38,16 @@ namespace eth #if ETH_DEBUG static const unsigned c_maxHashes = 2048; ///< Maximum number of hashes BlockHashes will ever send. -static const unsigned c_maxHashesAsk = 2048; ///< Maximum number of hashes GetBlockHashes will ever ask for. +static const unsigned c_maxHashesAsk = 256; ///< Maximum number of hashes GetBlockHashes will ever ask for. static const unsigned c_maxBlocks = 128; ///< Maximum number of blocks Blocks will ever send. -static const unsigned c_maxBlocksAsk = 128; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain). +static const unsigned c_maxBlocksAsk = 8; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain). +static const unsigned c_maxPayload = 262144; ///< Maximum size of packet for us to send. #else static const unsigned c_maxHashes = 2048; ///< Maximum number of hashes BlockHashes will ever send. static const unsigned c_maxHashesAsk = 2048; ///< Maximum number of hashes GetBlockHashes will ever ask for. static const unsigned c_maxBlocks = 128; ///< Maximum number of blocks Blocks will ever send. static const unsigned c_maxBlocksAsk = 128; ///< Maximum number of blocks we ask to receive in Blocks (when using GetChain). +static const unsigned c_maxPayload = 262144; ///< Maximum size of packet for us to send. #endif class BlockChain; diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 3965a214e..7c9b730ea 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -253,7 +253,9 @@ void EthereumHost::onPeerStatus(EthereumPeer* _peer) if (_peer->m_protocolVersion != protocolVersion()) estimatePeerHashes(_peer); else if (_peer->m_latestBlockNumber > m_chain.number()) - _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number(); + _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number() + 1000; + else + _peer->m_expectedHashes = 1000; if (m_hashMan.chainSize() < _peer->m_expectedHashes) m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); continueSync(_peer); diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index d6b0b50c3..a332e5b93 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -263,7 +263,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) // return the requested blocks. bytes rlp; unsigned n = 0; - for (unsigned i = 0; i < min(count, c_maxBlocks); ++i) + for (unsigned i = 0; i < min(count, c_maxBlocks) && rlp.size() < c_maxPayload; ++i) { auto h = _r[i].toHash(); if (host()->chain().isKnown(h)) @@ -286,7 +286,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) case BlocksPacket: { if (m_asking != Asking::Blocks) - clog(NetWarn) << "Peer giving us blocks when we didn't ask for them."; + clog(NetImpolite) << "Peer giving us blocks when we didn't ask for them."; else { setAsking(Asking::Nothing); From baf10f84b3324f0e641d7c7c2d941ae587a26ba0 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 8 Jun 2015 16:30:13 +0200 Subject: [PATCH 09/36] move test from stSpecialTest to transaction test --- .../StateTestsFiller/stSpecialTestFiller.json | 38 ------------------- .../ttTransactionTestFiller.json | 15 ++++++++ 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/test/libethereum/StateTestsFiller/stSpecialTestFiller.json b/test/libethereum/StateTestsFiller/stSpecialTestFiller.json index aeaebefd8..8dee4af11 100644 --- a/test/libethereum/StateTestsFiller/stSpecialTestFiller.json +++ b/test/libethereum/StateTestsFiller/stSpecialTestFiller.json @@ -194,44 +194,6 @@ } }, - "txfrom0_deja" : { - "env" : { - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "256", - "currentGasLimit" : "1000000", - "currentNumber" : "0", - "currentTimestamp" : 1, - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "1000000000000000000", - "code" : "0x6042601f53600064ffffffffff2080", - "nonce" : "0", - "storage" : { - } - }, - "0000000000000000000000000000000000000000" : { - "balance" : "1000000000000000000", - "code" : "0x", - "nonce" : "0", - "storage" : { - } - } - }, - "transaction" : { - "data" : "", - "gasLimit" : "1000000", - "gasPrice" : "0", - "nonce" : "0", - "r" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "s" : "0xbadf00d70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", - "v": "27", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "100000" - } - }, - "JUMPDEST_Attack" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", diff --git a/test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json b/test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json index 410434d1d..c5789f859 100644 --- a/test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json +++ b/test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json @@ -15,6 +15,21 @@ } }, + "invalidSignature" : { + "expect" : "invalid", + "transaction" : { + "data" : "", + "gasLimit" : "1000000", + "gasPrice" : "0", + "nonce" : "0", + "r" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "s" : "0xbadf00d70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", + "v": "27", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000" + } + }, + "NotEnoughGasLimit" : { "expect" : "invalid", "transaction" : From 1f9330a29c3791d4a4ae5e6e0561e4e6f8cd97c1 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 8 Jun 2015 23:54:16 +0900 Subject: [PATCH 10/36] Avoid divide by zero. --- alethzero/Transact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index e61092f33..fd466e475 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -360,7 +360,7 @@ void Transact::rejigData() return; } else - gasNeeded = (qint64)min(ethereum()->gasLimitRemaining(), ((b - value()) / gasPrice())); + gasNeeded = (qint64)min(ethereum()->gasLimitRemaining(), ((b - value()) / max(gasPrice(), 1))); // Dry-run execution to determine gas requirement and any execution errors Address to; From 3589c73b75937a4cba202e872d7b0269f035448a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 8 Jun 2015 23:54:42 +0900 Subject: [PATCH 11/36] Version bump. --- libdevcore/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index cb9b94de8..3dc3fd280 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -28,7 +28,7 @@ using namespace dev; namespace dev { -char const* Version = "0.9.23"; +char const* Version = "0.9.24"; const u256 UndefinedU256 = ~(u256)0; From 0c63c925039b1ee4fde08cf4c1b6e0ff9dc6da44 Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 8 Jun 2015 17:11:40 +0200 Subject: [PATCH 12/36] request hashes from all peers initially, pv61+ priority --- libethereum/EthereumHost.cpp | 73 +++++++++++++++++++++++++++--------- libethereum/EthereumHost.h | 5 ++- libethereum/EthereumPeer.cpp | 15 ++++---- libethereum/EthereumPeer.h | 5 ++- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 3965a214e..8b2427e42 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -237,7 +237,7 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) void EthereumHost::onPeerStatus(EthereumPeer* _peer) { - Guard l(x_sync); + RecursiveGuard l(x_sync); if (_peer->m_genesisHash != m_chain.genesisHash()) _peer->disable("Invalid genesis hash"); else if (_peer->m_protocolVersion != protocolVersion() && _peer->m_protocolVersion != c_oldProtocolVersion) @@ -252,10 +252,13 @@ void EthereumHost::onPeerStatus(EthereumPeer* _peer) { if (_peer->m_protocolVersion != protocolVersion()) estimatePeerHashes(_peer); - else if (_peer->m_latestBlockNumber > m_chain.number()) + else + { + if (_peer->m_latestBlockNumber > m_chain.number()) _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number(); - if (m_hashMan.chainSize() < _peer->m_expectedHashes) - m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); + if (m_hashMan.chainSize() < _peer->m_expectedHashes) + m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); + } continueSync(_peer); } } @@ -265,7 +268,7 @@ void EthereumHost::estimatePeerHashes(EthereumPeer* _peer) BlockInfo block = m_chain.info(); time_t lastBlockTime = (block.hash() == m_chain.genesisHash()) ? 1428192000 : (time_t)block.timestamp; time_t now = time(0); - unsigned blockCount = 1000; + unsigned blockCount = 30000; if (lastBlockTime > now) clog(NetWarn) << "Clock skew? Latest block is in the future"; else @@ -276,7 +279,7 @@ void EthereumHost::estimatePeerHashes(EthereumPeer* _peer) void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes) { - Guard l(x_sync); + RecursiveGuard l(x_sync); assert(_peer->m_asking == Asking::Nothing); onPeerHashes(_peer, _hashes, false); } @@ -285,13 +288,22 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool { if (_hashes.empty()) { - onPeerDoneHashes(_peer, true); + continueSync(); return; } + + bool syncByNumber = _peer->m_syncHashNumber; + if (!syncByNumber && _peer->m_latestHash != m_syncingLatestHash) + { + // Obsolete hashes, discard + continueSync(_peer); + return; + } + unsigned knowns = 0; unsigned unknowns = 0; h256s neededBlocks; - bool syncByNumber = !m_syncingLatestHash; + unsigned firstNumber = _peer->m_syncHashNumber - _hashes.size(); for (unsigned i = 0; i < _hashes.size(); ++i) { _peer->addRating(1); @@ -321,8 +333,11 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool } else knowns++; + if (!syncByNumber) m_syncingLatestHash = h; + else + _peer->m_hashSub.noteHash(firstNumber + i, 1); } if (syncByNumber) { @@ -368,13 +383,14 @@ void EthereumHost::onPeerDoneHashes(EthereumPeer* _peer, bool _localChain) { m_man.resetToChain(m_hashes); m_hashes.clear(); + m_hashMan.reset(m_chain.number() + 1); } continueSync(); } void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r) { - Guard l(x_sync); + RecursiveGuard l(x_sync); assert(_peer->m_asking == Asking::Nothing); unsigned itemCount = _r.itemCount(); clog(NetMessageSummary) << "Blocks (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBlocks"); @@ -450,7 +466,7 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r) void EthereumHost::onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes) { - Guard l(x_sync); + RecursiveGuard l(x_sync); if (isSyncing_UNSAFE()) { clog(NetMessageSummary) << "Ignoring new hashes since we're already downloading."; @@ -462,7 +478,7 @@ void EthereumHost::onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes) void EthereumHost::onPeerNewBlock(EthereumPeer* _peer, RLP const& _r) { - Guard l(x_sync); + RecursiveGuard l(x_sync); if (isSyncing_UNSAFE()) { clog(NetMessageSummary) << "Ignoring new blocks since we're already downloading."; @@ -549,6 +565,16 @@ void EthereumHost::onPeerTransactions(EthereumPeer* _peer, RLP const& _r) } } +void EthereumHost::onPeerAborting(EthereumPeer* _peer) +{ + RecursiveGuard l(x_sync); + if (_peer->isSyncing()) + { + _peer->setIdle(); + continueSync(); + } +} + void EthereumHost::continueSync() { clog(NetAllDetail) << "Getting help with downloading hashes and blocks"; @@ -562,21 +588,33 @@ void EthereumHost::continueSync() void EthereumHost::continueSync(EthereumPeer* _peer) { assert(_peer->m_asking == Asking::Nothing); - bool otherPeerSync = false; + bool otherPeerV60Sync = false; + bool otherPeerV61Sync = false; if (m_needSyncHashes && peerShouldGrabChain(_peer)) { foreachPeer([&](EthereumPeer* _p) { - if (_p != _peer && _p->m_asking == Asking::Hashes && _p->m_protocolVersion != protocolVersion()) - otherPeerSync = true; // Already have a peer downloading hash chain with old protocol, do nothing + if (_p != _peer && _p->m_asking == Asking::Hashes) + { + if (_p->m_protocolVersion != protocolVersion()) + otherPeerV60Sync = true; // Already have a peer downloading hash chain with old protocol, do nothing + else + otherPeerV61Sync = true; // Already have a peer downloading hash chain with V61+ protocol, join if supported + } }); - if (otherPeerSync) + if (otherPeerV60Sync && !m_hashes.empty()) { /// Downloading from other peer with v60 protocol, nothing ese we can do _peer->setIdle(); return; } - if (_peer->m_protocolVersion == protocolVersion() && !m_syncingLatestHash) + if (otherPeerV61Sync && _peer->m_protocolVersion != protocolVersion()) + { + /// Downloading from other peer with v61+ protocol which this peer does not support, + _peer->setIdle(); + return; + } + if (_peer->m_protocolVersion == protocolVersion() && !m_hashMan.isComplete()) _peer->requestHashes(); /// v61+ and not catching up to a particular hash else { @@ -586,7 +624,8 @@ void EthereumHost::continueSync(EthereumPeer* _peer) m_syncingLatestHash =_peer->m_latestHash; m_syncingTotalDifficulty = _peer->m_totalDifficulty; } - _peer->requestHashes(m_syncingLatestHash); + if (_peer->m_totalDifficulty >= m_syncingTotalDifficulty) + _peer->requestHashes(m_syncingLatestHash); } } else if (m_needSyncBlocks && peerShouldGrabBlocks(_peer)) // Check if this peer can help with downloading blocks diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index 8ca815a17..d9628de3a 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -70,7 +70,7 @@ public: void reset(); DownloadMan const& downloadMan() const { return m_man; } - bool isSyncing() const { Guard l(x_sync); return isSyncing_UNSAFE(); } + bool isSyncing() const { RecursiveGuard l(x_sync); return isSyncing_UNSAFE(); } bool isBanned(p2p::NodeId _id) const { return !!m_banned.count(_id); } void noteNewTransactions() { m_newTransactions = true; } @@ -82,6 +82,7 @@ public: void onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes); ///< Called by peer once it has new hashes void onPeerHashes(EthereumPeer* _peer, h256s const& _hashes); ///< Called by peer once it has another sequential block of hashes during sync void onPeerTransactions(EthereumPeer* _peer, RLP const& _r); ///< Called by peer when it has new transactions + void onPeerAborting(EthereumPeer* _peer); ///< Called by peer when it is disconnecting DownloadMan& downloadMan() { return m_man; } HashDownloadMan& hashDownloadMan() { return m_hashMan; } @@ -141,7 +142,7 @@ private: bool m_newTransactions = false; bool m_newBlocks = false; - mutable Mutex x_sync; + mutable RecursiveMutex x_sync; bool m_needSyncHashes = true; ///< Indicates if need to downlad hashes bool m_needSyncBlocks = true; ///< Indicates if we still need to download some blocks h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync. diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index d6b0b50c3..72015a5e9 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -40,7 +40,6 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h, unsigned _i, Cap m_hashSub(host()->hashDownloadMan()), m_peerCapabilityVersion(_cap.second) { - m_syncHashNumber = host()->chain().number() + 1; requestStatus(); } @@ -52,8 +51,7 @@ EthereumPeer::~EthereumPeer() void EthereumPeer::abortSync() { - if (isSyncing()) - setIdle(); + host()->onPeerAborting(this); } EthereumHost* EthereumPeer::host() const @@ -105,6 +103,7 @@ void EthereumPeer::requestHashes() { assert(m_asking == Asking::Nothing); m_syncHashNumber = m_hashSub.nextFetch(c_maxHashesAsk); + m_syncHash = h256(); setAsking(Asking::Hashes); RLPStream s; prep(s, GetBlockHashesByNumberPacket, 2) << m_syncHashNumber << c_maxHashesAsk; @@ -119,6 +118,8 @@ void EthereumPeer::requestHashes(h256 const& _lastHash) RLPStream s; prep(s, GetBlockHashesPacket, 2) << _lastHash << c_maxHashesAsk; clog(NetMessageDetail) << "Requesting block hashes staring from " << _lastHash; + m_syncHash = _lastHash; + m_syncHashNumber = 0; sealAndSend(s); } @@ -150,7 +151,7 @@ void EthereumPeer::setAsking(Asking _a) void EthereumPeer::tick() { - if (chrono::system_clock::now() - m_lastAsk > chrono::seconds(10) && m_asking != Asking::Nothing) + if (chrono::system_clock::now() - m_lastAsk > chrono::seconds(20) && m_asking != Asking::Nothing) // timeout session()->disconnect(PingTimeout); } @@ -240,12 +241,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) setAsking(Asking::Nothing); h256s hashes(itemCount); for (unsigned i = 0; i < itemCount; ++i) - { hashes[i] = _r[i].toHash(); - m_hashSub.noteHash(m_syncHashNumber + i, 1); - } - m_syncHashNumber += itemCount; + if (m_syncHashNumber > 0) + m_syncHashNumber += itemCount; host()->onPeerHashes(this, hashes); break; } diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index 94dc60501..f7a2e12af 100644 --- a/libethereum/EthereumPeer.h +++ b/libethereum/EthereumPeer.h @@ -128,8 +128,9 @@ private: /// This is built as we ask for hashes. Once no more hashes are given, we present this to the /// host who initialises the DownloadMan and m_sub becomes active for us to begin asking for blocks. - unsigned m_expectedHashes = 0; ///< Estimated upper bound of hashes to expect from this peer. - unsigned m_syncHashNumber = 0; ///< Number of latest hash we sync to + unsigned m_expectedHashes = 0; ///< Estimated upper bound of hashes to expect from this peer. + unsigned m_syncHashNumber = 0; ///< Number of latest hash we sync to (PV61+) + h256 m_syncHash; ///< Latest hash we sync to (PV60) /// Once we're asking for blocks, this becomes in use. DownloadSub m_sub; From c0ffe96826583614a2a88eaa20506a41e5aad4a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 8 Jun 2015 17:23:02 +0200 Subject: [PATCH 13/36] VM refactor: check requirements helper function. Move an instruction requirements checking in VM to a separated helper function. Instruction execution is now split into two parts what reduces OS stack memory usage. --- libevm/VM.cpp | 270 +++++++++++++++++++++++++------------------------- libevm/VM.h | 2 + 2 files changed, 139 insertions(+), 133 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index ed4cdb4dc..94d5f8376 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -45,163 +45,167 @@ static array metrics() return s_ret; } -bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) +void VM::checkRequirements(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, Instruction _inst) { - // Reset leftovers from possible previous run - m_curPC = 0; - m_jumpDests.clear(); + static const auto c_metrics = metrics(); + auto& metric = c_metrics[static_cast(_inst)]; - m_stack.reserve((unsigned)c_stackLimit); + if (metric.gasPriceTier == InvalidTier) + BOOST_THROW_EXCEPTION(BadInstruction()); - unique_ptr callParams; + // FEES... + bigint runGas = c_tierStepGas[metric.gasPriceTier]; + bigint newTempSize = m_temp.size(); + bigint copySize = 0; - static const array c_metrics = metrics(); + // should work, but just seems to result in immediate errorless exit on initial execution. yeah. weird. + //m_onFail = std::function(onOperation); - auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; }; - auto gasForMem = [](bigint _size) -> bigint + require(metric.args, metric.ret); + + auto onOperation = [&]() { - bigint s = _size / 32; - return (bigint)c_memoryGas * s + s * s / c_quadCoeffDiv; + if (_onOp) + _onOp(m_steps, _inst, newTempSize > m_temp.size() ? (newTempSize - m_temp.size()) / 32 : bigint(0), runGas, io_gas, this, &_ext); }; - if (m_jumpDests.empty()) - for (unsigned i = 0; i < _ext.code.size(); ++i) + auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; }; + + switch (_inst) + { + case Instruction::SSTORE: + if (!_ext.store(m_stack.back()) && m_stack[m_stack.size() - 2]) + runGas = c_sstoreSetGas; + else if (_ext.store(m_stack.back()) && !m_stack[m_stack.size() - 2]) { - if (_ext.code[i] == (byte)Instruction::JUMPDEST) - m_jumpDests.push_back(i); - else if (_ext.code[i] >= (byte)Instruction::PUSH1 && _ext.code[i] <= (byte)Instruction::PUSH32) - i += _ext.code[i] - (unsigned)Instruction::PUSH1 + 1; + runGas = c_sstoreResetGas; + _ext.sub.refunds += c_sstoreRefundGas; } - u256 nextPC = m_curPC + 1; - for (uint64_t steps = 0; true; m_curPC = nextPC, nextPC = m_curPC + 1, ++steps) + else + runGas = c_sstoreResetGas; + break; + + case Instruction::SLOAD: + runGas = c_sloadGas; + break; + + // These all operate on memory and therefore potentially expand it: + case Instruction::MSTORE: + newTempSize = (bigint)m_stack.back() + 32; + break; + case Instruction::MSTORE8: + newTempSize = (bigint)m_stack.back() + 1; + break; + case Instruction::MLOAD: + newTempSize = (bigint)m_stack.back() + 32; + break; + case Instruction::RETURN: + newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]); + break; + case Instruction::SHA3: + runGas = c_sha3Gas + (m_stack[m_stack.size() - 2] + 31) / 32 * c_sha3WordGas; + newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]); + break; + case Instruction::CALLDATACOPY: + copySize = m_stack[m_stack.size() - 3]; + newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); + break; + case Instruction::CODECOPY: + copySize = m_stack[m_stack.size() - 3]; + newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); + break; + case Instruction::EXTCODECOPY: + copySize = m_stack[m_stack.size() - 4]; + newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]); + break; + + case Instruction::JUMPDEST: + runGas = 1; + break; + + case Instruction::LOG0: + case Instruction::LOG1: + case Instruction::LOG2: + case Instruction::LOG3: + case Instruction::LOG4: { - // INSTRUCTION... - Instruction inst = (Instruction)_ext.getCode(m_curPC); - auto metric = c_metrics[(int)inst]; - int gasPriceTier = metric.gasPriceTier; - - if (gasPriceTier == InvalidTier) - BOOST_THROW_EXCEPTION(BadInstruction()); + unsigned n = (unsigned)_inst - (unsigned)Instruction::LOG0; + runGas = c_logGas + c_logTopicGas * n + (bigint)c_logDataGas * m_stack[m_stack.size() - 2]; + newTempSize = memNeed(m_stack[m_stack.size() - 1], m_stack[m_stack.size() - 2]); + break; + } - // FEES... - bigint runGas = c_tierStepGas[metric.gasPriceTier]; - bigint newTempSize = m_temp.size(); - bigint copySize = 0; + case Instruction::CALL: + case Instruction::CALLCODE: + runGas = (bigint)c_callGas + m_stack[m_stack.size() - 1]; + if (_inst != Instruction::CALLCODE && !_ext.exists(asAddress(m_stack[m_stack.size() - 2]))) + runGas += c_callNewAccountGas; + if (m_stack[m_stack.size() - 3] > 0) + runGas += c_callValueTransferGas; + newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); + break; + + case Instruction::CREATE: + { + newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 3]); + runGas = c_createGas; + break; + } + case Instruction::EXP: + { + auto expon = m_stack[m_stack.size() - 2]; + runGas = c_expGas + c_expByteGas * (32 - (h256(expon).firstBitSet() / 8)); + break; + } + default:; + } - // should work, but just seems to result in immediate errorless exit on initial execution. yeah. weird. - //m_onFail = std::function(onOperation); + auto gasForMem = [](bigint _size) -> bigint + { + bigint s = _size / 32; + return (bigint)c_memoryGas * s + s * s / c_quadCoeffDiv; + }; - require(metric.args, metric.ret); + newTempSize = (newTempSize + 31) / 32 * 32; + if (newTempSize > m_temp.size()) + runGas += gasForMem(newTempSize) - gasForMem(m_temp.size()); + runGas += c_copyGas * ((copySize + 31) / 32); - auto onOperation = [&]() - { - if (_onOp) - _onOp(steps, inst, newTempSize > m_temp.size() ? (newTempSize - m_temp.size()) / 32 : bigint(0), runGas, io_gas, this, &_ext); - }; + onOperation(); - switch (inst) - { - case Instruction::SSTORE: - if (!_ext.store(m_stack.back()) && m_stack[m_stack.size() - 2]) - runGas = c_sstoreSetGas; - else if (_ext.store(m_stack.back()) && !m_stack[m_stack.size() - 2]) - { - runGas = c_sstoreResetGas; - _ext.sub.refunds += c_sstoreRefundGas; - } - else - runGas = c_sstoreResetGas; - break; + if (io_gas < runGas) + BOOST_THROW_EXCEPTION(OutOfGas()); - case Instruction::SLOAD: - runGas = c_sloadGas; - break; + io_gas -= (u256)runGas; - // These all operate on memory and therefore potentially expand it: - case Instruction::MSTORE: - newTempSize = (bigint)m_stack.back() + 32; - break; - case Instruction::MSTORE8: - newTempSize = (bigint)m_stack.back() + 1; - break; - case Instruction::MLOAD: - newTempSize = (bigint)m_stack.back() + 32; - break; - case Instruction::RETURN: - newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]); - break; - case Instruction::SHA3: - runGas = c_sha3Gas + (m_stack[m_stack.size() - 2] + 31) / 32 * c_sha3WordGas; - newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]); - break; - case Instruction::CALLDATACOPY: - copySize = m_stack[m_stack.size() - 3]; - newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); - break; - case Instruction::CODECOPY: - copySize = m_stack[m_stack.size() - 3]; - newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 3]); - break; - case Instruction::EXTCODECOPY: - copySize = m_stack[m_stack.size() - 4]; - newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 4]); - break; + if (newTempSize > m_temp.size()) + m_temp.resize((size_t)newTempSize); +} - case Instruction::JUMPDEST: - runGas = 1; - break; +bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) +{ + // Reset leftovers from possible previous run + m_curPC = 0; + m_jumpDests.clear(); - case Instruction::LOG0: - case Instruction::LOG1: - case Instruction::LOG2: - case Instruction::LOG3: - case Instruction::LOG4: - { - unsigned n = (unsigned)inst - (unsigned)Instruction::LOG0; - runGas = c_logGas + c_logTopicGas * n + (bigint)c_logDataGas * m_stack[m_stack.size() - 2]; - newTempSize = memNeed(m_stack[m_stack.size() - 1], m_stack[m_stack.size() - 2]); - break; - } + m_stack.reserve((unsigned)c_stackLimit); - case Instruction::CALL: - case Instruction::CALLCODE: - runGas = (bigint)c_callGas + m_stack[m_stack.size() - 1]; - if (inst != Instruction::CALLCODE && !_ext.exists(asAddress(m_stack[m_stack.size() - 2]))) - runGas += c_callNewAccountGas; - if (m_stack[m_stack.size() - 3] > 0) - runGas += c_callValueTransferGas; - newTempSize = std::max(memNeed(m_stack[m_stack.size() - 6], m_stack[m_stack.size() - 7]), memNeed(m_stack[m_stack.size() - 4], m_stack[m_stack.size() - 5])); - break; + unique_ptr callParams; - case Instruction::CREATE: - { - newTempSize = memNeed(m_stack[m_stack.size() - 2], m_stack[m_stack.size() - 3]); - runGas = c_createGas; - break; - } - case Instruction::EXP: + if (m_jumpDests.empty()) + for (unsigned i = 0; i < _ext.code.size(); ++i) { - auto expon = m_stack[m_stack.size() - 2]; - runGas = c_expGas + c_expByteGas * (32 - (h256(expon).firstBitSet() / 8)); - break; - } - default:; + if (_ext.code[i] == (byte)Instruction::JUMPDEST) + m_jumpDests.push_back(i); + else if (_ext.code[i] >= (byte)Instruction::PUSH1 && _ext.code[i] <= (byte)Instruction::PUSH32) + i += _ext.code[i] - (unsigned)Instruction::PUSH1 + 1; } - - newTempSize = (newTempSize + 31) / 32 * 32; - if (newTempSize > m_temp.size()) - runGas += gasForMem(newTempSize) - gasForMem(m_temp.size()); - runGas += c_copyGas * ((copySize + 31) / 32); - - onOperation(); - - if (io_gas < runGas) - BOOST_THROW_EXCEPTION(OutOfGas()); - - io_gas -= (u256)runGas; - - if (newTempSize > m_temp.size()) - m_temp.resize((size_t)newTempSize); + u256 nextPC = m_curPC + 1; + for (m_steps = 0; true; m_curPC = nextPC, nextPC = m_curPC + 1, ++m_steps) + { + // INSTRUCTION... + Instruction inst = (Instruction)_ext.getCode(m_curPC); + checkRequirements(io_gas, _ext, _onOp, inst); // EXECUTE... switch (inst) diff --git a/libevm/VM.h b/libevm/VM.h index 9084769cf..7c0209329 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -60,10 +60,12 @@ public: u256s const& stack() const { return m_stack; } private: + void checkRequirements(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, Instruction _inst); void require(u256 _n, u256 _d) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } if (m_stack.size() - _n + _d > c_stackLimit) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_d - _n), (bigint)m_stack.size())); } } void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } } u256 m_curPC = 0; + uint64_t m_steps = 0; bytes m_temp; u256s m_stack; std::vector m_jumpDests; From cc774567466c3af97ffc8a498b5683e0add5c505 Mon Sep 17 00:00:00 2001 From: Alexandre Van de Sande Date: Mon, 8 Jun 2015 12:43:28 -0300 Subject: [PATCH 14/36] Add new icons for mix --- mix/qml/img/addblock.png | Bin 0 -> 801 bytes mix/qml/img/addblock@2x.png | Bin 0 -> 1768 bytes mix/qml/img/duplicateicon.png | Bin 0 -> 1020 bytes mix/qml/img/duplicateicon@2x.png | Bin 0 -> 2326 bytes mix/qml/img/leftarrow.png | Bin 0 -> 467 bytes mix/qml/img/leftarrow@2x.png | Bin 0 -> 947 bytes mix/qml/img/newaccounticon.png | Bin 0 -> 559 bytes mix/qml/img/newaccounticon@2x.png | Bin 0 -> 862 bytes mix/qml/img/recyclediscard.png | Bin 0 -> 976 bytes mix/qml/img/recyclediscard@2x.png | Bin 0 -> 2274 bytes mix/qml/img/recycleicon.png | Bin 0 -> 572 bytes mix/qml/img/recycleicon@2x.png | Bin 0 -> 1205 bytes mix/qml/img/recyclekeep.png | Bin 0 -> 704 bytes mix/qml/img/recyclekeep@2x.png | Bin 0 -> 1597 bytes mix/qml/img/restoreicon.png | Bin 0 -> 1124 bytes mix/qml/img/restoreicon@2x.png | Bin 0 -> 2447 bytes mix/qml/img/rightarrow.png | Bin 0 -> 297 bytes mix/qml/img/rightarrow@2x.png | Bin 0 -> 566 bytes mix/qml/img/saveicon.png | Bin 0 -> 1068 bytes mix/qml/img/saveicon@2x.png | Bin 0 -> 2359 bytes mix/qml/img/sendtransactionicon.png | Bin 0 -> 548 bytes mix/qml/img/sendtransactionicon@2x.png | Bin 0 -> 1114 bytes 22 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mix/qml/img/addblock.png create mode 100644 mix/qml/img/addblock@2x.png create mode 100644 mix/qml/img/duplicateicon.png create mode 100644 mix/qml/img/duplicateicon@2x.png create mode 100644 mix/qml/img/leftarrow.png create mode 100644 mix/qml/img/leftarrow@2x.png create mode 100644 mix/qml/img/newaccounticon.png create mode 100644 mix/qml/img/newaccounticon@2x.png create mode 100644 mix/qml/img/recyclediscard.png create mode 100644 mix/qml/img/recyclediscard@2x.png create mode 100644 mix/qml/img/recycleicon.png create mode 100644 mix/qml/img/recycleicon@2x.png create mode 100644 mix/qml/img/recyclekeep.png create mode 100644 mix/qml/img/recyclekeep@2x.png create mode 100644 mix/qml/img/restoreicon.png create mode 100644 mix/qml/img/restoreicon@2x.png create mode 100644 mix/qml/img/rightarrow.png create mode 100644 mix/qml/img/rightarrow@2x.png create mode 100644 mix/qml/img/saveicon.png create mode 100644 mix/qml/img/saveicon@2x.png create mode 100644 mix/qml/img/sendtransactionicon.png create mode 100644 mix/qml/img/sendtransactionicon@2x.png diff --git a/mix/qml/img/addblock.png b/mix/qml/img/addblock.png new file mode 100644 index 0000000000000000000000000000000000000000..016d0ddbba67d8fa3be547e66654fce086d228f4 GIT binary patch literal 801 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 KMNUMnLSTZ1M@~2Z literal 0 HcmV?d00001 diff --git a/mix/qml/img/duplicateicon.png b/mix/qml/img/duplicateicon.png new file mode 100644 index 0000000000000000000000000000000000000000..b3a2554208e3c2a942a9bfa9484a422c6d8a138e GIT binary patch literal 1020 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 JPDHLkV1kam(jfo< literal 0 HcmV?d00001 diff --git a/mix/qml/img/leftarrow@2x.png b/mix/qml/img/leftarrow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8602b02ea027ae2bbca2aa808d7f7d52c734b8ba GIT binary patch literal 947 zcmV;k15EshP)Px&ZAnByRA>e5m`zL*K@`VlX4_@~l^T(QD2RXoJ#a8e-~?)DF)Gf|00Lp&BzKcfLXXf#nm2tq3+7&$@xAe45;x9T+8h8PoewoRB`X5PQ; zoB99x-s}KE;w1V~qCbzd$J+NhYW} z+`TuV*NvWM4S++LJ3_D&gkQa0Zwh|(w@H-j2zTszuGe|ZO$TsPnJ$sBe4S!^78cj7 zPrs@v?HP*=-$h=p%FA$OUfl*V-!eAV`rM9pbsd57rD?_}da#C2_aj%?T$*lTz_kLL{@KICVhKW}H>7!@^qq=S*O;sP zS(=`OfJ+55`lpNXBzX{Sap%BO3NoDRix|^PK&lMpfpfA$|> z+V7Fl7l|Ztg}ch$r0JZ3tO3ycG z$FWdHX-kG?NSIRqm?Otvv`Hc)0BupLY0wXA^Gn~iOnMK-*=LLzC8H7h^8QI9*ATe`0YN|z5CjAPK|l}?1Ox#=KoAfF1OY)n5ZJT?egPFR V@a;D?vrqs4002ovPDHLkV1jBDp_Tvu literal 0 HcmV?d00001 diff --git a/mix/qml/img/newaccounticon.png b/mix/qml/img/newaccounticon.png new file mode 100644 index 0000000000000000000000000000000000000000..16bb66fcd0b56b918507463f5fdb56f8c3155a9d GIT binary patch literal 559 zcmV+~0?_@5P)Px$=}AOER7ef&RJ%$8K@{DYT_uTYFIpN=uu&{5f{$uRg5n3*S*A&6Yl4l~X%V#X zGqOpL5LB>=3ZnQ(8>`gOVA%0Y+?BA|87G2;n1Rcg`MPmP)0E0H4$pL>9O}*YzbhMDf)12dhGmVv(Q!p@8fFFX3L`lbV$;q02&&$s~V*Dd zXY4$e&*yVj+SoFobQLy@Xe5JPRW!mXT%UJdvK)g(zXfzS@Ek2nHc`k?p-{NwMznl~ zC+2him~-mFJVJ+`gzHE=2{?u=;~3sW0(bK#9a6dj x)oQhgSFnaVupml;!p=m#fql?{K?h_V_yEiirqkd_>y`ij002ovPDHLkV1jq-1MmO< literal 0 HcmV?d00001 diff --git a/mix/qml/img/newaccounticon@2x.png b/mix/qml/img/newaccounticon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..925dad67d2fd5d4bc5adf9815ad9e7b13f117e5a GIT binary patch literal 862 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 literal 0 HcmV?d00001 diff --git a/mix/qml/img/recycleicon.png b/mix/qml/img/recycleicon.png new file mode 100644 index 0000000000000000000000000000000000000000..a4bacb21f7807966eda8890c264587a446bbf1a4 GIT binary patch literal 572 zcmV-C0>k}@P)Px$_DMuRR7ef&RKH8ZKp1TjJ5(#pqMJBK7AHltgbtPtwGD!klOVW>uDUn~{sH13 zxVUu^T%2mt#R`QA4h}k~Z9xl)i?oV1NPqbb?jVHz_&Vv3gX6p0_rCYOyyMQ}afj=G z>%bp7AoZ&skH>dWqwumTCF)*mLtG#VGgl6G`1>9l2)x&_cEDG zo$XPEOaTc@I2`t4Z9wQ7O<47MJt%UOO63&mkk99PMHCK+bjL_Of>0$*=>)u%?IF`rJS@7rPQ zd!!?P_yok4%jNP0FK#Q&a=Bd2LfBUnWs_sO22umfW>bUpcbvQ{Ax}Ocj#Gf7TY$fr z2H7=*kYnE9*eC^0b>IUIs1!nunFaoaf+sZqq6f?=3L(d^>&a?*4pIZKGmAMEjYemB zF&c)k2&`Tzm5zF0S)P0iW3ku*h|es`8o^8VWhciinMCfgR;#Uey%%0r&1{s=X!vbZpldo@nhVSTZkth9;Avh9&!T=j3#yJ7dk*duyXSq!P0000< KMNUMnLSTX*X!vFT literal 0 HcmV?d00001 diff --git a/mix/qml/img/recycleicon@2x.png b/mix/qml/img/recycleicon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..00f42abd82f8ae1291a0703a9510db69bd022eee GIT binary patch literal 1205 zcmV;m1WNmfP)Px(Z%IT!RA>e5nO%sCQ5eT}c4ohZT_364EG~$!DU4i58nxdc7lgPW(QYXzACU`6 zzAhBYg$wz*P*Q~b%4%~#$y&4}iBKCmGnzhl7Xwa2x!wNb{%O*c+F z9$((l(sC_bzt`;nuLp3lpGYKb|IYcEnwot+pD)tW({s9`qa)^IW4L|U!!__H{l><| zyjUzY4QDSQ8@J`DCk6%vw%K*Ntg5OSi}Ty5Hxw5a->;~sm}>WVQF=}Qvsssulk*6t zR^xyW@WyiF0<-@()hXIOLQFmUe57x7AP{%}DRWchwCY|G;KTV-IDQJSK^!`VW9xXH zME=&_-@hZB6V1)dXIUF&pmP=dBER2%v%I`q^wg7Q1hDuu0KN{yedHBQO-&oJv$OYD z9vp0IYwL0HrnR*-(%09w5}9Ul2~pGt38S2JGU@Y#0A_wIVCu=e%;FN(fh&aZEb5b~ zzv}JnJ>~{%dwctLWQ7EIh01bsb5FR@8;XqjXOKl}Jn!vO30*>dy@az3C>#!#+QYFCpglz(Bf<{qj0l^G~G6CbHQ(0L#5&N>8 z{uYTu?mEd1rB9Urw!T+oaP|Xo7En#t+$shk_qygKi7ElikbM7T0i4hNeWn1`NZ6Wy z?ag8f0uF1~v~8#oz-}!Hz>8uWzzy~wLn*7Ps~57>9hsyf7%yON1m$JU7f+JXFs1BL;^fMLKepvJ%tIf{!> TQ1P@Z00000NkvXXu0mjf`4m8a literal 0 HcmV?d00001 diff --git a/mix/qml/img/recyclekeep.png b/mix/qml/img/recyclekeep.png new file mode 100644 index 0000000000000000000000000000000000000000..8f7232334ab1f5d3ef9ecd74d862c19dd5121197 GIT binary patch literal 704 zcmV;x0zdtUP)Px%dPzhCQ2fD5N!n@_-OaAwNEVjuhE74y!#)`1 z?Y!@O-`h7ogd~=9AnCwA?f~7aez{yej~ua|_Yn4cvm9Z(6#n4!Mc?-i3W6{Rd=+De z<)N_Slv1VJ?Orep!)0qcCh&j)jHYSB@GB7dfg)_zb;pBPr_;F$KbK0SzG4nK6od!P z+*^>#<+i8O=~W0XqJU*EZmZYpC!@^hgo(9h*qT~27Wd6v0En+aco?E5K*aL=I6_rb zQ<+TWL$BA%H=E73ahUKL*A_s0H^isg?e?jD@;dRoRWhVirHkSrb0;thq9~pY3k~wQ z4x#6H3J%>H(=_ckB5h8bqC~jv6Ms~a@qVNDMS@S$HVO(}@AoLCR9SpOP@pfPZgrj3KBuxn|5y3xGsL8kS$44Q+ zuI1UaRrkuvo5bl09>ChGjl@};s{_Ej!`KIbm0!z_N-24S?-`uLr@rH6jd}M{NE{); zt|!a+JBCBJwNj~kE*6Vpe;B8USeTXaaqPfNVOZI0c1v75y2h>(mz7GT!`O!Vwr!8# zrTZRELVRrq*lgZFleh0000Px)_en%SRA>e5S$%9%RTRJP^>y7EH`HJ@*+wF6D4WEO%KpINO0w^$F-GDSB(fNE zGeoA_G#X9B5D_*PWss zvUcryU;M*+liPdmdFPya&hMW4S;j;X2nYlO0s;YnfIvVXAP^7;2m}NI0s(=*{|*7k zY>%s}t7p+iO0<6be*dGry}e&X`))Q}F}s6U`ZY~EGN1ERRaI|Gk~BFnG4b)x(2y^d zj%2^d$tqY#zN@Rt=JWYh!r6o1_3Qj-Yk@%EWxcJJ6%`dX!}&(E+cGmVPn4CFpDBF1M^TjT0Lp!le7xFb0wBTp zeQdTR@c)i}HXioI>^z6slunIDrkk7DKEQd-n(uIS@^!hKv zNv9>*1!G(Rz#>-#i|ojUv4{;X);ebcyK8-e@-6hWvs;wl!WjyCS_^JSO-;RjvAQGW zxB>v><LCM;nF2W;xZ>~Ec}m+Q8%TNSJI1GH(o3nz_fZWd5qaJ8_X!$cOA&oI!Es&btI2>lz$n(^`R zOS)CLHtQ#{EH&9})`8-BwnC?)l%0*%7qM%Qg9hidKLc8z#FjwjqVoqN0?}+K>sr6r?nvFDbgUaV3lhGptp0>BhK!@bGy4${RW4jrxDIqi4NnJ zN*2~{k(HCEuOS*GO+%Qg8b;i=8KXY0^TY?42Sep`mnfnyCUFG-2L47yV1yjHG42-s z=aMElLAyXS@L2I1eZWFc46S;Bk250LWpcs;k}2>N_JH%o}EoQi0BG^a*lb@q8rV3IIlk z_J3Lci*SA~AcOUE?0t4#oAwn0gm%1yY;-lNWv*5>rhkuBLRSuSKTkXW;JsM9iGB-) zVxmIP_{YY^{CRnKWNZ;~!RYAd0VA*HB=dTX2Rc0i+K)!Mv0hnOS)7xTGv)Dk^r(>Y z^YiIlU?uoEa3X9o@+Vv88UbVs?(lR6p!vQYZvxK|E#8DP{!%#lwcTzXrJEz<=uw5< z6=)6l9arPJcy-0g#~lFN_%6X%{l>NzBl<|Z#-ydCZHKc7q@!@3X#N{aF%8i?3A-2ym;MX8mgYI8Pz7v@q zRUSs@A4$@rdBwR$fZhuXehr52KzkVPf2VYMv=YwK+aawya00000NkvXXu0mjf&_nSL literal 0 HcmV?d00001 diff --git a/mix/qml/img/restoreicon.png b/mix/qml/img/restoreicon.png new file mode 100644 index 0000000000000000000000000000000000000000..9fc6e8f22fc90710595e0ca4fe572bdecf87e7e9 GIT binary patch literal 1124 zcmV-q1e^PbP)Px(9!W$&R7ef&RclNfRTTbawzChGE^m-m6>z2P>LMh_qlHF8wQ16(h6XkA!zi)Q z_@nU={nr?yCiaJorbI}aMvZM!No`HjTFNF3sNgD5S{B-}<+bdxJj$}{?##~a%#L>_ zStusE4A_{Mbdt&3x#yhk`_8%do(nv9{?8SVBq^J`DgP#iO&bX&q-u72eDC~M-yWuu zv_jD3I;zRdwNMl#Yy@vzF@)T_c;WKtvBnn9fWAb!o>D4}H@`LOz1Ve%*tV?;j5t$D z0|+It0L!xZ;hw&B&v)nR_~DVwT>o`B$iJ%rBd@&)AuAh6N_+W0x2m@Cb-i9c9Zy6;0X)xdgU?s0ibO&o_k4@(?N6U~y!#=<^bC;7;16pr zc#?T#)edMi8mMpIL_zCk*xLSahdMj`lt|NRbw-AbRAFR80%Ad5TpH1o8g$lMbBkt< zwF^UV{PoQM0 z88y{4aJi;1J2Qh3701fH!BiYNeQ>?qeuWHgp#A)63N(Z`x6uPVVEnb zQBYVUXU|f}m~aKxLA#<)(Gr02T8t%yLo`jxsfEeL>+ih=OV<@l2a_%-5+lX|J5U z)Sb1gGQmL69taEEmafjOyu!jl?A%$4jIM?d|)WQ!^)~ z-EMi49cX-kn5Ym%;Y)5Y_)$~SZg0$2$#>lXVxY&5w|y`+={QpV%yU;mp~yQ2_w9;% q;lyI@`?syFjk)ij4*>t`3j7UbNvFs#r0;+L0000?64V literal 0 HcmV?d00001 diff --git a/mix/qml/img/restoreicon@2x.png b/mix/qml/img/restoreicon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3160b0bf348f7a9b2136ffa84c8eb11f19afbac2 GIT binary patch literal 2447 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 N002ovPDHLkV1ho6ksSa4 literal 0 HcmV?d00001 diff --git a/mix/qml/img/rightarrow.png b/mix/qml/img/rightarrow.png new file mode 100644 index 0000000000000000000000000000000000000000..54f2b401f26eff5f88be04bc20eddc9ff309d02d GIT binary patch literal 297 zcmV+^0oMMBP)Px#<4Ht8R7ef&(mf6VQ51&Z85%#y)EWvqP$(#5I=zNO)E1!;r9CJoqOb>@kf^Lc zMx_-J1>-#%n0t#8jdPNxy7zwHRzF=iUpo{V2+Azi$@xz4Xh!PVvOJaACz`+gv=gokMGyLLaF>88_1-( z>5eoCTi8i6b4KiVqH|194J*8H!xTlG^qdq*N|@n}7nX=}p6DG>G{OZkTQv339Z8f8 vrIk6M=eVwaOlgEZ3i|1mXdAE%{PPCBLLuBjak~HN00000NkvXXu0mjfKlORS literal 0 HcmV?d00001 diff --git a/mix/qml/img/rightarrow@2x.png b/mix/qml/img/rightarrow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed1e6d1ba7d874b2e7f1aaad1c77ecd7235e4f4 GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^4nSDaPU;cPEB*=VV?2*&jSz978f# z-_Eera0`?SZq!SJ~B9dzs-N<1}HJIR%)~v(UnqsEWJoQM%1V^<`fnH9h z(mj>d-`9Orl5?)ISnvG)y1Sq4OaDKwoEQE5?cU5xE!71qQyPQ2(oDyrBc{jXn==~-U@j+Q|^W1`z8Ze$u2)p9%tEYoGjzL6(`E>`^l+SY2;P%-RZz(ayG`4=-_8n%wY&9=rO4u4QS)|^TU2)~gi9-d# tF7l4Y71T|aXRJaEb)+ab&@c3ZA^-CvzuJV3*T96p;OXk;vd$@?2>|X=@Ol6M literal 0 HcmV?d00001 diff --git a/mix/qml/img/saveicon.png b/mix/qml/img/saveicon.png new file mode 100644 index 0000000000000000000000000000000000000000..46e17522b27729f5d8ad767813183ce12f2bfe03 GIT binary patch literal 1068 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 literal 0 HcmV?d00001 diff --git a/mix/qml/img/sendtransactionicon.png b/mix/qml/img/sendtransactionicon.png new file mode 100644 index 0000000000000000000000000000000000000000..02f35912223bede62471d2b77258611959b98de0 GIT binary patch literal 548 zcmV+<0^9wGP)Px$-bqA3R7ef&Qo&0UVHE$p*>!czT~ta^SVKJaAJoaK-a-aK`ZGLaVNizzEeZrZ zbV%x=i+JVc25W3+HG5aTldINiTg8?F>Hy1MtP#)mUizN8F0Lpj2tP9s zDP|6~`Rb?>*Jdy+XZR;LLTaqz!HR1%srP2v3>jYI-!Ao{J zXv@5>G3K6+4}5E^Z_HZ>kcU`$LK;m=V^GW1uVXUJ0**}+w&R0SS!8eI(4OwvSHQe- z+&425x2#5@usl@2%IAYLC9_jPJ19T-70TaP|M2nQX|+1qb8`sYeK{oBQX&bPzT#H~ zHrDdG?uQYDoremzs^QVO=`RcM>luAu=c?MMXOSP_1z=HT{?t{c3$yyr mQB;z+E_NVxAa>xtcHj@wAKh^2jcH^60000Px(6iGxuRA>e5mrrO^M;yn0^LF2Eve6hfCat7t6x53sYr$Sb2zZemD-VU6-||j2)?)$+eY1uyBgQH$(tF!^R~}ukeIxE zv4X$hy`6b8zxmDY_xa7gCE~;cm;e)C0!)AjFaajO1egF5U;<2l2`~XB@NN+hVchNQ zy=14?t=^8#n@Lbk335pZmnvn~*|a<#M(6+4Clr9d*weq2*2m)FTS4NJpiXQ32;~tH z0HVnifFreZ)uiWc-`FyWHXX>m4S7uf{&PSK{9gJ(2(b@NH_z^rexgZ?_+Yehm1SlQ z-YMl?ztH`6CX-RK_m93c3IM)U{l7j;TXE5)1$_ynRtQro=yMA*Xasq6<^YcNw0mRn zkH0dVon8o?uk8{UfM6tm*dS~&%i`mpuI5~mr-i;9EGdPhWy)k>ndR=}9B1uh*fAmp zU<|=jw$^^SYsc+dxjl%eS@h-yCA?ah2U6yf%vX?nDNSfpkQQ2@7=;#JxOGp^CJWr|F6iR_`+5^*NobkHd}?DS+>XiX92tItS<1g*7PX zhnYjAQjx}=RA^GiNyit_ghyjqsv}y!A$7D`-J(i{Hn=)tSV{V`IFX*j&nces z*4@WsQ|pJ8iFPuz_{FB@WjOvb4!CUBwIk Date: Mon, 8 Jun 2015 18:05:40 +0200 Subject: [PATCH 15/36] hash download reporting --- alethzero/MainWin.cpp | 4 +++- libdevcore/RangeMask.h | 8 ++++++++ libethereum/Client.cpp | 6 ++++++ libethereum/Client.h | 2 ++ libethereum/CommonNet.h | 7 +++++++ libethereum/DownloadMan.h | 5 +++++ libethereum/EthereumHost.cpp | 17 +++++++++++++++++ libethereum/EthereumHost.h | 5 ++++- 8 files changed, 52 insertions(+), 2 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 10038a80e..d603c18ea 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1240,7 +1240,9 @@ void Main::refreshBlockCount() { auto d = ethereum()->blockChain().details(); BlockQueueStatus b = ethereum()->blockQueueStatus(); - ui->chainStatus->setText(QString("%3 ready %4 verifying %5 unverified %6 future %7 unknown %8 bad %1 #%2").arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad)); + HashChainStatus h = ethereum()->hashChainStatus(); + ui->chainStatus->setText(QString("%9/%10%11 hashes %3 ready %4 verifying %5 unverified %6 future %7 unknown %8 bad %1 #%2") + .arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad).arg(h.received).arg(h.estimated ? "~" : "").arg(h.total)); } void Main::on_turboMining_triggered() diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h index bdf00e687..7c402fc98 100644 --- a/libdevcore/RangeMask.h +++ b/libdevcore/RangeMask.h @@ -219,6 +219,14 @@ public: return uit == m_ranges.end() ? m_all.second : uit->first; } + size_t size() const + { + size_t c = 0; + for (auto const& r: this->m_ranges) + c += r.second - r.first; + return c; + } + private: UnsignedRange m_all; std::map m_ranges; diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 46fbbdfb1..08bfcc935 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -745,3 +745,9 @@ void Client::flushTransactions() { doWork(); } + +HashChainStatus Client::hashChainStatus() const +{ + auto h = m_host.lock(); + return h ? h->status() : HashChainStatus { 0, 0, false }; +} diff --git a/libethereum/Client.h b/libethereum/Client.h index 5132b5a30..adfca38b6 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -156,6 +156,8 @@ public: CanonBlockChain const& blockChain() const { return m_bc; } /// Get some information on the block queue. BlockQueueStatus blockQueueStatus() const { return m_bq.status(); } + /// Get some information on the block queue. + HashChainStatus hashChainStatus() const; // Mining stuff: diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h index a2f4a2e7c..b9ad354f6 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -82,5 +82,12 @@ enum class Syncing Done }; +struct HashChainStatus +{ + unsigned total; + unsigned received; + bool estimated; +}; + } } diff --git a/libethereum/DownloadMan.h b/libethereum/DownloadMan.h index 3e1a071c9..0ffa6fdb0 100644 --- a/libethereum/DownloadMan.h +++ b/libethereum/DownloadMan.h @@ -255,6 +255,11 @@ public: return m_got.full(); } + unsigned gotCount() const + { + return m_got.size(); + } + size_t chainSize() const { ReadGuard l(m_lock); return m_chainCount; } size_t chainEmpty() const { ReadGuard l(m_lock); return m_chainCount == 0; } void foreachSub(std::function const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); } diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 8b2427e42..b52e319e7 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -615,7 +615,10 @@ void EthereumHost::continueSync(EthereumPeer* _peer) return; } if (_peer->m_protocolVersion == protocolVersion() && !m_hashMan.isComplete()) + { + m_syncingV61 = true; _peer->requestHashes(); /// v61+ and not catching up to a particular hash + } else { // Restart/continue sync in single peer mode @@ -625,7 +628,13 @@ void EthereumHost::continueSync(EthereumPeer* _peer) m_syncingTotalDifficulty = _peer->m_totalDifficulty; } if (_peer->m_totalDifficulty >= m_syncingTotalDifficulty) + { _peer->requestHashes(m_syncingLatestHash); + m_syncingV61 = false; + m_estimatedHashes = _peer->m_expectedHashes; + } + else + _peer->setIdle(); } } else if (m_needSyncBlocks && peerShouldGrabBlocks(_peer)) // Check if this peer can help with downloading blocks @@ -677,3 +686,11 @@ bool EthereumHost::isSyncing_UNSAFE() const }); return syncing; } + +HashChainStatus EthereumHost::status() +{ + RecursiveGuard l(x_sync); + if (m_syncingV61) + return HashChainStatus { static_cast(m_hashMan.chainSize()), static_cast(m_hashMan.gotCount()), false }; + return HashChainStatus { m_estimatedHashes, static_cast(m_hashes.size()), true }; +} diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index d9628de3a..7e03dee8c 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -87,6 +87,7 @@ public: DownloadMan& downloadMan() { return m_man; } HashDownloadMan& hashDownloadMan() { return m_hashMan; } BlockChain const& chain() { return m_chain; } + HashChainStatus status(); static unsigned const c_oldProtocolVersion; @@ -147,7 +148,9 @@ private: bool m_needSyncBlocks = true; ///< Indicates if we still need to download some blocks h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync. u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync. - h256s m_hashes; ///< List of hashes with unknown block numbers. Used for v60 chain downloading and catching up to a particular unknown + h256s m_hashes; ///< List of hashes with unknown block numbers. Used for PV60 chain downloading and catching up to a particular unknown + unsigned m_estimatedHashes = 0; ///< Number of estimated hashes for the last peer over PV60. Used for status reporting only. + bool m_syncingV61 = false; ///< True if recent activity was over pv61+. Used for status reporting only. }; } From cd2236b4687c23705ac8f3cb71f431cd035b6e52 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 9 Jun 2015 14:24:58 +0900 Subject: [PATCH 16/36] Much better exception error reporting. Readying things for phone-home on badblock. --- libethcore/Exceptions.h | 8 +-- libethereum/Executive.cpp | 2 +- libethereum/State.cpp | 110 +++++++++++++++++++++++------------- libethereum/State.h | 14 +++++ libethereum/Transaction.cpp | 43 +++++++++++++- libethereum/Transaction.h | 6 +- mix/MixClient.cpp | 44 ++++++++------- 7 files changed, 156 insertions(+), 71 deletions(-) diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index 9362e4fed..b35a3abe9 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -39,6 +39,7 @@ using BadFieldError = boost::tuple; struct DatabaseAlreadyOpen: virtual dev::Exception {}; struct OutOfGasBase: virtual dev::Exception {}; +struct OutOfGasIntrinsic: virtual dev::Exception {}; struct NotEnoughAvailableSpace: virtual dev::Exception {}; struct NotEnoughCash: virtual dev::Exception {}; struct GasPriceTooLow: virtual dev::Exception {}; @@ -51,20 +52,15 @@ struct ExtraDataTooBig: virtual dev::Exception {}; struct InvalidSignature: virtual dev::Exception {}; struct InvalidBlockFormat: virtual dev::Exception {}; struct InvalidUnclesHash: virtual dev::Exception {}; -struct InvalidUncle: virtual dev::Exception {}; struct TooManyUncles: virtual dev::Exception {}; struct UncleTooOld: virtual dev::Exception {}; struct UncleIsBrother: virtual dev::Exception {}; struct UncleInChain: virtual dev::Exception {}; -struct DuplicateUncleNonce: virtual dev::Exception {}; struct InvalidStateRoot: virtual dev::Exception {}; struct InvalidGasUsed: virtual dev::Exception {}; -struct InvalidTransactionsHash: virtual dev::Exception {}; -struct InvalidTransaction: virtual dev::Exception {}; +struct InvalidTransactionsRoot: virtual dev::Exception {}; struct InvalidDifficulty: virtual dev::Exception {}; struct InvalidGasLimit: virtual dev::Exception {}; -struct InvalidTransactionGasUsed: virtual dev::Exception {}; -struct InvalidTransactionsStateRoot: virtual dev::Exception {}; struct InvalidReceiptsStateRoot: virtual dev::Exception {}; struct InvalidTimestamp: virtual dev::Exception {}; struct InvalidLogBloom: virtual dev::Exception {}; diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 5ec5f7313..fe9a6c6c0 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -68,7 +68,7 @@ void Executive::initialize(Transaction const& _transaction) if (!m_t.checkPayment()) { clog(ExecutiveWarnChannel) << "Not enough gas to pay for the transaction: Require >" << m_t.gasRequired() << " Got" << m_t.gas(); - m_excepted = TransactionException::OutOfGas; + m_excepted = TransactionException::OutOfGasBase; BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError(m_t.gasRequired(), (bigint)m_t.gas())); } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index f40574fde..848a2ce5f 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -605,6 +605,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement #endif if (m_currentBlock.parentHash != m_previousBlock.hash()) + // Internal client error. BOOST_THROW_EXCEPTION(InvalidParentHash()); // Populate m_currentBlock with the correct values. @@ -624,16 +625,19 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement unsigned i = 0; for (auto const& tr: rlp[1]) { - try { + try + { LogOverride o(false); execute(lh, Transaction(tr.data(), CheckTransaction::Everything)); } - catch (...) + catch (Exception& ex) { - badBlock(_block, "Invalid transaction"); + badBlock(_block, "Invalid transaction: " + toString(toTransactionException(ex))); cwarn << " Transaction Index:" << i; LogOverride o(true); - execute(lh, Transaction(tr.data(), CheckTransaction::Everything)); + DEV_IGNORE_EXCEPTIONS(execute(lh, Transaction(tr.data(), CheckTransaction::Everything))); + + ex << errinfo_transactionIndex(i); throw; } @@ -658,7 +662,12 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement cwarn << " " << TransactionReceipt(&b); } cwarn << " VMTrace:\n" << vmTrace(_block, _bc, _ir); - BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot()); + + InvalidReceiptsStateRoot ex; + ex << HashMismatchError(receiptsRoot, m_currentBlock.receiptsRoot); + ex << errinfo_receipts(receipts); + ex << errinfo_vmtrace(vmTrace(_block, _bc, _ir)); + BOOST_THROW_EXCEPTION(ex); } if (m_currentBlock.logBloom != logBloom()) @@ -671,7 +680,10 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement cwarn << " " << j << ":" << TransactionReceipt(&b).bloom().hex(); } cwarn << " Final bloom:" << m_currentBlock.logBloom.hex(); - BOOST_THROW_EXCEPTION(InvalidLogBloom()); + InvalidLogBloom ex; + ex << LogBloomMismatchError(logBloom(), m_currentBlock.logBloom); + ex << errinfo_receipts(receipts); + BOOST_THROW_EXCEPTION(ex); } // Initialise total difficulty calculation. @@ -681,45 +693,70 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement if (rlp[2].itemCount() > 2) { badBlock(_block, "Too many uncles"); - BOOST_THROW_EXCEPTION(TooManyUncles()); + BOOST_THROW_EXCEPTION(TooManyUncles() << errinfo_max(2) << errinfo_got(rlp[2].itemCount())); } vector rewarded; h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6); excluded.insert(m_currentBlock.hash()); + unsigned ii = 0; for (auto const& i: rlp[2]) { - auto h = sha3(i.data()); - if (excluded.count(h)) + try { - badBlock(_block, "Invalid uncle included"); - BOOST_THROW_EXCEPTION(UncleInChain() << errinfo_comment("Uncle in block already mentioned") << errinfo_data(toString(excluded)) << errinfo_hash256(sha3(i.data()))); - } - excluded.insert(h); + auto h = sha3(i.data()); + if (excluded.count(h)) + { + badBlock(_block, "Invalid uncle included"); + UncleInChain ex; + ex << errinfo_comment("Uncle in block already mentioned"); + ex << errinfo_unclesExcluded(excluded); + ex << errinfo_hash256(sha3(i.data())); + BOOST_THROW_EXCEPTION(ex); + } + excluded.insert(h); - BlockInfo uncle = BlockInfo::fromHeader(i.data(), (_ir & ImportRequirements::CheckUncles) ? CheckEverything : IgnoreNonce, h); - BlockInfo uncleParent(_bc.block(uncle.parentHash)); - if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 7) - { - badBlock(_block, "Uncle too old"); - cwarn << " Uncle number: " << uncle.number; - cwarn << " Uncle parent number: " << uncleParent.number; - cwarn << " Block number: " << m_currentBlock.number; - BOOST_THROW_EXCEPTION(UncleTooOld()); + BlockInfo uncle; + BlockInfo uncleParent; + uncle = BlockInfo::fromHeader(i.data(), (_ir & ImportRequirements::CheckUncles) ? CheckEverything : IgnoreNonce, h); + if (!_bc.isKnown(uncle.parentHash)) + BOOST_THROW_EXCEPTION(UnknownParent()); + + uncleParent = BlockInfo(_bc.block(uncle.parentHash)); + if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 7) + { + badBlock(_block, "Uncle too old"); + cwarn << " Uncle number: " << uncle.number; + cwarn << " Uncle parent number: " << uncleParent.number; + cwarn << " Block number: " << m_currentBlock.number; + UncleTooOld ex; + ex << errinfo_uncleNumber(uncle.number); + ex << errinfo_currentNumber(m_currentBlock.number); + BOOST_THROW_EXCEPTION(ex); + } + else if (uncle.number == m_currentBlock.number) + { + badBlock(_block, "Uncle is brother"); + cwarn << " Uncle number: " << uncle.number; + cwarn << " Uncle parent number: " << uncleParent.number; + cwarn << " Block number: " << m_currentBlock.number; + UncleIsBrother ex; + ex << errinfo_uncleNumber(uncle.number); + ex << errinfo_currentNumber(m_currentBlock.number); + BOOST_THROW_EXCEPTION(ex); + } + uncle.verifyParent(uncleParent); + +// tdIncrease += uncle.difficulty; + rewarded.push_back(uncle); + ++ii; } - else if (uncle.number == m_currentBlock.number) + catch (Exception& ex) { - badBlock(_block, "Uncle is brother"); - cwarn << " Uncle number: " << uncle.number; - cwarn << " Uncle parent number: " << uncleParent.number; - cwarn << " Block number: " << m_currentBlock.number; - BOOST_THROW_EXCEPTION(UncleIsBrother()); + ex << errinfo_uncleIndex(ii); + throw; } - uncle.verifyParent(uncleParent); - -// tdIncrease += uncle.difficulty; - rewarded.push_back(uncle); } applyRewards(rewarded); @@ -731,15 +768,8 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement if (m_currentBlock.stateRoot != m_previousBlock.stateRoot && m_currentBlock.stateRoot != rootHash()) { badBlock(_block, "Bad state root"); - cnote << " Given to be:" << m_currentBlock.stateRoot; - // TODO: Fix -// cnote << SecureTrieDB(&m_db, m_currentBlock.stateRoot); - cnote << " Calculated to be:" << rootHash(); - cwarn << " VMTrace:\n" << vmTrace(_block, _bc, _ir); -// cnote << m_state; - // Rollback the trie. m_db.rollback(); - BOOST_THROW_EXCEPTION(InvalidStateRoot()); + BOOST_THROW_EXCEPTION(InvalidStateRoot() << HashMismatchError(rootHash(), m_currentBlock.stateRoot)); } if (m_currentBlock.gasUsed != gasUsed()) diff --git a/libethereum/State.h b/libethereum/State.h index 55d5cfb4c..fa41e312c 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -46,6 +46,20 @@ namespace test { class ImportTest; class StateLoader; } namespace eth { +// Import-specific errinfos +using errinfo_uncleIndex = boost::error_info; +using errinfo_currentNumber = boost::error_info; +using errinfo_uncleNumber = boost::error_info; +using errinfo_unclesExcluded = boost::error_info; + +using errinfo_transactionIndex = boost::error_info; + +using errinfo_vmtrace = boost::error_info; +using errinfo_receipts = boost::error_info>; +using errinfo_logBloom = boost::error_info; +using LogBloomMismatchError = boost::tuple; + + class BlockChain; class State; diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index b8d8d64c1..65c18f4fd 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -60,8 +60,25 @@ std::string badTransaction(bytesConstRef _tx, string const& _err) return ret.str(); } -TransactionException dev::eth::toTransactionException(VMException const& _e) +TransactionException dev::eth::toTransactionException(Exception const& _e) { + // Basic Transaction exceptions + if (!!dynamic_cast(&_e)) + return TransactionException::BadRLP; + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfGasIntrinsic; + if (!!dynamic_cast(&_e)) + return TransactionException::InvalidSignature; + // Executive exceptions + if (!!dynamic_cast(&_e)) + return TransactionException::OutOfGasBase; + if (!!dynamic_cast(&_e)) + return TransactionException::InvalidNonce; + if (!!dynamic_cast(&_e)) + return TransactionException::NotEnoughCash; + if (!!dynamic_cast(&_e)) + return TransactionException::BlockGasLimitReached; + // VM execution exceptions if (!!dynamic_cast(&_e)) return TransactionException::BadInstruction; if (!!dynamic_cast(&_e)) @@ -75,6 +92,28 @@ TransactionException dev::eth::toTransactionException(VMException const& _e) return TransactionException::Unknown; } +std::ostream& dev::eth::operator<<(std::ostream& _out, TransactionException const& _er) +{ + switch (_er) + { + case TransactionException::None: _out << "None"; break; + case TransactionException::BadRLP: _out << "BadRLP"; break; + case TransactionException::OutOfGasIntrinsic: _out << "OutOfGasIntrinsic"; break; + case TransactionException::InvalidSignature: _out << "InvalidSignature"; break; + case TransactionException::InvalidNonce: _out << "InvalidNonce"; break; + case TransactionException::NotEnoughCash: _out << "NotEnoughCash"; break; + case TransactionException::OutOfGasBase: _out << "OutOfGasBase"; break; + case TransactionException::BlockGasLimitReached: _out << "BlockGasLimitReached"; break; + case TransactionException::BadInstruction: _out << "BadInstruction"; break; + case TransactionException::BadJumpDestination: _out << "BadJumpDestination"; break; + case TransactionException::OutOfGas: _out << "OutOfGas"; break; + case TransactionException::OutOfStack: _out << "OutOfStack"; break; + case TransactionException::StackUnderflow: _out << "StackUnderflow"; break; + default: _out << "Unknown"; break; + } + return _out; +} + Transaction::Transaction(bytesConstRef _rlpData, CheckTransaction _checkSig) { int field = 0; @@ -114,7 +153,7 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckTransaction _checkSig) throw; } if (_checkSig >= CheckTransaction::Cheap && !checkPayment()) - BOOST_THROW_EXCEPTION(OutOfGasBase() << RequirementError(gasRequired(), (bigint)gas())); + BOOST_THROW_EXCEPTION(OutOfGasIntrinsic() << RequirementError(gasRequired(), (bigint)gas())); } Address const& Transaction::safeSender() const noexcept diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 33928cd37..fb5566d9a 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -25,6 +25,7 @@ #include #include #include + namespace dev { namespace eth @@ -48,6 +49,8 @@ enum class TransactionException { None = 0, Unknown, + BadRLP, + OutOfGasIntrinsic, ///< Too little gas to pay for the base transaction cost. InvalidSignature, InvalidNonce, NotEnoughCash, @@ -69,7 +72,8 @@ enum class CodeDeposit struct VMException; -TransactionException toTransactionException(VMException const& _e); +TransactionException toTransactionException(Exception const& _e); +std::ostream& operator<<(std::ostream& _out, TransactionException const& _er); /// Description of the result of executing a transaction. struct ExecutionResult diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 7c0498ef0..c69619fcd 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -203,27 +203,29 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c switch (er.excepted) { - case TransactionException::None: - break; - case TransactionException::NotEnoughCash: - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Insufficient balance for contract deployment")); - case TransactionException::OutOfGasBase: - case TransactionException::OutOfGas: - BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas")); - case TransactionException::BlockGasLimitReached: - BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Block gas limit reached")); - case TransactionException::OutOfStack: - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Out of stack")); - case TransactionException::StackUnderflow: - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Stack underflow")); - //these should not happen in mix - case TransactionException::Unknown: - case TransactionException::BadInstruction: - case TransactionException::BadJumpDestination: - case TransactionException::InvalidSignature: - case TransactionException::InvalidNonce: - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Internal execution error")); - }; + case TransactionException::None: + break; + case TransactionException::NotEnoughCash: + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Insufficient balance for contract deployment")); + case TransactionException::OutOfGasIntrinsic: + case TransactionException::OutOfGasBase: + case TransactionException::OutOfGas: + BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas")); + case TransactionException::BlockGasLimitReached: + BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Block gas limit reached")); + case TransactionException::OutOfStack: + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Out of stack")); + case TransactionException::StackUnderflow: + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Stack underflow")); + //these should not happen in mix + case TransactionException::Unknown: + case TransactionException::BadInstruction: + case TransactionException::BadJumpDestination: + case TransactionException::InvalidSignature: + case TransactionException::InvalidNonce: + case TransactionException::BadRLP: + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("Internal execution error")); + } ExecutionResult d; d.result = er; From 3bc335d59b421e78378a87db4fda479d495ec63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 9 Jun 2015 09:31:11 +0200 Subject: [PATCH 17/36] VM refactor: small changes --- libevm/VM.cpp | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 94d5f8376..08fad9d66 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -184,30 +184,24 @@ void VM::checkRequirements(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) { - // Reset leftovers from possible previous run - m_curPC = 0; - m_jumpDests.clear(); - m_stack.reserve((unsigned)c_stackLimit); unique_ptr callParams; - if (m_jumpDests.empty()) - for (unsigned i = 0; i < _ext.code.size(); ++i) - { - if (_ext.code[i] == (byte)Instruction::JUMPDEST) - m_jumpDests.push_back(i); - else if (_ext.code[i] >= (byte)Instruction::PUSH1 && _ext.code[i] <= (byte)Instruction::PUSH32) - i += _ext.code[i] - (unsigned)Instruction::PUSH1 + 1; - } + for (size_t i = 0; i < _ext.code.size(); ++i) + { + if (_ext.code[i] == (byte)Instruction::JUMPDEST) + m_jumpDests.push_back(i); + else if (_ext.code[i] >= (byte)Instruction::PUSH1 && _ext.code[i] <= (byte)Instruction::PUSH32) + i += _ext.code[i] - (size_t)Instruction::PUSH1 + 1; + } + u256 nextPC = m_curPC + 1; for (m_steps = 0; true; m_curPC = nextPC, nextPC = m_curPC + 1, ++m_steps) { - // INSTRUCTION... Instruction inst = (Instruction)_ext.getCode(m_curPC); checkRequirements(io_gas, _ext, _onOp, inst); - // EXECUTE... switch (inst) { case Instruction::ADD: @@ -303,7 +297,7 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) case Instruction::SIGNEXTEND: if (m_stack.back() < 31) { - unsigned const testBit(m_stack.back() * 8 + 7); + auto testBit = static_cast(m_stack.back()) * 8 + 7; u256& number = m_stack[m_stack.size() - 2]; u256 mask = ((u256(1) << testBit) - 1); if (boost::multiprecision::bit_test(number, testBit)) @@ -484,7 +478,7 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) case Instruction::DUP15: case Instruction::DUP16: { - auto n = 1 + (int)inst - (int)Instruction::DUP1; + auto n = 1 + (unsigned)inst - (unsigned)Instruction::DUP1; m_stack.push_back(m_stack[m_stack.size() - n]); break; } @@ -505,7 +499,7 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) case Instruction::SWAP15: case Instruction::SWAP16: { - unsigned n = (int)inst - (int)Instruction::SWAP1 + 2; + auto n = (unsigned)inst - (unsigned)Instruction::SWAP1 + 2; auto d = m_stack.back(); m_stack.back() = m_stack[m_stack.size() - n]; m_stack[m_stack.size() - n] = d; From d0da772f2a1b8bbad004d2054f2c4e4e3cfcb1c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 9 Jun 2015 10:22:58 +0200 Subject: [PATCH 18/36] VM refactor: change type of code pointer (pc) to uint64_t. --- libevm/VM.cpp | 14 +++++++------- libevm/VM.h | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 08fad9d66..ca54d2540 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -196,8 +196,8 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) i += _ext.code[i] - (size_t)Instruction::PUSH1 + 1; } - u256 nextPC = m_curPC + 1; - for (m_steps = 0; true; m_curPC = nextPC, nextPC = m_curPC + 1, ++m_steps) + m_steps = 0; + for (auto nextPC = m_curPC + 1; true; m_curPC = nextPC, nextPC = m_curPC + 1, ++m_steps) { Instruction inst = (Instruction)_ext.getCode(m_curPC); checkRequirements(io_gas, _ext, _onOp, inst); @@ -533,16 +533,16 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) m_stack.pop_back(); break; case Instruction::JUMP: - nextPC = m_stack.back(); - if (find(m_jumpDests.begin(), m_jumpDests.end(), (uint64_t)nextPC) == m_jumpDests.end() || nextPC > numeric_limits::max() ) + nextPC = static_cast(m_stack.back()); + if (find(m_jumpDests.begin(), m_jumpDests.end(), nextPC) == m_jumpDests.end() || m_stack.back() > numeric_limits::max()) BOOST_THROW_EXCEPTION(BadJumpDestination()); m_stack.pop_back(); break; case Instruction::JUMPI: if (m_stack[m_stack.size() - 2]) { - nextPC = m_stack.back(); - if (find(m_jumpDests.begin(), m_jumpDests.end(), (uint64_t)nextPC) == m_jumpDests.end() || nextPC > numeric_limits::max() ) + nextPC = static_cast(m_stack.back()); + if (find(m_jumpDests.begin(), m_jumpDests.end(), nextPC) == m_jumpDests.end() || m_stack.back() > numeric_limits::max()) BOOST_THROW_EXCEPTION(BadJumpDestination()); } m_stack.pop_back(); @@ -596,7 +596,7 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) break; case Instruction::CREATE: { - u256 endowment = m_stack.back(); + auto& endowment = m_stack.back(); m_stack.pop_back(); unsigned initOff = (unsigned)m_stack.back(); m_stack.pop_back(); diff --git a/libevm/VM.h b/libevm/VM.h index 7c0209329..1931ad748 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -54,7 +54,7 @@ class VM: public VMFace public: virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) override final; - u256 curPC() const { return m_curPC; } + uint64_t curPC() const { return m_curPC; } bytes const& memory() const { return m_temp; } u256s const& stack() const { return m_stack; } @@ -64,7 +64,7 @@ private: void require(u256 _n, u256 _d) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } if (m_stack.size() - _n + _d > c_stackLimit) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_d - _n), (bigint)m_stack.size())); } } void requireMem(unsigned _n) { if (m_temp.size() < _n) { m_temp.resize(_n); } } - u256 m_curPC = 0; + uint64_t m_curPC = 0; uint64_t m_steps = 0; bytes m_temp; u256s m_stack; From a9187870d67d4628af64cbe4a282d058281620c1 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 9 Jun 2015 10:34:54 +0200 Subject: [PATCH 19/36] fixed chain downloading over PV61 --- libethereum/EthereumHost.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 02fac5541..c76fcf82c 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -254,10 +254,7 @@ void EthereumHost::onPeerStatus(EthereumPeer* _peer) estimatePeerHashes(_peer); else { - if (_peer->m_latestBlockNumber > m_chain.number()) - _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number() + 1000; - else - _peer->m_expectedHashes = 1000; + _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number(); if (m_hashMan.chainSize() < _peer->m_expectedHashes) m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); } @@ -295,7 +292,7 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool } bool syncByNumber = _peer->m_syncHashNumber; - if (!syncByNumber && _peer->m_latestHash != m_syncingLatestHash) + if (!syncByNumber && _peer->m_syncHash != m_syncingLatestHash) { // Obsolete hashes, discard continueSync(_peer); From 7b87d29b831233dee285b03ccecc0bf54f2288b0 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 9 Jun 2015 11:21:13 +0200 Subject: [PATCH 20/36] Set timeout back to 10s --- libethereum/EthereumPeer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 7c0b56d7c..63d407187 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -151,7 +151,7 @@ void EthereumPeer::setAsking(Asking _a) void EthereumPeer::tick() { - if (chrono::system_clock::now() - m_lastAsk > chrono::seconds(20) && m_asking != Asking::Nothing) + if (chrono::system_clock::now() - m_lastAsk > chrono::seconds(10) && m_asking != Asking::Nothing) // timeout session()->disconnect(PingTimeout); } From 32fe8b893de5c3df88f22c1e14f18a78d7a0a948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 9 Jun 2015 11:27:24 +0200 Subject: [PATCH 21/36] VM refactor: place CALL params on stack (reduces OS stack usage by ~30%). --- libevm/VM.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index ca54d2540..f48701c21 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -186,8 +186,6 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) { m_stack.reserve((unsigned)c_stackLimit); - unique_ptr callParams; - for (size_t i = 0; i < _ext.code.size(); ++i) { if (_ext.code[i] == (byte)Instruction::JUMPDEST) @@ -612,16 +610,14 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) case Instruction::CALL: case Instruction::CALLCODE: { - if (!callParams) - callParams.reset(new CallParameters); - - callParams->gas = m_stack.back(); + CallParameters callParams; + callParams.gas = m_stack.back(); if (m_stack[m_stack.size() - 3] > 0) - callParams->gas += c_callStipend; + callParams.gas += c_callStipend; m_stack.pop_back(); - callParams->codeAddress = asAddress(m_stack.back()); + callParams.codeAddress = asAddress(m_stack.back()); m_stack.pop_back(); - callParams->value = m_stack.back(); + callParams.value = m_stack.back(); m_stack.pop_back(); unsigned inOff = (unsigned)m_stack.back(); @@ -633,19 +629,19 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) unsigned outSize = (unsigned)m_stack.back(); m_stack.pop_back(); - if (_ext.balance(_ext.myAddress) >= callParams->value && _ext.depth < 1024) + if (_ext.balance(_ext.myAddress) >= callParams.value && _ext.depth < 1024) { - callParams->onOp = _onOp; - callParams->senderAddress = _ext.myAddress; - callParams->receiveAddress = inst == Instruction::CALL ? callParams->codeAddress : callParams->senderAddress; - callParams->data = bytesConstRef(m_temp.data() + inOff, inSize); - callParams->out = bytesRef(m_temp.data() + outOff, outSize); - m_stack.push_back(_ext.call(*callParams)); + callParams.onOp = _onOp; + callParams.senderAddress = _ext.myAddress; + callParams.receiveAddress = inst == Instruction::CALL ? callParams.codeAddress : callParams.senderAddress; + callParams.data = bytesConstRef(m_temp.data() + inOff, inSize); + callParams.out = bytesRef(m_temp.data() + outOff, outSize); + m_stack.push_back(_ext.call(callParams)); } else m_stack.push_back(0); - io_gas += callParams->gas; + io_gas += callParams.gas; break; } case Instruction::RETURN: From 25270123d057fcf4273e1dfb03a82024f051c017 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 8 Jun 2015 17:16:53 +0200 Subject: [PATCH 22/36] Argument to list available opencl devices and platforms - Additionally some small refactoring in how some query functions are processed for GPU mining. --- ethminer/MinerAux.h | 7 ++++- libethash-cl/ethash_cl_miner.cpp | 51 +++++++++++++++++++++++++++++--- libethash-cl/ethash_cl_miner.h | 5 +++- libethcore/Ethash.cpp | 15 ++++++---- libethcore/Ethash.h | 6 ++-- 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h index 6a42dd774..245b97ceb 100644 --- a/ethminer/MinerAux.h +++ b/ethminer/MinerAux.h @@ -127,6 +127,11 @@ public: cerr << "Bad " << arg << " option: " << argv[i] << endl; throw BadArgument(); } + else if (arg == "--list-devices") + { + ProofOfWork::GPUMiner::listDevices(); + exit(0); + } else if (arg == "--use-chunks") { dagChunks = 4; @@ -175,7 +180,7 @@ public: m_minerType = MinerType::CPU; else if (arg == "-G" || arg == "--opencl") { - if (!ProofOfWork::GPUMiner::haveSufficientGPUMemory()) + if (!ProofOfWork::GPUMiner::haveSufficientMemory()) { cout << "No GPU device with sufficient memory was found. Defaulting to CPU" << endl; m_minerType = MinerType::CPU; diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index f501d9642..2bdcfcd9a 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -127,7 +127,7 @@ unsigned ethash_cl_miner::get_num_devices(unsigned _platformId) return devices.size(); } -bool ethash_cl_miner::haveSufficientGPUMemory(unsigned _platformId) +bool ethash_cl_miner::haveSufficientGPUMemory() { std::vector platforms; cl::Platform::get(&platforms); @@ -136,15 +136,25 @@ bool ethash_cl_miner::haveSufficientGPUMemory(unsigned _platformId) ETHCL_LOG("No OpenCL platforms found."); return false; } + for (unsigned i = 0; i < platforms.size(); ++i) + if (haveSufficientGPUMemory(i)) + return true; + + return false; +} + +bool ethash_cl_miner::haveSufficientGPUMemory(unsigned _platformId) +{ + std::vector platforms; + cl::Platform::get(&platforms); + if (_platformId >= platforms.size()) + return false; std::vector devices; unsigned platform_num = std::min(_platformId, platforms.size() - 1); platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); if (devices.empty()) - { - ETHCL_LOG("No OpenCL devices found."); return false; - } for (cl::Device const& device: devices) { @@ -168,6 +178,39 @@ bool ethash_cl_miner::haveSufficientGPUMemory(unsigned _platformId) return false; } +void ethash_cl_miner::listDevices() +{ + std::vector platforms; + cl::Platform::get(&platforms); + if (platforms.empty()) + { + ETHCL_LOG("No OpenCL platforms found."); + return; + } + for (unsigned i = 0; i < platforms.size(); ++i) + listDevices(i); +} + +void ethash_cl_miner::listDevices(unsigned _platformId) +{ + std::vector platforms; + cl::Platform::get(&platforms); + if (_platformId >= platforms.size()) + return; + + std::string outString ="Listing OpenCL devices for platform " + to_string(_platformId) + "\n[deviceID] deviceName\n"; + std::vector devices; + platforms[_platformId].getDevices(CL_DEVICE_TYPE_ALL, &devices); + unsigned i = 0; + std::string deviceString; + for (cl::Device const& device: devices) + { + outString += "[" + to_string(i) + "] " + device.getInfo() + "\n"; + ++i; + } + ETHCL_LOG(outString); +} + void ethash_cl_miner::finish() { if (m_queue()) diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h index cdc4cf07f..4d5317186 100644 --- a/libethash-cl/ethash_cl_miner.h +++ b/libethash-cl/ethash_cl_miner.h @@ -35,7 +35,10 @@ public: static unsigned get_num_platforms(); static unsigned get_num_devices(unsigned _platformId = 0); static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); - static bool haveSufficientGPUMemory(unsigned _platformId = 0); + static bool haveSufficientGPUMemory(); + static bool haveSufficientGPUMemory(unsigned _platformId); + static void listDevices(); + static void listDevices(unsigned _platformId); bool init( uint8_t const* _dag, diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 0ea09a5bc..f715d6912 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -364,11 +364,6 @@ void Ethash::GPUMiner::pause() stopWorking(); } -bool Ethash::GPUMiner::haveSufficientGPUMemory() -{ - return ethash_cl_miner::haveSufficientGPUMemory(s_platformId); -} - std::string Ethash::GPUMiner::platformInfo() { return ethash_cl_miner::platform_info(s_platformId, s_deviceId); @@ -379,6 +374,16 @@ unsigned Ethash::GPUMiner::getNumDevices() return ethash_cl_miner::get_num_devices(s_platformId); } +void Ethash::GPUMiner::listDevices() +{ + return ethash_cl_miner::listDevices(); +} + +bool Ethash::GPUMiner::haveSufficientMemory() +{ + return ethash_cl_miner::haveSufficientGPUMemory(); +} + #endif } diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index 68c21c609..99df1dc71 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -87,10 +87,11 @@ public: static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); } static std::string platformInfo(); - static bool haveSufficientGPUMemory() { return false; } static void setDefaultPlatform(unsigned) {} static void setDagChunks(unsigned) {} static void setDefaultDevice(unsigned) {} + static void listDevices() {} + static bool haveSufficientMemory() { return false; } static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, std::thread::hardware_concurrency()); } protected: void kickOff() override @@ -117,8 +118,9 @@ public: static unsigned instances() { return s_numInstances > 0 ? s_numInstances : 1; } static std::string platformInfo(); - static bool haveSufficientGPUMemory(); static unsigned getNumDevices(); + static void listDevices(); + static bool haveSufficientMemory(); static void setDefaultPlatform(unsigned _id) { s_platformId = _id; } static void setDefaultDevice(unsigned _id) { s_deviceId = _id; } static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } From 3a417e5fe52da9534d6b0dccb9c8a1c9c6a21951 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 9 Jun 2015 11:57:06 +0200 Subject: [PATCH 23/36] Improved type conversion error messages. --- libsolidity/AST.cpp | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 4c7168afa..acb7b50c5 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -410,7 +410,14 @@ void InheritanceSpecifier::checkTypeRequirements() BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for constructor call.")); for (size_t i = 0; i < m_arguments.size(); ++i) if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i])) - BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in constructer call.")); + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( + "Invalid type for argument in constructor call. " + "Invalid implicit conversion from " + + m_arguments[i]->getType()->toString() + + " to " + + parameterTypes[i]->toString() + + " requested." + )); } TypePointer StructDefinition::getType(ContractDefinition const*) const @@ -592,7 +599,14 @@ void ModifierInvocation::checkTypeRequirements(vector BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for modifier invocation.")); for (size_t i = 0; i < m_arguments.size(); ++i) if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*(*parameters)[i]->getType())) - BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in modifier invocation.")); + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( + "Invalid type for argument in modifier invocation. " + "Invalid implicit conversion from " + + m_arguments[i]->getType()->toString() + + " to " + + (*parameters)[i]->getType()->toString() + + " requested." + )); } void EventDefinition::checkTypeRequirements() @@ -782,9 +796,18 @@ void FunctionCall::checkTypeRequirements(TypePointers const*) { // call by positional arguments for (size_t i = 0; i < m_arguments.size(); ++i) - if (!functionType->takesArbitraryParameters() && - !m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i])) - BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError("Invalid type for argument in function call.")); + if ( + !functionType->takesArbitraryParameters() && + !m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]) + ) + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( + "Invalid type for argument in function call. " + "Invalid implicit conversion from " + + m_arguments[i]->getType()->toString() + + " to " + + parameterTypes[i]->toString() + + " requested." + )); } else { @@ -808,7 +831,14 @@ void FunctionCall::checkTypeRequirements(TypePointers const*) if (parameterNames[j] == *m_names[i]) { // check type convertible if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j])) - BOOST_THROW_EXCEPTION(createTypeError("Invalid type for argument in function call.")); + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( + "Invalid type for argument in function call. " + "Invalid implicit conversion from " + + m_arguments[i]->getType()->toString() + + " to " + + parameterTypes[i]->toString() + + " requested." + )); found = true; break; From 095b6f81892d5a4a41ce377b62153d919f886a92 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 9 Jun 2015 19:35:28 +0900 Subject: [PATCH 24/36] Report bad blocks using published standards. --- eth/main.cpp | 1 + ethminer/CMakeLists.txt | 7 +-- libdevcore/Exceptions.h | 39 ++++++++----- libethcore/BlockInfo.cpp | 24 ++++++-- libethcore/Exceptions.h | 73 ++++++++++++----------- libethereum/BlockChain.cpp | 48 ++++++++------- libethereum/BlockChain.h | 5 ++ libethereum/BlockQueue.cpp | 55 +++++++----------- libethereum/BlockQueue.h | 4 ++ libethereum/CMakeLists.txt | 7 +++ libethereum/Client.cpp | 104 +++++++++++++++++++++++++++++++++ libethereum/Client.h | 8 +++ libethereum/Executive.cpp | 116 +++++++++++++++++++++++++++++++------ libethereum/Executive.h | 18 ++++++ libethereum/Sentinel.h | 31 ++++++++++ libethereum/State.cpp | 17 +++--- libethereum/State.h | 8 ++- libevm/VMFace.h | 1 + libevmcore/Exceptions.h | 4 +- 19 files changed, 427 insertions(+), 143 deletions(-) create mode 100644 libethereum/Sentinel.h diff --git a/eth/main.cpp b/eth/main.cpp index 7a85141f4..06611deaa 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -125,6 +125,7 @@ void help() << " --session-sign-key
Sign all transactions with the key of the given address for this session only." << endl << " --master Give the master password for the key store." << endl << " --password Give a password for a private key." << endl + << " --sentinel Set the sentinel for reporting bad blocks or chain issues." << endl << endl << "Client transacting:" << endl /*<< " -B,--block-fees Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl diff --git a/ethminer/CMakeLists.txt b/ethminer/CMakeLists.txt index d364f6ed1..3ec92fc14 100644 --- a/ethminer/CMakeLists.txt +++ b/ethminer/CMakeLists.txt @@ -5,7 +5,10 @@ aux_source_directory(. SRC_LIST) include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) +if (JSONRPC) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +endif() set(EXECUTABLE ethminer) @@ -19,10 +22,6 @@ target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) if (JSONRPC) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_CLIENT_LIBRARIES}) - target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES}) - if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) - eth_copy_dlls(${EXECUTABLE} CURL_DLLS) - endif() endif() target_link_libraries(${EXECUTABLE} ethcore) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 025568efa..7d6fae77c 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -30,7 +30,8 @@ namespace dev { -// base class for all exceptions + +/// Base class for all exceptions. struct Exception: virtual std::exception, virtual boost::exception { Exception(std::string _message = std::string()): m_message(std::move(_message)) {} @@ -40,20 +41,26 @@ private: std::string m_message; }; -struct BadHexCharacter: virtual Exception {}; -struct RLPException: virtual Exception {}; -struct BadCast: virtual RLPException {}; -struct BadRLP: virtual RLPException {}; -struct OversizeRLP: virtual RLPException {}; -struct UndersizeRLP: virtual RLPException {}; -struct NoNetworking: virtual Exception {}; -struct NoUPnPDevice: virtual Exception {}; -struct RootNotFound: virtual Exception {}; -struct BadRoot: virtual Exception {}; -struct FileError: virtual Exception {}; -struct Overflow: virtual Exception {}; +#define DEV_SIMPLE_EXCEPTION(X) struct X: virtual Exception { public: X(): Exception(#X) {} } + +/// Base class for all RLP exceptions. +struct RLPException: virtual Exception { RLPException(std::string _message = std::string()): Exception(_message) {} }; +#define DEV_SIMPLE_EXCEPTION_RLP(X) struct X: virtual RLPException { public: X(): RLPException(#X) {} } + +DEV_SIMPLE_EXCEPTION_RLP(BadCast); +DEV_SIMPLE_EXCEPTION_RLP(BadRLP); +DEV_SIMPLE_EXCEPTION_RLP(OversizeRLP); +DEV_SIMPLE_EXCEPTION_RLP(UndersizeRLP); + +DEV_SIMPLE_EXCEPTION(BadHexCharacter); +DEV_SIMPLE_EXCEPTION(NoNetworking); +DEV_SIMPLE_EXCEPTION(NoUPnPDevice); +DEV_SIMPLE_EXCEPTION(RootNotFound); +DEV_SIMPLE_EXCEPTION(BadRoot); +DEV_SIMPLE_EXCEPTION(FileError); +DEV_SIMPLE_EXCEPTION(Overflow); +DEV_SIMPLE_EXCEPTION(FailedInvariant); struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; -struct FailedInvariant: virtual Exception {}; struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} }; // error information to be added to exceptions @@ -66,5 +73,7 @@ using errinfo_min = boost::error_info; using errinfo_max = boost::error_info; using RequirementError = boost::tuple; using errinfo_hash256 = boost::error_info; -using HashMismatchError = boost::tuple; +using errinfo_required_h256 = boost::error_info; +using errinfo_got_h256 = boost::error_info; +using Hash256RequirementError = boost::tuple; } diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index 0e125b607..69da52b09 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -139,7 +139,6 @@ void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const mixHash = _header[field = 13].toHash(RLP::VeryStrict); nonce = _header[field = 14].toHash(RLP::VeryStrict); } - catch (Exception const& _e) { _e << errinfo_name("invalid block header format") << BadFieldError(field, toHex(_header[field].data().toBytes())); @@ -151,9 +150,26 @@ void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const // check it hashes according to proof of work or that it's the genesis block. if (_s == CheckEverything && parentHash && !ProofOfWork::verify(*this)) - BOOST_THROW_EXCEPTION(InvalidBlockNonce() << errinfo_hash256(headerHash(WithoutNonce)) << errinfo_nonce(nonce) << errinfo_difficulty(difficulty)); + { + InvalidBlockNonce ex; + ex << errinfo_hash256(headerHash(WithoutNonce)); + ex << errinfo_nonce(nonce); + ex << errinfo_difficulty(difficulty); + ex << errinfo_seedHash(seedHash()); + ex << errinfo_target(boundary()); + ex << errinfo_mixHash(mixHash); + Ethash::Result er = EthashAux::eval(seedHash(), headerHash(WithoutNonce), nonce); + ex << errinfo_ethashResult(make_tuple(er.value, er.mixHash)); + BOOST_THROW_EXCEPTION(ex); + } else if (_s == QuickNonce && parentHash && !ProofOfWork::preVerify(*this)) - BOOST_THROW_EXCEPTION(InvalidBlockNonce() << errinfo_hash256(headerHash(WithoutNonce)) << errinfo_nonce(nonce) << errinfo_difficulty(difficulty)); + { + InvalidBlockNonce ex; + ex << errinfo_hash256(headerHash(WithoutNonce)); + ex << errinfo_nonce(nonce); + ex << errinfo_difficulty(difficulty); + BOOST_THROW_EXCEPTION(ex); + } if (_s != CheckNothing) { @@ -224,7 +240,7 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const for (auto const& t: txs) cdebug << toHex(t); - BOOST_THROW_EXCEPTION(InvalidTransactionsHash() << HashMismatchError(expectedRoot, transactionsRoot)); + BOOST_THROW_EXCEPTION(InvalidTransactionsRoot() << Hash256RequirementError(expectedRoot, transactionsRoot)); } clog(BlockInfoDiagnosticsChannel) << "Expected uncle hash:" << toString(sha3(root[2].data())); if (sha3Uncles != sha3(root[2].data())) diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index b35a3abe9..b411ea416 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -35,42 +35,45 @@ using errinfo_field = boost::error_info; using errinfo_data = boost::error_info; using errinfo_nonce = boost::error_info; using errinfo_difficulty = boost::error_info; +using errinfo_target = boost::error_info; +using errinfo_seedHash = boost::error_info; +using errinfo_mixHash = boost::error_info; +using errinfo_ethashResult = boost::error_info>; using BadFieldError = boost::tuple; -struct DatabaseAlreadyOpen: virtual dev::Exception {}; -struct OutOfGasBase: virtual dev::Exception {}; -struct OutOfGasIntrinsic: virtual dev::Exception {}; -struct NotEnoughAvailableSpace: virtual dev::Exception {}; -struct NotEnoughCash: virtual dev::Exception {}; -struct GasPriceTooLow: virtual dev::Exception {}; -struct BlockGasLimitReached: virtual dev::Exception {}; -struct NoSuchContract: virtual dev::Exception {}; -struct ContractAddressCollision: virtual dev::Exception {}; -struct FeeTooSmall: virtual dev::Exception {}; -struct TooMuchGasUsed: virtual dev::Exception {}; -struct ExtraDataTooBig: virtual dev::Exception {}; -struct InvalidSignature: virtual dev::Exception {}; -struct InvalidBlockFormat: virtual dev::Exception {}; -struct InvalidUnclesHash: virtual dev::Exception {}; -struct TooManyUncles: virtual dev::Exception {}; -struct UncleTooOld: virtual dev::Exception {}; -struct UncleIsBrother: virtual dev::Exception {}; -struct UncleInChain: virtual dev::Exception {}; -struct InvalidStateRoot: virtual dev::Exception {}; -struct InvalidGasUsed: virtual dev::Exception {}; -struct InvalidTransactionsRoot: virtual dev::Exception {}; -struct InvalidDifficulty: virtual dev::Exception {}; -struct InvalidGasLimit: virtual dev::Exception {}; -struct InvalidReceiptsStateRoot: virtual dev::Exception {}; -struct InvalidTimestamp: virtual dev::Exception {}; -struct InvalidLogBloom: virtual dev::Exception {}; -struct InvalidNonce: virtual dev::Exception {}; -struct InvalidBlockHeaderItemCount: virtual dev::Exception {}; -struct InvalidBlockNonce: virtual dev::Exception {}; -struct InvalidParentHash: virtual dev::Exception {}; -struct InvalidNumber: virtual dev::Exception {}; -struct InvalidContractAddress: virtual public dev::Exception {}; -struct DAGCreationFailure: virtual public dev::Exception {}; -struct DAGComputeFailure: virtual public dev::Exception {}; +DEV_SIMPLE_EXCEPTION(OutOfGasBase); +DEV_SIMPLE_EXCEPTION(OutOfGasIntrinsic); +DEV_SIMPLE_EXCEPTION(NotEnoughAvailableSpace); +DEV_SIMPLE_EXCEPTION(NotEnoughCash); +DEV_SIMPLE_EXCEPTION(GasPriceTooLow); +DEV_SIMPLE_EXCEPTION(BlockGasLimitReached); +DEV_SIMPLE_EXCEPTION(FeeTooSmall); +DEV_SIMPLE_EXCEPTION(TooMuchGasUsed); +DEV_SIMPLE_EXCEPTION(ExtraDataTooBig); +DEV_SIMPLE_EXCEPTION(InvalidSignature); +DEV_SIMPLE_EXCEPTION(InvalidBlockFormat); +DEV_SIMPLE_EXCEPTION(InvalidUnclesHash); +DEV_SIMPLE_EXCEPTION(TooManyUncles); +DEV_SIMPLE_EXCEPTION(UncleTooOld); +DEV_SIMPLE_EXCEPTION(UncleIsBrother); +DEV_SIMPLE_EXCEPTION(UncleInChain); +DEV_SIMPLE_EXCEPTION(InvalidStateRoot); +DEV_SIMPLE_EXCEPTION(InvalidGasUsed); +DEV_SIMPLE_EXCEPTION(InvalidTransactionsRoot); +DEV_SIMPLE_EXCEPTION(InvalidDifficulty); +DEV_SIMPLE_EXCEPTION(InvalidGasLimit); +DEV_SIMPLE_EXCEPTION(InvalidReceiptsStateRoot); +DEV_SIMPLE_EXCEPTION(InvalidTimestamp); +DEV_SIMPLE_EXCEPTION(InvalidLogBloom); +DEV_SIMPLE_EXCEPTION(InvalidNonce); +DEV_SIMPLE_EXCEPTION(InvalidBlockHeaderItemCount); +DEV_SIMPLE_EXCEPTION(InvalidBlockNonce); +DEV_SIMPLE_EXCEPTION(InvalidParentHash); +DEV_SIMPLE_EXCEPTION(InvalidNumber); + +DEV_SIMPLE_EXCEPTION(DatabaseAlreadyOpen); +DEV_SIMPLE_EXCEPTION(DAGCreationFailure); +DEV_SIMPLE_EXCEPTION(DAGComputeFailure); + } } diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 67e42d7c8..3838dd362 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -331,9 +331,18 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st // Can't continue - chain bad. badBlocks.push_back(block.first.hash()); } - catch (Exception const& _e) + catch (dev::eth::FutureTime) { - cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << LogTag::Error << diagnostic_information(_e); + cwarn << "ODD: Import queue contains a block with future time." << LogTag::Error << boost::current_exception_diagnostic_information(); + // NOTE: don't reimport since the queue should guarantee everything in the past. + // Can't continue - chain bad. + badBlocks.push_back(block.first.hash()); + } + catch (Exception& ex) + { + cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << LogTag::Error << diagnostic_information(ex); + if (m_onBad) + m_onBad(ex); // NOTE: don't reimport since the queue should guarantee everything in the right order. // Can't continue - chain bad. badBlocks.push_back(block.first.hash()); @@ -360,8 +369,10 @@ pair BlockChain::attemptImport(bytes const& _block, O { return make_pair(ImportResult::FutureTime, make_pair(h256s(), h256s())); } - catch (...) + catch (Exception& ex) { + if (m_onBad) + m_onBad(ex); return make_pair(ImportResult::Malformed, make_pair(h256s(), h256s())); } } @@ -379,10 +390,11 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import bi.verifyInternals(&_block); } #if ETH_CATCH - catch (Exception const& _e) + catch (Exception& ex) { - clog(BlockChainNote) << " Malformed block: " << diagnostic_information(_e); - _e << errinfo_comment("Malformed block "); + clog(BlockChainNote) << " Malformed block: " << diagnostic_information(ex); + ex << errinfo_now(time(0)); + ex << errinfo_block(_block); throw; } #endif @@ -470,14 +482,8 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla blb.blooms.push_back(s.receipt(i).bloom()); br.receipts.push_back(s.receipt(i)); } - try { - s.cleanup(true); - } - catch (BadRoot) - { - cwarn << "BadRoot error. Retrying import later."; - BOOST_THROW_EXCEPTION(FutureTime()); - } + + s.cleanup(true); td = pd.totalDifficulty + tdIncrease; @@ -520,20 +526,20 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla #endif } #if ETH_CATCH - catch (InvalidNonce const& _e) + catch (BadRoot& ex) { - clog(BlockChainNote) << " Malformed block: " << diagnostic_information(_e); - _e << errinfo_comment("Malformed block "); - throw; + cwarn << "BadRoot error. Retrying import later."; + BOOST_THROW_EXCEPTION(FutureTime()); } - catch (Exception const& _e) + catch (Exception& ex) { - clog(BlockChainWarn) << " Malformed block: " << diagnostic_information(_e); - _e << errinfo_comment("Malformed block "); + clog(BlockChainWarn) << " Malformed block: " << diagnostic_information(ex); clog(BlockChainWarn) << "Block: " << _bi.hash(); clog(BlockChainWarn) << _bi; clog(BlockChainWarn) << "Block parent: " << _bi.parentHash; clog(BlockChainWarn) << BlockInfo(block(_bi.parentHash)); + ex << errinfo_now(time(0)); + ex << errinfo_block(_block); throw; } #endif diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index a67ec9a9c..06a22e27b 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -256,6 +256,9 @@ public: /// Deallocate unused data. void garbageCollect(bool _force = false); + /// Change the function that is called with a bad block. + template void setOnBad(T const& _t) { m_onBad = _t; } + private: static h256 chunkId(unsigned _level, unsigned _index) { return h256(_index * 0xff + _level); } @@ -335,6 +338,8 @@ private: ldb::ReadOptions m_readOptions; ldb::WriteOptions m_writeOptions; + std::function m_onBad; ///< Called if we have a block that doesn't verify. + friend std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc); }; diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index 360bf915e..07c9ba090 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -26,6 +26,7 @@ #include #include #include "BlockChain.h" +#include "State.h" using namespace std; using namespace dev; using namespace dev::eth; @@ -76,56 +77,44 @@ void BlockQueue::verifierBody() std::pair res; swap(work.second, res.second); - try { - try { + try + { + try + { res.first.populate(res.second, CheckEverything, work.first); res.first.verifyInternals(&res.second); } - catch (InvalidBlockNonce&) - { - badBlock(res.second, "Invalid block nonce"); - cwarn << " Nonce:" << res.first.nonce.hex(); - cwarn << " PoWHash:" << res.first.headerHash(WithoutNonce).hex(); - cwarn << " SeedHash:" << res.first.seedHash().hex(); - cwarn << " Target:" << res.first.boundary().hex(); - cwarn << " MixHash:" << res.first.mixHash.hex(); - Ethash::Result er = EthashAux::eval(res.first.seedHash(), res.first.headerHash(WithoutNonce), res.first.nonce); - cwarn << " Ethash v:" << er.value.hex(); - cwarn << " Ethash mH:" << er.mixHash.hex(); - throw; - } - catch (Exception& _e) + catch (Exception& ex) { - badBlock(res.second, _e.what()); + clog(BlockChainNote) << " Malformed block: " << diagnostic_information(ex); + badBlock(res.second, ex.what()); + ex << errinfo_now(time(0)); + ex << errinfo_block(res.second); + if (m_onBad) + m_onBad(ex); throw; } RLP r(&res.second); + unsigned ii = 0; for (auto const& uncle: r[2]) { try { BlockInfo().populateFromHeader(RLP(uncle.data()), CheckEverything); } - catch (InvalidNonce&) - { - badBlockHeader(uncle.data(), "Invalid uncle nonce"); - BlockInfo bi = BlockInfo::fromHeader(uncle.data(), CheckNothing); - cwarn << " Nonce:" << bi.nonce.hex(); - cwarn << " PoWHash:" << bi.headerHash(WithoutNonce).hex(); - cwarn << " SeedHash:" << bi.seedHash().hex(); - cwarn << " Target:" << bi.boundary().hex(); - cwarn << " MixHash:" << bi.mixHash.hex(); - Ethash::Result er = EthashAux::eval(bi.seedHash(), bi.headerHash(WithoutNonce), bi.nonce); - cwarn << " Ethash v:" << er.value.hex(); - cwarn << " Ethash mH:" << er.mixHash.hex(); - throw; - } - catch (Exception& _e) + catch (Exception& ex) { - badBlockHeader(uncle.data(), _e.what()); + clog(BlockChainNote) << " Malformed block header: " << diagnostic_information(ex); + badBlockHeader(uncle.data(), ex.what()); + ex << errinfo_uncleIndex(ii); + ex << errinfo_now(time(0)); + ex << errinfo_block(res.second); + if (m_onBad) + m_onBad(ex); throw; } + ++ii; } } catch (...) diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h index 45043559b..3a299c5f6 100644 --- a/libethereum/BlockQueue.h +++ b/libethereum/BlockQueue.h @@ -110,6 +110,8 @@ public: template Handler onReady(T const& _t) { return m_onReady.add(_t); } + template void setOnBad(T const& _t) { m_onBad = _t; } + private: void noteReady_WITH_LOCK(h256 const& _b); @@ -134,6 +136,8 @@ private: std::vector m_verifiers; ///< Threads who only verify. bool m_deleting = false; ///< Exit condition for verifiers. + + std::function m_onBad; ///< Called if we have a block that doesn't verify. }; std::ostream& operator<<(std::ostream& _out, BlockQueueStatus const& _s); diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 8203402cb..7d8f27ee7 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -14,6 +14,10 @@ aux_source_directory(. SRC_LIST) include_directories(BEFORE ..) include_directories(${LEVELDB_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) +if (JSONRPC) +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +endif() set(EXECUTABLE ethereum) @@ -30,6 +34,9 @@ target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) target_link_libraries(${EXECUTABLE} secp256k1) +if (JSONRPC) + target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_CLIENT_LIBRARIES}) +endif() if (CMAKE_COMPILER_IS_MINGW) target_link_libraries(${EXECUTABLE} ssp shlwapi) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 9e2dfc0a6..ae03be9a4 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -25,9 +25,16 @@ #include #include #include +#if ETH_JSONRPC || !ETH_TRUE +#include +#include +#endif #include #include #include +#if ETH_JSONRPC || !ETH_TRUE +#include "Sentinel.h" +#endif #include "Defaults.h" #include "Executive.h" #include "EthereumHost.h" @@ -80,6 +87,101 @@ void VersionChecker::setOk() } } +void Client::onBadBlock(Exception& _ex) +{ + // BAD BLOCK!!! + bytes const& block = *boost::get_error_info(_ex); + if (!&block) + { + cwarn << "ODD: onBadBlock called but exception has no block in it."; + return; + } + + badBlock(block, _ex.what()); + cwarn << boost::diagnostic_information(_ex, true); + +#if ETH_JSONRPC || !ETH_TRUE + if (!m_sentinel.empty()) + { + Json::Value report; + + report["client"] = "cpp"; + report["version"] = Version; + report["protocolVersion"] = c_protocolVersion; + report["databaseVersion"] = c_databaseVersion; + report["errortype"] = _ex.what(); + report["block"] = toHex(block); + report["hint"] = Json::Value(Json::objectValue); + + // add the various hints. + if (unsigned const* uncleIndex = boost::get_error_info(_ex)) + { + // uncle that failed. + report["hints"]["uncleIndex"] = *uncleIndex; + } + else if (unsigned const* txIndex = boost::get_error_info(_ex)) + { + // transaction that failed. + report["hints"]["transactionIndex"] = *txIndex; + } + else + { + // general block failure. + } + + if (string const* vmtraceJson = boost::get_error_info(_ex)) + Json::Reader().parse(*vmtraceJson, report["hints"]["vmtrace"]); + if (vector const* receipts = boost::get_error_info(_ex)) + { + report["hints"]["receipts"] = Json::arrayValue; + for (auto const& r: *receipts) + report["hints"]["receipts"].append(toHex(r)); + } + if (h256Hash const* excluded = boost::get_error_info(_ex)) + { + report["hints"]["unclesExcluded"] = Json::arrayValue; + for (auto const& r: h256Set() + *excluded) + report["hints"]["unclesExcluded"].append(Json::Value(r.hex())); + } + +#define DEV_HINT_ERRINFO(X) \ + if (auto const* n = boost::get_error_info(_ex)) \ + report["hints"][#X] = toString(*n) +#define DEV_HINT_ERRINFO_HASH(X) \ + if (auto const* n = boost::get_error_info(_ex)) \ + report["hints"][#X] = n->hex() + + DEV_HINT_ERRINFO_HASH(hash256); + DEV_HINT_ERRINFO(uncleNumber); + DEV_HINT_ERRINFO(currentNumber); + DEV_HINT_ERRINFO(now); + DEV_HINT_ERRINFO(invalidSymbol); + DEV_HINT_ERRINFO(wrongAddress); + DEV_HINT_ERRINFO(comment); + DEV_HINT_ERRINFO(min); + DEV_HINT_ERRINFO(max); + + DEV_HINT_ERRINFO(required); + DEV_HINT_ERRINFO(got); + DEV_HINT_ERRINFO_HASH(required_LogBloom); + DEV_HINT_ERRINFO_HASH(got_LogBloom); + DEV_HINT_ERRINFO_HASH(required_h256); + DEV_HINT_ERRINFO_HASH(got_h256); + + jsonrpc::HttpClient client(m_sentinel); + Sentinel rpc(client); + try + { + rpc.eth_badBlock(report); + } + catch (...) + { + cwarn << "Error reporting to sentinel. Sure the address" << m_sentinel << "is correct?"; + } + } +#endif +} + void BasicGasPricer::update(BlockChain const& _bc) { unsigned c = 0; @@ -185,6 +287,8 @@ Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string c m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30); m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue); m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue); + m_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); + m_bc.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); }); m_gp->update(m_bc); diff --git a/libethereum/Client.h b/libethereum/Client.h index 5132b5a30..aed54f131 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -213,6 +213,8 @@ public: void retryUnkonwn() { m_bq.retryAllUnknown(); } /// Get a report of activity. ActivityReport activityReport() { ActivityReport ret; std::swap(m_report, ret); return ret; } + /// Set a JSONRPC server to which we can report bad blocks. + void setSentinel(std::string const& _server) { m_sentinel = _server; } protected: /// InterfaceStub methods @@ -278,6 +280,10 @@ private: /// @returns true only if it's worth bothering to prep the mining block. bool shouldServeWork() const { return m_bq.items().first == 0 && (isMining() || remoteActive()); } + /// Called when we have attempted to import a bad block. + /// @warning May be called from any thread. + void onBadBlock(Exception& _ex); + VersionChecker m_vc; ///< Dummy object to check & update the protocol version. CanonBlockChain m_bc; ///< Maintains block database. BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). @@ -317,6 +323,8 @@ private: Mutex x_signalled; std::atomic m_syncTransactionQueue = {false}; std::atomic m_syncBlockQueue = {false}; + + std::string m_sentinel; }; } diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index fe9a6c6c0..e89334370 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -19,6 +19,9 @@ #include "Executive.h" #include +#if ETH_JSONRPC || !ETH_TRUE +#include +#endif #include #include #include @@ -34,6 +37,101 @@ using namespace dev::eth; const char* VMTraceChannel::name() { return "EVM"; } const char* ExecutiveWarnChannel::name() { return WarnChannel::name(); } +StandardTrace::StandardTrace(): + m_trace(new Json::Value(Json::arrayValue)) +{} + +bool changesMemory(Instruction _inst) +{ + return + _inst == Instruction::MSTORE || + _inst == Instruction::MSTORE8 || + _inst == Instruction::CALL || + _inst == Instruction::CALLCODE || + _inst == Instruction::SHA3 || + _inst == Instruction::CALLDATACOPY || + _inst == Instruction::CODECOPY || + _inst == Instruction::EXTCODECOPY; +} + +bool changesStorage(Instruction _inst) +{ + return _inst == Instruction::SSTORE; +} + +void StandardTrace::operator()(uint64_t _steps, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, VM* voidVM, ExtVMFace const* voidExt) +{ + ExtVM const& ext = *static_cast(voidExt); + VM& vm = *voidVM; + + Json::Value r(Json::objectValue); + + Json::Value stack(Json::arrayValue); + for (auto const& i: vm.stack()) + stack.append(toHex(toCompactBigEndian(i), 1)); + r["stack"] = stack; + + bool newContext = false; + Instruction lastInst = Instruction::STOP; + + if (m_lastInst.size() == ext.depth) + { + // starting a new context + assert(m_lastInst.size() == ext.depth); + m_lastInst.push_back(inst); + newContext = true; + } + else if (m_lastInst.size() == ext.depth + 2) + { + // returned from old context + m_lastInst.pop_back(); + lastInst = m_lastInst.back(); + } + else if (m_lastInst.size() == ext.depth + 1) + { + // continuing in previous context + lastInst = m_lastInst.back(); + } + else + { + cwarn << "GAA!!! Tracing VM and more than one new/deleted stack frame between steps!"; + cwarn << "Attmepting naive recovery..."; + m_lastInst.resize(ext.depth + 1); + } + + if (changesMemory(lastInst) || newContext) + { + Json::Value mem(Json::arrayValue); + for (auto const& i: vm.memory()) + mem.append(toHex(toCompactBigEndian(i), 1)); + r["memory"] = mem; + } + + if (changesStorage(lastInst) || newContext) + { + Json::Value storage(Json::objectValue); + for (auto const& i: ext.state().storage(ext.myAddress)) + storage[toHex(toCompactBigEndian(i.first), 1)] = toHex(toCompactBigEndian(i.second), 1); + r["storage"] = storage; + } + + r["depth"] = ext.depth; + r["address"] = ext.myAddress.hex(); + r["steps"] = (unsigned)_steps; + r["inst"] = (unsigned)inst; + r["pc"] = toString(vm.curPC()); + r["gas"] = toString(gas); + r["gascost"] = toString(gasCost); + r["memexpand"] = toString(newMemSize); + + m_trace->append(r); +} + +string StandardTrace::json() const +{ + return Json::FastWriter().write(*m_trace); +} + Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level): m_s(_s), m_lastHashes(_bc.lastHashes((unsigned)_s.info().number - 1)), @@ -202,24 +300,6 @@ OnOpFunc Executive::simpleTrace() }; } -OnOpFunc Executive::standardTrace(ostream& o_output) -{ - return [&](uint64_t steps, Instruction inst, bigint newMemSize, bigint gasCost, bigint gas, VM* voidVM, ExtVMFace const* voidExt) - { - ExtVM const& ext = *static_cast(voidExt); - VM& vm = *voidVM; - - o_output << endl << " STACK" << endl; - for (auto i: vm.stack()) - o_output << (h256)i << endl; - o_output << " MEMORY" << endl << ((vm.memory().size() > 1000) ? " mem size greater than 1000 bytes " : memDump(vm.memory())); - o_output << " STORAGE" << endl; - for (auto const& i: ext.state().storage(ext.myAddress)) - o_output << showbase << hex << i.first << ": " << i.second << endl; - o_output << " < " << dec << ext.depth << " : " << ext.myAddress << " : #" << steps << " : " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " : " << dec << gas << " : -" << dec << gasCost << " : " << newMemSize << "x32" << " >"; - }; -} - bool Executive::go(OnOpFunc const& _onOp) { if (m_ext) diff --git a/libethereum/Executive.h b/libethereum/Executive.h index beeee3331..e2c910cd0 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -25,6 +25,11 @@ #include #include "Transaction.h" +namespace Json +{ + class Value; +} + namespace dev { namespace eth @@ -38,6 +43,19 @@ struct Manifest; struct VMTraceChannel: public LogChannel { static const char* name(); static const int verbosity = 11; }; struct ExecutiveWarnChannel: public LogChannel { static const char* name(); static const int verbosity = 6; }; +class StandardTrace +{ +public: + StandardTrace(); + void operator()(uint64_t _steps, Instruction _inst, bigint _newMemSize, bigint _gasCost, bigint _gas, VM* _vm, ExtVMFace const* _extVM); + + std::string json() const; + +private: + std::vector m_lastInst; + std::shared_ptr m_trace; +}; + /** * @brief Message-call/contract-creation executor; useful for executing transactions. * diff --git a/libethereum/Sentinel.h b/libethereum/Sentinel.h new file mode 100644 index 000000000..141a5ee58 --- /dev/null +++ b/libethereum/Sentinel.h @@ -0,0 +1,31 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_DEV_ETH_SENTINEL_H_ +#define JSONRPC_CPP_STUB_DEV_ETH_SENTINEL_H_ + +#include + +namespace dev { + namespace eth { + class Sentinel : public jsonrpc::Client + { + public: + Sentinel(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} + + int eth_badBlock(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_badBlock",p); + if (result.isInt()) + return result.asInt(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + }; + + } +} +#endif //JSONRPC_CPP_STUB_DEV_ETH_SENTINEL_H_ diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 848a2ce5f..d19cc556a 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -577,19 +577,20 @@ string State::vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequire LastHashes lh = _bc.lastHashes((unsigned)m_previousBlock.number); vector receipts; - ostringstream ss; + string ret; unsigned i = 0; for (auto const& tr: rlp[1]) { - ss << " VM Execution of transaction" << i << ":" << endl; - execute(lh, Transaction(tr.data(), CheckTransaction::Everything), Permanence::Committed, Executive::standardTrace(ss)); + StandardTrace st; + execute(lh, Transaction(tr.data(), CheckTransaction::Everything), Permanence::Committed, [&](uint64_t _steps, Instruction _inst, bigint _newMemSize, bigint _gasCost, bigint _gas, VM* _vm, ExtVMFace const* _extVM) { st(_steps, _inst, _newMemSize, _gasCost, _gas, _vm, _extVM); }); + ret += (ret.empty() ? "[" : ",") + st.json(); + RLPStream receiptRLP; m_receipts.back().streamRLP(receiptRLP); receipts.push_back(receiptRLP.out()); ++i; - ss << endl; } - return ss.str(); + return ret.empty() ? "[]" : (ret + "]"); } u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir) @@ -664,7 +665,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement cwarn << " VMTrace:\n" << vmTrace(_block, _bc, _ir); InvalidReceiptsStateRoot ex; - ex << HashMismatchError(receiptsRoot, m_currentBlock.receiptsRoot); + ex << Hash256RequirementError(receiptsRoot, m_currentBlock.receiptsRoot); ex << errinfo_receipts(receipts); ex << errinfo_vmtrace(vmTrace(_block, _bc, _ir)); BOOST_THROW_EXCEPTION(ex); @@ -681,7 +682,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement } cwarn << " Final bloom:" << m_currentBlock.logBloom.hex(); InvalidLogBloom ex; - ex << LogBloomMismatchError(logBloom(), m_currentBlock.logBloom); + ex << LogBloomRequirementError(logBloom(), m_currentBlock.logBloom); ex << errinfo_receipts(receipts); BOOST_THROW_EXCEPTION(ex); } @@ -769,7 +770,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement { badBlock(_block, "Bad state root"); m_db.rollback(); - BOOST_THROW_EXCEPTION(InvalidStateRoot() << HashMismatchError(rootHash(), m_currentBlock.stateRoot)); + BOOST_THROW_EXCEPTION(InvalidStateRoot() << Hash256RequirementError(rootHash(), m_currentBlock.stateRoot)); } if (m_currentBlock.gasUsed != gasUsed()) diff --git a/libethereum/State.h b/libethereum/State.h index fa41e312c..da9d6b23a 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -51,14 +51,16 @@ using errinfo_uncleIndex = boost::error_info; using errinfo_currentNumber = boost::error_info; using errinfo_uncleNumber = boost::error_info; using errinfo_unclesExcluded = boost::error_info; +using errinfo_block = boost::error_info; +using errinfo_now = boost::error_info; using errinfo_transactionIndex = boost::error_info; using errinfo_vmtrace = boost::error_info; using errinfo_receipts = boost::error_info>; -using errinfo_logBloom = boost::error_info; -using LogBloomMismatchError = boost::tuple; - +using errinfo_required_LogBloom = boost::error_info; +using errinfo_got_LogBloom = boost::error_info; +using LogBloomRequirementError = boost::tuple; class BlockChain; class State; diff --git a/libevm/VMFace.h b/libevm/VMFace.h index 2a9ed808e..cba1c7287 100644 --- a/libevm/VMFace.h +++ b/libevm/VMFace.h @@ -25,6 +25,7 @@ namespace dev namespace eth { +#define ETH_SIMPLE_EXCEPTION_VM(X) struct X: virtual VMException { public X(): VMException(#X) {} }; struct VMException: virtual Exception {}; struct BreakPointHit: virtual VMException {}; struct BadInstruction: virtual VMException {}; diff --git a/libevmcore/Exceptions.h b/libevmcore/Exceptions.h index 72af277df..f520ade5f 100644 --- a/libevmcore/Exceptions.h +++ b/libevmcore/Exceptions.h @@ -28,8 +28,8 @@ namespace dev namespace eth { -struct InvalidDeposit: virtual Exception {}; -struct InvalidOpcode: virtual Exception {}; +DEV_SIMPLE_EXCEPTION(InvalidDeposit); +DEV_SIMPLE_EXCEPTION(InvalidOpcode); } } From 45a589364e045396fcfd984f769677596a2dd44e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 9 Jun 2015 19:35:40 +0900 Subject: [PATCH 25/36] Add Sentinel RPC spec. --- libethereum/Sentinel.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 libethereum/Sentinel.json diff --git a/libethereum/Sentinel.json b/libethereum/Sentinel.json new file mode 100644 index 000000000..743e4ce44 --- /dev/null +++ b/libethereum/Sentinel.json @@ -0,0 +1,3 @@ +[ + { "name": "eth_badBlock", "params": [ {} ], "order": [], "returns": 0 } +] From cbf3a749afc625bdd550078deceefbcb6673618b Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 9 Jun 2015 12:46:02 +0200 Subject: [PATCH 26/36] fixed hashes estimation --- libethereum/EthereumHost.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index c76fcf82c..2483473c3 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -254,7 +254,8 @@ void EthereumHost::onPeerStatus(EthereumPeer* _peer) estimatePeerHashes(_peer); else { - _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number(); + if (_peer->m_latestBlockNumber > m_chain.number()) + _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number(); if (m_hashMan.chainSize() < _peer->m_expectedHashes) m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); } From 51c1e729e2a684f7ce071a3fb348761412e5afee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 9 Jun 2015 12:54:29 +0200 Subject: [PATCH 27/36] Fix use-after-free bug in VM. --- libevm/VM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index f48701c21..a1938231e 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -594,7 +594,7 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) break; case Instruction::CREATE: { - auto& endowment = m_stack.back(); + auto endowment = m_stack.back(); m_stack.pop_back(); unsigned initOff = (unsigned)m_stack.back(); m_stack.pop_back(); From 0858d06e11de400fa0c7bbb013e2873d6f98be7c Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 9 Jun 2015 14:26:23 +0200 Subject: [PATCH 28/36] Fixed null pointer issue with source name. --- mix/ClientModel.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index cad210f1b..17ff94503 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -539,7 +539,9 @@ void ClientModel::showDebuggerForTransaction(ExecutionResult const& _t) // filter out locations that match whole function or contract SourceLocation location = instruction.getLocation(); - QString source = QString::fromUtf8(location.sourceName->c_str()); + QString source; + if (location.sourceName) + source = QString::fromUtf8(location.sourceName->c_str()); if (m_codeModel->isContractOrFunctionLocation(location)) location = dev::SourceLocation(-1, -1, location.sourceName); From 15746684f851d02e42c3066e057423d9a181b63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 9 Jun 2015 14:28:20 +0200 Subject: [PATCH 29/36] VM refactor: use binary search to verify jump destination. --- libevm/VM.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index a1938231e..36fba6e43 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -194,6 +194,14 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) i += _ext.code[i] - (size_t)Instruction::PUSH1 + 1; } + auto verifyJumpDest = [](u256 const& _dest, std::vector const& _validDests) + { + auto nextPC = static_cast(_dest); + if (!std::binary_search(_validDests.begin(), _validDests.end(), nextPC) || _dest > std::numeric_limits::max()) + BOOST_THROW_EXCEPTION(BadJumpDestination()); + return nextPC; + }; + m_steps = 0; for (auto nextPC = m_curPC + 1; true; m_curPC = nextPC, nextPC = m_curPC + 1, ++m_steps) { @@ -531,18 +539,12 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) m_stack.pop_back(); break; case Instruction::JUMP: - nextPC = static_cast(m_stack.back()); - if (find(m_jumpDests.begin(), m_jumpDests.end(), nextPC) == m_jumpDests.end() || m_stack.back() > numeric_limits::max()) - BOOST_THROW_EXCEPTION(BadJumpDestination()); + nextPC = verifyJumpDest(m_stack.back(), m_jumpDests); m_stack.pop_back(); break; case Instruction::JUMPI: if (m_stack[m_stack.size() - 2]) - { - nextPC = static_cast(m_stack.back()); - if (find(m_jumpDests.begin(), m_jumpDests.end(), nextPC) == m_jumpDests.end() || m_stack.back() > numeric_limits::max()) - BOOST_THROW_EXCEPTION(BadJumpDestination()); - } + nextPC = verifyJumpDest(m_stack.back(), m_jumpDests); m_stack.pop_back(); m_stack.pop_back(); break; From d48574bfc6a8f773e353647a948fcdaf0ce872e7 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 9 Jun 2015 15:34:58 +0200 Subject: [PATCH 30/36] dont return anything when ecrecover fails --- libethereum/Precompiled.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libethereum/Precompiled.cpp b/libethereum/Precompiled.cpp index 0ae9bf3eb..780a8210f 100644 --- a/libethereum/Precompiled.cpp +++ b/libethereum/Precompiled.cpp @@ -55,9 +55,13 @@ void ecrecoverCode(bytesConstRef _in, bytesRef _out) { try { - ret = sha3(recover(sig, in.hash)); + Public rec = recover(sig, in.hash); + if (rec) + ret = dev::sha3(rec); + else + return; } - catch (...) {} + catch (...) { return; } } } From 78550b4a3a1cce2ae0835e72cebaf36667009ca0 Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 9 Jun 2015 15:46:59 +0200 Subject: [PATCH 31/36] fixed progress reporting --- libethereum/DownloadMan.cpp | 7 ++----- libethereum/DownloadMan.h | 3 +-- libethereum/EthereumHost.cpp | 3 +++ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libethereum/DownloadMan.cpp b/libethereum/DownloadMan.cpp index 3e33f3eb5..5e68e3c49 100644 --- a/libethereum/DownloadMan.cpp +++ b/libethereum/DownloadMan.cpp @@ -80,7 +80,6 @@ HashDownloadSub::HashDownloadSub(HashDownloadMan& _man): m_man(&_man) { WriteGuard l(m_man->x_subs); m_asked = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); - m_attempted = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); m_man->m_subs.insert(this); } @@ -98,7 +97,6 @@ void HashDownloadSub::resetFetch() Guard l(m_fetch); m_remaining = 0; m_asked = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); - m_attempted = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); } unsigned HashDownloadSub::nextFetch(unsigned _n) @@ -110,10 +108,9 @@ unsigned HashDownloadSub::nextFetch(unsigned _n) if (!m_man || m_man->chainEmpty()) return 0; - m_asked = (~(m_man->taken() + m_attempted)).lowest(_n); + m_asked = (~(m_man->taken())).lowest(_n); if (m_asked.empty()) - m_asked = (~(m_man->taken(true) + m_attempted)).lowest(_n); - m_attempted += m_asked; + m_asked = (~(m_man->taken(true))).lowest(_n); return *m_asked.begin(); } diff --git a/libethereum/DownloadMan.h b/libethereum/DownloadMan.h index 0ffa6fdb0..0c27e84ea 100644 --- a/libethereum/DownloadMan.h +++ b/libethereum/DownloadMan.h @@ -187,7 +187,6 @@ public: bool askedContains(unsigned _i) const { Guard l(m_fetch); return m_asked.contains(_i); } RangeMask const& asked() const { return m_asked; } - RangeMask const& attemped() const { return m_attempted; } private: void resetFetch(); // Called by DownloadMan when we need to reset the download. @@ -196,7 +195,6 @@ private: mutable Mutex m_fetch; unsigned m_remaining; RangeMask m_asked; - RangeMask m_attempted; }; class HashDownloadMan @@ -279,3 +277,4 @@ private: } } + diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 2483473c3..abeac0af9 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -288,6 +288,7 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool { if (_hashes.empty()) { + _peer->m_hashSub.doneFetch(); continueSync(); return; } @@ -400,6 +401,7 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r) // Got to this peer's latest block - just give up. clog(NetNote) << "Finishing blocks fetch..."; // NOTE: need to notify of giving up on chain-hashes, too, altering state as necessary. + _peer->m_sub.doneFetch(); _peer->setIdle(); return; } @@ -694,3 +696,4 @@ HashChainStatus EthereumHost::status() return HashChainStatus { static_cast(m_hashMan.chainSize()), static_cast(m_hashMan.gotCount()), false }; return HashChainStatus { m_estimatedHashes, static_cast(m_hashes.size()), true }; } + From d4724ee9aa1f165e3cd69e791dd7211f1118e6c9 Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 9 Jun 2015 10:20:40 -0400 Subject: [PATCH 32/36] Catch exception for maformed rlp received by node table. --- libp2p/NodeTable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index bf056c52f..cb7859091 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -422,8 +422,8 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes unsigned packetType = signedBytes[0]; bytesConstRef rlpBytes(_packet.cropped(h256::size + Signature::size + 1)); - RLP rlp(rlpBytes); try { + RLP rlp(rlpBytes); switch (packetType) { case Pong::type: From 7bff0d1f7d05463b0c6271459b5b9a0120f8cf05 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 9 Jun 2015 23:52:40 +0900 Subject: [PATCH 33/36] Faster State diffs. Support canary contract to stop mining. Manage rude nodes. --- eth/main.cpp | 9 ++++++ libdevcore/Log.cpp | 8 +++++ libdevcore/Log.h | 3 ++ libethereum/Client.cpp | 57 ++++++++++++++++++++++++++---------- libethereum/Client.h | 19 +++++++++++- libethereum/ClientBase.cpp | 5 ++-- libethereum/ClientBase.h | 1 + libethereum/EthereumHost.cpp | 17 ++++++++++- libethereum/EthereumHost.h | 7 ++++- libethereum/EthereumPeer.cpp | 14 +++++++-- libethereum/EthereumPeer.h | 10 ++++++- libethereum/Interface.h | 2 ++ libethereum/State.cpp | 30 ++++++++++++++----- libethereum/State.h | 12 ++++++-- 14 files changed, 159 insertions(+), 35 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 06611deaa..2c5d938aa 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -138,6 +138,7 @@ void help() << " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -m,--mining Enable mining, optionally for a specified number of blocks (default: off)" << endl << " -f,--force-mining Mine even when there are no transactions to mine (default: off)" << endl + << " --mine-on-wrong-chain Mine even when we know it's the wrong chain (default: off)" << endl << " -C,--cpu When mining, use the CPU." << endl << " -G,--opencl When mining use the GPU via OpenCL." << endl << " --opencl-platform When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl @@ -279,6 +280,7 @@ int main(int argc, char** argv) bool upnp = true; WithExisting killChain = WithExisting::Trust; bool jit = false; + string sentinel; /// Networking params. string clientName; @@ -294,6 +296,7 @@ int main(int argc, char** argv) /// Mining params unsigned mining = 0; bool forceMining = false; + bool mineOnWrongChain = false; Address signingKey; Address sessionKey; Address beneficiary = signingKey; @@ -376,6 +379,10 @@ int main(int argc, char** argv) mode = OperationMode::Export; filename = argv[++i]; } + else if (arg == "--sentinel" && i + 1 < argc) + sentinel = argv[++i]; + else if (arg == "--mine-on-wrong-chain") + mineOnWrongChain = true; else if (arg == "--format" && i + 1 < argc) { string m = argv[++i]; @@ -671,6 +678,8 @@ int main(int argc, char** argv) nodeMode == NodeMode::Full ? set{"eth"/*, "shh"*/} : set(), netPrefs, &nodesState); + web3.ethereum()->setMineOnBadChain(mineOnWrongChain); + web3.ethereum()->setSentinel(sentinel); auto toNumber = [&](string const& s) -> unsigned { if (s == "latest") diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp index f28a2c6b9..1e5c2d8ab 100644 --- a/libdevcore/Log.cpp +++ b/libdevcore/Log.cpp @@ -40,6 +40,14 @@ mutex x_logOverride; /// or equal to the currently output verbosity (g_logVerbosity). static map s_logOverride; +bool isLogVisible(std::type_info const* _ch, bool _default) +{ + Guard l(x_logOverride); + if (s_logOverride.count(_ch)) + return s_logOverride[_ch]; + return _default; +} + LogOverrideAux::LogOverrideAux(std::type_info const* _ch, bool _value): m_ch(_ch) { diff --git a/libdevcore/Log.h b/libdevcore/Log.h index ce0db17fe..e732ac73c 100644 --- a/libdevcore/Log.h +++ b/libdevcore/Log.h @@ -73,6 +73,9 @@ public: LogOverride(bool _value): LogOverrideAux(&typeid(Channel), _value) {} }; +bool isChannelVisible(std::type_info const* _ch, bool _default); +template bool isChannelVisible() { return isChannelVisible(&typeid(Channel), Channel::verbosity <= g_logVerbosity); } + /// Temporary changes system's verbosity for specific function. Restores the old verbosity when function returns. /// Not thread-safe, use with caution! struct VerbosityHolder diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index ae03be9a4..ea4e65ac4 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -310,6 +310,18 @@ Client::~Client() stopWorking(); } +static const Address c_canary("0x"); + +bool Client::isChainBad() const +{ + return stateAt(c_canary, 0) != 0; +} + +bool Client::isUpgradeNeeded() const +{ + return stateAt(c_canary, 0) == 2; +} + void Client::setNetworkId(u256 _n) { if (auto h = m_host.lock()) @@ -552,6 +564,9 @@ ProofOfWork::WorkPackage Client::getWork() bool oldShould = shouldServeWork(); m_lastGetWork = chrono::system_clock::now(); + if (!m_mineOnBadChain && isChainBad()) + return ProofOfWork::WorkPackage(); + // if this request has made us bother to serve work, prep it now. if (!oldShould && shouldServeWork()) onPostStateChanged(); @@ -709,11 +724,22 @@ bool Client::remoteActive() const void Client::onPostStateChanged() { - cnote << "Post state changed"; + cnote << "Post state changed."; + rejigMining(); + m_remoteWorking = false; +} + +void Client::startMining() +{ + m_wouldMine = true; + rejigMining(); +} - if (m_bq.items().first == 0 && (isMining() || remoteActive())) +void Client::rejigMining() +{ + if ((wouldMine() || remoteActive()) && !m_bq.items().first && (!isChainBad() || mineOnBadChain()) /*&& (forceMining() || transactionsWaiting())*/) { - cnote << "Restarting mining..."; + cnote << "Rejigging mining..."; DEV_WRITE_GUARDED(x_working) m_working.commitToMine(m_bc); DEV_READ_GUARDED(x_working) @@ -722,20 +748,21 @@ void Client::onPostStateChanged() m_postMine = m_working; m_miningInfo = m_postMine.info(); } - m_farm.setWork(m_miningInfo); - Ethash::ensurePrecomputed(m_bc.number()); - } - m_remoteWorking = false; -} + if (m_wouldMine) + { + m_farm.setWork(m_miningInfo); + if (m_turboMining) + m_farm.startGPU(); + else + m_farm.startCPU(); -void Client::startMining() -{ - if (m_turboMining) - m_farm.startGPU(); - else - m_farm.startCPU(); - onPostStateChanged(); + m_farm.setWork(m_miningInfo); + Ethash::ensurePrecomputed(m_bc.number()); + } + } + if (!m_wouldMine) + m_farm.stop(); } void Client::noteChanged(h256Hash const& _filters) diff --git a/libethereum/Client.h b/libethereum/Client.h index aed54f131..d2447e932 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -174,14 +174,26 @@ public: /// Enable/disable GPU mining. void setTurboMining(bool _enable = true) { m_turboMining = _enable; if (isMining()) startMining(); } + /// Check to see if we'd mine on an apparently bad chain. + bool mineOnBadChain() const { return m_mineOnBadChain; } + /// Set true if you want to mine even when the canary says you're on the wrong chain. + void setMineOnBadChain(bool _v) { m_mineOnBadChain = _v; } + + /// @returns true if the canary says that the chain is bad. + bool isChainBad() const; + /// @returns true if the canary says that the client should be upgraded. + bool isUpgradeNeeded() const; + /// Start mining. /// NOT thread-safe - call it & stopMining only from a single thread void startMining() override; /// Stop mining. /// NOT thread-safe - void stopMining() override { m_farm.stop(); } + void stopMining() override { m_wouldMine = false; rejigMining(); } /// Are we mining now? bool isMining() const override { return m_farm.isMining(); } + /// Are we mining now? + bool wouldMine() const override { return m_wouldMine; } /// The hashrate... uint64_t hashrate() const override; /// Check the progress of the mining. @@ -251,6 +263,9 @@ private: /// Called when Worker is exiting. void doneWorking() override; + /// Called when wouldMine(), turboMining(), isChainBad(), forceMining(), pendingTransactions() have changed. + void rejigMining(); + /// Magically called when the chain has changed. An import route is provided. /// Called by either submitWork() or in our main thread through syncBlockQueue(). void onChainChanged(ImportRoute const& _ir); @@ -308,8 +323,10 @@ private: Handler m_tqReady; Handler m_bqReady; + bool m_wouldMine = false; ///< True if we /should/ be mining. bool m_turboMining = false; ///< Don't squander all of our time mining actually just sleeping. bool m_forceMining = false; ///< Mine even when there are no transactions pending? + bool m_mineOnBadChain = false; ///< Mine even when the canary says it's a bad chain. bool m_paranoia = false; ///< Should we be paranoid about our state? mutable std::chrono::system_clock::time_point m_lastGarbageCollection; diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 8dc666bb5..6a2c76c0b 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -400,17 +400,16 @@ h256s ClientBase::pendingHashes() const return h256s() + postMine().pendingHashes(); } - StateDiff ClientBase::diff(unsigned _txi, h256 _block) const { State st = asOf(_block); - return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); + return st.fromPending(_txi).diff(st.fromPending(_txi + 1), true); } StateDiff ClientBase::diff(unsigned _txi, BlockNumber _block) const { State st = asOf(_block); - return st.fromPending(_txi).diff(st.fromPending(_txi + 1)); + return st.fromPending(_txi).diff(st.fromPending(_txi + 1), true); } Addresses ClientBase::addresses(BlockNumber _block) const diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 2b271b1df..6a38ba357 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -154,6 +154,7 @@ public: virtual void startMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::startMining")); } virtual void stopMining() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::stopMining")); } virtual bool isMining() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::isMining")); } + virtual bool wouldMine() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::wouldMine")); } virtual uint64_t hashrate() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::hashrate")); } virtual MiningProgress miningProgress() const override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::miningProgress")); } virtual ProofOfWork::WorkPackage getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("ClientBase::getWork")); } diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 7c9b730ea..4c1a65c7c 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -276,6 +276,13 @@ void EthereumHost::estimatePeerHashes(EthereumPeer* _peer) _peer->m_expectedHashes = blockCount; } +void EthereumHost::noteRude(p2p::NodeId const& _id, std::string const& _client) +{ + cwarn << "RUDE node/client: " << _id << _client; + m_rudeNodes.insert(_id); + m_rudeClients.insert(_client); +} + void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes) { Guard l(x_sync); @@ -574,7 +581,7 @@ void EthereumHost::continueSync(EthereumPeer* _peer) }); if (otherPeerSync) { - /// Downloading from other peer with v60 protocol, nothing ese we can do + /// Downloading from other peer with v60 protocol, nothing else we can do _peer->setIdle(); return; } @@ -599,6 +606,10 @@ void EthereumHost::continueSync(EthereumPeer* _peer) bool EthereumHost::peerShouldGrabBlocks(EthereumPeer* _peer) const { + // Early exit if this peer has proved unreliable. + if (_peer->isRude()) + return false; + auto td = _peer->m_totalDifficulty; auto lh = m_syncingLatestHash; auto ctd = m_chain.details().totalDifficulty; @@ -611,6 +622,10 @@ bool EthereumHost::peerShouldGrabBlocks(EthereumPeer* _peer) const bool EthereumHost::peerShouldGrabChain(EthereumPeer* _peer) const { + // Early exit if this peer has proved unreliable. + if (_peer->isRude()) + return false; + h256 c = m_chain.currentHash(); unsigned n = m_chain.number(); u256 td = m_chain.details().totalDifficulty; diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index 8ca815a17..a05e3f62f 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -71,7 +71,9 @@ public: DownloadMan const& downloadMan() const { return m_man; } bool isSyncing() const { Guard l(x_sync); return isSyncing_UNSAFE(); } - bool isBanned(p2p::NodeId _id) const { return !!m_banned.count(_id); } + bool isBanned(p2p::NodeId const& _id) const { return !!m_banned.count(_id); } + void noteRude(p2p::NodeId const& _id, std::string const& _client); + bool isRude(p2p::NodeId const& _id, std::string const& _client) const { return m_rudeClients.count(_client) && m_rudeNodes.count(_id); } void noteNewTransactions() { m_newTransactions = true; } void noteNewBlocks() { m_newBlocks = true; } @@ -147,6 +149,9 @@ private: h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync. u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync. h256s m_hashes; ///< List of hashes with unknown block numbers. Used for v60 chain downloading and catching up to a particular unknown + + std::unordered_set m_rudeNodes; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible. + std::unordered_set m_rudeClients; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible. }; } diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index a332e5b93..534d76795 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -40,6 +40,8 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h, unsigned _i, Cap m_hashSub(host()->hashDownloadMan()), m_peerCapabilityVersion(_cap.second) { + m_isRude = host()->isRude(session()->id(), session()->info().clientVersion); + session()->addNote("manners", m_isRude ? "RUDE" : "nice"); m_syncHashNumber = host()->chain().number() + 1; requestStatus(); } @@ -52,8 +54,16 @@ EthereumPeer::~EthereumPeer() void EthereumPeer::abortSync() { - if (isSyncing()) - setIdle(); + if (m_asking != Asking::Nothing) + setRude(); + setIdle(); +} + +void EthereumPeer::setRude() +{ + m_isRude = true; + host()->noteRude(session()->id(), session()->info().clientVersion); + session()->addNote("manners", m_isRude ? "RUDE" : "nice"); } EthereumHost* EthereumPeer::host() const diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index 94dc60501..bf62559ee 100644 --- a/libethereum/EthereumPeer.h +++ b/libethereum/EthereumPeer.h @@ -82,6 +82,12 @@ public: /// Request blocks. Uses block download manager. void requestBlocks(); + /// Check if this node is rude. + bool isRude() const { return m_isRude; } + + /// Set that it's a rude node. + void setRude(); + private: using p2p::Capability::sealAndSend; @@ -101,7 +107,7 @@ private: void setAsking(Asking _g); /// Do we presently need syncing with this peer? - bool needsSyncing() const { return !!m_latestHash; } + bool needsSyncing() const { return !isRude() && !!m_latestHash; } /// Are we presently syncing with this peer? bool isSyncing() const; @@ -145,6 +151,8 @@ private: h256Hash m_knownBlocks; ///< Blocks that the peer already knows about (that don't need to be sent to them). Mutex x_knownTransactions; h256Hash m_knownTransactions; ///< Transactions that the peer already knows of. + + bool m_isRude; ///< True if this node has been rude in the past. }; } diff --git a/libethereum/Interface.h b/libethereum/Interface.h index f7253ad29..636f73fbf 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -196,6 +196,8 @@ public: virtual void stopMining() = 0; /// Are we mining now? virtual bool isMining() const = 0; + /// Would we like to mine now? + virtual bool wouldMine() const = 0; /// Current hash rate. virtual uint64_t hashrate() const = 0; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index d19cc556a..cb514e8f8 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -158,6 +158,7 @@ State::State(State const& _s): m_transactions(_s.m_transactions), m_receipts(_s.m_receipts), m_transactionSet(_s.m_transactionSet), + m_touched(_s.m_touched), m_cache(_s.m_cache), m_previousBlock(_s.m_previousBlock), m_currentBlock(_s.m_currentBlock), @@ -206,7 +207,7 @@ State::~State() { } -StateDiff State::diff(State const& _c) const +StateDiff State::diff(State const& _c, bool _quick) const { StateDiff ret; @@ -217,10 +218,20 @@ StateDiff State::diff(State const& _c) const auto trie = SecureTrieDB(const_cast(&m_db), rootHash()); auto trieD = SecureTrieDB(const_cast(&_c.m_db), _c.rootHash()); - for (auto i: trie) - ads.insert(i.first), trieAds.insert(i.first); - for (auto i: trieD) - ads.insert(i.first), trieAdsD.insert(i.first); + if (_quick) + { + trieAds = m_touched; + trieAdsD = _c.m_touched; + (ads += m_touched) += _c.m_touched; + } + else + { + for (auto i: trie) + ads.insert(i.first), trieAds.insert(i.first); + for (auto i: trieD) + ads.insert(i.first), trieAdsD.insert(i.first); + } + for (auto i: m_cache) ads.insert(i.first); for (auto i: _c.m_cache) @@ -272,7 +283,7 @@ void State::ensureCached(std::unordered_map& _cache, Address _ void State::commit() { - dev::eth::commit(m_cache, m_db, m_state); + m_touched += dev::eth::commit(m_cache, m_db, m_state); m_cache.clear(); } @@ -450,6 +461,7 @@ void State::resetCurrent() m_receipts.clear(); m_transactionSet.clear(); m_cache.clear(); + m_touched.clear(); m_currentBlock = BlockInfo(); m_currentBlock.coinbaseAddress = m_ourAddress; m_currentBlock.timestamp = max(m_previousBlock.timestamp + 1, (u256)time(0)); @@ -1219,8 +1231,10 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per if (!e.execute()) #if ETH_VMTRACE { - (void)_onOp; - e.go(e.simpleTrace()); + if (isChannelVisible()) + e.go(e.simpleTrace()); + else + e.go(_onOp); } #else e.go(_onOp); diff --git a/libethereum/State.h b/libethereum/State.h index da9d6b23a..9ecab05b5 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -310,10 +310,12 @@ public: State fromPending(unsigned _i) const; /// @returns the StateDiff caused by the pending transaction of index @a _i. - StateDiff pendingDiff(unsigned _i) const { return fromPending(_i).diff(fromPending(_i + 1)); } + StateDiff pendingDiff(unsigned _i) const { return fromPending(_i).diff(fromPending(_i + 1), true); } /// @return the difference between this state (origin) and @a _c (destination). - StateDiff diff(State const& _c) const; + /// @param _quick if true doesn't check all addresses possible (/very/ slow for a full chain) + /// but rather only those touched by the transactions in creating the two States. + StateDiff diff(State const& _c, bool _quick = false) const; /// Sync our state with the block chain. /// This basically involves wiping ourselves if we've been superceded and rebuilding from the transaction queue. @@ -387,6 +389,7 @@ private: TransactionReceipts m_receipts; ///< The corresponding list of transaction receipts. h256Hash m_transactionSet; ///< The set of transaction hashes that we've included in the state. OverlayDB m_lastTx; + AddressHash m_touched; ///< Tracks all addresses touched by transactions so far. mutable std::unordered_map m_cache; ///< Our address cache. This stores the states of each address that has (or at least might have) been changed. @@ -410,8 +413,9 @@ private: std::ostream& operator<<(std::ostream& _out, State const& _s); template -void commit(std::unordered_map const& _cache, DB& _db, SecureTrieDB& _state) +AddressHash commit(std::unordered_map const& _cache, DB& _db, SecureTrieDB& _state) { + AddressHash ret; for (auto const& i: _cache) if (i.second.isDirty()) { @@ -450,7 +454,9 @@ void commit(std::unordered_map const& _cache, DB& _db, SecureT _state.insert(i.first, &s.out()); } + ret.insert(i.first); } + return ret; } } From feb2378b5a1b3e426304c7ef168684b4fe620210 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 9 Jun 2015 23:53:12 +0900 Subject: [PATCH 34/36] Optimised fors in State. --- libethereum/State.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index cb514e8f8..1212c2d74 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -226,21 +226,21 @@ StateDiff State::diff(State const& _c, bool _quick) const } else { - for (auto i: trie) + for (auto const& i: trie) ads.insert(i.first), trieAds.insert(i.first); - for (auto i: trieD) + for (auto const& i: trieD) ads.insert(i.first), trieAdsD.insert(i.first); } - for (auto i: m_cache) + for (auto const& i: m_cache) ads.insert(i.first); - for (auto i: _c.m_cache) + for (auto const& i: _c.m_cache) ads.insert(i.first); // cnote << *this; // cnote << _c; - for (auto i: ads) + for (auto const& i: ads) { auto it = m_cache.find(i); auto itD = _c.m_cache.find(i); From 2c71cea5d987aac25ce39c347837f233db91ad3a Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 9 Jun 2015 17:29:44 +0200 Subject: [PATCH 35/36] handle missing status field gracefully --- libethereum/EthereumPeer.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 50ed76d9b..497513b46 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -186,8 +186,16 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) m_genesisHash = _r[4].toHash(); if (m_peerCapabilityVersion == host()->protocolVersion()) { - m_protocolVersion = host()->protocolVersion(); - m_latestBlockNumber = _r[5].toInt(); + if (_r.itemCount() != 6) + { + clog(NetImpolite) << "Peer does not support PV61+ status extension."; + m_protocolVersion = EthereumHost::c_oldProtocolVersion; + } + else + { + m_protocolVersion = host()->protocolVersion(); + m_latestBlockNumber = _r[5].toInt(); + } } clog(NetMessageSummary) << "Status:" << m_protocolVersion << "/" << m_networkId << "/" << m_genesisHash << "/" << m_latestBlockNumber << ", TD:" << m_totalDifficulty << "=" << m_latestHash; From afd84b0b4b8600970559af03353b6203c19d8ba3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 10 Jun 2015 00:52:12 +0900 Subject: [PATCH 36/36] Expand eth cli Fixes #2125 --- eth/main.cpp | 185 ++++++++++++++++++++++++++++++++++++++++- libdevcore/FixedHash.h | 2 +- libethereum/Client.h | 2 + 3 files changed, 187 insertions(+), 2 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 2c5d938aa..5497a2cda 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -84,15 +84,24 @@ void interactiveHelp() << " minestop Stops mining." << endl << " mineforce Forces mining, even when there are no transactions." << endl << " block Gives the current block height." << endl + << " blockhashfromnumber Gives the block hash with the givne number." << endl + << " numberfromblockhash Gives the block number with the given hash." << endl + << " blockqueue Gives the current block queue status." << endl + << " findblock Searches for the block in the blockchain and blockqueue." << endl + << " firstunknown Gives the first unknown block from the blockqueue." << endl + << " retryunknown retries to import all unknown blocks from the blockqueue." << endl << " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl << " newaccount Creates a new account with the given name." << endl << " transact Execute a given transaction." << endl + << " txcreate Execute a given contract creation transaction." << endl << " send Execute a given transaction with current secret." << endl << " contract Create a new contract with current secret." << endl << " peers List the peers that are connected" << endl #if ETH_FATDB || !ETH_TRUE << " listaccounts List the accounts on the network." << endl << " listcontracts List the contracts on the network." << endl + << " balanceat
Gives the balance of the given account." << endl + << " codeat
Gives the code of the given account." << endl #endif << " setsigningkey Set the address with which to sign transactions." << endl << " setaddress Set the coinbase (mining payout) address." << endl @@ -971,9 +980,88 @@ int main(int argc, char** argv) cout << "Current mining beneficiary:" << endl << beneficiary << endl; cout << "Current signing account:" << endl << signingKey << endl; } + else if (c && cmd == "blockhashfromnumber") + { + if (iss.peek() != -1) + { + unsigned number; + iss >> number; + cout << " hash of block: " << c->hashFromNumber(number).hex() << endl; + } + } + else if (c && cmd == "numberfromblockhash") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + h256 hash = h256(fromHex(stringHash)); + cout << " number of block: " << c->numberFromHash(hash) << endl; + } + } else if (c && cmd == "block") { - cout << "Current block: " <blockChain().details().number << endl; + cout << "Current block: " << c->blockChain().details().number << endl; + } + else if (c && cmd == "blockqueue") + { + cout << "Current blockqueue status: " << endl << c->blockQueueStatus() << endl; + } + else if (c && cmd == "findblock") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + h256 hash = h256(fromHex(stringHash)); + + // search in blockchain + cout << "search in blockchain... " << endl; + try + { + cout << c->blockInfo(hash) << endl; + } + catch(Exception& _e) + { + cout << "block not in blockchain" << endl; + cout << boost::diagnostic_information(_e) << endl; + } + + cout << "search in blockqueue... " << endl; + + switch(c->blockQueue().blockStatus(hash)) + { + case QueueStatus::Ready: + cout << "Ready" << endl; + break; + case QueueStatus::Importing: + cout << "Importing" << endl; + break; + case QueueStatus::UnknownParent: + cout << "UnknownParent" << endl; + break; + case QueueStatus::Bad: + cout << "Bad" << endl; + break; + case QueueStatus::Unknown: + cout << "Unknown" << endl; + break; + default: + cout << "invalid queueStatus" << endl; + } + } + else + cwarn << "Require parameter: findblock HASH"; + } + else if (c && cmd == "firstunknown") + { + cout << "first unknown blockhash: " << c->blockQueue().firstUnknown().hex() << endl; + } + else if (c && cmd == "retryunknown") + { + c->retryUnkonwn(); } else if (cmd == "peers") { @@ -1087,6 +1175,64 @@ int main(int argc, char** argv) else cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA"; } + else if (c && cmd == "txcreate") + { + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + if (iss.peek() != -1) + { + u256 amount; + u256 gasPrice; + u256 gas; + string sechex; + string sdata; + + iss >> amount >> gasPrice >> gas >> sechex >> sdata; + + if (!gasPrice) + gasPrice = gasPricer->bid(priority); + + cnote << "Data:"; + cnote << sdata; + bytes data = dev::eth::parseData(sdata); + cnote << "Bytes:"; + string sbd = asString(data); + bytes bbd = asBytes(sbd); + stringstream ssbd; + ssbd << bbd; + cnote << ssbd.str(); + int ssize = sechex.length(); + u256 minGas = (u256)Transaction::gasRequired(data, 0); + if (gas < minGas) + cwarn << "Minimum gas amount is" << minGas; + else if (ssize < 40) + { + if (ssize > 0) + cwarn << "Invalid secret length:" << ssize; + } + else + { + try + { + Secret secret = h256(fromHex(sechex)); + cout << " new contract address : " << c->submitTransaction(secret, amount, data, gas, gasPrice) << endl; + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } + } + } + else + cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET INIT"; + } #if ETH_FATDB else if (c && cmd == "listcontracts") { @@ -1110,6 +1256,43 @@ int main(int argc, char** argv) cout << ss << endl; } } + else if (c && cmd == "balanceat") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "balance of " << stringHash << " is: " << toString(c->balanceAt(address)) << endl; + } + } + // TODO implement << operator for std::unorderd_map +// else if (c && cmd == "storageat") +// { +// if (iss.peek() != -1) +// { +// string stringHash; +// iss >> stringHash; + +// Address address = h160(fromHex(stringHash)); + +// cout << "storage at " << stringHash << " is: " << c->storageAt(address) << endl; +// } +// } + else if (c && cmd == "codeat") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "code at " << stringHash << " is: " << toHex(c->codeAt(address)) << endl; + } + } #endif else if (c && cmd == "send") { diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index 9b25837af..88bc0fe95 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -113,7 +113,7 @@ public: /// @returns an abridged version of the hash as a user-readable hex string. std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; } - /// @returns an abridged version of the hash as a user-readable hex string. + /// @returns the hash as a user-readable hex string. std::string hex() const { return toHex(ref()); } /// @returns a mutable byte vector_ref to the object's data. diff --git a/libethereum/Client.h b/libethereum/Client.h index 6251fbc9c..2de6e9403 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -158,6 +158,8 @@ public: BlockQueueStatus blockQueueStatus() const { return m_bq.status(); } /// Get some information on the block queue. HashChainStatus hashChainStatus() const; + /// Get the block queue. + BlockQueue const& blockQueue() const { return m_bq; } // Mining stuff: