Skip to content

Commit 51915df

Browse files
committed
optimize contract storage read method
1 parent 355829f commit 51915df

File tree

10 files changed

+75
-60
lines changed

10 files changed

+75
-60
lines changed

crates/client/src/state_dump.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ use cfx_rpc_eth_types::{AccountState, StateDump, EOA_STORAGE_ROOT_H256};
44
use cfx_rpc_primitives::Bytes;
55
use cfx_statedb::{StateDbExt, StateDbGeneric};
66
use cfx_storage::state_manager::StateManagerTrait;
7-
use cfx_types::{Address, Space, H256};
7+
use cfx_types::{Address, Space, H256, U256};
88
use cfxcore::NodeType;
99
use chrono::Utc;
1010
use keccak_hash::{keccak, KECCAK_EMPTY};
1111
use parking_lot::{Condvar, Mutex};
1212
use primitives::{
13-
Account, SkipInputCheck, SpaceStorageFilter, StorageKey,
14-
StorageKeyWithSpace, StorageValue,
13+
Account, SkipInputCheck, StorageKey, StorageKeyWithSpace, StorageValue,
1514
};
1615
use rlp::Rlp;
1716
use std::{
@@ -260,7 +259,7 @@ pub fn export_space_accounts_with_callback<F: Fn(AccountState)>(
260259
let mut core_space_key_count: u64 = 0;
261260
let mut total_key_count: u64 = 0;
262261

263-
for i in 0..=255 {
262+
for i in 198..=255 {
264263
let prefix = [i];
265264
let start_key = StorageKey::AddressPrefixKey(&prefix).with_space(space);
266265

@@ -295,18 +294,15 @@ pub fn export_space_accounts_with_callback<F: Fn(AccountState)>(
295294
}
296295
};
297296

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

304299
if account_states.len() > 0 {
305300
println("Start to read account code and storage data...");
306301
}
307302

308303
for (_address, account) in account_states {
309-
let account_state = get_account_state(state, &account, config)?;
304+
let account_state =
305+
get_account_state(state, &account, config, space)?;
310306
callback(account_state);
311307
found_accounts += 1;
312308
if config.limit > 0 && found_accounts >= config.limit as usize {
@@ -321,6 +317,7 @@ pub fn export_space_accounts_with_callback<F: Fn(AccountState)>(
321317
#[allow(unused)]
322318
fn get_account_state(
323319
state: &mut StateDbGeneric, account: &Account, config: &StateDumpConfig,
320+
space: Space,
324321
) -> Result<AccountState, Box<dyn std::error::Error>> {
325322
let address = account.address();
326323

@@ -335,7 +332,7 @@ fn get_account_state(
335332
};
336333

337334
let storage = if is_contract && !config.no_storage {
338-
let storage = state.get_account_storage_entries(&address, None)?;
335+
let storage = get_contract_storage(state, &address.address, space)?;
339336
Some(storage)
340337
} else {
341338
None
@@ -358,6 +355,36 @@ fn get_account_state(
358355
})
359356
}
360357

358+
fn get_contract_storage(
359+
state: &mut StateDbGeneric, address: &Address, space: Space,
360+
) -> Result<BTreeMap<H256, U256>, Box<dyn std::error::Error>> {
361+
let mut storage: BTreeMap<H256, U256> = Default::default();
362+
363+
let mut inner_callback = |(key, value): (Vec<u8>, Box<[u8]>)| {
364+
let storage_key_with_space =
365+
StorageKeyWithSpace::from_key_bytes::<SkipInputCheck>(&key);
366+
if storage_key_with_space.space != space {
367+
return;
368+
}
369+
370+
if let StorageKey::StorageKey {
371+
address_bytes: _,
372+
storage_key,
373+
} = storage_key_with_space.key
374+
{
375+
let h256_storage_key = H256::from_slice(storage_key);
376+
let storage_value_with_owner: StorageValue =
377+
rlp::decode(&value).expect("Failed to decode storage value");
378+
storage.insert(h256_storage_key, storage_value_with_owner.value);
379+
};
380+
};
381+
382+
let start_key = StorageKey::new_storage_root_key(address).with_space(space);
383+
state.read_all_with_callback(start_key, &mut inner_callback, false)?;
384+
385+
Ok(storage)
386+
}
387+
361388
fn println(message: &str) {
362389
println!("[{}] {}", Utc::now().format("%Y-%m-%d %H:%M:%S"), message);
363390
}

crates/dbs/statedb/src/lib.rs

Lines changed: 3 additions & 4 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::{SpaceStorageFilter, StorageValue};
15+
use primitives::StorageValue;
1616

1717
use cfx_db_errors::statedb as error;
1818

@@ -190,14 +190,13 @@ mod impls {
190190

191191
pub fn read_all_with_callback(
192192
&mut self, access_key_prefix: StorageKeyWithSpace,
193-
callback: &mut dyn FnMut(MptKeyValue),
194-
space_storage_filter: Option<SpaceStorageFilter>,
193+
callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool,
195194
) -> Result<()> {
196195
self.storage
197196
.read_all_with_callback(
198197
access_key_prefix,
199198
callback,
200-
space_storage_filter,
199+
only_account_key,
201200
)
202201
.map_err(|err| err.into())
203202
}

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

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

625-
// space_storage_filter can be used to filter the wanted space storage keys
625+
// only_account_key can be used to filter the only account key
626626
pub fn iterate_internal_with_callback(
627627
&self, owned_node_set: &OwnedNodeSet, trie: &DeltaMpt,
628628
guarded_trie_node: GuardedMaybeOwnedTrieNodeAsCowCallParam,
629629
key_prefix: CompressedPathRaw, db: &mut DeltaDbOwnedReadTraitObj,
630630
callback: &mut dyn FnMut(MptKeyValue), is_delta_mpt: bool,
631-
space_storage_filter: Option<SpaceStorageFilter>,
631+
only_account_key: bool,
632632
) -> Result<()> {
633-
if let Some(filter) = space_storage_filter {
634-
if filter.is_filtered(is_delta_mpt, key_prefix.path_slice()) {
633+
// filter out all the key that is longer than the account key
634+
if only_account_key {
635+
let key_len =
636+
SpaceStorageFilter::space_flag_index(is_delta_mpt) + 1;
637+
if key_prefix.path_slice().len() > key_len {
635638
return Ok(());
636639
}
637640
}
@@ -675,7 +678,7 @@ impl CowNodeRef {
675678
db,
676679
callback,
677680
is_delta_mpt,
678-
space_storage_filter,
681+
only_account_key,
679682
)?;
680683
}
681684

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ impl<'trie, 'db: 'trie> SubTrieVisitor<'trie, 'db> {
637637
pub fn traversal_with_callback(
638638
mut self, key: KeyPart, key_remaining: KeyPart,
639639
callback: &mut dyn FnMut(MptKeyValue), is_delta_mpt: bool,
640-
space_storage_filter: Option<SpaceStorageFilter>,
640+
only_account_key: bool,
641641
) -> Result<()> {
642642
let node_memory_manager = self.node_memory_manager();
643643
let allocator = node_memory_manager.get_allocator();
@@ -684,7 +684,7 @@ impl<'trie, 'db: 'trie> SubTrieVisitor<'trie, 'db> {
684684
key_remaining,
685685
callback,
686686
is_delta_mpt,
687-
space_storage_filter,
687+
only_account_key,
688688
)?;
689689
return Ok(());
690690
}
@@ -699,7 +699,7 @@ impl<'trie, 'db: 'trie> SubTrieVisitor<'trie, 'db> {
699699
&mut *self.db.get_mut().to_owned_read()?,
700700
callback,
701701
is_delta_mpt,
702-
space_storage_filter,
702+
only_account_key,
703703
)?;
704704
Ok(())
705705
}
@@ -928,5 +928,5 @@ use super::{
928928
ChildrenTableDeltaMpt, DeltaMpt, *,
929929
};
930930
use parking_lot::MutexGuard;
931-
use primitives::{MerkleHash, MptValue, SpaceStorageFilter, MERKLE_NULL_NODE};
931+
use primitives::{MerkleHash, MptValue, MERKLE_NULL_NODE};
932932
use std::marker::PhantomData;

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

Lines changed: 2 additions & 4 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), space_storage_filter: Option<SpaceStorageFilter>) -> Result<()>;
57+
fn read_all_with_callback(&mut self, access_key_prefix: StorageKeyWithSpace, callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool) -> Result<()>;
5858
}
5959
}
6060

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

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use cfx_internal_common::StateRootWithAuxInfo;
66
use cfx_types::Space;
77
use parking_lot::Mutex;
88
use primitives::{
9-
EpochId, NodeMerkleTriplet, SpaceStorageFilter, StaticBool, StorageKey,
10-
StorageKeyWithSpace,
9+
EpochId, NodeMerkleTriplet, StaticBool, StorageKey, StorageKeyWithSpace,
1110
};
1211
use std::{
1312
sync::mpsc::{channel, Sender},
@@ -316,13 +315,12 @@ impl<Main: StateTrait> StateTrait for ReplicatedState<Main> {
316315

317316
fn read_all_with_callback(
318317
&mut self, access_key_prefix: StorageKeyWithSpace,
319-
callback: &mut dyn FnMut(MptKeyValue),
320-
space_storage_filter: Option<SpaceStorageFilter>,
318+
callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool,
321319
) -> Result<()> {
322320
self.state.read_all_with_callback(
323321
access_key_prefix,
324322
callback,
325-
space_storage_filter,
323+
only_account_key,
326324
)
327325
}
328326

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

Lines changed: 6 additions & 8 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, SpaceStorageFilter, StateRoot,
11-
StorageKeyWithSpace, MERKLE_NULL_NODE,
10+
EpochId, MerkleHash, MptValue, StateRoot, StorageKeyWithSpace,
11+
MERKLE_NULL_NODE,
1212
};
1313
use rustc_hex::ToHex;
1414
use std::{cell::UnsafeCell, sync::Arc};
@@ -309,8 +309,7 @@ impl SingleMptState {
309309

310310
fn read_all_with_callback_impl(
311311
&mut self, access_key_prefix: StorageKeyWithSpace,
312-
callback: &mut dyn FnMut(MptKeyValue),
313-
space_storage_filter: Option<SpaceStorageFilter>,
312+
callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool,
314313
) -> Result<()> {
315314
self.ensure_temp_slab_for_db_load();
316315

@@ -342,7 +341,7 @@ impl SingleMptState {
342341
&key_prefix,
343342
&mut inner_callback,
344343
false,
345-
space_storage_filter,
344+
only_account_key,
346345
)?;
347346

348347
Ok(())
@@ -412,13 +411,12 @@ impl StateTrait for SingleMptState {
412411

413412
fn read_all_with_callback(
414413
&mut self, access_key_prefix: StorageKeyWithSpace,
415-
callback: &mut dyn FnMut(MptKeyValue),
416-
space_storage_filter: Option<SpaceStorageFilter>,
414+
callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool,
417415
) -> Result<()> {
418416
self.read_all_with_callback_impl(
419417
access_key_prefix,
420418
callback,
421-
space_storage_filter,
419+
only_account_key,
422420
)
423421
}
424422

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,12 @@ impl StateTrait for State {
311311

312312
fn read_all_with_callback(
313313
&mut self, access_key_prefix: StorageKeyWithSpace,
314-
callback: &mut dyn FnMut(MptKeyValue),
315-
space_storage_filter: Option<SpaceStorageFilter>,
314+
callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool,
316315
) -> Result<()> {
317316
self.read_all_with_callback_impl(
318317
access_key_prefix,
319318
callback,
320-
space_storage_filter,
319+
only_account_key,
321320
)
322321
}
323322

@@ -994,8 +993,7 @@ impl State {
994993

995994
pub fn read_all_with_callback_impl(
996995
&mut self, access_key_prefix: StorageKeyWithSpace,
997-
callback: &mut dyn FnMut(MptKeyValue),
998-
space_storage_filter: Option<SpaceStorageFilter>,
996+
callback: &mut dyn FnMut(MptKeyValue), only_account_key: bool,
999997
) -> Result<()> {
1000998
self.ensure_temp_slab_for_db_load();
1001999

@@ -1040,7 +1038,7 @@ impl State {
10401038
&delta_mpt_key_prefix,
10411039
&mut inner_callback,
10421040
true,
1043-
space_storage_filter,
1041+
only_account_key,
10441042
)?;
10451043
};
10461044

@@ -1082,7 +1080,7 @@ impl State {
10821080
&intermediate_mpt_key_prefix,
10831081
&mut inner_callback,
10841082
true,
1085-
space_storage_filter,
1083+
only_account_key,
10861084
)?;
10871085
}
10881086
}
@@ -1131,8 +1129,8 @@ use cfx_types::AddressWithSpace;
11311129
use fallible_iterator::FallibleIterator;
11321130
use primitives::{
11331131
DeltaMptKeyPadding, EpochId, MerkleHash, MptValue, NodeMerkleTriplet,
1134-
SkipInputCheck, SpaceStorageFilter, StateRoot, StaticBool, StorageKey,
1135-
StorageKeyWithSpace, StorageRoot, MERKLE_NULL_NODE, NULL_EPOCH,
1132+
SkipInputCheck, StateRoot, StaticBool, StorageKey, StorageKeyWithSpace,
1133+
StorageRoot, MERKLE_NULL_NODE, NULL_EPOCH,
11361134
};
11371135
use rustc_hex::ToHex;
11381136
use std::{

crates/dbs/storage/src/state.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,9 @@ 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
4642
fn read_all_with_callback(
4743
&mut self, _access_key_prefix: StorageKeyWithSpace,
48-
_callback: &mut dyn FnMut(MptKeyValue),
49-
_space_storage_filter: Option<SpaceStorageFilter>,
44+
_callback: &mut dyn FnMut(MptKeyValue), _only_account_key: bool,
5045
) -> Result<()> {
5146
Err(Error::Msg("Not implemented".into()))
5247
}
@@ -95,6 +90,5 @@ use super::{
9590
};
9691
use crate::StorageRootProof;
9792
use primitives::{
98-
EpochId, NodeMerkleTriplet, SpaceStorageFilter, StaticBool,
99-
StorageKeyWithSpace, StorageRoot,
93+
EpochId, NodeMerkleTriplet, StaticBool, StorageKeyWithSpace, StorageRoot,
10094
};

crates/primitives/src/storage_key.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ impl SpaceStorageFilter {
764764
// return the flag index according the trie type
765765
// if is_delta_mpt is true, then the space flag is at the 32th index
766766
// otherwise, the space flag is at the 20th index
767-
fn flag_index(&self, is_delta_mpt: bool) -> usize {
767+
pub fn space_flag_index(is_delta_mpt: bool) -> usize {
768768
if is_delta_mpt {
769769
delta_mpt_storage_key::KEY_PADDING_BYTES
770770
} else {
@@ -774,7 +774,7 @@ impl SpaceStorageFilter {
774774

775775
// return true if the key is filtered out
776776
pub fn is_filtered(&self, is_delta_mpt: bool, key: &[u8]) -> bool {
777-
let flag_index = self.flag_index(is_delta_mpt);
777+
let flag_index = Self::space_flag_index(is_delta_mpt);
778778
if key.len() > flag_index {
779779
match self.0 {
780780
Space::Native => {

0 commit comments

Comments
 (0)