From a89018dcdba406b9716c16680366867b43189955 Mon Sep 17 00:00:00 2001 From: Boyu Yang Date: Tue, 10 Oct 2023 11:31:00 +0800 Subject: [PATCH] fix: the default (or empty) values of genesis fields should be same as normal blocks --- common/config-parser/src/types/spec.rs | 7 +- core/run/src/lib.rs | 13 +++- core/run/src/tests.rs | 98 +++++++++++++++++--------- 3 files changed, 82 insertions(+), 36 deletions(-) diff --git a/common/config-parser/src/types/spec.rs b/common/config-parser/src/types/spec.rs index 0733fc8c1..6991f77d1 100644 --- a/common/config-parser/src/types/spec.rs +++ b/common/config-parser/src/types/spec.rs @@ -10,7 +10,10 @@ use strum_macros::EnumIter; use common_crypto::Secp256k1RecoverablePrivateKey; use protocol::{ codec::{decode_256bits_key, deserialize_address, ProtocolCodec}, - types::{ExtraData, HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, U256}, + types::{ + ExtraData, HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, RLP_EMPTY_LIST, + RLP_NULL, U256, + }, }; use crate::parse_file; @@ -203,6 +206,8 @@ impl Genesis { /// Build a `Header` of the genesis block from the user provided parameters. pub fn build_header(&self) -> Header { Header { + transactions_root: RLP_NULL, + signed_txs_hash: RLP_EMPTY_LIST, timestamp: self.timestamp, // todo: if Hardforkinput is empty, it must change to latest hardfork info to init // genesis diff --git a/core/run/src/lib.rs b/core/run/src/lib.rs index ee4422c81..99381440e 100644 --- a/core/run/src/lib.rs +++ b/core/run/src/lib.rs @@ -15,8 +15,8 @@ use protocol::traits::{ Context, Executor, Gossip, MemPool, Network, NodeInfo, PeerTrust, ReadOnlyStorage, Rpc, Storage, }; use protocol::types::{ - Block, ExecResp, HardforkInfoInner, Header, Metadata, Proposal, RichBlock, SignedTransaction, - Validator, ValidatorExtend, H256, + Block, Bloom, BloomInput, ExecResp, HardforkInfoInner, Header, Metadata, Proposal, RichBlock, + SignedTransaction, Validator, ValidatorExtend, H256, }; use protocol::{lazy::CHAIN_ID, trie::DB as TrieDB, ProtocolResult}; @@ -463,6 +463,15 @@ async fn execute_genesis( partial_genesis.block.header.state_root = resp.state_root; partial_genesis.block.header.receipts_root = resp.receipt_root; + let logs = resp + .tx_resp + .iter() + .map(|r| Bloom::from(BloomInput::Raw(rlp::encode_list(&r.logs).as_ref()))) + .collect::>(); + let log_bloom = Bloom::from(BloomInput::Raw(rlp::encode_list(&logs).as_ref())); + + partial_genesis.block.header.log_bloom = log_bloom; + log::info!("The genesis block is executed {:?}", partial_genesis.block); log::info!("Response for genesis is {:?}", resp); diff --git a/core/run/src/tests.rs b/core/run/src/tests.rs index 331c5bf39..746b158e5 100644 --- a/core/run/src/tests.rs +++ b/core/run/src/tests.rs @@ -24,7 +24,9 @@ use protocol::{ codec::{hex_decode, ProtocolCodec as _}, tokio, trie::{MemoryDB, PatriciaTrie, Trie as _}, - types::{Header, Metadata, Proposal, RichBlock, H256}, + types::{ + Bloom, BloomInput, Header, Metadata, Proposal, RichBlock, H256, RLP_EMPTY_LIST, RLP_NULL, + }, }; use crate::{components::chain_spec::ChainSpecExt as _, execute_genesis, DatabaseGroup}; @@ -32,42 +34,38 @@ use crate::{components::chain_spec::ChainSpecExt as _, execute_genesis, Database const DEV_CONFIG_DIR: &str = "../../devtools/chain"; struct TestCase<'a> { - chain_name: &'a str, - config_file: &'a str, - chain_spec_file: &'a str, - key_file: &'a str, - input_genesis_hash: &'a str, - genesis_state_root: &'a str, - genesis_receipts_root: &'a str, + chain_name: &'a str, + config_file: &'a str, + chain_spec_file: &'a str, + key_file: &'a str, + input_genesis_hash: &'a str, + genesis_state_root: &'a str, } const TESTCASES: &[TestCase] = &[ TestCase { - chain_name: "single_node", - config_file: "config.toml", - chain_spec_file: "specs/single_node/chain-spec.toml", - key_file: "debug.key", - input_genesis_hash: "0x57db5b4b5c7dd1246c97b0c28aa4d10664035b2ee367df2ae1916c86b6fdffa9", - genesis_state_root: "0x2f1e8e50d5ab97af96fdb5d6de8e691e5bb80f46f2c98c4133d265bd8b60de61", - genesis_receipts_root: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + chain_name: "single_node", + config_file: "config.toml", + chain_spec_file: "specs/single_node/chain-spec.toml", + key_file: "debug.key", + input_genesis_hash: "0xe3a40f0115fbf101520ceea1ce7103a73cb46554187ac7ed67f3522103e06d99", + genesis_state_root: "0x2f1e8e50d5ab97af96fdb5d6de8e691e5bb80f46f2c98c4133d265bd8b60de61", }, TestCase { - chain_name: "multi_nodes", - config_file: "nodes/node_1.toml", - chain_spec_file: "specs/multi_nodes/chain-spec.toml", - key_file: "debug.key", - input_genesis_hash: "0x9dc9e22c984214a8a82f24045079e2c4dc7aa3c8510343b9c40a6e50986f3c9f", - genesis_state_root: "0xf684cbec490eb5b8a07b80f369f3bf87f05ec73494b869111010a6ad6fa89894", - genesis_receipts_root: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + chain_name: "multi_nodes", + config_file: "nodes/node_1.toml", + chain_spec_file: "specs/multi_nodes/chain-spec.toml", + key_file: "debug.key", + input_genesis_hash: "0x1b4cf78373961dabcba5d4a9402c924fc4fecdd9ce367239f02c8971a052f3b5", + genesis_state_root: "0xf684cbec490eb5b8a07b80f369f3bf87f05ec73494b869111010a6ad6fa89894", }, TestCase { - chain_name: "multi_nodes_short_epoch_len", - config_file: "nodes/node_1.toml", - chain_spec_file: "specs/multi_nodes_short_epoch_len/chain-spec.toml", - key_file: "debug.key", - input_genesis_hash: "0x02c6715381ee05c5e6b2a432c9da4843108c573aca6369a85ca06d26b88c1fb7", - genesis_state_root: "0xa5e1e7ac3e03f7dc26cc93ab69c0ec49e591cbdaa7694c75682745c40bfca468", - genesis_receipts_root: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + chain_name: "multi_nodes_short_epoch_len", + config_file: "nodes/node_1.toml", + chain_spec_file: "specs/multi_nodes_short_epoch_len/chain-spec.toml", + key_file: "debug.key", + input_genesis_hash: "0xd930632a7565acfc149c1d896d79910608768de5b936fdb34cc47c9b2296dd2a", + genesis_state_root: "0xa5e1e7ac3e03f7dc26cc93ab69c0ec49e591cbdaa7694c75682745c40bfca468", }, ]; @@ -141,7 +139,7 @@ async fn check_genesis_data<'a>(case: &TestCase<'a>) { assert!(genesis.block.tx_hashes.is_empty()); println!("checking genesis hash"); - check_hashes( + check_hashes_via_str( case.chain_name, "input genesis hash", case.input_genesis_hash, @@ -149,19 +147,49 @@ async fn check_genesis_data<'a>(case: &TestCase<'a>) { ); println!("checking state root"); - check_hashes( + check_hashes_via_str( case.chain_name, "genesis state root", case.genesis_state_root, genesis.block.header.state_root, ); + check_hashes( + case.chain_name, + "genesis transactions root", + genesis.block.header.transactions_root, + RLP_NULL, + ); + + check_hashes( + case.chain_name, + "genesis signed transactions hash", + genesis.block.header.signed_txs_hash, + RLP_EMPTY_LIST, + ); + println!("checking receipts hash"); check_hashes( case.chain_name, "genesis receipts root", - case.genesis_receipts_root, genesis.block.header.receipts_root, + RLP_NULL, + ); + + let logs: Vec = Default::default(); + let expected_log_bloom = Bloom::from(BloomInput::Raw(rlp::encode_list(&logs).as_ref())); + assert_eq!( + genesis.block.header.log_bloom, expected_log_bloom, + "log bloom in genesis of chain {} should be empty since no transactions, \ + expect {expected_log_bloom:#x}, actual {:#x}", + case.chain_name, genesis.block.header.log_bloom, + ); + + assert!( + genesis.block.header.gas_used.is_zero(), + "gas used in genesis of chain {} should be zero since no transactions, actual {}", + case.chain_name, + genesis.block.header.gas_used, ); println!("checking state"); @@ -198,9 +226,13 @@ fn check_state(spec: &ChainSpec, genesis_header: &Header, db_group: &DatabaseGro assert_metadata(metadata_1, handle.get_metadata_by_epoch(1).unwrap()); } -fn check_hashes(chain: &str, name: &str, expected_str: &str, actual: H256) { +fn check_hashes_via_str(chain: &str, name: &str, expected_str: &str, actual: H256) { let expected = H256::from_str(expected_str) .unwrap_or_else(|err| panic!("failed to parse hash {name} of chain {chain} since {err}")); + check_hashes(chain, name, expected, actual); +} + +fn check_hashes(chain: &str, name: &str, expected: H256, actual: H256) { assert_eq!( expected, actual, "hash {name} of chain {chain} is changed, expect {expected:#x}, but got {actual:#x}",