From ec3afa9d713cd30c4fd52a57f379e0428cf6a120 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Sun, 7 Jun 2015 09:06:06 +0200 Subject: [PATCH 01/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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/25] 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 baf10f84b3324f0e641d7c7c2d941ae587a26ba0 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 8 Jun 2015 16:30:13 +0200 Subject: [PATCH 08/25] 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 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 09/25] 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 10/25] 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: Tue, 9 Jun 2015 14:24:58 +0900 Subject: [PATCH 11/25] 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 12/25] 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 13/25] 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 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 14/25] 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 15/25] 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 16/25] 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 17/25] 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 18/25] 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 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 19/25] 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 20/25] 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 21/25] 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 22/25] 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 d4724ee9aa1f165e3cd69e791dd7211f1118e6c9 Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 9 Jun 2015 10:20:40 -0400 Subject: [PATCH 23/25] 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 24/25] 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 25/25] 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);