diff --git a/core/executor/src/system_contract/metadata/mod.rs b/core/executor/src/system_contract/metadata/mod.rs index 9fc794ea8..dca580017 100644 --- a/core/executor/src/system_contract/metadata/mod.rs +++ b/core/executor/src/system_contract/metadata/mod.rs @@ -1,6 +1,6 @@ mod abi; pub(crate) mod handle; -mod segment; +pub mod segment; mod store; pub use abi::metadata_abi; @@ -30,7 +30,7 @@ pub const METADATA_CONTRACT_ADDRESS: H160 = system_contract_address(0x1); const METADATA_CACHE_SIZE: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(10) }; lazy_static::lazy_static! { - static ref EPOCH_SEGMENT_KEY: H256 = Hasher::digest("epoch_segment"); + pub static ref EPOCH_SEGMENT_KEY: H256 = Hasher::digest("epoch_segment"); static ref CKB_RELATED_INFO_KEY: H256 = Hasher::digest("ckb_related_info"); static ref HARDFORK_KEY: H256 = Hasher::digest("hardfork"); static ref HARDFORK_INFO: ArcSwap = ArcSwap::new(Arc::new(H256::zero())); diff --git a/core/run/src/tests.rs b/core/run/src/tests.rs index 0d86e17ec..5c1b8a5f0 100644 --- a/core/run/src/tests.rs +++ b/core/run/src/tests.rs @@ -1,9 +1,11 @@ use std::{ + collections::BTreeMap, convert::AsRef, env::{current_dir, set_current_dir}, fs, io, path::{Path, PathBuf}, str::FromStr, + sync::Arc, }; use clap::{builder::TypedValueParser as _, Command}; @@ -14,7 +16,10 @@ use common_config_parser::types::{ Config, ConfigValueParser, }; use common_crypto::Secp256k1RecoverablePrivateKey; -use core_executor::{AxonExecutorApplyAdapter, MetadataHandle}; +use core_executor::{ + system_contract::metadata::{segment::EpochSegment, EPOCH_SEGMENT_KEY}, + AxonExecutorApplyAdapter, MetadataHandle, +}; use protocol::{ codec::{hex_decode, ProtocolCodec as _}, tokio, @@ -218,6 +223,11 @@ fn check_state(spec: &ChainSpec, genesis_header: &Header, db_group: &DatabaseGro }; let handle = MetadataHandle::new(backend.get_metadata_root()); + assert_eq!( + backend.get_metadata_root().as_bytes(), + generate_memory_mpt_root(metadata_0.clone(), metadata_1.clone()) + ); + assert_metadata(metadata_0, handle.get_metadata_by_epoch(0).unwrap()); assert_metadata(metadata_1, handle.get_metadata_by_epoch(1).unwrap()); } @@ -253,8 +263,47 @@ fn copy_dir(src: impl AsRef, dst: impl AsRef) -> io::Result<()> { } fn generate_memory_mpt_root(metadata_0: Metadata, metadata_1: Metadata) -> Vec { - let mut memory_mpt = PatriciaTrie::new(Arc::new(MemoryDB::new(false)), HasherKeccak::new()); - memory_mpt.insert(metadata_0.epoch.to_be_bytes().to_vec(), metadata_0.encode()); - memory_mpt.insert(metadata_1.epoch.to_be_bytes().to_vec(), metadata_1.encode()); + let metadata_0 = sort_metadata(metadata_0); + let metadata_1 = sort_metadata(metadata_1); + let mut memory_mpt = PatriciaTrie::new( + Arc::new(MemoryDB::new(false)), + Arc::new(HasherKeccak::new()), + ); + let mut seg = EpochSegment::new(); + + memory_mpt + .insert(EPOCH_SEGMENT_KEY.as_bytes().to_vec(), seg.as_bytes()) + .unwrap(); + seg.append_endpoint(metadata_0.version.end).unwrap(); + memory_mpt + .insert(EPOCH_SEGMENT_KEY.as_bytes().to_vec(), seg.as_bytes()) + .unwrap(); + seg.append_endpoint(metadata_1.version.end).unwrap(); + memory_mpt + .insert(EPOCH_SEGMENT_KEY.as_bytes().to_vec(), seg.as_bytes()) + .unwrap(); + + memory_mpt + .insert( + metadata_0.epoch.to_be_bytes().to_vec(), + metadata_0.encode().unwrap().to_vec(), + ) + .unwrap(); + memory_mpt + .insert( + metadata_1.epoch.to_be_bytes().to_vec(), + metadata_1.encode().unwrap().to_vec(), + ) + .unwrap(); memory_mpt.root().unwrap() } + +fn sort_metadata(mut metadata: Metadata) -> Metadata { + let map = metadata + .verifier_list + .iter() + .map(|v| (v.address, 0u64)) + .collect::>(); + metadata.propose_counter = map.into_iter().map(Into::into).collect(); + metadata +}