Skip to content

Commit 7bee403

Browse files
committed
split state dump into multiple task
1 parent 9b43388 commit 7bee403

File tree

4 files changed

+116
-35
lines changed

4 files changed

+116
-35
lines changed

crates/client/src/state_dump.rs

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -276,45 +276,52 @@ pub fn export_space_accounts_with_callback<F: Fn(AccountState)>(
276276
"[{}] Start to iterate state...",
277277
Utc::now().format("%Y-%m-%d %H:%M:%S")
278278
);
279-
let mut account_states = BTreeMap::new();
280279

281-
let mut inner_callback = |(key, value): (Vec<u8>, Box<[u8]>)| {
282-
let storage_key_with_space =
283-
StorageKeyWithSpace::from_key_bytes::<SkipInputCheck>(&key);
284-
if storage_key_with_space.space != space {
285-
return;
286-
}
280+
for i in 0..=255 {
281+
let prefix = [i];
282+
let start_key = StorageKey::AddressPrefixKey(&prefix).with_space(space);
287283

288-
if let StorageKey::AccountKey(address_bytes) =
289-
storage_key_with_space.key
290-
{
291-
let address = Address::from_slice(address_bytes);
292-
println!(
293-
"[{}] Find account: {:?}",
294-
Utc::now().format("%Y-%m-%d %H:%M:%S"),
295-
address
296-
);
297-
let account = Account::new_from_rlp(address, &Rlp::new(&value))
298-
.expect("Failed to decode account");
284+
let mut account_states = BTreeMap::new();
299285

300-
account_states.insert(address, account);
301-
}
302-
};
286+
let mut inner_callback = |(key, value): (Vec<u8>, Box<[u8]>)| {
287+
let storage_key_with_space =
288+
StorageKeyWithSpace::from_key_bytes::<SkipInputCheck>(&key);
289+
if storage_key_with_space.space != space {
290+
return;
291+
}
303292

304-
let empty_key = StorageKey::EmptyKey.with_space(space);
305-
state.read_all_with_callback(empty_key, &mut inner_callback)?;
293+
if let StorageKey::AccountKey(address_bytes) =
294+
storage_key_with_space.key
295+
{
296+
let address = Address::from_slice(address_bytes);
297+
println!(
298+
"[{}] Find account: {:?}",
299+
Utc::now().format("%Y-%m-%d %H:%M:%S"),
300+
address
301+
);
302+
let account = Account::new_from_rlp(address, &Rlp::new(&value))
303+
.expect("Failed to decode account");
306304

307-
println!(
308-
"[{}] Start to read account code and storage data...",
309-
Utc::now().format("%Y-%m-%d %H:%M:%S")
310-
);
311-
let mut found_accounts = 0;
312-
for (_address, account) in account_states {
313-
let account_state = get_account_state(state, &account, config)?;
314-
callback(account_state);
315-
found_accounts += 1;
316-
if config.limit > 0 && found_accounts >= config.limit as usize {
317-
break;
305+
account_states.insert(address, account);
306+
}
307+
};
308+
309+
state.read_all_with_callback(start_key, &mut inner_callback)?;
310+
311+
if account_states.len() > 0 {
312+
println!(
313+
"[{}] Start to read account code and storage data...",
314+
Utc::now().format("%Y-%m-%d %H:%M:%S")
315+
);
316+
}
317+
let mut found_accounts = 0;
318+
for (_address, account) in account_states {
319+
let account_state = get_account_state(state, &account, config)?;
320+
callback(account_state);
321+
found_accounts += 1;
322+
if config.limit > 0 && found_accounts >= config.limit as usize {
323+
break;
324+
}
318325
}
319326
}
320327

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ enum OwnedStorageKey {
161161
DepositListKey(Vec<u8>),
162162
VoteListKey(Vec<u8>),
163163
EmptyKey,
164+
AddressPrefixKey(Vec<u8>),
164165
}
165166

166167
impl OwnedStorageKey {
@@ -196,6 +197,9 @@ impl OwnedStorageKey {
196197
StorageKey::VoteListKey(k.as_slice())
197198
}
198199
OwnedStorageKey::EmptyKey => StorageKey::EmptyKey,
200+
OwnedStorageKey::AddressPrefixKey(k) => {
201+
StorageKey::AddressPrefixKey(k.as_slice())
202+
}
199203
}
200204
}
201205
}
@@ -248,6 +252,9 @@ impl<'a> From<StorageKey<'a>> for OwnedStorageKey {
248252
OwnedStorageKey::VoteListKey(k.to_vec())
249253
}
250254
StorageKey::EmptyKey => OwnedStorageKey::EmptyKey,
255+
StorageKey::AddressPrefixKey(k) => {
256+
OwnedStorageKey::AddressPrefixKey(k.to_vec())
257+
}
251258
}
252259
}
253260
}

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

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,13 +909,30 @@ impl State {
909909
snapshot_kvs.push((key, value));
910910
}
911911

