diff --git a/common/config-parser/src/types/spec.rs b/common/config-parser/src/types/spec.rs index 7ef2cb0c7..76caa7e84 100644 --- a/common/config-parser/src/types/spec.rs +++ b/common/config-parser/src/types/spec.rs @@ -9,8 +9,8 @@ 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}, + codec::{decode_256bits_key, deserialize_address}, + types::{HardforkInfoInner, Header, Key256Bits, Metadata, H160, H256, U256}, }; use crate::parse_file; @@ -204,29 +204,24 @@ impl Genesis { pub fn build_header(&self) -> Header { Header { timestamp: self.timestamp, - // todo: if Hardforkinput is empty, it must change to latest hardfork info to init - // genesis - extra_data: { - vec![ExtraData { - inner: { - let mut info = Into::::into(HardforkInput { - hardforks: self.hardforks.clone(), - block_number: 0, - }); - - if info.flags.is_zero() { - info.flags = H256::from_low_u64_be(HardforkName::all().to_be()); - } - - info.encode().unwrap() - }, - }] - }, base_fee_per_gas: self.base_fee_per_gas, chain_id: self.chain_id, ..Default::default() } } + + pub fn generate_hardfork_info(&self) -> HardforkInfoInner { + let mut info = Into::::into(HardforkInput { + hardforks: self.hardforks.clone(), + block_number: 0, + }); + + if info.flags.is_zero() { + info.flags = H256::from_low_u64_be(HardforkName::all().to_be()); + } + + info + } } #[derive(Clone, Debug, Deserialize, Args)] diff --git a/core/executor/src/system_contract/metadata/store.rs b/core/executor/src/system_contract/metadata/store.rs index 96ff43fb2..d3d61c182 100644 --- a/core/executor/src/system_contract/metadata/store.rs +++ b/core/executor/src/system_contract/metadata/store.rs @@ -22,6 +22,7 @@ use crate::{adapter::RocksTrieDB, MPTTrie, CURRENT_METADATA_ROOT}; /// | -------------------- | ------------------------ | /// | EPOCH_SEGMENT_KEY | `EpochSegment.encode()` | /// | CKB_RELATED_INFO_KEY | `CkbRelatedInfo.encode()`| +/// | HARDFORK_KEY | `HardforkInfo.encode()` | /// | epoch_0.be_bytes() | `Metadata.encode()` | /// | epoch_1.be_bytes() | `Metadata.encode()` | /// | ... | ... | @@ -120,10 +121,9 @@ impl MetadataStore { )?; self.trie .insert(inner.epoch.to_be_bytes().to_vec(), inner.encode()?.to_vec())?; - self.trie.insert( - CONSENSUS_CONFIG.as_bytes().to_vec(), - encode_consensus_config(current_hardfork, config.encode()?.to_vec()), - )?; + let config = encode_consensus_config(current_hardfork, config.encode()?.to_vec()); + self.trie + .insert(CONSENSUS_CONFIG.as_bytes().to_vec(), config)?; let new_root = self.trie.commit()?; CURRENT_METADATA_ROOT.with(|r| *r.borrow_mut() = new_root); @@ -231,6 +231,7 @@ impl MetadataStore { }, } }; + self.trie.insert( HARDFORK_KEY.as_bytes().to_vec(), current_info.encode()?.to_vec(), diff --git a/core/executor/src/system_contract/mod.rs b/core/executor/src/system_contract/mod.rs index e6bf19df7..201334a1f 100644 --- a/core/executor/src/system_contract/mod.rs +++ b/core/executor/src/system_contract/mod.rs @@ -28,7 +28,9 @@ use parking_lot::RwLock; use rocksdb::DB; use protocol::traits::{CkbDataProvider, ExecutorAdapter}; -use protocol::types::{Bytes, Hasher, Metadata, SignedTransaction, TxResp, H160, H256}; +use protocol::types::{ + Bytes, HardforkInfoInner, Hasher, Metadata, SignedTransaction, TxResp, H160, H256, +}; use protocol::{ckb_blake2b_256, ProtocolResult}; use crate::adapter::RocksTrieDB; @@ -115,9 +117,10 @@ pub fn init( db: Arc, adapter: &mut Adapter, metadata_list: &[Metadata], + hardfork: HardforkInfoInner, ) -> ProtocolResult<(H256, H256)> { let ret = init_system_contract_db(db, adapter); - init_metadata(adapter, ret.0, metadata_list)?; + init_metadata_and_hardfork(adapter, ret.0, metadata_list, hardfork)?; Ok(ret) } @@ -165,16 +168,18 @@ pub fn init_system_contract_db( /// This method is used for insert the first two metadata, so the /// `metadata_list.len()` should be equal to 2. -fn init_metadata( +fn init_metadata_and_hardfork( adapter: &mut Adapter, metadata_root: H256, metadata_list: &[Metadata], + hardfork: HardforkInfoInner, ) -> ProtocolResult<()> { debug_assert!(metadata_list.len() == 2); let mut store = MetadataStore::new(metadata_root)?; store.append_metadata(&metadata_list[0])?; store.append_metadata(&metadata_list[1])?; + store.set_hardfork_info(hardfork.block_number, hardfork.flags)?; let changes = generate_mpt_root_changes(adapter, METADATA_CONTRACT_ADDRESS); adapter.apply(changes, vec![], false); diff --git a/core/run/src/lib.rs b/core/run/src/lib.rs index ee4422c81..7cf0ae6fc 100644 --- a/core/run/src/lib.rs +++ b/core/run/src/lib.rs @@ -456,9 +456,13 @@ async fn execute_genesis( tmp }; - let resp = execute_genesis_transactions(&partial_genesis, db_group, &spec.accounts, &[ - metadata_0, metadata_1, - ])?; + let resp = execute_genesis_transactions( + &partial_genesis, + db_group, + &spec.accounts, + &[metadata_0, metadata_1], + spec.genesis.generate_hardfork_info(), + )?; partial_genesis.block.header.state_root = resp.state_root; partial_genesis.block.header.receipts_root = resp.receipt_root; @@ -479,6 +483,7 @@ fn execute_genesis_transactions( db_group: &DatabaseGroup, accounts: &[InitialAccount], metadata_list: &[Metadata], + hardfork: HardforkInfoInner, ) -> ProtocolResult { let state_root = MPTTrie::new(db_group.trie_db()) .insert_accounts(accounts) @@ -491,7 +496,7 @@ fn execute_genesis_transactions( Proposal::new_without_state_root(&rich.block.header).into(), )?; - system_contract::init(db_group.inner_db(), &mut backend, metadata_list)?; + system_contract::init(db_group.inner_db(), &mut backend, metadata_list, hardfork)?; let resp = AxonExecutor.exec(&mut backend, &rich.txs, &[]); diff --git a/core/run/src/tests.rs b/core/run/src/tests.rs index ed87860c3..54b761d38 100644 --- a/core/run/src/tests.rs +++ b/core/run/src/tests.rs @@ -52,8 +52,8 @@ const TESTCASES: &[TestCase] = &[ config_file: "config.toml", chain_spec_file: "specs/single_node/chain-spec.toml", key_file: "debug.key", - input_genesis_hash: "0x7360659a70f5713a4cc30b51e819dacd421047faf3295371cccbd34f7e5536c3", - genesis_state_root: "0xfcb1f7a0000aac13be142babea87b3ee29a562111bf7e70ee22eae152ac40991", + input_genesis_hash: "0xe8ab86e48fc2ac4123a7ecf512e755a2580405612185a9ecba21c128b60331e0", + genesis_state_root: "0xf939bf06a1d818aee1555a11f06b20c215003c056e26403ecb1cb4b15958f6ac", genesis_receipts_root: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", }, TestCase { @@ -61,8 +61,8 @@ const TESTCASES: &[TestCase] = &[ config_file: "nodes/node_1.toml", chain_spec_file: "specs/multi_nodes/chain-spec.toml", key_file: "debug.key", - input_genesis_hash: "0x6b2214dc0bd93c64c234a99d996c90ccd97b0f89a888d50292dc34897486e30a", - genesis_state_root: "0x11f586d996d7706bd2ee430224c279cd75b1a12bcb743dc139bea9cba2516f89", + input_genesis_hash: "0x7ff0215535900861c18964e83e1f8b049e4d68357a966f70e75268ed1b71ea3d", + genesis_state_root: "0xe911923f522acff78d3f08b851aca86870bda9f24f1722f1d97518ff3b8697c6", genesis_receipts_root: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", }, TestCase { @@ -70,8 +70,8 @@ const TESTCASES: &[TestCase] = &[ 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: "0x7360659a70f5713a4cc30b51e819dacd421047faf3295371cccbd34f7e5536c3", - genesis_state_root: "0xc6ed6cbebcdcd05d72c9fb0ed6a9303179ca226a940c638b6dee63e7ffaec7bb", + input_genesis_hash: "0xe8ab86e48fc2ac4123a7ecf512e755a2580405612185a9ecba21c128b60331e0", + genesis_state_root: "0x1fc51ffe40ba5f03523370e8a1baba3046574db9abf769f21e42458f50047a2c", genesis_receipts_root: "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", }, ]; @@ -176,9 +176,13 @@ async fn check_genesis_data<'a>(case: &TestCase<'a>) { tmp.version.end = tmp.version.start + metadata_0.version.end - 1; tmp }; - let resp = execute_genesis_transactions(&genesis, &db_group, &chain_spec.accounts, &[ - metadata_0, metadata_1, - ]) + let resp = execute_genesis_transactions( + &genesis, + &db_group, + &chain_spec.accounts, + &[metadata_0, metadata_1], + chain_spec.genesis.generate_hardfork_info(), + ) .expect("execute transactions"); let mut header = genesis.block.header.clone(); @@ -277,10 +281,12 @@ fn generate_memory_mpt_root(metadata_0: Metadata, metadata_1: Metadata) -> Vec Vec