From a2911a4df0cb7871acbfbb593b1743c83a23b84f Mon Sep 17 00:00:00 2001 From: yarkin Date: Fri, 15 Mar 2024 23:34:38 +0800 Subject: [PATCH] Use hash as consensus paramter index. --- eosevm/CMakeLists.txt | 1 + eosevm/consensus_parameters.cpp | 7 ++++++ eosevm/consensus_parameters.hpp | 1 + silkworm/core/types/block.cpp | 4 ++-- silkworm/core/types/block.hpp | 2 +- silkworm/core/types/block_test.cpp | 2 +- silkworm/node/db/access_layer.cpp | 8 +++---- silkworm/node/db/access_layer.hpp | 4 ++-- silkworm/node/db/access_layer_test.cpp | 30 +++++++++++++++----------- silkworm/node/db/util.cpp | 8 ++++++- silkworm/node/db/util.hpp | 4 +++- silkworm/node/db/util_test.cpp | 2 +- 12 files changed, 48 insertions(+), 25 deletions(-) diff --git a/eosevm/CMakeLists.txt b/eosevm/CMakeLists.txt index 912b68d0..5b94fd8c 100644 --- a/eosevm/CMakeLists.txt +++ b/eosevm/CMakeLists.txt @@ -25,6 +25,7 @@ add_library(eos_evm ${EOS_EVM_SRC}) target_include_directories(eos_evm PUBLIC ${SILKWORM_MAIN_DIR}) set(EOS_EVM_PUBLIC_LIBS + ethash::ethash intx::intx evmc tl::expected diff --git a/eosevm/consensus_parameters.cpp b/eosevm/consensus_parameters.cpp index 86c30db1..51c6fb93 100644 --- a/eosevm/consensus_parameters.cpp +++ b/eosevm/consensus_parameters.cpp @@ -3,6 +3,7 @@ #if not defined(ANTELOPE) #include #include +#include #endif namespace eosevm { @@ -73,6 +74,12 @@ std::optional ConsensusParameters::decode(silkworm::ByteVie return config; } + +[[nodiscard]] evmc::bytes32 ConsensusParameters::hash() const noexcept { + auto encoded = this->encode(); + evmc::bytes32 header_hash = std::bit_cast(silkworm::keccak256(encoded)); + return header_hash; +} #endif } // namespace eosevm \ No newline at end of file diff --git a/eosevm/consensus_parameters.hpp b/eosevm/consensus_parameters.hpp index 5342bbb9..1994d86a 100644 --- a/eosevm/consensus_parameters.hpp +++ b/eosevm/consensus_parameters.hpp @@ -49,6 +49,7 @@ struct ConsensusParameters { // Decode from storage in db. static std::optional decode(silkworm::ByteView encoded) noexcept; + evmc::bytes32 hash() const noexcept; #endif friend bool operator==(const ConsensusParameters&, const ConsensusParameters&); diff --git a/silkworm/core/types/block.cpp b/silkworm/core/types/block.cpp index fa686d70..285446af 100644 --- a/silkworm/core/types/block.cpp +++ b/silkworm/core/types/block.cpp @@ -286,7 +286,7 @@ namespace rlp { to.consensus_parameter_index = std::nullopt; if (from.length() > leftover) { - uint64_t consensus_parameter_index; + evmc::bytes32 consensus_parameter_index; if (DecodingResult res{decode(from, consensus_parameter_index, Leftover::kAllow)}; !res) { return res; } @@ -327,7 +327,7 @@ namespace rlp { to.consensus_parameter_index = std::nullopt; if (from.length() > leftover) { - uint64_t consensus_parameter_index; + evmc::bytes32 consensus_parameter_index; if (DecodingResult res{decode(from, consensus_parameter_index, Leftover::kAllow)}; !res) { return res; } diff --git a/silkworm/core/types/block.hpp b/silkworm/core/types/block.hpp index 3472d66a..f02d248b 100644 --- a/silkworm/core/types/block.hpp +++ b/silkworm/core/types/block.hpp @@ -97,7 +97,7 @@ struct BlockBody { std::optional> withdrawals{std::nullopt}; // EOS-EVM - std::optional consensus_parameter_index{std::nullopt}; + std::optional consensus_parameter_index{std::nullopt}; friend bool operator==(const BlockBody&, const BlockBody&); }; diff --git a/silkworm/core/types/block_test.cpp b/silkworm/core/types/block_test.cpp index bc86ddb3..60d79273 100644 --- a/silkworm/core/types/block_test.cpp +++ b/silkworm/core/types/block_test.cpp @@ -104,7 +104,7 @@ TEST_CASE("BlockBody RLP 2") { body.ommers[0].prev_randao = 0xf0a53dfdd6c2f2a661e718ef29092de60d81d45f84044bec7bf4b36630b2bc08_bytes32; body.ommers[0].nonce[7] = 35; - body.consensus_parameter_index = 1234; + body.consensus_parameter_index = evmc::bytes32(1234); Bytes rlp{}; rlp::encode(rlp, body); diff --git a/silkworm/node/db/access_layer.cpp b/silkworm/node/db/access_layer.cpp index 937acb63..8bb3a5f7 100644 --- a/silkworm/node/db/access_layer.cpp +++ b/silkworm/node/db/access_layer.cpp @@ -1219,9 +1219,9 @@ void write_runtime_states_u64(RWTxn& txn, uint64_t num, RuntimeState runtime_sta write_runtime_states_bytes(txn, value, runtime_state); } -std::optional read_consensus_parameters(ROTxn& txn, BlockNum index) { +std::optional read_consensus_parameters(ROTxn& txn, const evmc::bytes32& index) { auto cursor = txn.ro_cursor(table::kConsensusParameters); - auto key{db::block_key(index)}; + auto key{db::block_key(index.bytes)}; auto data{cursor->find(to_slice(key), /*throw_notfound=*/false)}; if (!data) { return std::nullopt; @@ -1230,9 +1230,9 @@ std::optional read_consensus_parameters(ROTxn& txn, return eosevm::ConsensusParameters::decode(encoded); } -void update_consensus_parameters(RWTxn& txn, BlockNum index, const eosevm::ConsensusParameters& config) { +void update_consensus_parameters(RWTxn& txn, const evmc::bytes32& index, const eosevm::ConsensusParameters& config) { auto cursor = txn.rw_cursor(table::kConsensusParameters); - auto key{db::block_key(index)}; + auto key{db::block_key(index.bytes)}; cursor->upsert(to_slice(key), mdbx::slice(config.encode())); } diff --git a/silkworm/node/db/access_layer.hpp b/silkworm/node/db/access_layer.hpp index 5ad62635..e3830987 100644 --- a/silkworm/node/db/access_layer.hpp +++ b/silkworm/node/db/access_layer.hpp @@ -252,10 +252,10 @@ std::optional read_runtime_states_u64(ROTxn& txn, RuntimeState runtime void write_runtime_states_u64(RWTxn& txn, uint64_t num, RuntimeState runtime_state); //! \brief Read ConsensusParameters indexed by blocknum that it is added. -std::optional read_consensus_parameters(ROTxn& txn, BlockNum index); +std::optional read_consensus_parameters(ROTxn& txn, const evmc::bytes32& index); //! \brief Write ConsensusParameters indexed by blocknum that it is added. Can overwrite during forks. -void update_consensus_parameters(RWTxn& txn, BlockNum index, const eosevm::ConsensusParameters& config); +void update_consensus_parameters(RWTxn& txn, const evmc::bytes32&, const eosevm::ConsensusParameters& config); class DataModel { public: diff --git a/silkworm/node/db/access_layer_test.cpp b/silkworm/node/db/access_layer_test.cpp index 2365bf91..c2d796ac 100644 --- a/silkworm/node/db/access_layer_test.cpp +++ b/silkworm/node/db/access_layer_test.cpp @@ -81,7 +81,7 @@ static BlockBody sample_block_body() { body.ommers[0].prev_randao = 0xf0a53dfdd6c2f2a661e718ef29092de60d81d45f84044bec7bf4b36630b2bc08_bytes32; body.ommers[0].nonce[7] = 35; - body.consensus_parameter_index = 1234; + body.consensus_parameter_index = evmc::bytes32(1234); return body; } @@ -529,7 +529,7 @@ TEST_CASE("Headers and bodies") { REQUIRE(b == header.number); REQUIRE(h == header.hash()); - CHECK(block.consensus_parameter_index == 1234); + CHECK(block.consensus_parameter_index == evmc::bytes32(1234)); } SECTION("process_blocks_at_height") { @@ -940,21 +940,27 @@ TEST_CASE("ConsensusParameters") { }, }; - CHECK(read_consensus_parameters(txn, 0) == std::nullopt); + CHECK(read_consensus_parameters(txn, evmc::bytes32(0)) == std::nullopt); - update_consensus_parameters(txn, 0, value1 ); - CHECK(read_consensus_parameters(txn, 0) == value1); + update_consensus_parameters(txn, evmc::bytes32(0), value1 ); + CHECK(read_consensus_parameters(txn, evmc::bytes32(0)) == value1); - update_consensus_parameters(txn, 0, value2 ); - CHECK(read_consensus_parameters(txn, 0) == value2); + update_consensus_parameters(txn, evmc::bytes32(0), value2 ); + CHECK(read_consensus_parameters(txn, evmc::bytes32(0)) == value2); - CHECK(read_consensus_parameters(txn, 1) == std::nullopt); + CHECK(read_consensus_parameters(txn, evmc::bytes32(1)) == std::nullopt); - update_consensus_parameters(txn, 1, value2 ); - CHECK(read_consensus_parameters(txn, 1) == value2); + update_consensus_parameters(txn, evmc::bytes32(1), value2 ); + CHECK(read_consensus_parameters(txn, evmc::bytes32(1)) == value2); - update_consensus_parameters(txn, 1, value1 ); - CHECK(read_consensus_parameters(txn, 1) == value1); + update_consensus_parameters(txn, evmc::bytes32(1), value1 ); + CHECK(read_consensus_parameters(txn, evmc::bytes32(1)) == value1); + + update_consensus_parameters(txn, value1.hash(), value1 ); + CHECK(read_consensus_parameters(txn, value1.hash()) == value1); + + update_consensus_parameters(txn, value2.hash(), value2 ); + CHECK(read_consensus_parameters(txn, value2.hash()) == value2); } diff --git a/silkworm/node/db/util.cpp b/silkworm/node/db/util.cpp index fa0cbc73..0eea21cb 100644 --- a/silkworm/node/db/util.cpp +++ b/silkworm/node/db/util.cpp @@ -54,6 +54,12 @@ Bytes block_key(BlockNum block_number, std::span has return key; } +Bytes block_key(std::span hash) { + Bytes key(kHashLength, '\0'); + std::memcpy(&key[0], hash.data(), kHashLength); + return key; +} + auto split_block_key(ByteView key) -> std::tuple { SILKWORM_ASSERT(key.size() == sizeof(BlockNum) + kHashLength); @@ -195,7 +201,7 @@ namespace detail { to.consensus_parameter_index = std::nullopt; if (from.length() > leftover) { - uint64_t consensus_parameter_index; + evmc::bytes32 consensus_parameter_index; if (DecodingResult res{rlp::decode(from, consensus_parameter_index, rlp::Leftover::kAllow)}; !res) { return res; } diff --git a/silkworm/node/db/util.hpp b/silkworm/node/db/util.hpp index 89f17462..677cbb93 100644 --- a/silkworm/node/db/util.hpp +++ b/silkworm/node/db/util.hpp @@ -86,6 +86,8 @@ Bytes block_key(BlockNum block_number); // Erigon HeaderKey & BlockBodyKey Bytes block_key(BlockNum block_number, std::span hash); +Bytes block_key(std::span hash); + // Split a block key in BlockNum and Hash auto split_block_key(ByteView key) -> std::tuple; @@ -131,7 +133,7 @@ namespace detail { std::vector ommers; std::optional> withdrawals{std::nullopt}; // EIP-4895 - std::optional consensus_parameter_index{std::nullopt}; + std::optional consensus_parameter_index{std::nullopt}; [[nodiscard]] Bytes encode() const; diff --git a/silkworm/node/db/util_test.cpp b/silkworm/node/db/util_test.cpp index 82dce395..3ad55d31 100644 --- a/silkworm/node/db/util_test.cpp +++ b/silkworm/node/db/util_test.cpp @@ -47,7 +47,7 @@ TEST_CASE("BlockBodyForStorage encoding") { CHECK(decoded == body); // No withdrawals - body.consensus_parameter_index = 1234; + body.consensus_parameter_index = evmc::bytes32(1234); encoded = body.encode(); view = encoded; decoded = decode_stored_block_body(view);