diff --git a/silkworm/core/execution/execution_test.cpp b/silkworm/core/execution/execution_test.cpp index 5d8abda898..638f7a5559 100644 --- a/silkworm/core/execution/execution_test.cpp +++ b/silkworm/core/execution/execution_test.cpp @@ -165,7 +165,7 @@ TEST_CASE("Execute block with tracing") { std::vector receipts; const auto rule_set{protocol::rule_set_factory(chain_config)}; REQUIRE(rule_set); - ExecutionProcessor processor{block, *rule_set, state, chain_config, false}; + ExecutionProcessor processor{block, *rule_set, state, chain_config, true}; BlockTracer block_tracer{}; processor.evm().add_tracer(block_tracer); diff --git a/silkworm/core/execution/processor.cpp b/silkworm/core/execution/processor.cpp index 4b69d45d89..168c5c5445 100644 --- a/silkworm/core/execution/processor.cpp +++ b/silkworm/core/execution/processor.cpp @@ -180,6 +180,31 @@ void ExecutionProcessor::execute_transaction(const Transaction& txn, Receipt& re receipt.logs.emplace_back(Log{addr, std::move(topics), std::move(data)}); receipt.bloom = logs_bloom(receipt.logs); + if (evm1_v2_) { + // Apply the state diff produced by evmone APIv2 to the state and skip the Silkworm execution. + const auto& state_diff = evm1_receipt.state_diff; + for (const auto& m : state_diff.modified_accounts) { + if (!m.code.empty()) { + state_.create_contract(m.addr); + state_.set_code(m.addr, m.code); + } + + auto& acc = state_.get_or_create_object(m.addr); + acc.current->nonce = m.nonce; + acc.current->balance = m.balance; + + auto& storage = state_.storage_[m.addr]; + for (const auto& [k, v] : m.modified_storage) { + storage.committed[k].original = v; + } + } + + for (const auto& a : state_diff.deleted_accounts) { + state_.destruct(a); + } + return; + } + state_.clear_journal_and_substate(); const std::optional sender{txn.sender()}; diff --git a/silkworm/core/execution/processor_test.cpp b/silkworm/core/execution/processor_test.cpp index dee0a19ae2..6d7929adb1 100644 --- a/silkworm/core/execution/processor_test.cpp +++ b/silkworm/core/execution/processor_test.cpp @@ -45,7 +45,7 @@ TEST_CASE("Zero gas price") { InMemoryState state; auto rule_set{protocol::rule_set_factory(kMainnetConfig)}; - ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, false}; + ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, true}; Receipt receipt; processor.execute_transaction(txn, receipt); @@ -85,7 +85,7 @@ TEST_CASE("No refund on error") { InMemoryState state; auto rule_set{protocol::rule_set_factory(kMainnetConfig)}; - ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, false}; + ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, true}; Transaction txn{}; txn.nonce = nonce; @@ -179,7 +179,7 @@ TEST_CASE("Self-destruct") { InMemoryState state; auto rule_set{protocol::rule_set_factory(kMainnetConfig)}; - ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, false}; + ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, true}; processor.evm().state().add_to_balance(originator, kEther); processor.evm().state().set_code(caller_address, caller_code); @@ -327,7 +327,7 @@ TEST_CASE("Out of Gas during account re-creation") { txn.set_sender(caller); auto rule_set{protocol::rule_set_factory(kMainnetConfig)}; - ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, false}; + ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, true}; processor.evm().state().add_to_balance(caller, kEther); Receipt receipt; @@ -370,7 +370,7 @@ TEST_CASE("Empty suicide beneficiary") { InMemoryState state; auto rule_set{protocol::rule_set_factory(kMainnetConfig)}; - ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, false}; + ExecutionProcessor processor{block, *rule_set, state, kMainnetConfig, true}; processor.evm().state().add_to_balance(caller, kEther); Receipt receipt; diff --git a/silkworm/core/state/intra_block_state.hpp b/silkworm/core/state/intra_block_state.hpp index 8d4fd80cec..c413fba86a 100644 --- a/silkworm/core/state/intra_block_state.hpp +++ b/silkworm/core/state/intra_block_state.hpp @@ -133,6 +133,7 @@ class IntraBlockState { friend class state::AccountAccessDelta; friend class state::TransientStorageChangeDelta; friend class StateView; + friend class ExecutionProcessor; evmc::bytes32 get_storage(const evmc::address& address, const evmc::bytes32& key, bool original) const noexcept;