Skip to content

Commit 5f5f338

Browse files
authored
Merge pull request #5 from Pana/feat/stateDump2
add logic to filter core space storage keys
2 parents 5118c30 + 95af03c commit 5f5f338

File tree

10 files changed

+136
-21
lines changed

10 files changed

+136
-21
lines changed

crates/client/src/state_dump.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use chrono::Utc;
1010
use keccak_hash::{keccak, KECCAK_EMPTY};
1111
use parking_lot::{Condvar, Mutex};
1212
use primitives::{
13-
Account, SkipInputCheck, StorageKey, StorageKeyWithSpace, StorageValue,
13+
Account, SkipInputCheck, SpaceStorageFilter, StorageKey,
14+
StorageKeyWithSpace, StorageValue,
1415
};
1516
use rlp::Rlp;
1617
use std::{
@@ -293,7 +294,11 @@ pub fn export_space_accounts_with_callback<F: Fn(AccountState)>(
293294
}
294295
};
295296

296-
state.read_all_with_callback(start_key, &mut inner_callback)?;
297+
state.read_all_with_callback(
298+
start_key,
299+
&mut inner_callback,
300+
Some(SpaceStorageFilter::from(space)),
301+
)?;
297302

298303
if account_states.len() > 0 {
299304
println("Start to read account code and storage data...");

crates/dbs/statedb/src/lib.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub mod global_params;
1212
mod in_memory_storage;
1313
mod statedb_ext;
1414
use cfx_types::H256;
15-
use primitives::StorageValue;
15+
use primitives::{SpaceStorageFilter, StorageValue};
1616

1717
use cfx_db_errors::statedb as error;
1818

@@ -191,9 +191,14 @@ mod impls {
191191
pub fn read_all_with_callback(
192192
&mut self, access_key_prefix: StorageKeyWithSpace,
193193
callback: &mut dyn FnMut(MptKeyValue),
194+
space_storage_filter: Option<SpaceStorageFilter>,
194195
) -> Result<()> {
195196
self.storage
196-
.read_all_with_callback(access_key_prefix, callback)
197+
.read_all_with_callback(
198+
access_key_prefix,
199+
callback,
200+
space_storage_filter,
201+
)
197202
.map_err(|err| err.into())
198203
}
199204

crates/dbs/storage/src/impls/delta_mpt/cow_node_ref.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,12 +622,19 @@ impl CowNodeRef {
622622
Ok(())
623623
}
624624

625+
// space_storage_filter can be used to filter the wanted space storage keys
625626
pub fn iterate_internal_with_callback(
626627
&self, owned_node_set: &OwnedNodeSet, trie: &DeltaMpt,
627628
guarded_trie_node: GuardedMaybeOwnedTrieNodeAsCowCallParam,
628629
key_prefix: CompressedPathRaw, db: &mut DeltaDbOwnedReadTraitObj,
629-
callback: &mut dyn FnMut(MptKeyValue),
630+
callback: &mut dyn FnMut(MptKeyValue), is_delta_mpt: bool,
631+
space_storage_filter: Option<SpaceStorageFilter>,
630632
) -> Result<()> {
633+
if let Some(filter) = space_storage_filter {
634+
if filter.is_filtered(is_delta_mpt, key_prefix.path_slice()) {
635+
return Ok(());
636+
}
637+
}
631638
if guarded_trie_node.as_ref().as_ref().has_value() {
632639
assert!(CompressedPathRaw::has_second_nibble(
633640
key_prefix.path_mask()
@@ -667,6 +674,8 @@ impl CowNodeRef {
667674
key_prefix,
668675
db,
669676
callback,
677+
is_delta_mpt,
678+
space_storage_filter,
670679
)?;
671680
}
672681

@@ -961,7 +970,7 @@ use super::{
961970
AtomicCommitTransaction, DeltaMpt, *,
962971
};
963972
use parking_lot::MutexGuard;
964-
use primitives::{MerkleHash, MptValue, MERKLE_NULL_NODE};
973+
use primitives::{MerkleHash, MptValue, SpaceStorageFilter, MERKLE_NULL_NODE};
965974
use rlp::*;
966975
use std::{
967976
borrow::BorrowMut, cell::Cell, convert::TryInto, ops::Deref,

crates/dbs/storage/src/impls/delta_mpt/subtrie_visitor.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,8 @@ impl<'trie, 'db: 'trie> SubTrieVisitor<'trie, 'db> {
636636
/// return all key/value pairs given the prefix
637637
pub fn traversal_with_callback(
638638
mut self, key: KeyPart, key_remaining: KeyPart,
639-
callback: &mut dyn FnMut(MptKeyValue),
639+
callback: &mut dyn FnMut(MptKeyValue), is_delta_mpt: bool,
640+
space_storage_filter: Option<SpaceStorageFilter>,
640641
) -> Result<()> {
641642
let node_memory_manager = self.node_memory_manager();
642643
let allocator = node_memory_manager.get_allocator();
@@ -678,7 +679,13 @@ impl<'trie, 'db: 'trie> SubTrieVisitor<'trie, 'db> {
678679
} => {
679680
drop(trie_node_ref);
680681
self.new_visitor_for_subtree(child_node.clone().into())
681-
.traversal_with_callback(key, key_remaining, callback)?;
682+
.traversal_with_callback(
683+
key,
684+
key_remaining,
685+
callback,
686+
is_delta_mpt,
687+
space_storage_filter,
688+
)?;
682689
return Ok(());
683690
}
684691
}
@@ -691,6 +698,8 @@ impl<'trie, 'db: 'trie> SubTrieVisitor<'trie, 'db> {
691698
key_prefix,
692699
&mut *self.db.get_mut().to_owned_read()?,
693700
callback,
701+
is_delta_mpt,
702+
space_storage_filter,
694703
)?;
695704
Ok(())
696705
}
@@ -919,5 +928,5 @@ use super::{
919928
ChildrenTableDeltaMpt, DeltaMpt, *,
920929
};
921930
use parking_lot::MutexGuard;
922-
use primitives::{MerkleHash, MptValue, MERKLE_NULL_NODE};
931+
use primitives::{MerkleHash, MptValue, SpaceStorageFilter, MERKLE_NULL_NODE};
923932
use std::marker::PhantomData;

crates/dbs/storage/src/impls/recording_storage.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl<Storage: StateTrait + StateTraitExt> StateTrait
5454
fn compute_state_root(&mut self) -> Result<StateRootWithAuxInfo>;
5555
fn get_state_root(&self) -> Result<StateRootWithAuxInfo>;
5656
fn commit(&mut self, epoch_id: EpochId) -> Result<StateRootWithAuxInfo>;
57-
fn read_all_with_callback(&mut self, access_key_prefix: StorageKeyWithSpace, callback: &mut dyn FnMut(MptKeyValue)) -> Result<()>;
57+
fn read_all_with_callback(&mut self, access_key_prefix: StorageKeyWithSpace, callback: &mut dyn FnMut(MptKeyValue), space_storage_filter: Option<SpaceStorageFilter>) -> Result<()>;
5858
}
5959
}
6060

@@ -102,4 +102,6 @@ use crate::{
102102
use cfx_internal_common::StateRootWithAuxInfo;
103103
use delegate::delegate;
104104
use parking_lot::Mutex;
105-
use primitives::{CheckInput, EpochId, StorageKeyWithSpace};
105+
use primitives::{
106+
CheckInput, EpochId, SpaceStorageFilter, StorageKeyWithSpace,
107+
};

crates/dbs/storage/src/impls/replicated_state.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use cfx_internal_common::StateRootWithAuxInfo;
66
use cfx_types::Space;
77
use parking_lot::Mutex;
88
use primitives::{
9-
EpochId, NodeMerkleTriplet, StaticBool, StorageKey, StorageKeyWithSpace,
9+
EpochId, NodeMerkleTriplet, SpaceStorageFilter, StaticBool, StorageKey,
10+
StorageKeyWithSpace,
1011
};
1112
use std::{
1213
sync::mpsc::{channel, Sender},
@@ -316,9 +317,13 @@ impl<Main: StateTrait> StateTrait for ReplicatedState<Main> {
316317
fn read_all_with_callback(
317318
&mut self, access_key_prefix: StorageKeyWithSpace,
318319
callback: &mut dyn FnMut(MptKeyValue),
320+
space_storage_filter: Option<SpaceStorageFilter>,
319321
) -> Result<()> {
320-
self.state
321-
.read_all_with_callback(access_key_prefix, callback)
322+
self.state.read_all_with_callback(
323+
access_key_prefix,
324+
callback,
325+
space_storage_filter,
326+
)
322327
}
323328

324329
fn compute_state_root(&mut self) -> Result<StateRootWithAuxInfo> {

crates/dbs/storage/src/impls/single_mpt_state.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::{
77
};
88
use cfx_internal_common::{StateRootAuxInfo, StateRootWithAuxInfo};
99
use primitives::{
10-
EpochId, MerkleHash, MptValue, StateRoot, StorageKeyWithSpace,
11-
MERKLE_NULL_NODE,
10+
EpochId, MerkleHash, MptValue, SpaceStorageFilter, StateRoot,
11+
StorageKeyWithSpace, MERKLE_NULL_NODE,
1212
};
1313
use rustc_hex::ToHex;
1414
use std::{cell::UnsafeCell, sync::Arc};
@@ -310,6 +310,7 @@ impl SingleMptState {
310310
fn read_all_with_callback_impl(
311311
&mut self, access_key_prefix: StorageKeyWithSpace,
312312
callback: &mut dyn FnMut(MptKeyValue),
313+
space_storage_filter: Option<SpaceStorageFilter>,
313314
) -> Result<()> {
314315
self.ensure_temp_slab_for_db_load();
315316

@@ -340,6 +341,8 @@ impl SingleMptState {
340341
&key_prefix,
341342
&key_prefix,
342343
&mut inner_callback,
344+
false,
345+
space_storage_filter,
343346
)?;
344347

345348
Ok(())
@@ -410,8 +413,13 @@ impl StateTrait for SingleMptState {
410413
fn read_all_with_callback(
411414
&mut self, access_key_prefix: StorageKeyWithSpace,
412415
callback: &mut dyn FnMut(MptKeyValue),
416+
space_storage_filter: Option<SpaceStorageFilter>,
413417
) -> Result<()> {
414-
self.read_all_with_callback_impl(access_key_prefix, callback)
418+
self.read_all_with_callback_impl(
419+
access_key_prefix,
420+
callback,
421+
space_storage_filter,
422+
)
415423
}
416424

417425
fn compute_state_root(&mut self) -> Result<StateRootWithAuxInfo> {

crates/dbs/storage/src/impls/state.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,13 @@ impl StateTrait for State {
312312
fn read_all_with_callback(
313313
&mut self, access_key_prefix: StorageKeyWithSpace,
314314
callback: &mut dyn FnMut(MptKeyValue),
315+
space_storage_filter: Option<SpaceStorageFilter>,
315316
) -> Result<()> {
316-
self.read_all_with_callback_impl(access_key_prefix, callback)
317+
self.read_all_with_callback_impl(
318+
access_key_prefix,
319+
callback,
320+
space_storage_filter,
321+
)
317322
}
318323

319324
fn compute_state_root(&mut self) -> Result<StateRootWithAuxInfo> {
@@ -990,6 +995,7 @@ impl State {
990995
pub fn read_all_with_callback_impl(
991996
&mut self, access_key_prefix: StorageKeyWithSpace,
992997
callback: &mut dyn FnMut(MptKeyValue),
998+
space_storage_filter: Option<SpaceStorageFilter>,
993999
) -> Result<()> {
9941000
self.ensure_temp_slab_for_db_load();
9951001

@@ -1033,6 +1039,8 @@ impl State {
10331039
&delta_mpt_key_prefix,
10341040
&delta_mpt_key_prefix,
10351041
&mut inner_callback,
1042+
true,
1043+
space_storage_filter,
10361044
)?;
10371045
};
10381046

@@ -1073,6 +1081,8 @@ impl State {
10731081
&intermediate_mpt_key_prefix,
10741082
&intermediate_mpt_key_prefix,
10751083
&mut inner_callback,
1084+
true,
1085+
space_storage_filter,
10761086
)?;
10771087
}
10781088
}
@@ -1121,8 +1131,8 @@ use cfx_types::AddressWithSpace;
11211131
use fallible_iterator::FallibleIterator;
11221132
use primitives::{
11231133
DeltaMptKeyPadding, EpochId, MerkleHash, MptValue, NodeMerkleTriplet,
1124-
SkipInputCheck, StateRoot, StaticBool, StorageKey, StorageKeyWithSpace,
1125-
StorageRoot, MERKLE_NULL_NODE, NULL_EPOCH,
1134+
SkipInputCheck, SpaceStorageFilter, StateRoot, StaticBool, StorageKey,
1135+
StorageKeyWithSpace, StorageRoot, MERKLE_NULL_NODE, NULL_EPOCH,
11261136
};
11271137
use rustc_hex::ToHex;
11281138
use std::{

crates/dbs/storage/src/state.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,14 @@ pub trait StateTrait: Sync + Send {
3939
&mut self, access_key_prefix: StorageKeyWithSpace,
4040
) -> Result<Option<Vec<MptKeyValue>>>;
4141

42+
/// space_storage_filter can be used to filter only the wanted contract
43+
/// storage key if you specify SpaceStorageFilter::Native, it will
44+
/// filter out the ethereum space storage key/value, by this way, we can
45+
/// speedup space key/value traversal
4246
fn read_all_with_callback(
4347
&mut self, _access_key_prefix: StorageKeyWithSpace,
4448
_callback: &mut dyn FnMut(MptKeyValue),
49+
_space_storage_filter: Option<SpaceStorageFilter>,
4550
) -> Result<()> {
4651
Err(Error::Msg("Not implemented".into()))
4752
}
@@ -90,5 +95,6 @@ use super::{
9095
};
9196
use crate::StorageRootProof;
9297
use primitives::{
93-
EpochId, NodeMerkleTriplet, StaticBool, StorageKeyWithSpace, StorageRoot,
98+
EpochId, NodeMerkleTriplet, SpaceStorageFilter, StaticBool,
99+
StorageKeyWithSpace, StorageRoot,
94100
};

crates/primitives/src/storage_key.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,62 @@ mod delta_mpt_storage_key {
739739
}
740740
}
741741

742+
// This enum is used to filter only the wanted contract storage key when
743+
// traversal the trie for example, when traverse eth space key/value, we can
744+
// only filter the eSpace storage key/value to accelerate the traversal
745+
// speed
746+
// Native means filter(keep) the native space storage key/value
747+
// Ethereum means filter(keep) the ethereum space storage key/value
748+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
749+
pub struct SpaceStorageFilter(pub Space);
750+
751+
impl From<Space> for SpaceStorageFilter {
752+
fn from(space: Space) -> Self { SpaceStorageFilter(space) }
753+
}
754+
755+
impl From<SpaceStorageFilter> for Space {
756+
fn from(filter: SpaceStorageFilter) -> Self { filter.0 }
757+
}
758+
759+
impl SpaceStorageFilter {
760+
pub fn is_native(&self) -> bool { matches!(self.0, Space::Native) }
761+
762+
pub fn is_ethereum(&self) -> bool { matches!(self.0, Space::Ethereum) }
763+
764+
// return the flag index according the trie type
765+
// if is_delta_mpt is true, then the space flag is at the 32th index
766+
// otherwise, the space flag is at the 20th index
767+
fn flag_index(&self, is_delta_mpt: bool) -> usize {
768+
if is_delta_mpt {
769+
delta_mpt_storage_key::KEY_PADDING_BYTES
770+
} else {
771+
StorageKeyWithSpace::ACCOUNT_BYTES
772+
}
773+
}
774+
775+
// return true if the key is filtered out
776+
pub fn is_filtered(&self, is_delta_mpt: bool, key: &[u8]) -> bool {
777+
let flag_index = self.flag_index(is_delta_mpt);
778+
if key.len() > flag_index {
779+
match self.0 {
780+
Space::Native => {
781+
if key[flag_index] == StorageKeyWithSpace::EVM_SPACE_TYPE[0]
782+
{
783+
return true;
784+
}
785+
}
786+
Space::Ethereum => {
787+
if key[flag_index] != StorageKeyWithSpace::EVM_SPACE_TYPE[0]
788+
{
789+
return true;
790+
}
791+
}
792+
}
793+
}
794+
false
795+
}
796+
}
797+
742798
use super::{MerkleHash, MERKLE_NULL_NODE};
743799
use crate::{
744800
hash::keccak, storage_key::delta_mpt_storage_key::ACCOUNT_KEYPART_BYTES,

0 commit comments

Comments
 (0)