Skip to content

Commit 2b0f6ca

Browse files
committed
Boost the speed of get_storages_changes with rayon
1 parent fd3f474 commit 2b0f6ca

File tree

3 files changed

+56
-47
lines changed

3 files changed

+56
-47
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/phala-node-rpc-ext/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,5 @@ phala-pallets = { path = "../../pallets/phala" }
3535
pallet-mq-runtime-api = { path = "../../pallets/phala/mq-runtime-api" }
3636
ext-types = { path = "./types", package = "phala-node-rpc-ext-types" }
3737

38+
rayon = "1"
39+

crates/phala-node-rpc-ext/src/storage_changes.rs

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::*;
22
pub use ext_types::*;
3+
use rayon::prelude::*;
34

45
/// State RPC errors.
56
#[derive(Debug, thiserror::Error)]
@@ -86,63 +87,68 @@ where
8687
return Err(Error::ResourceLimited("Too large number of blocks".into()));
8788
}
8889

89-
let api = client.runtime_api();
90-
let mut changes = vec![];
90+
let mut headers = std::collections::VecDeque::new();
91+
9192
let mut this_block = to;
9293

9394
loop {
9495
let id = BlockId::Hash(this_block);
95-
let mut header = header(client, id)?;
96-
let extrinsics = client
97-
.block_body(&id)
98-
.map_err(|e| Error::invalid_block(id, e))?
99-
.ok_or_else(|| Error::invalid_block(id, "block body not found"))?;
100-
let parent_hash = *header.parent_hash();
101-
let parent_id = BlockId::Hash(parent_hash);
102-
103-
if (*header.number()).into() == 0u64 {
104-
let state = backend
105-
.state_at(id)
106-
.map_err(|e| Error::invalid_block(parent_id, e))?;
107-
changes.push(StorageChanges {
108-
main_storage_changes: state
109-
.pairs()
110-
.into_iter()
111-
.map(|(k, v)| (StorageKey(k), Some(StorageKey(v))))
112-
.collect(),
113-
child_storage_changes: vec![],
114-
});
96+
let header = header(client, id)?;
97+
let parent = *header.parent_hash();
98+
headers.push_front((id, header));
99+
if this_block == from {
115100
break;
116101
}
102+
this_block = parent;
103+
}
117104

118-
// Remove all `Seal`s as they are added by the consensus engines after building the block.
119-
// On import they are normally removed by the consensus engine.
120-
header.digest_mut().logs.retain(|d| d.as_seal().is_none());
121-
122-
let block = Block::new(header, extrinsics);
123-
api.execute_block(&parent_id, block)
124-
.map_err(|e| Error::invalid_block(id, e))?;
105+
headers
106+
.into_par_iter()
107+
.map(|(id, mut header)| -> Result<_, Error> {
108+
let api = client.runtime_api();
109+
if (*header.number()).into() == 0u64 {
110+
let state = backend
111+
.state_at(id)
112+
.map_err(|e| Error::invalid_block(id, e))?;
113+
return Ok(StorageChanges {
114+
main_storage_changes: state
115+
.pairs()
116+
.into_iter()
117+
.map(|(k, v)| (StorageKey(k), Some(StorageKey(v))))
118+
.collect(),
119+
child_storage_changes: vec![],
120+
});
121+
}
122+
123+
let extrinsics = client
124+
.block_body(&id)
125+
.map_err(|e| Error::invalid_block(id, e))?
126+
.ok_or_else(|| Error::invalid_block(id, "block body not found"))?;
127+
let parent_hash = *header.parent_hash();
128+
let parent_id = BlockId::Hash(parent_hash);
129+
130+
// Remove all `Seal`s as they are added by the consensus engines after building the block.
131+
// On import they are normally removed by the consensus engine.
132+
header.digest_mut().logs.retain(|d| d.as_seal().is_none());
133+
134+
let block = Block::new(header, extrinsics);
135+
api.execute_block(&parent_id, block)
136+
.map_err(|e| Error::invalid_block(id, e))?;
125137

126-
let state = backend
127-
.state_at(parent_id)
128-
.map_err(|e| Error::invalid_block(parent_id, e))?;
138+
let state = backend
139+
.state_at(parent_id)
140+
.map_err(|e| Error::invalid_block(parent_id, e))?;
129141

130-
let storage_changes = api
131-
.into_storage_changes(&state, parent_hash)
132-
.map_err(|e| Error::invalid_block(parent_id, e))?;
142+
let storage_changes = api
143+
.into_storage_changes(&state, parent_hash)
144+
.map_err(|e| Error::invalid_block(parent_id, e))?;
133145

134-
changes.push(StorageChanges {
135-
main_storage_changes: storage_changes.main_storage_changes.into_(),
136-
child_storage_changes: storage_changes.child_storage_changes.into_(),
137-
});
138-
if this_block == from {
139-
break;
140-
} else {
141-
this_block = parent_hash;
142-
}
143-
}
144-
changes.reverse();
145-
Ok(changes)
146+
Ok(StorageChanges {
147+
main_storage_changes: storage_changes.main_storage_changes.into_(),
148+
child_storage_changes: storage_changes.child_storage_changes.into_(),
149+
})
150+
})
151+
.collect()
146152
}
147153

148154
// Stuffs to convert ChildStorageCollection and StorageCollection types,

0 commit comments

Comments
 (0)