From a6538f61263c542e0842f4186f62ebf05914b329 Mon Sep 17 00:00:00 2001 From: Stan Kladko <13399135+kladkogex@users.noreply.github.com> Date: Mon, 22 Jul 2024 13:36:32 +0100 Subject: [PATCH] #1545 state locking --- libethereum/Block.cpp | 7 ++----- libethereum/Block.h | 2 +- libethereum/Client.cpp | 19 +++++++++---------- libethereum/Client.h | 5 +++-- libethereum/ClientBase.cpp | 1 - libethereum/SkaleHost.cpp | 2 +- 6 files changed, 16 insertions(+), 20 deletions(-) diff --git a/libethereum/Block.cpp b/libethereum/Block.cpp index 0d10593bf..e09926590 100644 --- a/libethereum/Block.cpp +++ b/libethereum/Block.cpp @@ -146,11 +146,11 @@ Block& Block::operator=( Block const& _s ) { } -// make a lightweight copy for eth_call. +// make a lightweight read only copy // we only copy the fields we need for eth_call // in particular we do not copy receipts and transactions // as well as raw bytes -Block Block::getCopyForEthCalls() const { +Block Block::getReadOnlyCopy() const { Block copy(Null); copy.m_state = m_state.createReadOnlySnapBasedCopy(); copy.m_author = m_author; @@ -1097,9 +1097,6 @@ bool Block::sealBlock( bytesConstRef _header ) { return true; } -void Block::startReadState() { - m_state = m_state.createStateCopyWithReadLock(); -} h256 Block::stateRootBeforeTx( unsigned _i ) const { _i = min< unsigned >( _i, m_transactions.size() ); diff --git a/libethereum/Block.h b/libethereum/Block.h index 9ff6cec5e..08b5830ea 100644 --- a/libethereum/Block.h +++ b/libethereum/Block.h @@ -112,7 +112,7 @@ class Block { /// Copy state object. Block& operator=( Block const& _s ); - Block getCopyForEthCalls() const; + Block getReadOnlyCopy() const; /// Get the author address for any transactions we do and rewards we get. Address author() const { return m_author; } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 69ac17952..03efbb03f 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -1114,8 +1114,7 @@ TransactionSkeleton Client::populateTransactionWithDefaults( TransactionSkeleton // value used by geth and testrpc. const u256 defaultTransactionGas = 90000; if ( ret.nonce == Invalid256 ) { - Block block = postSeal(); - block.startReadState(); + Block block = getReadOnlyLatestBlockCopy(); ret.nonce = max< u256 >( block.transactionsFrom( ret.from ), m_tq.maxNonce( ret.from ) ); } if ( ret.gasPrice == Invalid256 ) @@ -1246,7 +1245,7 @@ ExecutionResult Client::call( Address const& _from, u256 _value, Address _dest, } #endif - Block temp = getLatestBlockCopyForEthCall(); + Block temp = getReadOnlyLatestBlockCopy(); u256 nonce = max< u256 >( temp.transactionsFrom( _from ), m_tq.maxNonce( _from ) ); // if the user did not specify transaction gas limit, we give transaction block gas @@ -1524,7 +1523,7 @@ std::pair< u256, ExecutionResult > Client::estimateGas( Address const& _from, u2 else lowerBound = Transaction::baseGasRequired( !_dest, &_data, EVMSchedule() ); - Block latest = getLatestBlockCopyForEthCall(); + Block latest = getReadOnlyLatestBlockCopy(); Block pending = latest; if ( upperBound > pending.info().gasLimit() ) { @@ -1606,25 +1605,25 @@ std::pair< bool, ExecutionResult > Client::estimateGasStep( int64_t _gas, Block& } u256 Client::countAt( Address _a ) const { - return getLatestBlockCopyForEthCall().state().getNonce( _a ); + return getReadOnlyLatestBlockCopy().state().getNonce( _a ); } u256 Client::balanceAt( Address _a ) const { - return getLatestBlockCopyForEthCall().state().balance( _a ); + return getReadOnlyLatestBlockCopy().state().balance( _a ); } u256 Client::stateAt( Address _a, u256 _l ) const { - return getLatestBlockCopyForEthCall().state().storage( _a, _l ); + return getReadOnlyLatestBlockCopy().state().storage( _a, _l ); } bytes Client::codeAt( Address _a ) const { - return getLatestBlockCopyForEthCall().state().code( _a ); + return getReadOnlyLatestBlockCopy().state().code( _a ); } h256 Client::codeHashAt( Address _a ) const { - return getLatestBlockCopyForEthCall().state().codeHash( _a ); + return getReadOnlyLatestBlockCopy().state().codeHash( _a ); } map< h256, pair< u256, u256 > > Client::storageAt( Address _a ) const { - return getLatestBlockCopyForEthCall().state().storage( _a ); + return getReadOnlyLatestBlockCopy().state().storage( _a ); } \ No newline at end of file diff --git a/libethereum/Client.h b/libethereum/Client.h index 26999e17c..931b567e0 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -451,9 +451,10 @@ namespace dev { return m_preSeal; } - Block getLatestBlockCopyForEthCall() const { + // get read only latest block copy + Block getReadOnlyLatestBlockCopy() const { ReadGuard l(x_postSeal); - return m_postSeal.getCopyForEthCalls(); + return m_postSeal.getReadOnlyCopy(); } Block postSeal() const override { diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index eaca2edf1..55f1bec14 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -466,7 +466,6 @@ bool ClientBase::isKnownTransaction( h256 const& _blockHash, unsigned _i ) const Block ClientBase::latestBlock() const { Block res = postSeal(); - res.startReadState(); return res; } diff --git a/libethereum/SkaleHost.cpp b/libethereum/SkaleHost.cpp index 531625481..d3c985524 100644 --- a/libethereum/SkaleHost.cpp +++ b/libethereum/SkaleHost.cpp @@ -415,7 +415,7 @@ ConsensusExtFace::transactions_vector SkaleHost::pendingTransactions( MICROPROFILE_SCOPEI( "SkaleHost", "pendingTransactions", MP_LAWNGREEN ); - _stateRoot = dev::h256::Arith( this->m_client.latestBlock().info().stateRoot() ); + _stateRoot = dev::h256::Arith( m_client.getReadOnlyLatestBlockCopy().info().stateRoot() ); h256Hash to_delete;