Skip to content

Commit

Permalink
#1750 multiple transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
kladkogex committed Jan 15, 2024
1 parent 4188e5f commit 8141ca5
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 61 deletions.
66 changes: 39 additions & 27 deletions libethereum/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -795,41 +795,53 @@ u256 Block::enact( VerifiedBlockRef const& _block, BlockChain const& _bc ) {
#ifdef HISTORIC_STATE
ExecutionResult Block::executeHistoricCall( LastBlockHashesFace const& _lh, Transaction const& _t,
std::shared_ptr< AlethStandardTrace > _tracer, uint64_t _transactionIndex ) {
auto onOp = OnOpFunc();
try {
auto onOp = OnOpFunc();

if ( _tracer ) {
onOp = _tracer->functionToExecuteOnEachOperation();
}
if ( _tracer ) {
onOp = _tracer->functionToExecuteOnEachOperation();
}


if ( isSealed() )
BOOST_THROW_EXCEPTION( InvalidOperationOnSealedBlock() );
if ( isSealed() )
BOOST_THROW_EXCEPTION( InvalidOperationOnSealedBlock() );

// Uncommitting is a non-trivial operation - only do it once we've verified as much of the
// transaction as possible.
uncommitToSeal();
// Uncommitting is a non-trivial operation - only do it once we've verified as much of the
// transaction as possible.
uncommitToSeal();

u256 const gasUsed =
_transactionIndex ? receipt( _transactionIndex - 1 ).cumulativeGasUsed() : 0;
u256 const gasUsed =
_transactionIndex ? receipt( _transactionIndex - 1 ).cumulativeGasUsed() : 0;

EnvInfo const envInfo{ info(), _lh, gasUsed, m_sealEngine->chainParams().chainID };
EnvInfo const envInfo{ info(), _lh, gasUsed, m_sealEngine->chainParams().chainID };

if ( _tracer ) {
HistoricState stateBefore( m_state.mutableHistoricState() );
auto resultReceipt = m_state.mutableHistoricState().execute(
envInfo, *m_sealEngine, _t, skale::Permanence::Uncommitted, onOp );
HistoricState stateAfter( m_state.mutableHistoricState() );
try {
_tracer->finalizeAndPrintTrace( resultReceipt.first, stateBefore, stateAfter );
} catch ( std::exception& e ) {
throw dev::eth::VMTracingError( "Exception doing trace for transaction index:" +
std::to_string( _transactionIndex ) + ":" + e.what() );
if ( _tracer ) {
try {
HistoricState stateBefore( m_state.mutableHistoricState() );

auto resultReceipt = m_state.mutableHistoricState().execute(
envInfo, *m_sealEngine, _t, skale::Permanence::Uncommitted, onOp );
HistoricState stateAfter( m_state.mutableHistoricState() );
_tracer->finalizeAndPrintTrace( resultReceipt.first, stateBefore, stateAfter );
return resultReceipt.first;
} catch ( std::exception& e ) {
throw dev::eth::VMTracingError( "Exception doing trace for transaction index:" +
std::to_string( _transactionIndex ) + ":" +
e.what() );
}
} else {
auto resultReceipt = m_state.mutableHistoricState().execute(
envInfo, *m_sealEngine, _t, skale::Permanence::Reverted, onOp );
return resultReceipt.first;
}
return resultReceipt.first;
} else {
auto resultReceipt = m_state.mutableHistoricState().execute(
envInfo, *m_sealEngine, _t, skale::Permanence::Reverted, onOp );
return resultReceipt.first;
} catch ( std::exception& e ) {
BOOST_THROW_EXCEPTION(
std::runtime_error( "Could not execute historic call for transactionIndex:" +
to_string( _transactionIndex ) + ":" + e.what() ) );
} catch ( ... ) {
BOOST_THROW_EXCEPTION(
std::runtime_error( "Could not execute historic call for transactionIndex:" +
to_string( _transactionIndex ) + ": unknown error" ) );
}
}
#endif
Expand Down
78 changes: 44 additions & 34 deletions libethereum/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,9 @@ Block Client::blockByNumber( BlockNumber _h ) const {

auto readState = m_state.createStateReadOnlyCopy();
readState.mutableHistoricState().setRootByBlockNumber( _h );
DEV_GUARDED( m_blockImportMutex ) { return Block( bc(), hash, readState ); }
DEV_GUARDED( m_blockImportMutex ) {
return Block( bc(), hash, readState );
}
assert( false );
return Block( bc() );
} catch ( Exception& ex ) {
Expand All @@ -1106,7 +1108,9 @@ Block Client::blockByNumber( BlockNumber _h ) const {
Block Client::latestBlock() const {
// TODO Why it returns not-filled block??! (see Block ctor)
try {
DEV_GUARDED( m_blockImportMutex ) { return Block( bc(), bc().currentHash(), m_state ); }
DEV_GUARDED( m_blockImportMutex ) {
return Block( bc(), bc().currentHash(), m_state );
}
assert( false );
return Block( bc() );
} catch ( Exception& ex ) {
Expand Down Expand Up @@ -1259,7 +1263,7 @@ ExecutionResult Client::call( Address const& _from, u256 _value, Address _dest,
// geth does a similar thing, we need to check whether it is fully compatible with
// geth
historicBlock.mutableState().mutableHistoricState().addBalance(
_from, ( u256 )( t.gas() * t.gasPrice() + t.value() ) );
_from, ( u256 ) ( t.gas() * t.gasPrice() + t.value() ) );
ret = historicBlock.executeHistoricCall( bc().lastBlockHashes(), t, nullptr, 0 );
} catch ( ... ) {
cwarn << boost::current_exception_diagnostic_information();
Expand All @@ -1283,7 +1287,8 @@ ExecutionResult Client::call( Address const& _from, u256 _value, Address _dest,
t.forceChainId( chainParams().chainID );
t.checkOutExternalGas( ~u256( 0 ) );
if ( _ff == FudgeFactor::Lenient )
temp.mutableState().addBalance( _from, ( u256 )( t.gas() * t.gasPrice() + t.value() ) );
temp.mutableState().addBalance(
_from, ( u256 ) ( t.gas() * t.gasPrice() + t.value() ) );
ret = temp.execute( bc().lastBlockHashes(), t, skale::Permanence::Reverted );
} catch ( InvalidNonce const& in ) {
LOG( m_logger ) << "exception in client call(1):"
Expand Down Expand Up @@ -1316,7 +1321,7 @@ Json::Value Client::traceCall( Address const& _from, u256 _value, Address _to, b
// lots of gas to it
auto originalFromBalance = historicBlock.mutableState().balance( _from );
historicBlock.mutableState().mutableHistoricState().addBalance(
_from, ( u256 )( t.gas() * t.gasPrice() + t.value() ) );
_from, ( u256 ) ( t.gas() * t.gasPrice() + t.value() ) );
auto traceOptions = TraceOptions::make( _jsonTraceConfig );
auto tracer =
make_shared< AlethStandardTrace >( t, historicBlock.author(), traceOptions, true );
Expand Down Expand Up @@ -1346,43 +1351,48 @@ Transaction Client::createTransactionForCallOrTraceCall( const Address& _from, c


Json::Value Client::traceBlock( BlockNumber _blockNumber, Json::Value const& _jsonTraceConfig ) {
Block previousBlock = blockByNumber( _blockNumber - 1 );
Block historicBlock = blockByNumber( _blockNumber );
try {
Block previousBlock = blockByNumber( _blockNumber - 1 );
Block historicBlock = blockByNumber( _blockNumber );

Json::Value traces( Json::arrayValue );
Json::Value traces( Json::arrayValue );

auto hash = ClientBase::hashFromNumber( _blockNumber );
Transactions transactions = this->transactions( hash );
auto hash = ClientBase::hashFromNumber( _blockNumber );
Transactions transactions = this->transactions( hash );

auto traceOptions = TraceOptions::make( _jsonTraceConfig );
auto traceOptions = TraceOptions::make( _jsonTraceConfig );

// cache results for better peformance
string key = to_string( _blockNumber ) + traceOptions.toString();
// cache results for better peformance
string key = to_string( _blockNumber ) + traceOptions.toString();

auto cachedResult = m_blockTraceCache.getIfExists( key );
if ( cachedResult.has_value() ) {
return std::any_cast< Json::Value >( cachedResult );
}
auto cachedResult = m_blockTraceCache.getIfExists( key );
if ( cachedResult.has_value() ) {
return std::any_cast< Json::Value >( cachedResult );
}

for ( unsigned k = 0; k < transactions.size(); k++ ) {
Json::Value transactionLog( Json::objectValue );
Transaction tx = transactions.at( k );
auto hashString = toHexPrefixed( tx.sha3() );
transactionLog["txHash"] = hashString;
tx.checkOutExternalGas( chainParams().externalGasDifficulty );
auto tracer =
std::make_shared< AlethStandardTrace >( tx, historicBlock.author(), traceOptions );
auto executionResult =
previousBlock.executeHistoricCall( bc().lastBlockHashes(), tx, tracer, k );
auto result = tracer->getJSONResult();
transactionLog["result"] = result;
traces.append( transactionLog );
}
for ( unsigned k = 0; k < transactions.size(); k++ ) {
Json::Value transactionLog( Json::objectValue );
Transaction tx = transactions.at( k );
auto hashString = toHexPrefixed( tx.sha3() );
transactionLog["txHash"] = hashString;
tx.checkOutExternalGas( chainParams().externalGasDifficulty );
auto tracer =
std::make_shared< AlethStandardTrace >( tx, historicBlock.author(), traceOptions );
auto executionResult =
previousBlock.executeHistoricCall( bc().lastBlockHashes(), tx, tracer, k );
auto result = tracer->getJSONResult();
transactionLog["result"] = result;
traces.append( transactionLog );
}

auto tracesSize = traces.toStyledString().size();
m_blockTraceCache.put( key, traces, tracesSize );
auto tracesSize = traces.toStyledString().size();
m_blockTraceCache.put( key, traces, tracesSize );

return traces;
return traces;
} catch ( std::exception& e ) {
BOOST_THROW_EXCEPTION(
std::runtime_error( "Could not trace block:" + to_string( _blockNumber ) + ":" + e.what() ) );
}
}

#endif
Expand Down

0 comments on commit 8141ca5

Please sign in to comment.