From 837061d809da1dbadbad7974237ad76e8173a745 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Mon, 21 Aug 2023 10:50:14 +0200 Subject: [PATCH] state: Support pre-Byzantium receipt format --- test/state/state.cpp | 25 +++++++++++++----- test/state/state.hpp | 3 +++ test/t8n/t8n.cpp | 2 ++ test/unittests/state_mpt_hash_test.cpp | 35 ++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/test/state/state.cpp b/test/state/state.cpp index da052b6fe0..df52ddfd09 100644 --- a/test/state/state.cpp +++ b/test/state/state.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "state.hpp" +#include "../utils/stdx/utility.hpp" #include "errors.hpp" #include "host.hpp" #include "rlp.hpp" @@ -213,8 +214,8 @@ std::variant transition(State& state, const [](const std::pair& p) noexcept { return p.second.destructed; }); // Cumulative gas used is unknown in this scope. - auto receipt = TransactionReceipt{tx.type, result.status_code, gas_used, {}, host.take_logs(), - {}}; + auto receipt = + TransactionReceipt{tx.type, result.status_code, gas_used, {}, host.take_logs(), {}, {}}; // Cannot put it into constructor call because logs are std::moved from host instance. receipt.logs_bloom_filter = compute_bloom_filter(receipt.logs); @@ -275,10 +276,22 @@ std::variant transition(State& state, const [[nodiscard]] bytes rlp_encode(const TransactionReceipt& receipt) { - const auto prefix = receipt.type == Transaction::Type::eip1559 ? bytes{0x02} : bytes{}; - return prefix + rlp::encode_tuple(receipt.status == EVMC_SUCCESS, - static_cast(receipt.cumulative_gas_used), - bytes_view(receipt.logs_bloom_filter), receipt.logs); + if (receipt.post_state.has_value()) + { + return rlp::encode_tuple(receipt.post_state.value(), + static_cast(receipt.cumulative_gas_used), + bytes_view(receipt.logs_bloom_filter), receipt.logs); + } + else + { + const auto prefix = receipt.type == Transaction::Type::legacy ? + bytes{} : + bytes{stdx::to_underlying(receipt.type)}; + + return prefix + rlp::encode_tuple(receipt.status == EVMC_SUCCESS, + static_cast(receipt.cumulative_gas_used), + bytes_view(receipt.logs_bloom_filter), receipt.logs); + } } } // namespace evmone::state diff --git a/test/state/state.hpp b/test/state/state.hpp index 0d22642e1e..051192f121 100644 --- a/test/state/state.hpp +++ b/test/state/state.hpp @@ -144,6 +144,9 @@ struct TransactionReceipt int64_t cumulative_gas_used = 0; std::vector logs; BloomFilter logs_bloom_filter; + /// Root hash of the state after this transaction. It's used in old pre-Byzantium transaction + /// only. + std::optional post_state; }; /// Finalize state after applying a "block" of transactions. diff --git a/test/t8n/t8n.cpp b/test/t8n/t8n.cpp index 2ab753d54c..80e15d1531 100644 --- a/test/t8n/t8n.cpp +++ b/test/t8n/t8n.cpp @@ -146,6 +146,8 @@ int main(int argc, const char* argv[]) j_receipt["gasUsed"] = hex0x(static_cast(receipt.gas_used)); cumulative_gas_used += receipt.gas_used; receipt.cumulative_gas_used = cumulative_gas_used; + if (rev < EVMC_BYZANTIUM) + receipt.post_state = state::mpt_hash(state.get_accounts()); j_receipt["cumulativeGasUsed"] = hex0x(cumulative_gas_used); j_receipt["blockHash"] = hex0x(bytes32{}); diff --git a/test/unittests/state_mpt_hash_test.cpp b/test/unittests/state_mpt_hash_test.cpp index 5fa1ec0c3e..b7c1728cf6 100644 --- a/test/unittests/state_mpt_hash_test.cpp +++ b/test/unittests/state_mpt_hash_test.cpp @@ -244,3 +244,38 @@ TEST(state_mpt_hash, legacy_and_eip1559_receipt_three_logs_no_logs) EXPECT_EQ(mpt_hash(std::array{receipt0, receipt1}), 0x7199a3a86010634dc205a1cdd6ec609f70b954167583cb3acb6a2e3057916016_bytes32); } + +TEST(state_mpt_hash, pre_byzantium_receipt) +{ + // Block taken from Ethereum mainnet + // https://etherscan.io/txs?block=4276370 + + using namespace evmone::state; + + TransactionReceipt receipt0{ + .type = Transaction::Type::legacy, + .cumulative_gas_used = 0x8323, + .logs = {}, + .logs_bloom_filter = compute_bloom_filter(receipt0.logs), + .post_state = 0x4a8f9db452b100f9ec85830785b2d1744c3e727561c334c4f18022daa113290a_bytes32, + }; + + TransactionReceipt receipt1{ + .type = Transaction::Type::legacy, + .cumulative_gas_used = 0x10646, + .logs = {}, + .logs_bloom_filter = compute_bloom_filter(receipt1.logs), + .post_state = 0xb14ab7c32b3e126591731850976a15e2359c1f3628f1b0ff37776c210b9cadb8_bytes32, + }; + + TransactionReceipt receipt2{ + .type = Transaction::Type::legacy, + .cumulative_gas_used = 0x1584e, + .logs = {}, + .logs_bloom_filter = compute_bloom_filter(receipt2.logs), + .post_state = 0x7bda915deb201cae321d31028d322877e8fb98264db3ffcbfec7ea7b9b2106b1_bytes32, + }; + + EXPECT_EQ(mpt_hash(std::array{receipt0, receipt1, receipt2}), + 0x8a4fa43a95939b06ad13ce8cd08e026ae6e79ea3c5fc80c732d252e2769ce778_bytes32); +}