diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 93054fd67..4d96b77ff 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -240,6 +240,10 @@ Main::Main(QWidget *parent) : #if !ETH_FATDB removeDockWidget(ui->dockWidget_accounts); +#endif +#if !ETH_EVMJIT + ui->jitvm->setEnabled(false); + ui->jitvm->setChecked(false); #endif installWatches(); startTimer(100); @@ -805,6 +809,7 @@ void Main::readSettings(bool _skipGeometry) ui->usePrivate->setChecked(m_privateChain.size()); ui->verbosity->setValue(s.value("verbosity", 1).toInt()); ui->jitvm->setChecked(s.value("jitvm", true).toBool()); + on_jitvm_triggered(); ui->urlEdit->setText(s.value("url", "about:blank").toString()); //http://gavwood.com/gavcoin.html on_urlEdit_returnPressed(); @@ -1240,7 +1245,9 @@ void Main::refreshBlockCount() { auto d = ethereum()->blockChain().details(); BlockQueueStatus b = ethereum()->blockQueueStatus(); - ui->chainStatus->setText(QString("%3 ready %4 verifying %5 unverified %6 future %7 unknown %8 bad %1 #%2").arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad)); + HashChainStatus h = ethereum()->hashChainStatus(); + ui->chainStatus->setText(QString("%10/%11%12 hashes %3 importing %4 ready %5 verifying %6 unverified %7 future %8 unknown %9 bad %1 #%2") + .arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.importing).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad).arg(h.received).arg(h.estimated ? "~" : "").arg(h.total)); } void Main::on_turboMining_triggered() diff --git a/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/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index eb8588ceb..53535a489 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -21,7 +21,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_RELEASE") if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libstdc++ -fcolor-diagnostics -Qunused-arguments -DBOOST_ASIO_HAS_CLANG_LIBCXX") diff --git a/eth/main.cpp b/eth/main.cpp index 7a85141f4..5497a2cda 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -84,15 +84,24 @@ void interactiveHelp() << " minestop Stops mining." << endl << " mineforce Forces mining, even when there are no transactions." << endl << " block Gives the current block height." << endl + << " blockhashfromnumber Gives the block hash with the givne number." << endl + << " numberfromblockhash Gives the block number with the given hash." << endl + << " blockqueue Gives the current block queue status." << endl + << " findblock Searches for the block in the blockchain and blockqueue." << endl + << " firstunknown Gives the first unknown block from the blockqueue." << endl + << " retryunknown retries to import all unknown blocks from the blockqueue." << endl << " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl << " newaccount Creates a new account with the given name." << endl << " transact Execute a given transaction." << endl + << " txcreate Execute a given contract creation transaction." << endl << " send Execute a given transaction with current secret." << endl << " contract Create a new contract with current secret." << endl << " peers List the peers that are connected" << endl #if ETH_FATDB || !ETH_TRUE << " listaccounts List the accounts on the network." << endl << " listcontracts List the contracts on the network." << endl + << " balanceat
Gives the balance of the given account." << endl + << " codeat
Gives the code of the given account." << endl #endif << " setsigningkey Set the address with which to sign transactions." << endl << " setaddress Set the coinbase (mining payout) address." << endl @@ -125,6 +134,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 @@ -137,6 +147,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 @@ -278,6 +289,7 @@ int main(int argc, char** argv) bool upnp = true; WithExisting killChain = WithExisting::Trust; bool jit = false; + string sentinel; /// Networking params. string clientName; @@ -293,6 +305,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; @@ -375,6 +388,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]; @@ -670,6 +687,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") @@ -961,9 +980,88 @@ int main(int argc, char** argv) cout << "Current mining beneficiary:" << endl << beneficiary << endl; cout << "Current signing account:" << endl << signingKey << endl; } + else if (c && cmd == "blockhashfromnumber") + { + if (iss.peek() != -1) + { + unsigned number; + iss >> number; + cout << " hash of block: " << c->hashFromNumber(number).hex() << endl; + } + } + else if (c && cmd == "numberfromblockhash") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + h256 hash = h256(fromHex(stringHash)); + cout << " number of block: " << c->numberFromHash(hash) << endl; + } + } else if (c && cmd == "block") { - cout << "Current block: " <blockChain().details().number << endl; + cout << "Current block: " << c->blockChain().details().number << endl; + } + else if (c && cmd == "blockqueue") + { + cout << "Current blockqueue status: " << endl << c->blockQueueStatus() << endl; + } + else if (c && cmd == "findblock") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + h256 hash = h256(fromHex(stringHash)); + + // search in blockchain + cout << "search in blockchain... " << endl; + try + { + cout << c->blockInfo(hash) << endl; + } + catch(Exception& _e) + { + cout << "block not in blockchain" << endl; + cout << boost::diagnostic_information(_e) << endl; + } + + cout << "search in blockqueue... " << endl; + + switch(c->blockQueue().blockStatus(hash)) + { + case QueueStatus::Ready: + cout << "Ready" << endl; + break; + case QueueStatus::Importing: + cout << "Importing" << endl; + break; + case QueueStatus::UnknownParent: + cout << "UnknownParent" << endl; + break; + case QueueStatus::Bad: + cout << "Bad" << endl; + break; + case QueueStatus::Unknown: + cout << "Unknown" << endl; + break; + default: + cout << "invalid queueStatus" << endl; + } + } + else + cwarn << "Require parameter: findblock HASH"; + } + else if (c && cmd == "firstunknown") + { + cout << "first unknown blockhash: " << c->blockQueue().firstUnknown().hex() << endl; + } + else if (c && cmd == "retryunknown") + { + c->retryUnkonwn(); } else if (cmd == "peers") { @@ -1077,6 +1175,64 @@ int main(int argc, char** argv) else cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA"; } + else if (c && cmd == "txcreate") + { + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + if (iss.peek() != -1) + { + u256 amount; + u256 gasPrice; + u256 gas; + string sechex; + string sdata; + + iss >> amount >> gasPrice >> gas >> sechex >> sdata; + + if (!gasPrice) + gasPrice = gasPricer->bid(priority); + + cnote << "Data:"; + cnote << sdata; + bytes data = dev::eth::parseData(sdata); + cnote << "Bytes:"; + string sbd = asString(data); + bytes bbd = asBytes(sbd); + stringstream ssbd; + ssbd << bbd; + cnote << ssbd.str(); + int ssize = sechex.length(); + u256 minGas = (u256)Transaction::gasRequired(data, 0); + if (gas < minGas) + cwarn << "Minimum gas amount is" << minGas; + else if (ssize < 40) + { + if (ssize > 0) + cwarn << "Invalid secret length:" << ssize; + } + else + { + try + { + Secret secret = h256(fromHex(sechex)); + cout << " new contract address : " << c->submitTransaction(secret, amount, data, gas, gasPrice) << endl; + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } + } + } + else + cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET INIT"; + } #if ETH_FATDB else if (c && cmd == "listcontracts") { @@ -1100,6 +1256,43 @@ int main(int argc, char** argv) cout << ss << endl; } } + else if (c && cmd == "balanceat") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "balance of " << stringHash << " is: " << toString(c->balanceAt(address)) << endl; + } + } + // TODO implement << operator for std::unorderd_map +// else if (c && cmd == "storageat") +// { +// if (iss.peek() != -1) +// { +// string stringHash; +// iss >> stringHash; + +// Address address = h160(fromHex(stringHash)); + +// cout << "storage at " << stringHash << " is: " << c->storageAt(address) << endl; +// } +// } + else if (c && cmd == "codeat") + { + if (iss.peek() != -1) + { + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "code at " << stringHash << " is: " << toHex(c->codeAt(address)) << endl; + } + } #endif else if (c && cmd == "send") { diff --git a/ethminer/CMakeLists.txt b/ethminer/CMakeLists.txt index d364f6ed1..df828bc47 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) 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/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp index 0d6a6e00a..68161526d 100644 --- a/evmjit/libevmjit-cpp/JitVM.cpp +++ b/evmjit/libevmjit-cpp/JitVM.cpp @@ -51,7 +51,7 @@ bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _on m_data.timestamp = static_cast(_ext.currentBlock.timestamp); m_data.code = _ext.code.data(); m_data.codeSize = _ext.code.size(); - m_data.codeHash = eth2llvm(sha3(_ext.code)); + m_data.codeHash = eth2llvm(_ext.codeHash); auto env = reinterpret_cast(&_ext); auto exitCode = m_engine.run(&m_data, env); 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 ) diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 025568efa..b0bab7d81 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 { const char* what() const noexcept override { return #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 { const char* what() const noexcept override { return #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/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index 9b25837af..88bc0fe95 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -113,7 +113,7 @@ public: /// @returns an abridged version of the hash as a user-readable hex string. std::string abridged() const { return toHex(ref().cropped(0, 4)) + "\342\200\246"; } - /// @returns an abridged version of the hash as a user-readable hex string. + /// @returns the hash as a user-readable hex string. std::string hex() const { return toHex(ref()); } /// @returns a mutable byte vector_ref to the object's data. diff --git a/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/libdevcore/MemoryDB.cpp b/libdevcore/MemoryDB.cpp index 2cf56475b..f71931bdd 100644 --- a/libdevcore/MemoryDB.cpp +++ b/libdevcore/MemoryDB.cpp @@ -32,7 +32,9 @@ const char* DBWarn::name() { return "TDB"; } std::unordered_map MemoryDB::get() const { +#if DEV_GUARDED_DB ReadGuard l(x_this); +#endif std::unordered_map ret; for (auto const& i: m_main) if (!m_enforceRefs || i.second.second > 0) @@ -44,8 +46,10 @@ MemoryDB& MemoryDB::operator=(MemoryDB const& _c) { if (this == &_c) return *this; +#if DEV_GUARDED_DB ReadGuard l(_c.x_this); WriteGuard l2(x_this); +#endif m_main = _c.m_main; m_aux = _c.m_aux; return *this; @@ -53,7 +57,9 @@ MemoryDB& MemoryDB::operator=(MemoryDB const& _c) std::string MemoryDB::lookup(h256 const& _h) const { +#if DEV_GUARDED_DB ReadGuard l(x_this); +#endif auto it = m_main.find(_h); if (it != m_main.end()) { @@ -67,7 +73,9 @@ std::string MemoryDB::lookup(h256 const& _h) const bool MemoryDB::exists(h256 const& _h) const { +#if DEV_GUARDED_DB ReadGuard l(x_this); +#endif auto it = m_main.find(_h); if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0)) return true; @@ -76,7 +84,9 @@ bool MemoryDB::exists(h256 const& _h) const void MemoryDB::insert(h256 const& _h, bytesConstRef _v) { +#if DEV_GUARDED_DB WriteGuard l(x_this); +#endif auto it = m_main.find(_h); if (it != m_main.end()) { @@ -92,7 +102,9 @@ void MemoryDB::insert(h256 const& _h, bytesConstRef _v) bool MemoryDB::kill(h256 const& _h) { +#if DEV_GUARDED_DB ReadGuard l(x_this); +#endif if (m_main.count(_h)) { if (m_main[_h].second > 0) @@ -117,9 +129,38 @@ bool MemoryDB::kill(h256 const& _h) return false; } +bytes MemoryDB::lookupAux(h256 const& _h) const +{ +#if DEV_GUARDED_DB + ReadGuard l(x_this); +#endif + auto it = m_aux.find(_h); + if (it != m_aux.end() && (!m_enforceRefs || it->second.second)) + return it->second.first; + return bytes(); +} + +void MemoryDB::removeAux(h256 const& _h) +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + m_aux[_h].second = false; +} + +void MemoryDB::insertAux(h256 const& _h, bytesConstRef _v) +{ +#if DEV_GUARDED_DB + WriteGuard l(x_this); +#endif + m_aux[_h] = make_pair(_v.toBytes(), true); +} + void MemoryDB::purge() { +#if DEV_GUARDED_DB WriteGuard l(x_this); +#endif for (auto it = m_main.begin(); it != m_main.end(); ) if (it->second.second) ++it; @@ -129,7 +170,9 @@ void MemoryDB::purge() h256Hash MemoryDB::keys() const { +#if DEV_GUARDED_DB ReadGuard l(x_this); +#endif h256Hash ret; for (auto const& i: m_main) if (i.second.second) diff --git a/libdevcore/MemoryDB.h b/libdevcore/MemoryDB.h index 169682815..a39c0efd0 100644 --- a/libdevcore/MemoryDB.h +++ b/libdevcore/MemoryDB.h @@ -57,14 +57,16 @@ public: bool kill(h256 const& _h); void purge(); - bytes lookupAux(h256 const& _h) const { ReadGuard l(x_this); auto it = m_aux.find(_h); if (it != m_aux.end() && (!m_enforceRefs || it->second.second)) return it->second.first; return bytes(); } - void removeAux(h256 const& _h) { WriteGuard l(x_this); m_aux[_h].second = false; } - void insertAux(h256 const& _h, bytesConstRef _v) { WriteGuard l(x_this); m_aux[_h] = make_pair(_v.toBytes(), true); } + bytes lookupAux(h256 const& _h) const; + void removeAux(h256 const& _h); + void insertAux(h256 const& _h, bytesConstRef _v); h256Hash keys() const; protected: +#if DEV_GUARDED_DB mutable SharedMutex x_this; +#endif std::unordered_map> m_main; std::unordered_map> m_aux; diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h index bdf00e687..7c402fc98 100644 --- a/libdevcore/RangeMask.h +++ b/libdevcore/RangeMask.h @@ -219,6 +219,14 @@ public: return uit == m_ranges.end() ? m_all.second : uit->first; } + size_t size() const + { + size_t c = 0; + for (auto const& r: this->m_ranges) + c += r.second - r.first; + return c; + } + private: UnsignedRange m_all; std::map m_ranges; diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index e68381427..4ebd6a04b 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..40eae10f1 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) @@ -264,7 +264,6 @@ Public Secp256k1::recover(Signature _signature, bytesConstRef _message) ECP::Element x; { - Guard l(x_curve); m_curve.DecodePoint(x, encodedpoint, 33); if (!m_curve.VerifyPoint(x)) return recovered; @@ -286,7 +285,6 @@ Public Secp256k1::recover(Signature _signature, bytesConstRef _message) ECP::Point p; byte recoveredbytes[65]; { - Guard l(x_curve); // todo: make generator member p = m_curve.CascadeMultiply(u2, x, u1, m_params.GetSubgroupGenerator()); m_curve.EncodePoint(recoveredbytes, p, false); 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..a6aa684f2 100644 --- a/libdevcrypto/OverlayDB.cpp +++ b/libdevcrypto/OverlayDB.cpp @@ -50,7 +50,9 @@ void OverlayDB::commit() { ldb::WriteBatch batch; // cnote << "Committing nodes to disk DB:"; +#if DEV_GUARDED_DB DEV_READ_GUARDED(x_this) +#endif { for (auto const& i: m_main) { @@ -83,7 +85,9 @@ void OverlayDB::commit() cwarn << "Sleeping for" << (i + 1) << "seconds, then retrying."; this_thread::sleep_for(chrono::seconds(i + 1)); } +#if DEV_GUARDED_DB DEV_WRITE_GUARDED(x_this) +#endif { m_aux.clear(); m_main.clear(); @@ -95,7 +99,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 @@ -107,7 +111,9 @@ bytes OverlayDB::lookupAux(h256 const& _h) const void OverlayDB::rollback() { +#if DEV_GUARDED_DB WriteGuard l(x_this); +#endif m_main.clear(); } @@ -116,7 +122,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/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/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/Common.cpp b/libethcore/Common.cpp index 63f4a19f9..618703e22 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -112,25 +112,26 @@ std::string formatBalance(bigint const& _b) static void badBlockInfo(BlockInfo const& _bi, string const& _err) { - cwarn << EthRedBold << "========================================================================"; - cwarn << EthRedBold << "== Software Failure " + _err + string(max(0, 44 - _err.size()), ' ') + " =="; + string const c_line = EthReset EthOnMaroon + string(80, ' '); + string const c_border = EthReset EthOnMaroon + string(2, ' ') + EthReset EthMaroonBold; + string const c_space = c_border + string(76, ' ') + c_border; + stringstream ss; + ss << c_line << endl; + ss << c_space << endl; + ss << c_border + " Import Failure " + _err + string(max(0, 53 - _err.size()), ' ') + " " + c_border << endl; + ss << c_space << endl; string bin = toString(_bi.number); - cwarn << EthRedBold << ("== Guru Meditation #" + string(max(0, 8 - bin.size()), '0') + bin + "." + _bi.hash().abridged() + " =="); - cwarn << EthRedBold << "========================================================================"; + ss << c_border + (" Guru Meditation #" + string(max(0, 8 - bin.size()), '0') + bin + "." + _bi.hash().abridged() + " ") + c_border << endl; + ss << c_space << endl; + ss << c_line; + cwarn << "\n" + ss.str(); } void badBlock(bytesConstRef _block, string const& _err) { - badBlockInfo(BlockInfo(_block, CheckNothing), _err); - cwarn << " Block:" << toHex(_block); - cwarn << " Block RLP:" << RLP(_block); -} - -void badBlockHeader(bytesConstRef _header, string const& _err) -{ - badBlockInfo(BlockInfo::fromHeader(_header, CheckNothing), _err); - cwarn << " Header:" << toHex(_header); - cwarn << " Header RLP:" << RLP(_header);; + BlockInfo bi; + DEV_IGNORE_EXCEPTIONS(bi = BlockInfo(_block, CheckNothing)); + badBlockInfo(bi, _err); } } diff --git a/libethcore/Common.h b/libethcore/Common.h index 87ebffab7..131feed4b 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -156,8 +156,6 @@ struct TransactionSkeleton u256 gasPrice = UndefinedU256; }; -void badBlockHeader(bytesConstRef _header, std::string const& _err); -inline void badBlockHeader(bytes const& _header, std::string const& _err) { badBlockHeader(&_header, _err); } void badBlock(bytesConstRef _header, std::string const& _err); inline void badBlock(bytes const& _header, std::string const& _err) { badBlock(&_header, _err); } diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 0ea09a5bc..f4a8c25c4 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -340,6 +340,7 @@ void Ethash::GPUMiner::workLoop() if (shouldStop()) { delete m_miner; + m_miner = nullptr; return; } cnote << "Awaiting DAG"; @@ -354,6 +355,8 @@ void Ethash::GPUMiner::workLoop() } catch (cl::Error const& _e) { + delete m_miner; + m_miner = nullptr; cwarn << "Error GPU mining: " << _e.what() << "(" << _e.err() << ")"; } } @@ -364,11 +367,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 +377,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()); } diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h index 9362e4fed..b411ea416 100644 --- a/libethcore/Exceptions.h +++ b/libethcore/Exceptions.h @@ -35,46 +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 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 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 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 {}; -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..479524f89 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -42,13 +43,14 @@ #include "GenesisInfo.h" #include "State.h" #include "Defaults.h" + using namespace std; using namespace dev; using namespace dev::eth; namespace js = json_spirit; #define ETH_CATCH 1 -#define ETH_TIMED_IMPORTS 0 +#define ETH_TIMED_IMPORTS 1 #ifdef _WIN32 const char* BlockChainDebug::name() { return EthBlue "8" EthWhite " <>"; } @@ -307,7 +309,7 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st { // _bq.tick(*this); - vector> blocks; + VerifiedBlocks blocks; _bq.drain(blocks, _max); h256s fresh; @@ -320,7 +322,7 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st // Nonce & uncle nonces already verified in verification thread at this point. ImportRoute r; DEV_TIMED_ABOVE(Block import, 500) - r = import(block.first, block.second, _stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce & ~ImportRequirements::CheckUncles); + r = import(block.verified, _stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce & ~ImportRequirements::CheckUncles); fresh += r.first; dead += r.second; } @@ -329,14 +331,23 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st cwarn << "ODD: Import queue contains block with unknown parent." << LogTag::Error << boost::current_exception_diagnostic_information(); // 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()); + badBlocks.push_back(block.verified.info.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.verified.info.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()); + badBlocks.push_back(block.verified.info.hash()); } } return make_tuple(fresh, dead, _bq.doneDrain(badBlocks)); @@ -346,7 +357,7 @@ pair BlockChain::attemptImport(bytes const& _block, O { try { - return make_pair(ImportResult::Success, import(_block, _stateDB, _ir)); + return make_pair(ImportResult::Success, import(verifyBlock(_block, m_onBad), _stateDB, _ir)); } catch (UnknownParent&) { @@ -360,8 +371,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())); } } @@ -369,28 +382,28 @@ pair BlockChain::attemptImport(bytes const& _block, O ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, ImportRequirements::value _ir) { // VERIFY: populates from the block and checks the block is internally coherent. - BlockInfo bi; + VerifiedBlockRef block; #if ETH_CATCH try #endif { - bi.populate(&_block); - bi.verifyInternals(&_block); + block = verifyBlock(_block, m_onBad); } #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 - return import(bi, _block, _db, _ir); + return import(block, _db, _ir); } -ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, OverlayDB const& _db, ImportRequirements::value _ir) +ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& _db, ImportRequirements::value _ir) { //@tidy This is a behemoth of a method - could do to be split into a few smaller ones. @@ -405,28 +418,28 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla #endif // Check block doesn't already exist first! - if (isKnown(_bi.hash()) && (_ir & ImportRequirements::DontHave)) + if (isKnown(_block.info.hash()) && (_ir & ImportRequirements::DontHave)) { - clog(BlockChainNote) << _bi.hash() << ": Not new."; + clog(BlockChainNote) << _block.info.hash() << ": Not new."; BOOST_THROW_EXCEPTION(AlreadyHaveBlock()); } // Work out its number as the parent's number + 1 - if (!isKnown(_bi.parentHash)) + if (!isKnown(_block.info.parentHash)) { - clog(BlockChainNote) << _bi.hash() << ": Unknown parent " << _bi.parentHash; + clog(BlockChainNote) << _block.info.hash() << ": Unknown parent " << _block.info.parentHash; // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. BOOST_THROW_EXCEPTION(UnknownParent()); } - auto pd = details(_bi.parentHash); + auto pd = details(_block.info.parentHash); if (!pd) { auto pdata = pd.rlp(); clog(BlockChainDebug) << "Details is returning false despite block known:" << RLP(pdata); - auto parentBlock = block(_bi.parentHash); - clog(BlockChainDebug) << "isKnown:" << isKnown(_bi.parentHash); - clog(BlockChainDebug) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << _bi.number; + auto parentBlock = block(_block.info.parentHash); + clog(BlockChainDebug) << "isKnown:" << isKnown(_block.info.parentHash); + clog(BlockChainDebug) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << _block.info.number; clog(BlockChainDebug) << "Block:" << BlockInfo(parentBlock); clog(BlockChainDebug) << "RLP:" << RLP(parentBlock); clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; @@ -434,14 +447,14 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla } // Check it's not crazy - if (_bi.timestamp > (u256)time(0)) + if (_block.info.timestamp > (u256)time(0)) { - clog(BlockChainChat) << _bi.hash() << ": Future time " << _bi.timestamp << " (now at " << time(0) << ")"; + clog(BlockChainChat) << _block.info.hash() << ": Future time " << _block.info.timestamp << " (now at " << time(0) << ")"; // Block has a timestamp in the future. This is no good. BOOST_THROW_EXCEPTION(FutureTime()); } - clog(BlockChainChat) << "Attempting import of " << _bi.hash() << "..."; + clog(BlockChainChat) << "Attempting import of " << _block.info.hash() << "..."; #if ETH_TIMED_IMPORTS preliminaryChecks = t.elapsed(); @@ -461,7 +474,7 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla // Check transactions are valid and that they result in a state equivalent to our state_root. // Get total difficulty increase and update state, checking it. State s(_db); - auto tdIncrease = s.enactOn(&_block, _bi, *this, _ir); + auto tdIncrease = s.enactOn(_block, *this, _ir); BlockLogBlooms blb; BlockReceipts br; @@ -470,14 +483,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; @@ -497,22 +504,22 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla // together with an "ensureCachedWithUpdatableLock(l)" method. // This is safe in practice since the caches don't get flushed nearly often enough to be // done here. - details(_bi.parentHash); + details(_block.info.parentHash); DEV_WRITE_GUARDED(x_details) - m_details[_bi.parentHash].children.push_back(_bi.hash()); + m_details[_block.info.parentHash].children.push_back(_block.info.hash()); #if ETH_TIMED_IMPORTS || !ETH_TRUE collation = t.elapsed(); t.restart(); #endif - blocksBatch.Put(toSlice(_bi.hash()), (ldb::Slice)ref(_block)); + blocksBatch.Put(toSlice(_block.info.hash()), ldb::Slice(_block.block)); DEV_READ_GUARDED(x_details) - extrasBatch.Put(toSlice(_bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[_bi.parentHash].rlp())); + extrasBatch.Put(toSlice(_block.info.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[_block.info.parentHash].rlp())); - extrasBatch.Put(toSlice(_bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, _bi.parentHash, {}).rlp())); - extrasBatch.Put(toSlice(_bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); - extrasBatch.Put(toSlice(_bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, _block.info.parentHash, {}).rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); + extrasBatch.Put(toSlice(_block.info.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp())); #if ETH_TIMED_IMPORTS || !ETH_TRUE writing = t.elapsed(); @@ -520,30 +527,25 @@ 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) << "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.block.toBytes()); throw; } #endif StructuredLogger::chainReceivedNewBlock( - _bi.headerHash(WithoutNonce).abridged(), - _bi.nonce.abridged(), + _block.info.headerHash(WithoutNonce).abridged(), + _block.info.nonce.abridged(), currentHash().abridged(), "", // TODO: remote id ?? - _bi.parentHash.abridged() + _block.info.parentHash.abridged() ); // cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children."; @@ -556,8 +558,8 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla // don't include bi.hash() in treeRoute, since it's not yet in details DB... // just tack it on afterwards. unsigned commonIndex; - tie(route, common, commonIndex) = treeRoute(last, _bi.parentHash); - route.push_back(_bi.hash()); + tie(route, common, commonIndex) = treeRoute(last, _block.info.parentHash); + route.push_back(_block.info.hash()); // Most of the time these two will be equal - only when we're doing a chain revert will they not be if (common != last) @@ -569,8 +571,8 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla for (auto i = route.rbegin(); i != route.rend() && *i != common; ++i) { BlockInfo tbi; - if (*i == _bi.hash()) - tbi = _bi; + if (*i == _block.info.hash()) + tbi = _block.info; else tbi = BlockInfo(block(*i)); @@ -597,7 +599,7 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla h256s newTransactionAddresses; { bytes blockBytes; - RLP blockRLP(*i == _bi.hash() ? _block : (blockBytes = block(*i))); + RLP blockRLP(*i == _block.info.hash() ? _block.block : &(blockBytes = block(*i))); TransactionAddress ta; ta.blockHash = tbi.hash(); for (ta.index = 0; ta.index < blockRLP[1].itemCount(); ++ta.index) @@ -613,17 +615,17 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla // FINALLY! change our best hash. { - newLastBlockHash = _bi.hash(); - newLastBlockNumber = (unsigned)_bi.number; + newLastBlockHash = _block.info.hash(); + newLastBlockNumber = (unsigned)_block.info.number; } - clog(BlockChainNote) << " Imported and best" << td << " (#" << _bi.number << "). Has" << (details(_bi.parentHash).children.size() - 1) << "siblings. Route:" << route; + clog(BlockChainNote) << " Imported and best" << td << " (#" << _block.info.number << "). Has" << (details(_block.info.parentHash).children.size() - 1) << "siblings. Route:" << route; StructuredLogger::chainNewHead( - _bi.headerHash(WithoutNonce).abridged(), - _bi.nonce.abridged(), + _block.info.headerHash(WithoutNonce).abridged(), + _block.info.nonce.abridged(), currentHash().abridged(), - _bi.parentHash.abridged() + _block.info.parentHash.abridged() ); } else @@ -634,24 +636,26 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla m_blocksDB->Write(m_writeOptions, &blocksBatch); m_extrasDB->Write(m_writeOptions, &extrasBatch); - if (isKnown(_bi.hash()) && !details(_bi.hash())) +#if ETH_PARANOIA || !ETH_TRUE + if (isKnown(_block.info.hash()) && !details(_block.info.hash())) { clog(BlockChainDebug) << "Known block just inserted has no details."; - clog(BlockChainDebug) << "Block:" << _bi; + clog(BlockChainDebug) << "Block:" << _block.info; clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; exit(-1); } try { - State canary(_db, *this, _bi.hash(), ImportRequirements::DontHave); + State canary(_db, *this, _block.info.hash(), ImportRequirements::DontHave); } catch (...) { clog(BlockChainDebug) << "Failed to initialise State object form imported block."; - clog(BlockChainDebug) << "Block:" << _bi; + clog(BlockChainDebug) << "Block:" << _block.info; clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; exit(-1); } +#endif if (m_lastBlockHash != newLastBlockHash) DEV_WRITE_GUARDED(x_lastBlockHash) @@ -667,12 +671,16 @@ ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, Overla #if ETH_TIMED_IMPORTS checkBest = t.elapsed(); - cnote << "Import took:" << total.elapsed(); - cnote << "preliminaryChecks:" << preliminaryChecks; - cnote << "enactment:" << enactment; - cnote << "collation:" << collation; - cnote << "writing:" << writing; - cnote << "checkBest:" << checkBest; + if (total.elapsed() > 1.0) + { + cnote << "SLOW IMPORT:" << _block.info.hash(); + cnote << " Import took:" << total.elapsed(); + cnote << " preliminaryChecks:" << preliminaryChecks; + cnote << " enactment:" << enactment; + cnote << " collation:" << collation; + cnote << " writing:" << writing; + cnote << " checkBest:" << checkBest; + } #endif if (!route.empty()) @@ -1054,3 +1062,59 @@ bytes BlockChain::block(h256 const& _hash) const return m_blocks[_hash]; } + +VerifiedBlockRef BlockChain::verifyBlock(bytes const& _block, function const& _onBad) +{ + VerifiedBlockRef res; + try + { + res.info.populate(_block, CheckEverything); + res.info.verifyInternals(&_block); + } + catch (Exception& ex) + { + ex << errinfo_now(time(0)); + ex << errinfo_block(_block); + if (_onBad) + _onBad(ex); + throw; + } + + RLP r(_block); + unsigned i = 0; + for (auto const& uncle: r[2]) + { + try + { + BlockInfo().populateFromHeader(RLP(uncle.data()), CheckEverything); + } + catch (Exception& ex) + { + ex << errinfo_uncleIndex(i); + ex << errinfo_now(time(0)); + ex << errinfo_block(_block); + if (_onBad) + _onBad(ex); + throw; + } + ++i; + } + i = 0; + for (auto const& tr: r[1]) + { + try + { + res.transactions.push_back(Transaction(tr.data(), CheckTransaction::Everything)); + } + catch (Exception& ex) + { + ex << errinfo_transactionIndex(i); + ex << errinfo_block(_block); + throw; + } + ++i; + } + res.block = bytesConstRef(&_block); + return move(res); +} + diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index a67ec9a9c..4934d4f2a 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -40,6 +40,7 @@ #include "Account.h" #include "Transaction.h" #include "BlockQueue.h" +#include "VerifiedBlock.h" namespace ldb = leveldb; namespace std @@ -120,7 +121,7 @@ public: /// Import block into disk-backed DB /// @returns the block hashes of any blocks that came into/went out of the canonical block chain. ImportRoute import(bytes const& _block, OverlayDB const& _stateDB, ImportRequirements::value _ir = ImportRequirements::Default); - ImportRoute import(BlockInfo const& _bi, bytes const& _block, OverlayDB const& _stateDB, ImportRequirements::value _ir = ImportRequirements::Default); + ImportRoute import(VerifiedBlockRef const& _block, OverlayDB const& _db, ImportRequirements::value _ir = ImportRequirements::Default); /// Returns true if the given block is known (though not necessarily a part of the canon chain). bool isKnown(h256 const& _hash) const; @@ -256,6 +257,12 @@ public: /// Deallocate unused data. void garbageCollect(bool _force = false); + /// Verify block and prepare it for enactment + static VerifiedBlockRef verifyBlock(bytes const& _block, std::function const& _onBad = std::function()); + + /// 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 +342,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..f055f911a 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -22,10 +22,11 @@ #include "BlockQueue.h" #include #include -#include #include #include #include "BlockChain.h" +#include "VerifiedBlock.h" +#include "State.h" using namespace std; using namespace dev; using namespace dev::eth; @@ -71,62 +72,14 @@ void BlockQueue::verifierBody() m_unverified.pop_front(); BlockInfo bi; bi.mixHash = work.first; - m_verifying.push_back(make_pair(bi, bytes())); + m_verifying.push_back(VerifiedBlock { VerifiedBlockRef { bytesConstRef(), move(bi), Transactions() }, bytes() }); } - std::pair res; - swap(work.second, res.second); - 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) - { - badBlock(res.second, _e.what()); - throw; - } - - RLP r(&res.second); - 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) - { - badBlockHeader(uncle.data(), _e.what()); - throw; - } - } + VerifiedBlock res; + swap(work.second, res.blockData); + try + { + res.verified = BlockChain::verifyBlock(res.blockData, m_onBad); } catch (...) { @@ -141,7 +94,7 @@ void BlockQueue::verifierBody() unique_lock l(m_verification); for (auto it = m_verifying.begin(); it != m_verifying.end(); ++it) - if (it->first.mixHash == work.first) + if (it->verified.info.mixHash == work.first) { m_verifying.erase(it); goto OK1; @@ -154,12 +107,12 @@ void BlockQueue::verifierBody() bool ready = false; { unique_lock l(m_verification); - if (m_verifying.front().first.mixHash == work.first) + if (m_verifying.front().verified.info.mixHash == work.first) { // we're next! m_verifying.pop_front(); m_verified.push_back(move(res)); - while (m_verifying.size() && !m_verifying.front().second.empty()) + while (m_verifying.size() && !m_verifying.front().blockData.empty()) { m_verified.push_back(move(m_verifying.front())); m_verifying.pop_front(); @@ -169,7 +122,7 @@ void BlockQueue::verifierBody() else { for (auto& i: m_verifying) - if (i.first.mixHash == work.first) + if (i.verified.info.mixHash == work.first) { i = move(res); goto OK; @@ -277,15 +230,15 @@ bool BlockQueue::doneDrain(h256s const& _bad) m_drainingSet.clear(); if (_bad.size()) { - vector> old; + vector old; DEV_GUARDED(m_verification) swap(m_verified, old); for (auto& b: old) { - if (m_knownBad.count(b.first.parentHash)) + if (m_knownBad.count(b.verified.info.parentHash)) { - m_knownBad.insert(b.first.hash()); - m_readySet.erase(b.first.hash()); + m_knownBad.insert(b.verified.info.hash()); + m_readySet.erase(b.verified.info.hash()); } else DEV_GUARDED(m_verification) @@ -348,7 +301,7 @@ QueueStatus BlockQueue::blockStatus(h256 const& _h) const QueueStatus::Unknown; } -void BlockQueue::drain(std::vector>& o_out, unsigned _max) +void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max) { WriteGuard l(m_lock); DEV_INVARIANT_CHECK; @@ -364,7 +317,7 @@ void BlockQueue::drain(std::vector>& o_out, unsigned for (auto const& bs: o_out) { // TODO: @optimise use map rather than vector & set. - auto h = bs.first.hash(); + auto h = bs.verified.info.hash(); m_drainingSet.insert(h); m_readySet.erase(h); } @@ -421,6 +374,7 @@ void BlockQueue::retryAllUnknown() std::ostream& dev::eth::operator<<(std::ostream& _out, BlockQueueStatus const& _bqs) { + _out << "importing: " << _bqs.importing << endl; _out << "verified: " << _bqs.verified << endl; _out << "verifying: " << _bqs.verifying << endl; _out << "unverified: " << _bqs.unverified << endl; diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h index 45043559b..0e3e640b1 100644 --- a/libethereum/BlockQueue.h +++ b/libethereum/BlockQueue.h @@ -31,6 +31,7 @@ #include #include #include +#include "VerifiedBlock.h" namespace dev { @@ -45,6 +46,7 @@ struct BlockQueueChannel: public LogChannel { static const char* name(); static struct BlockQueueStatus { + size_t importing; size_t verified; size_t verifying; size_t unverified; @@ -81,7 +83,7 @@ public: /// Grabs at most @a _max of the blocks that are ready, giving them in the correct order for insertion into the chain. /// Don't forget to call doneDrain() once you're done importing. - void drain(std::vector>& o_out, unsigned _max); + void drain(std::vector& o_out, unsigned _max); /// Must be called after a drain() call. Notes that the drained blocks have been imported into the blockchain, so we can forget about them. /// @returns true iff there are additional blocks ready to be processed. @@ -103,13 +105,15 @@ public: h256 firstUnknown() const { ReadGuard l(m_lock); return m_unknownSet.size() ? *m_unknownSet.begin() : h256(); } /// Get some infomration on the current status. - BlockQueueStatus status() const { ReadGuard l(m_lock); Guard l2(m_verification); return BlockQueueStatus{m_verified.size(), m_verifying.size(), m_unverified.size(), m_future.size(), m_unknown.size(), m_knownBad.size()}; } + BlockQueueStatus status() const { ReadGuard l(m_lock); Guard l2(m_verification); return BlockQueueStatus{m_drainingSet.size(), m_verified.size(), m_verifying.size(), m_unverified.size(), m_future.size(), m_unknown.size(), m_knownBad.size()}; } /// Get some infomration on the given block's status regarding us. QueueStatus blockStatus(h256 const& _h) const; 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); @@ -128,12 +132,14 @@ private: mutable Mutex m_verification; ///< Mutex that allows writing to m_verified, m_verifying and m_unverified. std::condition_variable m_moreToVerify; ///< Signaled when m_unverified has a new entry. - std::vector> m_verified; ///< List of blocks, in correct order, verified and ready for chain-import. - std::deque> m_verifying; ///< List of blocks being verified; as long as the second component (bytes) is empty, it's not finished. + std::vector m_verified; ///< List of blocks, in correct order, verified and ready for chain-import. + std::deque m_verifying; ///< List of blocks being verified; as long as the second component (bytes) is empty, it's not finished. std::deque> m_unverified; ///< List of blocks, in correct order, ready for verification. 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..6598e1bd7 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,13 @@ 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}) + target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES}) + if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) + eth_copy_dlls(${EXECUTABLE} CURL_DLLS) + endif() +endif() if (CMAKE_COMPILER_IS_MINGW) target_link_libraries(${EXECUTABLE} ssp shlwapi) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 9e2dfc0a6..029a0041c 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,113 @@ 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()); + +#if ETH_JSONRPC || !ETH_TRUE + 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); + + // 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(name); + DEV_HINT_ERRINFO(field); + DEV_HINT_ERRINFO(data); + DEV_HINT_ERRINFO_HASH(nonce); + DEV_HINT_ERRINFO(difficulty); + DEV_HINT_ERRINFO(target); + DEV_HINT_ERRINFO_HASH(seedHash); + DEV_HINT_ERRINFO_HASH(mixHash); + if (tuple const* r = boost::get_error_info(_ex)) + { + report["hints"]["ethashResult"]["value"] = get<0>(*r).hex(); + report["hints"]["ethashResult"]["mixHash"] = get<1>(*r).hex(); + } + 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); + + cwarn << ("Report: \n" + Json::StyledWriter().write(report)); + + if (!m_sentinel.empty()) + { + 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; @@ -174,7 +288,7 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _for } Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): - Worker("eth"), + Worker("eth", 0), m_vc(_dbPath), m_bc(_dbPath, max(m_vc.action(), _forceAction), [](unsigned d, unsigned t){ cerr << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }), m_gp(_gp), @@ -185,6 +299,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); @@ -206,6 +322,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()) @@ -448,6 +576,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(); @@ -605,11 +736,22 @@ bool Client::remoteActive() const void Client::onPostStateChanged() { - cnote << "Post state changed"; + cnote << "Post state changed."; + rejigMining(); + m_remoteWorking = false; +} - if (m_bq.items().first == 0 && (isMining() || remoteActive())) +void Client::startMining() +{ + m_wouldMine = true; + rejigMining(); +} + +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) @@ -618,20 +760,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) @@ -746,3 +889,9 @@ void Client::flushTransactions() { doWork(); } + +HashChainStatus Client::hashChainStatus() const +{ + auto h = m_host.lock(); + return h ? h->status() : HashChainStatus { 0, 0, false }; +} diff --git a/libethereum/Client.h b/libethereum/Client.h index 5132b5a30..2de6e9403 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; @@ -156,10 +156,14 @@ public: CanonBlockChain const& blockChain() const { return m_bc; } /// Get some information on the block queue. BlockQueueStatus blockQueueStatus() const { return m_bq.status(); } + /// Get some information on the block queue. + HashChainStatus hashChainStatus() const; + /// Get the block queue. + BlockQueue const& blockQueue() const { return m_bq; } // 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; } @@ -174,14 +178,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. @@ -213,6 +229,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 @@ -249,6 +267,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); @@ -278,6 +299,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). @@ -302,8 +327,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; @@ -317,6 +344,8 @@ private: Mutex x_signalled; std::atomic m_syncTransactionQueue = {false}; std::atomic m_syncBlockQueue = {false}; + + std::string m_sentinel; }; } 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..b2afe3597 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; @@ -154,6 +151,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/CommonNet.h b/libethereum/CommonNet.h index 8cf2647cf..1515c844d 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -84,5 +84,12 @@ enum class Syncing Done }; +struct HashChainStatus +{ + unsigned total; + unsigned received; + bool estimated; +}; + } } diff --git a/libethereum/DownloadMan.cpp b/libethereum/DownloadMan.cpp index 3e33f3eb5..5e68e3c49 100644 --- a/libethereum/DownloadMan.cpp +++ b/libethereum/DownloadMan.cpp @@ -80,7 +80,6 @@ HashDownloadSub::HashDownloadSub(HashDownloadMan& _man): m_man(&_man) { WriteGuard l(m_man->x_subs); m_asked = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); - m_attempted = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); m_man->m_subs.insert(this); } @@ -98,7 +97,6 @@ void HashDownloadSub::resetFetch() Guard l(m_fetch); m_remaining = 0; m_asked = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); - m_attempted = RangeMask(m_man->m_chainStart, m_man->m_chainStart + m_man->m_chainCount); } unsigned HashDownloadSub::nextFetch(unsigned _n) @@ -110,10 +108,9 @@ unsigned HashDownloadSub::nextFetch(unsigned _n) if (!m_man || m_man->chainEmpty()) return 0; - m_asked = (~(m_man->taken() + m_attempted)).lowest(_n); + m_asked = (~(m_man->taken())).lowest(_n); if (m_asked.empty()) - m_asked = (~(m_man->taken(true) + m_attempted)).lowest(_n); - m_attempted += m_asked; + m_asked = (~(m_man->taken(true))).lowest(_n); return *m_asked.begin(); } diff --git a/libethereum/DownloadMan.h b/libethereum/DownloadMan.h index 3e1a071c9..0c27e84ea 100644 --- a/libethereum/DownloadMan.h +++ b/libethereum/DownloadMan.h @@ -187,7 +187,6 @@ public: bool askedContains(unsigned _i) const { Guard l(m_fetch); return m_asked.contains(_i); } RangeMask const& asked() const { return m_asked; } - RangeMask const& attemped() const { return m_attempted; } private: void resetFetch(); // Called by DownloadMan when we need to reset the download. @@ -196,7 +195,6 @@ private: mutable Mutex m_fetch; unsigned m_remaining; RangeMask m_asked; - RangeMask m_attempted; }; class HashDownloadMan @@ -255,6 +253,11 @@ public: return m_got.full(); } + unsigned gotCount() const + { + return m_got.size(); + } + size_t chainSize() const { ReadGuard l(m_lock); return m_chainCount; } size_t chainEmpty() const { ReadGuard l(m_lock); return m_chainCount == 0; } void foreachSub(std::function const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); } @@ -274,3 +277,4 @@ private: } } + diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 7c9b730ea..a5a03297f 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -237,7 +237,7 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) void EthereumHost::onPeerStatus(EthereumPeer* _peer) { - Guard l(x_sync); + RecursiveGuard l(x_sync); if (_peer->m_genesisHash != m_chain.genesisHash()) _peer->disable("Invalid genesis hash"); else if (_peer->m_protocolVersion != protocolVersion() && _peer->m_protocolVersion != c_oldProtocolVersion) @@ -252,12 +252,13 @@ void EthereumHost::onPeerStatus(EthereumPeer* _peer) { if (_peer->m_protocolVersion != protocolVersion()) estimatePeerHashes(_peer); - else if (_peer->m_latestBlockNumber > m_chain.number()) - _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number() + 1000; else - _peer->m_expectedHashes = 1000; - if (m_hashMan.chainSize() < _peer->m_expectedHashes) - m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); + { + if (_peer->m_latestBlockNumber > m_chain.number()) + _peer->m_expectedHashes = (unsigned)_peer->m_latestBlockNumber - m_chain.number(); + if (m_hashMan.chainSize() < _peer->m_expectedHashes) + m_hashMan.resetToRange(m_chain.number() + 1, _peer->m_expectedHashes); + } continueSync(_peer); } } @@ -267,7 +268,7 @@ void EthereumHost::estimatePeerHashes(EthereumPeer* _peer) BlockInfo block = m_chain.info(); time_t lastBlockTime = (block.hash() == m_chain.genesisHash()) ? 1428192000 : (time_t)block.timestamp; time_t now = time(0); - unsigned blockCount = 1000; + unsigned blockCount = 30000; if (lastBlockTime > now) clog(NetWarn) << "Clock skew? Latest block is in the future"; else @@ -278,7 +279,7 @@ void EthereumHost::estimatePeerHashes(EthereumPeer* _peer) void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes) { - Guard l(x_sync); + RecursiveGuard l(x_sync); assert(_peer->m_asking == Asking::Nothing); onPeerHashes(_peer, _hashes, false); } @@ -287,13 +288,23 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool { if (_hashes.empty()) { - onPeerDoneHashes(_peer, true); + _peer->m_hashSub.doneFetch(); + continueSync(); + return; + } + + bool syncByNumber = _peer->m_syncHashNumber; + if (!syncByNumber && _peer->m_syncHash != m_syncingLatestHash) + { + // Obsolete hashes, discard + continueSync(_peer); return; } + unsigned knowns = 0; unsigned unknowns = 0; h256s neededBlocks; - bool syncByNumber = !m_syncingLatestHash; + unsigned firstNumber = _peer->m_syncHashNumber - _hashes.size(); for (unsigned i = 0; i < _hashes.size(); ++i) { _peer->addRating(1); @@ -323,8 +334,11 @@ void EthereumHost::onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool } else knowns++; + if (!syncByNumber) m_syncingLatestHash = h; + else + _peer->m_hashSub.noteHash(firstNumber + i, 1); } if (syncByNumber) { @@ -370,13 +384,14 @@ void EthereumHost::onPeerDoneHashes(EthereumPeer* _peer, bool _localChain) { m_man.resetToChain(m_hashes); m_hashes.clear(); + m_hashMan.reset(m_chain.number() + 1); } continueSync(); } void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r) { - Guard l(x_sync); + RecursiveGuard l(x_sync); assert(_peer->m_asking == Asking::Nothing); unsigned itemCount = _r.itemCount(); clog(NetMessageSummary) << "Blocks (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBlocks"); @@ -386,6 +401,7 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r) // Got to this peer's latest block - just give up. clog(NetNote) << "Finishing blocks fetch..."; // NOTE: need to notify of giving up on chain-hashes, too, altering state as necessary. + _peer->m_sub.doneFetch(); _peer->setIdle(); return; } @@ -452,7 +468,7 @@ void EthereumHost::onPeerBlocks(EthereumPeer* _peer, RLP const& _r) void EthereumHost::onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes) { - Guard l(x_sync); + RecursiveGuard l(x_sync); if (isSyncing_UNSAFE()) { clog(NetMessageSummary) << "Ignoring new hashes since we're already downloading."; @@ -464,7 +480,7 @@ void EthereumHost::onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes) void EthereumHost::onPeerNewBlock(EthereumPeer* _peer, RLP const& _r) { - Guard l(x_sync); + RecursiveGuard l(x_sync); if (isSyncing_UNSAFE()) { clog(NetMessageSummary) << "Ignoring new blocks since we're already downloading."; @@ -551,6 +567,18 @@ void EthereumHost::onPeerTransactions(EthereumPeer* _peer, RLP const& _r) } } +void EthereumHost::onPeerAborting(EthereumPeer* _peer) +{ + RecursiveGuard l(x_sync); + if (_peer->isConversing()) + { + _peer->setIdle(); + if (_peer->isCriticalSyncing()) + _peer->setRude(); + continueSync(); + } +} + void EthereumHost::continueSync() { clog(NetAllDetail) << "Getting help with downloading hashes and blocks"; @@ -564,22 +592,37 @@ void EthereumHost::continueSync() void EthereumHost::continueSync(EthereumPeer* _peer) { assert(_peer->m_asking == Asking::Nothing); - bool otherPeerSync = false; + bool otherPeerV60Sync = false; + bool otherPeerV61Sync = false; if (m_needSyncHashes && peerShouldGrabChain(_peer)) { foreachPeer([&](EthereumPeer* _p) { - if (_p != _peer && _p->m_asking == Asking::Hashes && _p->m_protocolVersion != protocolVersion()) - otherPeerSync = true; // Already have a peer downloading hash chain with old protocol, do nothing + if (_p != _peer && _p->m_asking == Asking::Hashes) + { + if (_p->m_protocolVersion != protocolVersion()) + otherPeerV60Sync = true; // Already have a peer downloading hash chain with old protocol, do nothing + else + otherPeerV61Sync = true; // Already have a peer downloading hash chain with V61+ protocol, join if supported + } }); - if (otherPeerSync) + if (otherPeerV60Sync && !m_hashes.empty()) + { + /// Downloading from other peer with v60 protocol, nothing else we can do + _peer->setIdle(); + return; + } + if (otherPeerV61Sync && _peer->m_protocolVersion != protocolVersion()) { - /// Downloading from other peer with v60 protocol, nothing ese we can do + /// Downloading from other peer with v61+ protocol which this peer does not support, _peer->setIdle(); return; } - if (_peer->m_protocolVersion == protocolVersion() && !m_syncingLatestHash) + if (_peer->m_protocolVersion == protocolVersion() && !m_hashMan.isComplete()) + { + m_syncingV61 = true; _peer->requestHashes(); /// v61+ and not catching up to a particular hash + } else { // Restart/continue sync in single peer mode @@ -588,17 +631,33 @@ void EthereumHost::continueSync(EthereumPeer* _peer) m_syncingLatestHash =_peer->m_latestHash; m_syncingTotalDifficulty = _peer->m_totalDifficulty; } - _peer->requestHashes(m_syncingLatestHash); + if (_peer->m_totalDifficulty >= m_syncingTotalDifficulty) + { + _peer->requestHashes(m_syncingLatestHash); + m_syncingV61 = false; + m_estimatedHashes = _peer->m_expectedHashes; + } + else + _peer->setIdle(); } } - else if (m_needSyncBlocks && peerShouldGrabBlocks(_peer)) // Check if this peer can help with downloading blocks + else if (m_needSyncBlocks && peerCanHelp(_peer)) // Check if this peer can help with downloading blocks _peer->requestBlocks(); else _peer->setIdle(); } +bool EthereumHost::peerCanHelp(EthereumPeer* _peer) const +{ + (void)_peer; + return true; +} + bool EthereumHost::peerShouldGrabBlocks(EthereumPeer* _peer) const { + // this is only good for deciding whether to go ahead and grab a particular peer's hash chain, + // yet it's being used in determining whether to allow a peer help with downloading an existing + // chain of blocks. auto td = _peer->m_totalDifficulty; auto lh = m_syncingLatestHash; auto ctd = m_chain.details().totalDifficulty; @@ -611,6 +670,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; @@ -640,3 +703,12 @@ bool EthereumHost::isSyncing_UNSAFE() const }); return syncing; } + +HashChainStatus EthereumHost::status() +{ + RecursiveGuard l(x_sync); + if (m_syncingV61) + return HashChainStatus { static_cast(m_hashMan.chainSize()), static_cast(m_hashMan.gotCount()), false }; + return HashChainStatus { m_estimatedHashes - 30000, static_cast(m_hashes.size()), true }; +} + diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index 8ca815a17..df17b1e4e 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -70,8 +70,8 @@ public: void reset(); 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 isSyncing() const { RecursiveGuard l(x_sync); return isSyncing_UNSAFE(); } + bool isBanned(p2p::NodeId const& _id) const { return !!m_banned.count(_id); } void noteNewTransactions() { m_newTransactions = true; } void noteNewBlocks() { m_newBlocks = true; } @@ -82,10 +82,12 @@ public: void onPeerNewHashes(EthereumPeer* _peer, h256s const& _hashes); ///< Called by peer once it has new hashes void onPeerHashes(EthereumPeer* _peer, h256s const& _hashes); ///< Called by peer once it has another sequential block of hashes during sync void onPeerTransactions(EthereumPeer* _peer, RLP const& _r); ///< Called by peer when it has new transactions + void onPeerAborting(EthereumPeer* _peer); ///< Called by peer when it is disconnecting DownloadMan& downloadMan() { return m_man; } HashDownloadMan& hashDownloadMan() { return m_hashMan; } BlockChain const& chain() { return m_chain; } + HashChainStatus status(); static unsigned const c_oldProtocolVersion; @@ -122,6 +124,7 @@ private: void onPeerHashes(EthereumPeer* _peer, h256s const& _hashes, bool _complete); bool peerShouldGrabBlocks(EthereumPeer* _peer) const; bool peerShouldGrabChain(EthereumPeer* _peer) const; + bool peerCanHelp(EthereumPeer* _peer) const; void estimatePeerHashes(EthereumPeer* _peer); BlockChain const& m_chain; @@ -141,12 +144,14 @@ private: bool m_newTransactions = false; bool m_newBlocks = false; - mutable Mutex x_sync; + mutable RecursiveMutex x_sync; bool m_needSyncHashes = true; ///< Indicates if need to downlad hashes bool m_needSyncBlocks = true; ///< Indicates if we still need to download some blocks h256 m_syncingLatestHash; ///< Latest block's hash, as of the current sync. u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty, as of the current sync. - h256s m_hashes; ///< List of hashes with unknown block numbers. Used for v60 chain downloading and catching up to a particular unknown + h256s m_hashes; ///< List of hashes with unknown block numbers. Used for PV60 chain downloading and catching up to a particular unknown + unsigned m_estimatedHashes = 0; ///< Number of estimated hashes for the last peer over PV60. Used for status reporting only. + bool m_syncingV61 = false; ///< True if recent activity was over pv61+. Used for status reporting only. }; } diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index a332e5b93..8167baeda 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "BlockChain.h" #include "EthereumHost.h" #include "TransactionQueue.h" @@ -40,6 +41,7 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h, unsigned _i, Cap m_hashSub(host()->hashDownloadMan()), m_peerCapabilityVersion(_cap.second) { + session()->addNote("manners", isRude() ? "RUDE" : "nice"); m_syncHashNumber = host()->chain().number() + 1; requestStatus(); } @@ -50,10 +52,20 @@ EthereumPeer::~EthereumPeer() abortSync(); } +bool EthereumPeer::isRude() const +{ + return repMan().isRude(*session(), name()); +} + +void EthereumPeer::setRude() +{ + repMan().noteRude(*session(), name()); + session()->addNote("manners", "RUDE"); +} + void EthereumPeer::abortSync() { - if (isSyncing()) - setIdle(); + host()->onPeerAborting(this); } EthereumHost* EthereumPeer::host() const @@ -105,6 +117,7 @@ void EthereumPeer::requestHashes() { assert(m_asking == Asking::Nothing); m_syncHashNumber = m_hashSub.nextFetch(c_maxHashesAsk); + m_syncHash = h256(); setAsking(Asking::Hashes); RLPStream s; prep(s, GetBlockHashesByNumberPacket, 2) << m_syncHashNumber << c_maxHashesAsk; @@ -119,13 +132,15 @@ void EthereumPeer::requestHashes(h256 const& _lastHash) RLPStream s; prep(s, GetBlockHashesPacket, 2) << _lastHash << c_maxHashesAsk; clog(NetMessageDetail) << "Requesting block hashes staring from " << _lastHash; + m_syncHash = _lastHash; + m_syncHashNumber = 0; sealAndSend(s); } void EthereumPeer::requestBlocks() { setAsking(Asking::Blocks); - auto blocks = m_sub.nextFetch(c_maxBlocksAsk); + auto blocks = m_sub.nextFetch(isRude() ? 1 : c_maxBlocksAsk); if (blocks.size()) { RLPStream s; @@ -145,7 +160,7 @@ void EthereumPeer::setAsking(Asking _a) m_lastAsk = chrono::system_clock::now(); session()->addNote("ask", _a == Asking::Nothing ? "nothing" : _a == Asking::State ? "state" : _a == Asking::Hashes ? "hashes" : _a == Asking::Blocks ? "blocks" : "?"); - session()->addNote("sync", string(isSyncing() ? "ongoing" : "holding") + (needsSyncing() ? " & needed" : "")); + session()->addNote("sync", string(isCriticalSyncing() ? "ONGOING" : "holding") + (needsSyncing() ? " & needed" : "")); } void EthereumPeer::tick() @@ -155,11 +170,16 @@ void EthereumPeer::tick() session()->disconnect(PingTimeout); } -bool EthereumPeer::isSyncing() const +bool EthereumPeer::isConversing() const { return m_asking != Asking::Nothing; } +bool EthereumPeer::isCriticalSyncing() const +{ + return m_asking == Asking::Hashes || m_asking == Asking::State || (m_asking == Asking::Blocks && m_protocolVersion == 60); +} + bool EthereumPeer::interpret(unsigned _id, RLP const& _r) { try @@ -175,8 +195,16 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) m_genesisHash = _r[4].toHash(); if (m_peerCapabilityVersion == host()->protocolVersion()) { - m_protocolVersion = host()->protocolVersion(); - m_latestBlockNumber = _r[5].toInt(); + if (_r.itemCount() != 6) + { + clog(NetImpolite) << "Peer does not support PV61+ status extension."; + m_protocolVersion = EthereumHost::c_oldProtocolVersion; + } + else + { + m_protocolVersion = host()->protocolVersion(); + m_latestBlockNumber = _r[5].toInt(); + } } clog(NetMessageSummary) << "Status:" << m_protocolVersion << "/" << m_networkId << "/" << m_genesisHash << "/" << m_latestBlockNumber << ", TD:" << m_totalDifficulty << "=" << m_latestHash; @@ -240,12 +268,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) setAsking(Asking::Nothing); h256s hashes(itemCount); for (unsigned i = 0; i < itemCount; ++i) - { hashes[i] = _r[i].toHash(); - m_hashSub.noteHash(m_syncHashNumber + i, 1); - } - m_syncHashNumber += itemCount; + if (m_syncHashNumber > 0) + m_syncHashNumber += itemCount; host()->onPeerHashes(this, hashes); break; } diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index 94dc60501..a12b7a197 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; + + /// Set that it's a rude node. + void setRude(); + private: using p2p::Capability::sealAndSend; @@ -101,10 +107,13 @@ 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 in the process of communicating with this peer? + bool isConversing() const; - /// Are we presently syncing with this peer? - bool isSyncing() const; + /// Are we presently in a critical part of the syncing process with this peer? + bool isCriticalSyncing() const; /// Runs period checks to check up on the peer. void tick(); @@ -128,8 +137,9 @@ private: /// This is built as we ask for hashes. Once no more hashes are given, we present this to the /// host who initialises the DownloadMan and m_sub becomes active for us to begin asking for blocks. - unsigned m_expectedHashes = 0; ///< Estimated upper bound of hashes to expect from this peer. - unsigned m_syncHashNumber = 0; ///< Number of latest hash we sync to + unsigned m_expectedHashes = 0; ///< Estimated upper bound of hashes to expect from this peer. + unsigned m_syncHashNumber = 0; ///< Number of latest hash we sync to (PV61+) + h256 m_syncHash; ///< Latest hash we sync to (PV60) /// Once we're asking for blocks, this becomes in use. DownloadSub m_sub; diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 5ec5f7313..4e741795c 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)), @@ -68,7 +166,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())); } @@ -151,7 +249,8 @@ bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address co { m_outRef = _p.out; // Save ref to expected output buffer to be used in go() bytes const& c = m_s.code(_p.codeAddress); - m_ext = make_shared(m_s, m_lastHashes, _p.receiveAddress, _p.senderAddress, _origin, _p.value, _gasPrice, _p.data, &c, m_depth); + h256 codeHash = m_s.codeHash(_p.codeAddress); + m_ext = make_shared(m_s, m_lastHashes, _p.receiveAddress, _p.senderAddress, _origin, _p.value, _gasPrice, _p.data, &c, codeHash, m_depth); } } @@ -171,7 +270,7 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g // Execute _init. if (!_init.empty()) - m_ext = make_shared(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, m_depth); + m_ext = make_shared(m_s, m_lastHashes, m_newAddress, _sender, _origin, _endowment, _gasPrice, bytesConstRef(), _init, sha3(_init), m_depth); m_s.m_cache[m_newAddress] = Account(m_s.balance(m_newAddress), Account::ContractConception); m_s.transferBalance(_sender, m_newAddress, _endowment); @@ -202,24 +301,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/ExtVM.h b/libethereum/ExtVM.h index babff4edf..853787493 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -39,8 +39,8 @@ class ExtVM: public ExtVMFace { public: /// Full constructor. - ExtVM(State& _s, LastHashes const& _lh, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, unsigned _depth = 0): - ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _s.m_previousBlock, _s.m_currentBlock, _lh, _depth), m_s(_s), m_origCache(_s.m_cache) + ExtVM(State& _s, LastHashes const& _lh, Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytesConstRef _code, h256 const& _codeHash, unsigned _depth = 0): + ExtVMFace(_myAddress, _caller, _origin, _value, _gasPrice, _data, _code.toBytes(), _codeHash, _s.m_previousBlock, _s.m_currentBlock, _lh, _depth), m_s(_s), m_origCache(_s.m_cache) { m_s.ensureCached(_myAddress, true, true); } 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/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; } } } 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/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 } +] diff --git a/libethereum/State.cpp b/libethereum/State.cpp index f40574fde..464cba9d4 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -141,7 +141,7 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h, ImportRequire // 2. Enact the block's transactions onto this state. m_ourAddress = bi.coinbaseAddress; - enact(&b, _bc, _ir); + enact(BlockChain::verifyBlock(b), _bc, _ir); } else { @@ -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,19 +218,29 @@ 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); - for (auto i: m_cache) + if (_quick) + { + trieAds = m_touched; + trieAdsD = _c.m_touched; + (ads += m_touched) += _c.m_touched; + } + else + { + for (auto const& i: trie) + ads.insert(i.first), trieAds.insert(i.first); + for (auto const& i: trieD) + ads.insert(i.first), trieAdsD.insert(i.first); + } + + 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); @@ -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(); } @@ -382,7 +393,7 @@ bool State::sync(BlockChain const& _bc, h256 _block, BlockInfo const& _bi, Impor return ret; } -u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc, ImportRequirements::value _ir) +u256 State::enactOn(VerifiedBlockRef const& _block, BlockChain const& _bc, ImportRequirements::value _ir) { #if ETH_TIMED_ENACTMENTS boost::timer t; @@ -393,8 +404,8 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const #endif // Check family: - BlockInfo biParent = _bc.info(_bi.parentHash); - _bi.verifyParent(biParent); + BlockInfo biParent = _bc.info(_block.info.parentHash); + _block.info.verifyParent(biParent); #if ETH_TIMED_ENACTMENTS populateVerify = t.elapsed(); @@ -410,7 +421,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const t.restart(); #endif - sync(_bc, _bi.parentHash, BlockInfo(), _ir); + sync(_bc, _block.info.parentHash, BlockInfo(), _ir); resetCurrent(); #if ETH_TIMED_ENACTMENTS @@ -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)); @@ -577,101 +589,93 @@ 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) +u256 State::enact(VerifiedBlockRef const& _block, BlockChain const& _bc, ImportRequirements::value _ir) { - // m_currentBlock is assumed to be prepopulated and reset. - - BlockInfo bi(_block, (_ir & ImportRequirements::ValidNonce) ? CheckEverything : IgnoreNonce); + DEV_TIMED_FUNCTION_ABOVE(500); + // m_currentBlock is assumed to be prepopulated and reset. #if !ETH_RELEASE - assert(m_previousBlock.hash() == bi.parentHash); - assert(m_currentBlock.parentHash == bi.parentHash); + assert(m_previousBlock.hash() == _block.info.parentHash); + assert(m_currentBlock.parentHash == _block.info.parentHash); assert(rootHash() == m_previousBlock.stateRoot); #endif if (m_currentBlock.parentHash != m_previousBlock.hash()) + // Internal client error. BOOST_THROW_EXCEPTION(InvalidParentHash()); // Populate m_currentBlock with the correct values. - m_currentBlock = bi; - m_currentBlock.verifyInternals(_block); + m_currentBlock = _block.info; m_currentBlock.noteDirty(); // cnote << "playback begins:" << m_state.root(); // cnote << m_state; - LastHashes lh = _bc.lastHashes((unsigned)m_previousBlock.number); - RLP rlp(_block); + LastHashes lh; + DEV_TIMED_ABOVE(lastHashes, 500) + lh = _bc.lastHashes((unsigned)m_previousBlock.number); + + RLP rlp(_block.block); vector receipts; // All ok with the block generally. Play back the transactions now... unsigned i = 0; - for (auto const& tr: rlp[1]) - { - try { - LogOverride o(false); - execute(lh, Transaction(tr.data(), CheckTransaction::Everything)); - } - catch (...) + DEV_TIMED_ABOVE(txEcec, 500) + for (auto const& tr: _block.transactions) { - badBlock(_block, "Invalid transaction"); - cwarn << " Transaction Index:" << i; - LogOverride o(true); - execute(lh, Transaction(tr.data(), CheckTransaction::Everything)); - throw; + try + { + LogOverride o(false); + execute(lh, tr); + } + catch (Exception& ex) + { + ex << errinfo_transactionIndex(i); + throw; + } + + RLPStream receiptRLP; + m_receipts.back().streamRLP(receiptRLP); + receipts.push_back(receiptRLP.out()); + ++i; } - RLPStream receiptRLP; - m_receipts.back().streamRLP(receiptRLP); - receipts.push_back(receiptRLP.out()); - ++i; - } + h256 receiptsRoot; + DEV_TIMED_ABOVE(receiptsRoot, 500) + receiptsRoot = orderedTrieRoot(receipts); - auto receiptsRoot = orderedTrieRoot(receipts); if (receiptsRoot != m_currentBlock.receiptsRoot) { - badBlock(_block, "Bad receipts state root"); - cwarn << " Received: " << toString(m_currentBlock.receiptsRoot); - cwarn << " Expected: " << toString(receiptsRoot) << " which is:"; - for (unsigned j = 0; j < i; ++j) - { - auto b = receipts[j]; - cwarn << j << ": "; - cwarn << " RLP: " << RLP(b); - cwarn << " Hex: " << toHex(b); - cwarn << " " << TransactionReceipt(&b); - } - cwarn << " VMTrace:\n" << vmTrace(_block, _bc, _ir); - BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot()); + InvalidReceiptsStateRoot ex; + ex << Hash256RequirementError(receiptsRoot, m_currentBlock.receiptsRoot); + ex << errinfo_receipts(receipts); + ex << errinfo_vmtrace(vmTrace(_block.block, _bc, _ir)); + BOOST_THROW_EXCEPTION(ex); } if (m_currentBlock.logBloom != logBloom()) { - badBlock(_block, "Bad log bloom"); - cwarn << " Receipt blooms:"; - for (unsigned j = 0; j < i; ++j) - { - auto b = receipts[j]; - cwarn << " " << j << ":" << TransactionReceipt(&b).bloom().hex(); - } - cwarn << " Final bloom:" << m_currentBlock.logBloom.hex(); - BOOST_THROW_EXCEPTION(InvalidLogBloom()); + InvalidLogBloom ex; + ex << LogBloomRequirementError(logBloom(), m_currentBlock.logBloom); + ex << errinfo_receipts(receipts); + BOOST_THROW_EXCEPTION(ex); } // Initialise total difficulty calculation. @@ -680,72 +684,85 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement // Check uncles & apply their rewards to state. if (rlp[2].itemCount() > 2) { - badBlock(_block, "Too many uncles"); - BOOST_THROW_EXCEPTION(TooManyUncles()); + TooManyUncles ex; + ex << errinfo_max(2); + ex << errinfo_got(rlp[2].itemCount()); + BOOST_THROW_EXCEPTION(ex); } vector rewarded; - h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6); + h256Hash excluded; + DEV_TIMED_ABOVE(allKin, 500) + excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6); excluded.insert(m_currentBlock.hash()); - for (auto const& i: rlp[2]) - { - auto h = sha3(i.data()); - if (excluded.count(h)) + unsigned ii = 0; + DEV_TIMED_ABOVE(uncleCheck, 500) + for (auto const& i: rlp[2]) { - 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); + try + { + auto h = sha3(i.data()); + if (excluded.count(h)) + { + 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()); - } - 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; - BOOST_THROW_EXCEPTION(UncleIsBrother()); - } - uncle.verifyParent(uncleParent); + BlockInfo uncle = BlockInfo::fromHeader(i.data(), (_ir & ImportRequirements::CheckUncles) ? CheckEverything : IgnoreNonce, h); -// tdIncrease += uncle.difficulty; - rewarded.push_back(uncle); - } + BlockInfo uncleParent; + if (!_bc.isKnown(uncle.parentHash)) + BOOST_THROW_EXCEPTION(UnknownParent()); + uncleParent = BlockInfo(_bc.block(uncle.parentHash)); - applyRewards(rewarded); + if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 7) + { + UncleTooOld ex; + ex << errinfo_uncleNumber(uncle.number); + ex << errinfo_currentNumber(m_currentBlock.number); + BOOST_THROW_EXCEPTION(ex); + } + else if (uncle.number == m_currentBlock.number) + { + UncleIsBrother ex; + ex << errinfo_uncleNumber(uncle.number); + ex << errinfo_currentNumber(m_currentBlock.number); + BOOST_THROW_EXCEPTION(ex); + } + uncle.verifyParent(uncleParent); + + rewarded.push_back(uncle); + ++ii; + } + catch (Exception& ex) + { + ex << errinfo_uncleIndex(ii); + throw; + } + } + + DEV_TIMED_ABOVE(applyRewards, 500) + applyRewards(rewarded); // Commit all cached state changes to the state trie. - commit(); + DEV_TIMED_ABOVE(commit, 500) + commit(); // Hash the state trie and check against the state_root hash in m_currentBlock. 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() << Hash256RequirementError(rootHash(), m_currentBlock.stateRoot)); } if (m_currentBlock.gasUsed != gasUsed()) { // Rollback the trie. - badBlock(_block, "Invalid gas used"); m_db.rollback(); BOOST_THROW_EXCEPTION(InvalidGasUsed() << RequirementError(bigint(gasUsed()), bigint(m_currentBlock.gasUsed))); } @@ -823,7 +840,7 @@ bool State::amIJustParanoid(BlockChain const& _bc) cnote << "PARANOIA root:" << s.rootHash(); // s.m_currentBlock.populate(&block.out(), false); // s.m_currentBlock.verifyInternals(&block.out()); - s.enact(&block.out(), _bc, false); // don't check nonce for this since we haven't mined it yet. + s.enact(BlockChain::verifyBlock(block.out()), _bc, false); // don't check nonce for this since we haven't mined it yet. s.cleanup(false); return true; } @@ -1122,6 +1139,8 @@ h256 State::codeHash(Address _contract) const { if (!addressHasCode(_contract)) return EmptySHA3; + if (m_cache[_contract].isFreshCode()) + return sha3(code(_contract)); return m_cache[_contract].codeHash(); } @@ -1160,6 +1179,8 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const return true; } +#define ETH_VMTIMER 1 + ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp) { #if ETH_PARANOIA @@ -1187,9 +1208,26 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per #endif if (!e.execute()) #if ETH_VMTRACE + { + if (isChannelVisible()) + e.go(e.simpleTrace()); + else + e.go(_onOp); + } +#elif ETH_VMTIMER { (void)_onOp; - e.go(e.simpleTrace()); + boost::timer t; + unordered_map counts; + unsigned total = 0; + e.go([&](uint64_t, Instruction inst, bigint, bigint, bigint, VM*, ExtVMFace const*) { + counts[(byte)inst]++; + total++; + }); + cnote << total << "total in" << t.elapsed(); + for (auto const& c: {Instruction::SSTORE, Instruction::SLOAD, Instruction::CALL, Instruction::CREATE, Instruction::CALLCODE, Instruction::MSTORE8, Instruction::MSTORE, Instruction::MLOAD, Instruction::SHA3}) + cnote << instructionInfo(c).name << counts[(byte)c]; + cnote; } #else e.go(_onOp); diff --git a/libethereum/State.h b/libethereum/State.h index 55d5cfb4c..771cdb6bf 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -46,8 +46,25 @@ 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_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_required_LogBloom = boost::error_info; +using errinfo_got_LogBloom = boost::error_info; +using LogBloomRequirementError = boost::tuple; + class BlockChain; class State; +struct VerifiedBlockRef; struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 5; }; @@ -294,10 +311,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. @@ -308,7 +327,7 @@ public: /// Execute all transactions within a given block. /// @returns the additional total difficulty. - u256 enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const& _bc, ImportRequirements::value _ir = ImportRequirements::Default); + u256 enactOn(VerifiedBlockRef const& _block, BlockChain const& _bc, ImportRequirements::value _ir = ImportRequirements::Default); /// Returns back to a pristine state after having done a playback. /// @arg _fullCommit if true flush everything out to disk. If false, this effectively only validates @@ -349,7 +368,7 @@ private: /// Execute the given block, assuming it corresponds to m_currentBlock. /// Throws on failure. - u256 enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirements::value _ir = ImportRequirements::Default); + u256 enact(VerifiedBlockRef const& _block, BlockChain const& _bc, ImportRequirements::value _ir = ImportRequirements::Default); /// Finalise the block, applying the earned rewards. void applyRewards(std::vector const& _uncleBlockHeaders); @@ -371,6 +390,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. @@ -394,8 +414,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()) { @@ -434,7 +455,9 @@ void commit(std::unordered_map const& _cache, DB& _db, SecureT _state.insert(i.first, &s.out()); } + ret.insert(i.first); } + return ret; } } diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index b8d8d64c1..58ecc44fa 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -39,29 +39,25 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, ExecutionResult const& _e return _out; } -std::string badTransaction(bytesConstRef _tx, string const& _err) -{ - stringstream ret; - ret << "========================================================================" << endl; - ret << "== Software Failure " << (_err + string(max(0, 44 - _err.size()), ' ')) << " ==" << endl; - ret << "== Guru Meditation " << sha3(_tx).abridged() << " ==" << endl; - ret << "========================================================================" << endl; - ret << " Transaction: " << toHex(_tx) << endl; - ret << " Transaction RLP: "; - try { - ret << RLP(_tx); - } - catch (Exception& _e) - { - ret << "Invalid: " << _e.what(); - } - ret << endl; - - 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 +71,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 +132,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..e9b1cbf80 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 @@ -224,8 +228,5 @@ inline std::ostream& operator<<(std::ostream& _out, Transaction const& _t) return _out; } -void badTransaction(bytesConstRef _tx, std::string const& _err); -inline void badTransaction(bytes const& _tx, std::string const& _err) { badTransaction(&_tx, _err); } - } } diff --git a/libethereum/VerifiedBlock.h b/libethereum/VerifiedBlock.h new file mode 100644 index 000000000..ddd808901 --- /dev/null +++ b/libethereum/VerifiedBlock.h @@ -0,0 +1,53 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file VerfiedBlock.h + * @author Gav Wood + * @date 2014 + */ + + +#include +#include + +#pragma once + +namespace dev +{ +namespace eth +{ + +class Transaction; + +/// @brief Verified block info, does not hold block data, but a reference instead +struct VerifiedBlockRef +{ + bytesConstRef block; ///< Block data reference + BlockInfo info; ///< Prepopulated block info + std::vector transactions; ///< Verified list of block transactions +}; + +/// @brief Verified block info, combines block data and verified info/transactions +struct VerifiedBlock +{ + VerifiedBlockRef verified; ///< Verified block structures + bytes blockData; ///< Block data +}; + +using VerifiedBlocks = std::vector; + +} +} diff --git a/libevm/ExtVMFace.cpp b/libevm/ExtVMFace.cpp index ebef1fdb0..ad419d2a3 100644 --- a/libevm/ExtVMFace.cpp +++ b/libevm/ExtVMFace.cpp @@ -25,7 +25,7 @@ using namespace std; using namespace dev; using namespace dev::eth; -ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth): +ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth): myAddress(_myAddress), caller(_caller), origin(_origin), @@ -33,6 +33,7 @@ ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 gasPrice(_gasPrice), data(_data), code(_code), + codeHash(_codeHash), lastHashes(_lh), previousBlock(_previousBlock), currentBlock(_currentBlock), diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 6b35094bb..bb102bef3 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -130,7 +130,7 @@ public: ExtVMFace() = default; /// Full constructor. - ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth); + ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth); virtual ~ExtVMFace() = default; @@ -186,6 +186,7 @@ public: u256 gasPrice; ///< Price of gas (that we already paid). bytesConstRef data; ///< Current input data. bytes code; ///< Current code that is executing. + h256 codeHash; ///< SHA3 hash of the executing code LastHashes lastHashes; ///< Most recent 256 blocks' hashes. BlockInfo previousBlock; ///< The previous block's information. TODO: PoC-8: REMOVE BlockInfo currentBlock; ///< The current block's information. diff --git a/libevm/VM.cpp b/libevm/VM.cpp index ed4cdb4dc..36fba6e43 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -45,165 +45,169 @@ 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()); - - // FEES... - bigint runGas = c_tierStepGas[metric.gasPriceTier]; - bigint newTempSize = m_temp.size(); - bigint copySize = 0; - - // should work, but just seems to result in immediate errorless exit on initial execution. yeah. weird. - //m_onFail = std::function(onOperation); - - require(metric.args, metric.ret); - - auto onOperation = [&]() - { - if (_onOp) - _onOp(steps, inst, newTempSize > m_temp.size() ? (newTempSize - m_temp.size()) / 32 : bigint(0), runGas, io_gas, this, &_ext); - }; - - 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; + 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; + } - case Instruction::SLOAD: - runGas = c_sloadGas; - break; + 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:; + } - // 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; + auto gasForMem = [](bigint _size) -> bigint + { + bigint s = _size / 32; + return (bigint)c_memoryGas * s + s * s / c_quadCoeffDiv; + }; - case Instruction::JUMPDEST: - runGas = 1; - break; + newTempSize = (newTempSize + 31) / 32 * 32; + if (newTempSize > m_temp.size()) + runGas += gasForMem(newTempSize) - gasForMem(m_temp.size()); + runGas += c_copyGas * ((copySize + 31) / 32); - 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; - } + onOperation(); - 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; + if (io_gas < runGas) + BOOST_THROW_EXCEPTION(OutOfGas()); - 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:; - } + io_gas -= (u256)runGas; - newTempSize = (newTempSize + 31) / 32 * 32; - if (newTempSize > m_temp.size()) - runGas += gasForMem(newTempSize) - gasForMem(m_temp.size()); - runGas += c_copyGas * ((copySize + 31) / 32); + if (newTempSize > m_temp.size()) + m_temp.resize((size_t)newTempSize); +} - onOperation(); +bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) +{ + m_stack.reserve((unsigned)c_stackLimit); - if (io_gas < runGas) - BOOST_THROW_EXCEPTION(OutOfGas()); + 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; + } - io_gas -= (u256)runGas; + 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; + }; - if (newTempSize > m_temp.size()) - m_temp.resize((size_t)newTempSize); + 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); - // EXECUTE... switch (inst) { case Instruction::ADD: @@ -299,7 +303,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)) @@ -480,7 +484,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; } @@ -501,7 +505,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; @@ -535,18 +539,12 @@ 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() ) - 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 = m_stack.back(); - if (find(m_jumpDests.begin(), m_jumpDests.end(), (uint64_t)nextPC) == m_jumpDests.end() || nextPC > numeric_limits::max() ) - BOOST_THROW_EXCEPTION(BadJumpDestination()); - } + nextPC = verifyJumpDest(m_stack.back(), m_jumpDests); m_stack.pop_back(); m_stack.pop_back(); break; @@ -598,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(); @@ -614,16 +612,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(); @@ -635,19 +631,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: diff --git a/libevm/VM.h b/libevm/VM.h index 9084769cf..1931ad748 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -54,16 +54,18 @@ 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; } 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_curPC = 0; + uint64_t m_steps = 0; bytes m_temp; u256s m_stack; std::vector m_jumpDests; 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/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/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); } } diff --git a/libp2p/Capability.cpp b/libp2p/Capability.cpp index ecc458730..bc4aa0b04 100644 --- a/libp2p/Capability.cpp +++ b/libp2p/Capability.cpp @@ -23,18 +23,19 @@ #include #include "Session.h" +#include "Host.h" using namespace std; using namespace dev; using namespace dev::p2p; -Capability::Capability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset): m_session(_s), m_host(_h), m_idOffset(_idOffset) +Capability::Capability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset): m_session(_s), m_hostCap(_h), m_idOffset(_idOffset) { - clog(NetConnect) << "New session for capability" << m_host->name() << "; idOffset:" << m_idOffset; + clog(NetConnect) << "New session for capability" << m_hostCap->name() << "; idOffset:" << m_idOffset; } void Capability::disable(std::string const& _problem) { - clog(NetWarn) << "DISABLE: Disabling capability '" << m_host->name() << "'. Reason:" << _problem; + clog(NetWarn) << "DISABLE: Disabling capability '" << m_hostCap->name() << "'. Reason:" << _problem; m_enabled = false; } @@ -52,3 +53,8 @@ void Capability::addRating(int _r) { m_session->addRating(_r); } + +ReputationManager& Capability::repMan() const +{ + return host()->repMan(); +} diff --git a/libp2p/Capability.h b/libp2p/Capability.h index d09391655..b4f59b243 100644 --- a/libp2p/Capability.h +++ b/libp2p/Capability.h @@ -29,6 +29,8 @@ namespace dev namespace p2p { +class ReputationManager; + class Capability { friend class Session; @@ -43,7 +45,9 @@ public: static unsigned messageCount() { return 0; } */ Session* session() const { return m_session; } - HostCapabilityFace* hostCapability() const { return m_host; } + HostCapabilityFace* hostCapability() const { return m_hostCap; } + Host* host() const { return m_hostCap->host(); } + ReputationManager& repMan() const; protected: virtual bool interpret(unsigned _id, RLP const&) = 0; @@ -56,7 +60,7 @@ protected: private: Session* m_session; - HostCapabilityFace* m_host; + HostCapabilityFace* m_hostCap; bool m_enabled = true; unsigned m_idOffset; }; 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..f4cceebf2 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -55,6 +55,25 @@ void HostNodeTableHandler::processEvent(NodeId const& _n, NodeTableEventType con m_host.onNodeTableEvent(_n, _e); } +ReputationManager::ReputationManager() +{ +} + +void ReputationManager::noteRude(Session const& _s, std::string const& _sub) +{ + m_nodes[make_pair(_s.id(), _s.info().clientVersion)].subs[_sub].isRude = true; +} + +bool ReputationManager::isRude(Session const& _s, std::string const& _sub) const +{ + auto nit = m_nodes.find(make_pair(_s.id(), _s.info().clientVersion)); + if (nit == m_nodes.end()) + return false; + auto sit = nit->second.subs.find(_sub); + bool ret = sit == nit->second.subs.end() ? false : sit->second.isRude; + return _sub.empty() ? ret : (ret || isRude(_s)); +} + Host::Host(std::string const& _clientVersion, NetworkPreferences const& _n, bytesConstRef _restoreNetwork): Worker("p2p", 0), m_restoreNetwork(_restoreNetwork.toBytes()), @@ -834,7 +853,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/Host.h b/libp2p/Host.h index 3c7ce257a..c7514cf19 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -45,6 +45,18 @@ namespace ba = boost::asio; namespace bi = ba::ip; +namespace std +{ +template<> struct hash> +{ + size_t operator()(pair const& _value) const + { + size_t ret = hash()(_value.first); + return ret ^ hash()(_value.second) + 0x9e3779b9 + (ret << 6) + (ret >> 2); + } +}; +} + namespace dev { @@ -66,6 +78,29 @@ private: Host& m_host; }; +struct SubReputation +{ + bool isRude = false; + int utility = 0; +}; + +struct Reputation +{ + std::unordered_map subs; +}; + +class ReputationManager +{ +public: + ReputationManager(); + + void noteRude(Session const& _s, std::string const& _sub = std::string()); + bool isRude(Session const& _s, std::string const& _sub = std::string()) const; + +private: + std::unordered_map, Reputation> m_nodes; ///< Nodes that were impolite while syncing. We avoid syncing from these if possible. +}; + /** * @brief The Host class * Capabilities should be registered prior to startNetwork, since m_capabilities is not thread-safe. @@ -152,6 +187,9 @@ public: /// @returns if network has been started. bool isStarted() const { return isWorking(); } + /// @returns our reputation manager. + ReputationManager& repMan() { return m_repMan; } + /// @returns if network is started and interactive. bool haveNetwork() const { return m_run && !!m_nodeTable; } @@ -255,6 +293,8 @@ private: std::chrono::steady_clock::time_point m_lastPing; ///< Time we sent the last ping to all peers. bool m_accepting = false; bool m_dropPeers = false; + + ReputationManager m_repMan; }; } 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..6344dc263 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 @@ -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: 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/RLPxFrameIO.h b/libp2p/RLPxFrameIO.h index 0f0504e48..9d4c274be 100644 --- a/libp2p/RLPxFrameIO.h +++ b/libp2p/RLPxFrameIO.h @@ -56,7 +56,7 @@ public: bool isConnected() const { return m_socket.is_open(); } void close() { try { boost::system::error_code ec; m_socket.shutdown(bi::tcp::socket::shutdown_both, ec); if (m_socket.is_open()) m_socket.close(); } catch (...){} } - bi::tcp::endpoint remoteEndpoint() { try { return m_socket.remote_endpoint(); } catch (...){ return bi::tcp::endpoint(); } } + bi::tcp::endpoint remoteEndpoint() { boost::system::error_code ec; return m_socket.remote_endpoint(ec); } bi::tcp::socket& ref() { return m_socket; } protected: @@ -130,4 +130,4 @@ private: }; } -} \ No newline at end of file +} diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 462fea7b1..6400a5849 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -70,6 +70,11 @@ Session::~Session() delete m_io; } +ReputationManager& Session::repMan() const +{ + return m_server->repMan(); +} + NodeId Session::id() const { return m_peer ? m_peer->id : NodeId(); @@ -450,6 +455,7 @@ void Session::doRead() else if (ec && length < tlen) { clog(NetWarn) << "Error reading - Abrupt peer disconnect: " << ec.message(); + repMan().noteRude(*this); drop(TCPError); return; } diff --git a/libp2p/Session.h b/libp2p/Session.h index bcbf8022b..1e5d69ee0 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -43,6 +43,7 @@ namespace p2p { class Peer; +class ReputationManager; /** * @brief The Session class @@ -75,6 +76,7 @@ public: static RLPStream& prep(RLPStream& _s, PacketType _t, unsigned _args = 0); void sealAndSend(RLPStream& _s); + ReputationManager& repMan() const; int rating() const; void addRating(int _r); 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/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; 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/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/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.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/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/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::AbstractServerc_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); 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.cpp b/mix/MixClient.cpp index 90b44b0e7..62d6636c2 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file MixClient.cpp * @author Arkadiy Paronyan arkadiy@ethdev.com @@ -48,29 +48,29 @@ namespace struct MixPow //dummy POW { - typedef int Solution; - static void assignResult(int, BlockInfo const&) {} - static bool verify(BlockInfo const&) { return true; } + typedef int Solution; + static void assignResult(int, BlockInfo const&) {} + static bool verify(BlockInfo const&) { return true; } }; } bytes MixBlockChain::createGenesisBlock(h256 _stateRoot) { - RLPStream block(3); - block.appendList(15) - << h256() << EmptyListSHA3 << h160() << _stateRoot << EmptyTrie << EmptyTrie - << LogBloom() << c_mixGenesisDifficulty << 0 << c_genesisGasLimit << 0 << (unsigned)0 - << std::string() << h256() << h64(u64(42)); - block.appendRaw(RLPEmptyList); - block.appendRaw(RLPEmptyList); - return block.out(); + RLPStream block(3); + block.appendList(15) + << h256() << EmptyListSHA3 << h160() << _stateRoot << EmptyTrie << EmptyTrie + << LogBloom() << c_mixGenesisDifficulty << 0 << c_genesisGasLimit << 0 << (unsigned)0 + << std::string() << h256() << h64(u64(42)); + block.appendRaw(RLPEmptyList); + block.appendRaw(RLPEmptyList); + return block.out(); } MixClient::MixClient(std::string const& _dbPath): - m_dbPath(_dbPath) + m_dbPath(_dbPath) { - resetState(std::unordered_map()); + resetState(std::unordered_map()); } MixClient::~MixClient() @@ -79,54 +79,54 @@ MixClient::~MixClient() LocalisedLogEntries MixClient::logs() { - return m_watches.at(0).changes; + return m_watches.at(0).changes; } void MixClient::resetState(std::unordered_map const& _accounts, Secret const& _miner) { - WriteGuard l(x_state); - Guard fl(x_filtersWatches); - m_filters.clear(); - m_watches.clear(); - //LogFilter filter; - //m_filters.insert(std::make_pair(filter.sha3(), filter)); - //m_watches.insert(std::make_pair(0, ClientWatch(filter.sha3(), Reaping::Automatic))); - - m_stateDB = OverlayDB(); - SecureTrieDB accountState(&m_stateDB); - accountState.init(); - - dev::eth::commit(_accounts, static_cast(m_stateDB), accountState); - h256 stateRoot = accountState.root(); - m_bc.reset(); - m_bc.reset(new MixBlockChain(m_dbPath, stateRoot)); - m_state = eth::State(m_stateDB, BaseState::PreExisting, KeyPair(_miner).address()); - m_state.sync(bc()); - m_startState = m_state; - WriteGuard lx(x_executions); - m_executions.clear(); + WriteGuard l(x_state); + Guard fl(x_filtersWatches); + m_filters.clear(); + m_watches.clear(); + //LogFilter filter; + //m_filters.insert(std::make_pair(filter.sha3(), filter)); + //m_watches.insert(std::make_pair(0, ClientWatch(filter.sha3(), Reaping::Automatic))); + + m_stateDB = OverlayDB(); + SecureTrieDB accountState(&m_stateDB); + accountState.init(); + + dev::eth::commit(_accounts, static_cast(m_stateDB), accountState); + h256 stateRoot = accountState.root(); + m_bc.reset(); + m_bc.reset(new MixBlockChain(m_dbPath, stateRoot)); + m_state = eth::State(m_stateDB, BaseState::PreExisting, KeyPair(_miner).address()); + m_state.sync(bc()); + m_startState = m_state; + WriteGuard lx(x_executions); + m_executions.clear(); } Transaction MixClient::replaceGas(Transaction const& _t, u256 const& _gas, Secret const& _secret) { - Transaction ret; - if (_secret) - { - if (_t.isCreation()) - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret); - else - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret); - } - else - { - if (_t.isCreation()) - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); - else - ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); - ret.forceSender(_t.safeSender()); - } - return ret; + Transaction ret; + if (_secret) + { + if (_t.isCreation()) + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce(), _secret); + else + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce(), _secret); + } + else + { + if (_t.isCreation()) + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.data(), _t.nonce()); + else + ret = Transaction(_t.value(), _t.gasPrice(), _gas, _t.receiveAddress(), _t.data(), _t.nonce()); + ret.forceSender(_t.safeSender()); + } + return ret; } void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _call, bool _gasAuto, Secret const& _secret) @@ -193,19 +193,19 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c levels.resize(ext.depth); machineStates.push_back(MachineState{ - steps, - vm.curPC(), - inst, - newMemSize, - static_cast(gas), - vm.stack(), - vm.memory(), - gasCost, - ext.state().storage(ext.myAddress), - std::move(levels), - codeIndex, - dataIndex - }); + steps, + vm.curPC(), + inst, + newMemSize, + static_cast(gas), + vm.stack(), + vm.memory(), + gasCost, + ext.state().storage(ext.myAddress), + std::move(levels), + codeIndex, + dataIndex + }); }; execution.go(onOp); @@ -213,27 +213,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.inputParameters = t.data(); @@ -299,149 +301,149 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c void MixClient::mine() { - WriteGuard l(x_state); - m_state.commitToMine(bc()); - m_state.completeMine(0); - bc().import(m_state.blockData(), m_state.db(), ImportRequirements::Default & ~ImportRequirements::ValidNonce); - m_state.sync(bc()); - m_startState = m_state; - h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter }; - //noteChanged(changed); + WriteGuard l(x_state); + m_state.commitToMine(bc()); + m_state.completeMine(0); + bc().import(m_state.blockData(), m_state.db(), ImportRequirements::Default & ~ImportRequirements::ValidNonce); + m_state.sync(bc()); + m_startState = m_state; + h256Set changed { dev::eth::PendingChangedFilter, dev::eth::ChainChangedFilter }; + //noteChanged(changed); } ExecutionResult MixClient::lastExecution() const { - ReadGuard l(x_executions); - return m_executions.empty() ? ExecutionResult() : m_executions.back(); + ReadGuard l(x_executions); + return m_executions.empty() ? ExecutionResult() : m_executions.back(); } ExecutionResult MixClient::execution(unsigned _index) const { - ReadGuard l(x_executions); - return m_executions.at(_index); + ReadGuard l(x_executions); + return m_executions.at(_index); } State MixClient::asOf(h256 const& _block) const { - ReadGuard l(x_state); - return State(m_stateDB, bc(), _block); + ReadGuard l(x_state); + return State(m_stateDB, bc(), _block); } void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, bool _gasAuto) { - WriteGuard l(x_state); - u256 n = m_state.transactionsFrom(toAddress(_secret)); - Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); - executeTransaction(t, m_state, false, _gasAuto, _secret); + WriteGuard l(x_state); + u256 n = m_state.transactionsFrom(toAddress(_secret)); + Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); + executeTransaction(t, m_state, false, _gasAuto, _secret); } Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto) { - WriteGuard l(x_state); - u256 n = m_state.transactionsFrom(toAddress(_secret)); - eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - executeTransaction(t, m_state, false, _gasAuto, _secret); - Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); - return address; + WriteGuard l(x_state); + u256 n = m_state.transactionsFrom(toAddress(_secret)); + eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); + executeTransaction(t, m_state, false, _gasAuto, _secret); + Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); + return address; } dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff) { - (void)_blockNumber; - State temp = asOf(eth::PendingBlock); - u256 n = temp.transactionsFrom(_from); - Transaction t(_value, _gasPrice, _gas, _dest, _data, n); - t.forceSender(_from); - if (_ff == FudgeFactor::Lenient) - temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); - WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, temp, true, _gasAuto); - return lastExecution().result; + (void)_blockNumber; + State temp = asOf(eth::PendingBlock); + u256 n = temp.transactionsFrom(_from); + Transaction t(_value, _gasPrice, _gas, _dest, _data, n); + t.forceSender(_from); + if (_ff == FudgeFactor::Lenient) + temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); + WriteGuard lw(x_state); //TODO: lock is required only for last execution state + executeTransaction(t, temp, true, _gasAuto); + return lastExecution().result; } void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) { - submitTransaction(_secret, _value, _dest, _data, _gas, _gasPrice, false); + submitTransaction(_secret, _value, _dest, _data, _gas, _gasPrice, false); } Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) { - return submitTransaction(_secret, _endowment, _init, _gas, _gasPrice, false); + return submitTransaction(_secret, _endowment, _init, _gas, _gasPrice, false); } dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff) { - return call(_from, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff); + return call(_from, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff); } dev::eth::ExecutionResult MixClient::create(Address const& _from, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff) { - (void)_blockNumber; - u256 n; - State temp; - { - ReadGuard lr(x_state); - temp = asOf(eth::PendingBlock); - n = temp.transactionsFrom(_from); - } - Transaction t(_value, _gasPrice, _gas, _data, n); - t.forceSender(_from); - if (_ff == FudgeFactor::Lenient) - temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); - WriteGuard lw(x_state); //TODO: lock is required only for last execution state - executeTransaction(t, temp, true, false); - return lastExecution().result; + (void)_blockNumber; + u256 n; + State temp; + { + ReadGuard lr(x_state); + temp = asOf(eth::PendingBlock); + n = temp.transactionsFrom(_from); + } + Transaction t(_value, _gasPrice, _gas, _data, n); + t.forceSender(_from); + if (_ff == FudgeFactor::Lenient) + temp.addBalance(_from, (u256)(t.gasRequired() * t.gasPrice() + t.value())); + WriteGuard lw(x_state); //TODO: lock is required only for last execution state + executeTransaction(t, temp, true, false); + return lastExecution().result; } /*void MixClient::noteChanged(h256Set const& _filters) { - for (auto& i: m_watches) - if (_filters.count(i.second.id)) - { - if (m_filters.count(i.second.id)) - i.second.changes += m_filters.at(i.second.id).changes; - else - i.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, 0)); - } - for (auto& i: m_filters) - i.second.changes.clear(); + for (auto& i: m_watches) + if (_filters.count(i.second.id)) + { + if (m_filters.count(i.second.id)) + i.second.changes += m_filters.at(i.second.id).changes; + else + i.second.changes.push_back(LocalisedLogEntry(SpecialLogEntry, 0)); + } + for (auto& i: m_filters) + i.second.changes.clear(); }*/ eth::BlockInfo MixClient::blockInfo() const { - ReadGuard l(x_state); - return BlockInfo(bc().block()); + ReadGuard l(x_state); + return BlockInfo(bc().block()); } void MixClient::setAddress(Address _us) { - WriteGuard l(x_state); - m_state.setAddress(_us); + WriteGuard l(x_state); + m_state.setAddress(_us); } void MixClient::startMining() { - //no-op + //no-op } void MixClient::stopMining() { - //no-op + //no-op } bool MixClient::isMining() const { - return false; + return false; } uint64_t MixClient::hashrate() const { - return 0; + return 0; } eth::MiningProgress MixClient::miningProgress() const { - return eth::MiningProgress(); + return eth::MiningProgress(); } } diff --git a/mix/MixClient.h b/mix/MixClient.h index ece603942..4e05e5104 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -83,7 +83,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; } diff --git a/mix/qml/BlockChain.qml b/mix/qml/BlockChain.qml index ea5a09cb5..69e2bbf34 100644 --- a/mix/qml/BlockChain.qml +++ b/mix/qml/BlockChain.qml @@ -230,7 +230,6 @@ ColumnLayout { if (ensureNotFuturetime.running) return; reBuildNeeded.stop() - console.log("model block length " + model.blocks.length) var retBlocks = []; var bAdded = 0; for (var j = 0; j < model.blocks.length; j++) diff --git a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json index 1b2d59385..1c870c543 100644 --- a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json +++ b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json @@ -42,7 +42,2072 @@ } }, + "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", + "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 ]] (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", + "nonce" : "0", + "code": "{ (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (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" : "" + } + }, + + "CallEcrecover0_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 ]] (CALL 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" : "" + } + }, + + + "CallEcrecover0_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 ]] (CALL 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" : "" + } + }, + + "CallEcrecover0_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 ]] (CALL 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" : "" + } + }, + + "CallEcrecover0_NoGas": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0x011248" + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 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" : "" + } + }, + + "CallEcrecover0_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 ]] (CALL 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" : "" + } + }, + + "CallEcrecover0_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 ]] (CALL 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" : "" + } + }, + + "CallEcrecover1": { + "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 ]] (CALL 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" : "" + } + }, + + "CallEcrecover2": { + "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 ]] (CALL 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" : "" + } + }, + + "CallEcrecover3": { + "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 ]] (CALL 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" : "" + } + }, + + "CallSha256_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" : "0x600160005260206000602060006000600260fff1600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallSha256_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 ]] (CALL 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" : "" + } + }, + + "CallSha256_1_nonzeroValue": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "0000000000000000000000000000000000000002" : { + "balance" : "19" + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "200000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 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" : "" + } + }, + + "CallSha256_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 ]] (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": { + "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 ]] (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_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", + "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 ]] (CALL 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" : "" + } + }, + + "CallSha256_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 ]] (CALL 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" : "" + } + }, + + "CallSha256_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 ]] (CALL 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" : "" + } + }, + + "CallRipemd160_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" : "0x600160005260206000602060006000600360fff1600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallRipemd160_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 ]] (CALL 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" : "" + } + }, + + "CallRipemd160_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 ]] (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": { + "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 ]] (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_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 ]] (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" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallRipemd160_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 ]] (CALL 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" : "" + } + }, + + "CallRipemd160_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 ]] (CALL 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" : "" + } + }, + + "CallIdentitiy_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" : "0x600160005260206000602060006000600460fff1600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentitiy_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 ]] (CALL 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" : "" + } + }, + + "CallIdentity_1_nonzeroValue": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "0000000000000000000000000000000000000004" : { + "balance" : "19" + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "200000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 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" : "" + } + }, + + "CallIdentity_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 ]] (CALL 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" : "" + } + }, + + "CallIdentity_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 ]] (CALL 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" : "" + } + }, + + "CallIdentity_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 ]] (CALL 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" : "" + } + }, + + "CallIdentity_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 ]] (CALL 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" : "" + } + }, + + "CallIdentity_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 ]] (CALL 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" : "" + } + }, + + "CallIdentity_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 ]] (CALL 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" : "" + } + }, + + "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", @@ -55,7 +2120,6 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x01" : "0x01", "0x02" : "0x01" } } @@ -64,7 +2128,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0x00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 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" : { @@ -77,7 +2141,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "3652240", + "gasLimit" : "365224", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -85,7 +2149,7 @@ } }, - "CallEcrecover0_overlappingInputOutput": { + "CALLCODEEcrecover0_gas3000": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -107,7 +2171,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 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" : { @@ -128,8 +2192,7 @@ } }, - - "CallEcrecover0_completeReturnValue": { + "CALLCODEEcrecover0_NoGas": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -139,18 +2202,15 @@ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "expect" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "storage" : { - "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x02" : "0x01" - } + "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" : { + "balance" : "0xb0a0" } }, "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }", + "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" : { @@ -171,7 +2231,7 @@ } }, - "CallEcrecover0_gas3000": { + "CALLCODEEcrecover0_Gas2999": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -183,9 +2243,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x01" : "0x01", - "0x02" : "0x01" + "0x02" : "0x00" } } }, @@ -193,7 +2251,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 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" : { @@ -214,7 +2272,7 @@ } }, - "CallEcrecover0_BonusGas": { + "CALLCODEEcrecover0_0input": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -226,6 +2284,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { + "0x02" : "0x01" } } }, @@ -233,7 +2292,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 0 1 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ [[ 2 ]] (CALLCODE 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -246,7 +2305,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "365224", + "gasLimit" : "3652240", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -254,7 +2313,7 @@ } }, - "CallEcrecover0_Gas2999": { + "CALLCODEEcrecover1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -266,6 +2325,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { + "0x02" : "0x01" } } }, @@ -273,7 +2333,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 2999 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 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" : { @@ -294,7 +2354,7 @@ } }, - "CallEcrecover0_0input": { + "CALLCODEEcrecover2": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -314,7 +2374,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", + "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" : { @@ -327,7 +2387,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "3652240", + "gasLimit" : "365224", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -335,7 +2395,7 @@ } }, - "CallEcrecover1": { + "CALLCODEEcrecover3": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -347,6 +2407,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { + "0x" : "0xe4319f4b631c6d0fcfc84045dbcb676865fe5e13", "0x02" : "0x01" } } @@ -355,7 +2416,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 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" : { @@ -376,7 +2437,7 @@ } }, - "CallEcrecover2": { + "CALLCODESha256_0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -388,7 +2449,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x02" : "0x01" + "0x" : "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5" } } }, @@ -396,7 +2457,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code" : "0x600160005260206000602060006000600260fff2600051600055", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -417,7 +2478,7 @@ } }, - "CallEcrecover3": { + "CALLCODESha256_1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -429,7 +2490,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xe4319f4b631c6d0fcfc84045dbcb676865fe5e13", + "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "0x02" : "0x01" } } @@ -438,7 +2499,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code" : "{ [[ 2 ]] (CALLCODE 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -459,11 +2520,11 @@ } }, - "CallSha256_0": { + "CALLCODESha256_1_nonzeroValue": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", - "currentGasLimit" : "10000000", + "currentGasLimit" : "100000000", "currentDifficulty" : "256", "currentTimestamp" : 1, "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" @@ -471,15 +2532,16 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5" + "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "0x02" : "0x01" } } }, "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", + "balance" : "200000000", "nonce" : "0", - "code" : "0x600160005260206000602060006000600260fff1600051600055", + "code" : "{ [[ 2 ]] (CALLCODE 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -500,7 +2562,7 @@ } }, - "CallSha256_1": { + "CALLCODESha256_2": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -512,7 +2574,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "0x" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d", "0x02" : "0x01" } } @@ -521,7 +2583,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -542,31 +2604,28 @@ } }, - "CallSha256_1_nonzeroValue": { + "CALLCODESha256_3": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", - "currentGasLimit" : "100000000", + "currentGasLimit" : "10000000", "currentDifficulty" : "256", "currentTimestamp" : 1, "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "expect" : { - "0000000000000000000000000000000000000002" : { - "balance" : "19" - }, "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", "0x02" : "0x01" } } }, "pre" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "200000000", + "balance" : "20000000", "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -587,7 +2646,7 @@ } }, - "CallSha256_2": { + "CALLCODESha256_3_prefix0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -599,7 +2658,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d", + "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", "0x02" : "0x01" } } @@ -608,7 +2667,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0x00f34578907f) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -629,7 +2688,7 @@ } }, - "CallSha256_3": { + "CALLCODESha256_3_postfix0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -641,7 +2700,7 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", + "0x" : "0x3b745a1c00d035c334f358d007a430e4cf0ae63aa0556fb05529706de546464d", "0x02" : "0x01" } } @@ -650,7 +2709,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f00) [[ 2 ]] (CALLCODE 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -671,7 +2730,7 @@ } }, - "CallSha256_4": { + "CALLCODESha256_4": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -692,7 +2751,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -713,7 +2772,7 @@ } }, - "CallSha256_4_gas99": { + "CALLCODESha256_4_gas99": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -734,7 +2793,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -755,7 +2814,7 @@ } }, - "CallSha256_5": { + "CALLCODESha256_5": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -775,7 +2834,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -796,7 +2855,7 @@ } }, - "CallRipemd160_0": { + "CALLCODERipemd160_0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -816,7 +2875,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "0x600160005260206000602060006000600360fff1600051600055", + "code" : "0x600160005260206000602060006000600360fff2600051600055", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -837,7 +2896,7 @@ } }, - "CallRipemd160_1": { + "CALLCODERipemd160_1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -858,7 +2917,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ [[ 2 ]] (CALLCODE 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -879,7 +2938,7 @@ } }, - "CallRipemd160_2": { + "CALLCODERipemd160_2": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -891,6 +2950,8 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { + "0x00" : "0xdbc100f916bfbc53535573d98cf0cbb3a5b36124", + "0x02" : "0x01" } } }, @@ -898,7 +2959,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 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -919,7 +2980,7 @@ } }, - "CallRipemd160_3": { + "CALLCODERipemd160_3": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -931,7 +2992,8 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xf34578907f" + "0x00" : "0x316750573f9be26bc17727b47cacedbd0ab3e6ca", + "0x02" : "0x01" } } }, @@ -939,7 +3001,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 ]] (CALLCODE 6000 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -960,7 +3022,7 @@ } }, - "CallRipemd160_4": { + "CALLCODERipemd160_3_prefixed0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -972,7 +3034,50 @@ "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { - "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "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" } } }, @@ -980,7 +3085,48 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 120 3 0 0 32 0 32) [[ 0 ]] (MLOAD 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" : { @@ -1001,7 +3147,7 @@ } }, - "CallRipemd160_4_gas99": { + "CALLCODERipemd160_4_gas719": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1021,7 +3167,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 ]] (CALLCODE 719 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1042,7 +3188,7 @@ } }, - "CallRipemd160_5": { + "CALLCODERipemd160_5": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1062,7 +3208,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 ]] (CALLCODE 6000 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1083,7 +3229,7 @@ } }, - "CallIdentitiy_0": { + "CALLCODEIdentitiy_0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1103,7 +3249,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "0x600160005260206000602060006000600460fff1600051600055", + "code" : "0x600160005260206000602060006000600460fff2600051600055", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1124,7 +3270,7 @@ } }, - "CallIdentitiy_1": { + "CALLCODEIdentitiy_1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1145,7 +3291,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 500 4 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ [[ 2 ]] (CALLCODE 500 4 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1166,7 +3312,7 @@ } }, - "CallIdentity_1_nonzeroValue": { + "CALLCODEIdentity_1_nonzeroValue": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1176,9 +3322,6 @@ "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" }, "expect" : { - "0000000000000000000000000000000000000004" : { - "balance" : "19" - }, "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0x00", @@ -1190,7 +3333,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "200000000", "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 200000 4 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ [[ 2 ]] (CALLCODE 200000 4 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1211,7 +3354,7 @@ } }, - "CallIdentity_2": { + "CALLCODEIdentity_2": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1232,7 +3375,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1253,7 +3396,7 @@ } }, - "CallIdentity_3": { + "CALLCODEIdentity_3": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1274,7 +3417,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALLCODE 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1295,7 +3438,7 @@ } }, - "CallIdentity_4": { + "CALLCODEIdentity_4": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1316,7 +3459,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 100 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1337,7 +3480,7 @@ } }, - "CallIdentity_4_gas18": { + "CALLCODEIdentity_4_gas18": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1358,7 +3501,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 18 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 18 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1379,7 +3522,7 @@ } }, - "CallIdentity_4_gas17": { + "CALLCODEIdentity_4_gas17": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1400,7 +3543,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 17 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALLCODE 17 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -1421,7 +3564,7 @@ } }, - "CallIdentity_5": { + "CALLCODEIdentity_5": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -1441,7 +3584,48 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 4 0 0 1000000 0 32) [[ 0 ]] (MLOAD 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" : "" + } + }, + + "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" : { @@ -1460,6 +3644,6 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - } + }, } 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" : diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp index d52c650f9..ec66837e1 100644 --- a/test/libevm/vm.cpp +++ b/test/libevm/vm.cpp @@ -33,7 +33,7 @@ using namespace dev::eth; using namespace dev::test; FakeExtVM::FakeExtVM(eth::BlockInfo const& _previousBlock, eth::BlockInfo const& _currentBlock, unsigned _depth): /// TODO: XXX: remove the default argument & fix. - ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), _previousBlock, _currentBlock, test::lastHashes(_currentBlock.number), _depth) {} + ExtVMFace(Address(), Address(), Address(), 0, 1, bytesConstRef(), bytes(), EmptySHA3, _previousBlock, _currentBlock, test::lastHashes(_currentBlock.number), _depth) {} h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpFunc const&) { 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/libweb3jsonrpc/webthreestubclient.h b/test/libweb3jsonrpc/webthreestubclient.h index 51d556eec..99fe48034 100644 --- a/test/libweb3jsonrpc/webthreestubclient.h +++ b/test/libweb3jsonrpc/webthreestubclient.h @@ -374,16 +374,26 @@ class WebThreeStubClient : public jsonrpc::Client else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } - std::string eth_newBlockFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + std::string eth_newBlockFilter() throw (jsonrpc::JsonRpcException) { Json::Value p; - p.append(param1); + p = Json::nullValue; Json::Value result = this->CallMethod("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; 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) diff --git a/third/MainWin.cpp b/third/MainWin.cpp index 3cfc016e3..f2a90cc0b 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -100,7 +100,7 @@ Main::Main(QWidget *parent) : setWindowFlags(Qt::Window); ui->setupUi(this); - cerr << "State root: " << CanonBlockChain::genesis().stateRoot << endl; + cerr << "State root: " << CanonBlockChain::genesis().stateRoot << endl; auto gb = CanonBlockChain::createGenesisBlock(); cerr << "Block Hash: " << sha3(gb) << endl; cerr << "Block RLP: " << RLP(gb) << endl;