912+
let is_address_search_prefix =
913+
if let StorageKey::AddressPrefixKey(prefix) = access_key_prefix.key
914+
{
915+
Some(prefix)
916+
} else {
917+
None
918+
};
919+
912920
let mut result = Vec::new();
913921
// This is used to keep track of the deleted keys.
914922
let mut deleted_keys = HashSet::new();
915923
if let Some(kvs) = delta_trie_kvs {
916924
for (k, v) in kvs {
917925
let storage_key = StorageKeyWithSpace::from_delta_mpt_key(&k);
918926
let k = storage_key.to_key_bytes();
927+
928+
// If it's an address search prefix, and k is not start with
929+
// prefix, skip the key.
930+
if let Some(prefix) = is_address_search_prefix {
931+
if !k.starts_with(prefix) {
932+
continue;
933+
}
934+
}
935+
919936
deleted_keys.insert(k.clone());
920937
if v.len() > 0 {
921938
result.push((k, v));
@@ -926,11 +943,21 @@ impl State {
926943
if let Some(kvs) = intermediate_trie_kvs {
927944
for (k, v) in kvs {
928945
let storage_key = StorageKeyWithSpace::from_delta_mpt_key(&k);
946+
let k = storage_key.to_key_bytes();
947+
948+
// If it's an address search prefix, and k is not start with
949+
// prefix, skip the key.
950+
if let Some(prefix) = is_address_search_prefix {
951+
if !k.starts_with(prefix) {
952+
continue;
953+
}
954+
}
955+
929956
// Only delete non-empty keys.
930957
if v.len() > 0 && !AM::READ_ONLY {
931958
self.delete(storage_key)?;
932959
}
933-
let k = storage_key.to_key_bytes();
960+
934961
if !deleted_keys.contains(&k) {
935962
deleted_keys.insert(k.clone());
936963
if v.len() > 0 {
@@ -966,6 +993,14 @@ impl State {
966993
) -> Result<()> {
967994
self.ensure_temp_slab_for_db_load();
968995

996+
let is_address_search_prefix =
997+
if let StorageKey::AddressPrefixKey(prefix) = access_key_prefix.key
998+
{
999+
Some(prefix)
1000+
} else {
1001+
None
1002+
};
1003+
9691004
// This is used to keep track of the deleted keys.
9701005
let mut deleted_keys = HashSet::new();
9711006

@@ -974,6 +1009,14 @@ impl State {
9741009
let mut inner_callback = |(k, v): MptKeyValue| {
9751010
let storage_key = StorageKeyWithSpace::from_delta_mpt_key(&k);
9761011
let k = storage_key.to_key_bytes();
1012+
1013+
// If it's an address search prefix, and k is not start with
1014+
// prefix, skip the key.
1015+
if let Some(prefix) = is_address_search_prefix {
1016+
if !k.starts_with(prefix) {
1017+
return;
1018+
}
1019+
}
9771020
deleted_keys.insert(k.clone());
9781021
if v.len() > 0 {
9791022
callback((k, v));
@@ -998,6 +1041,15 @@ impl State {
9981041
let mut inner_callback = |(k, v): MptKeyValue| {
9991042
let storage_key = StorageKeyWithSpace::from_delta_mpt_key(&k);
10001043
let k = storage_key.to_key_bytes();
1044+
1045+
// If it's an address search prefix, and k is not start with
1046+
// prefix, skip the key.
1047+
if let Some(prefix) = is_address_search_prefix {
1048+
if !k.starts_with(prefix) {
1049+
return;
1050+
}
1051+
}
1052+
10011053
if !deleted_keys.contains(&k) {
10021054
deleted_keys.insert(k.clone());
10031055
if v.len() > 0 {

crates/primitives/src/storage_key.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pub enum StorageKey<'a> {
6060
VoteListKey(&'a [u8]),
6161
// Empty key is used to traverse all key and value pairs.
6262
EmptyKey,
63+
// Address prefix key is used to search all keys with the same address
64+
// prefix, eg [1, 2](0x0102) will search all keys with prefix 0x0102
65+
AddressPrefixKey(&'a [u8]),
6366
}
6467

6568
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -200,6 +203,13 @@ impl<'a> StorageKeyWithSpace<'a> {
200203
StorageKey::EmptyKey => {
201204
return vec![];
202205
}
206+
StorageKey::AddressPrefixKey(_address_bytes) => {
207+
// delta mpt trie does not support address prefix key search
208+
// so we search all keys and filter them by address prefix
209+
// due to delta mpt trie won't be very big, so the performance
210+
// impact is not very big
211+
return vec![];
212+
}
203213
};
204214

205215
return if self.space == Space::Native {
@@ -292,6 +302,11 @@ impl<'a> StorageKeyWithSpace<'a> {
292302
StorageKey::EmptyKey => {
293303
return vec![];
294304
}
305+
StorageKey::AddressPrefixKey(address_bytes) => {
306+
let mut key = Vec::with_capacity(address_bytes.len());
307+
key.extend_from_slice(address_bytes);
308+
return key;
309+
}
295310
};
296311

297312
return if self.space == Space::Native {

0 commit comments

Comments
 (0)