From 9c2ea6466a66c01fe8091ccf4535268093e62c51 Mon Sep 17 00:00:00 2001 From: Stan Kladko <13399135+kladkogex@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:04:01 +0100 Subject: [PATCH] #1545 state locking --- libethereum/Client.cpp | 124 --------------------------------------- libethereum/Client.h | 26 +------- libethereum/ClientBase.h | 3 +- 3 files changed, 2 insertions(+), 151 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 2a085377f..68e357ef3 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -72,8 +72,6 @@ using namespace skale::error; static_assert( BOOST_VERSION >= 106400, "Wrong boost headers version" ); -static const int64_t c_maxGasEstimate = 50000000; - namespace { std::string filtersToString( h256Hash const& _fs ) { std::stringstream str; @@ -1507,127 +1505,5 @@ bytes Client::historicStateCodeAt( Address _a, BlockNumber _block ) const { } #endif -std::pair< u256, ExecutionResult > Client::estimateGas( Address const& _from, u256 _value, - Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, - GasEstimationCallback const& _callback ) { - try { - int64_t upperBound = _maxGas; - if ( upperBound == Invalid256 || upperBound > c_maxGasEstimate ) - upperBound = c_maxGasEstimate; - int64_t lowerBound; - if ( CorrectForkInPowPatch::isEnabledInWorkingBlock() ) - lowerBound = Transaction::baseGasRequired( !_dest, &_data, - bc().sealEngine()->chainParams().makeEvmSchedule( - bc().info().timestamp(), bc().number() ) ); - else - lowerBound = Transaction::baseGasRequired( !_dest, &_data, EVMSchedule() ); - - Block latest = getReadOnlyLatestBlockCopy(); - Block pending = latest; - - if ( upperBound > pending.info().gasLimit() ) { - upperBound = pending.info().gasLimit().convert_to< int64_t >(); - } - u256 gasPrice = _gasPrice == Invalid256 ? gasBidPrice() : _gasPrice; - - // We execute transact u256 countAt( Address _a ) const override; - // u256 balanceAt( Address _a ) const override; - // u256 stateAt( Address _a, u256 _l ) const override; - // bytes codeAt( Address _a ) const override; - // h256 codeHashAt( Address _a ) const override; - // std::map< h256, std::pair< u256, u256 > > storageAt( Address _a ) const override;ion with maximum gas limit - // to calculate how many of gas will be used. - // Then we execute transaction with this gas limit - // and check if it will be enough. - // If not run binary search to find optimal gas limit. - - auto estimatedStep = - estimateGasStep( upperBound, latest, pending, _from, _dest, _value, gasPrice, _data ); - if ( estimatedStep.first ) { - auto executionResult = estimatedStep.second; - auto gasUsed = std::max( executionResult.gasUsed.convert_to< int64_t >(), lowerBound ); - - estimatedStep = - estimateGasStep( gasUsed, latest, pending, _from, _dest, _value, gasPrice, _data ); - if ( estimatedStep.first ) { - return make_pair( gasUsed, executionResult ); - } - while ( lowerBound + 1 < upperBound ) { - int64_t middle = ( lowerBound + upperBound ) / 2; - estimatedStep = estimateGasStep( - middle, latest, pending, _from, _dest, _value, gasPrice, _data ); - if ( estimatedStep.first ) { - upperBound = middle; - } else { - lowerBound = middle; - } - if ( _callback ) { - _callback( GasEstimationProgress{ lowerBound, upperBound } ); - } - } - } - - return make_pair( upperBound, - estimateGasStep( upperBound, latest, pending, _from, _dest, _value, gasPrice, _data ) - .second ); - } catch ( ... ) { - // TODO: Some sort of notification of failure. - return make_pair( u256(), ExecutionResult() ); - } -} - -std::pair< bool, ExecutionResult > Client::estimateGasStep( int64_t _gas, Block& _latestBlock, - Block& _pendingBlock, Address const& _from, Address const& _destination, u256 const& _value, - u256 const& _gasPrice, bytes const& _data ) { - u256 nonce = _latestBlock.transactionsFrom( _from ); - Transaction t; - if ( _destination ) - t = Transaction( _value, _gasPrice, _gas, _destination, _data, nonce ); - else - t = Transaction( _value, _gasPrice, _gas, _data, nonce ); - t.forceSender( _from ); - t.forceChainId( chainId() ); - t.ignoreExternalGas(); - EnvInfo const env( _pendingBlock.info(), bc().lastBlockHashes(), - _pendingBlock.previousInfo().timestamp(), 0, _gas ); - // Make a copy of state!! It will be deleted after step! - State tempState = _latestBlock.mutableState(); - tempState.addBalance( _from, ( u256 )( t.gas() * t.gasPrice() + t.value() ) ); - ExecutionResult executionResult = - tempState.execute( env, bc().chainParams(), t, Permanence::Reverted ).first; - if ( executionResult.excepted == TransactionException::OutOfGas || - executionResult.excepted == TransactionException::OutOfGasBase || - executionResult.excepted == TransactionException::OutOfGasIntrinsic || - executionResult.codeDeposit == CodeDeposit::Failed || - executionResult.excepted == TransactionException::BadJumpDestination || - executionResult.excepted == TransactionException::RevertInstruction ) { - return make_pair( false, executionResult ); - } else { - return make_pair( true, executionResult ); - } -} - -u256 Client::countAt( Address _a ) const { - return getReadOnlyLatestBlockCopy().state().getNonce( _a ); -} - -u256 Client::balanceAt( Address _a ) const { - return getReadOnlyLatestBlockCopy().state().balance( _a ); -} - -u256 Client::stateAt( Address _a, u256 _l ) const { - return getReadOnlyLatestBlockCopy().state().storage( _a, _l ); -} - -bytes Client::codeAt( Address _a ) const { - return getReadOnlyLatestBlockCopy().state().code( _a ); -} - -h256 Client::codeHashAt( Address _a ) const { - return getReadOnlyLatestBlockCopy().state().codeHash( _a ); -} -map< h256, pair< u256, u256 > > Client::storageAt( Address _a ) const { - return getReadOnlyLatestBlockCopy().state().storage( _a ); -} \ No newline at end of file diff --git a/libethereum/Client.h b/libethereum/Client.h index ab7b2ac9a..9ceda6f05 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -128,16 +128,7 @@ namespace dev { /// Imports the given transaction into the transaction queue h256 importTransaction(Transaction const &_t) override; - - /// Estimate gas usage for call/create. - /// @param _maxGas An upper bound value for estimation, if not provided default value of - /// c_maxGasEstimate will be used. - /// @param _callback Optional callback function for progress reporting - std::pair estimateGas(Address const &_from, u256 _value, Address _dest, - bytes const &_data, int64_t _maxGas, - u256 _gasPrice, - GasEstimationCallback const &_callback = GasEstimationCallback()) override; - + /// Makes the given call. Nothing is recorded into the state. ExecutionResult call(Address const &_secret, u256 _value, Address _dest, bytes const &_data, u256 _gas, u256 _gasPrice, @@ -762,21 +753,6 @@ namespace dev { void initStateFromDiskOrGenesis(); void populateNewChainStateFromGenesis(); - - u256 countAt( Address _a ) const override; - u256 balanceAt( Address _a ) const override; - u256 stateAt( Address _a, u256 _l ) const override; - bytes codeAt( Address _a ) const override; - h256 codeHashAt( Address _a ) const override; - std::map< h256, std::pair< u256, u256 > > storageAt( Address _a ) const override; - - - private: - std::pair estimateGasStep(int64_t _gas, Block &_latestBlock, - Block &_pendingBlock, Address const &_from, - Address const &_destination, u256 const &_value, - u256 const &_gasPrice, bytes const &_data); - }; } // namespace eth diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index b8845cca4..cbc684fc2 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -191,8 +191,7 @@ class ClientBase : public Interface { std::map< h256, std::pair< u256, u256 > > storageAt( Address _a ) const override; std::pair< u256, ExecutionResult > estimateGas( Address const& _from, u256 _value, Address _dest, bytes const& _data, int64_t _maxGas, u256 _gasPrice, - GasEstimationCallback const& _callback ) override; - + GasEstimationCallback const& _callback = GasEstimationCallback() ) override; std::pair< bool, ExecutionResult > estimateGasStep( int64_t _gas, Block& _latestBlock, Block& _pendingBlock, Address const& _from, Address const& _destination, u256 const& _value, u256 const& _gasPrice, bytes const& _data );