Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit b79e2b9

Browse files
authored
Fetch runtime code from storage cache when using proofing backend (#9611)
Before we fetched the runtime code from the `TrieBackend` and this lead to not using the storage cache. Thus, we recalculated the storage hash for the runtime code on every call into the runtime and this killed the performance on parachains block authoring. The solution is to fetch the runtime code from the storage cache, to make sure we use the cached storage cache.
1 parent 16e17ae commit b79e2b9

File tree

11 files changed

+31
-41
lines changed

11 files changed

+31
-41
lines changed

client/api/src/cht.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ where
117117
.into_iter()
118118
.map(|(k, v)| (k, Some(v)))
119119
.collect::<Vec<_>>();
120-
let mut storage = InMemoryBackend::<Hasher>::default().update(vec![(None, transaction)]);
120+
let storage = InMemoryBackend::<Hasher>::default().update(vec![(None, transaction)]);
121121
let trie_storage = storage
122122
.as_trie_backend()
123123
.expect("InMemoryState::as_trie_backend always returns Some; qed");

client/db/src/bench.rs

-6
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,6 @@ impl<B: BlockT> StateBackend<HashFor<B>> for BenchmarkingState<B> {
454454
.map_or(Default::default(), |s| s.child_keys(child_info, prefix))
455455
}
456456

457-
fn as_trie_backend(
458-
&mut self,
459-
) -> Option<&sp_state_machine::TrieBackend<Self::TrieBackendStorage, HashFor<B>>> {
460-
None
461-
}
462-
463457
fn commit(
464458
&self,
465459
storage_root: <HashFor<B> as Hasher>::Out,

client/db/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<B: BlockT> StateBackend<HashFor<B>> for RefTrackingState<B> {
274274
}
275275

276276
fn as_trie_backend(
277-
&mut self,
277+
&self,
278278
) -> Option<&sp_state_machine::TrieBackend<Self::TrieBackendStorage, HashFor<B>>> {
279279
self.state.as_trie_backend()
280280
}

client/db/src/storage_cache.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ impl<S: StateBackend<HashFor<B>>, B: BlockT> StateBackend<HashFor<B>> for Cachin
703703
self.state.child_keys(child_info, prefix)
704704
}
705705

706-
fn as_trie_backend(&mut self) -> Option<&TrieBackend<Self::TrieBackendStorage, HashFor<B>>> {
706+
fn as_trie_backend(&self) -> Option<&TrieBackend<Self::TrieBackendStorage, HashFor<B>>> {
707707
self.state.as_trie_backend()
708708
}
709709

@@ -901,9 +901,9 @@ impl<S: StateBackend<HashFor<B>>, B: BlockT> StateBackend<HashFor<B>>
901901
self.caching_state().child_keys(child_info, prefix)
902902
}
903903

904-
fn as_trie_backend(&mut self) -> Option<&TrieBackend<Self::TrieBackendStorage, HashFor<B>>> {
904+
fn as_trie_backend(&self) -> Option<&TrieBackend<Self::TrieBackendStorage, HashFor<B>>> {
905905
self.caching_state
906-
.as_mut()
906+
.as_ref()
907907
.expect("`caching_state` is valid for the lifetime of the object; qed")
908908
.as_trie_backend()
909909
}

client/light/src/backend.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,9 @@ where
569569
sp_state_machine::UsageInfo::empty()
570570
}
571571

572-
fn as_trie_backend(&mut self) -> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
572+
fn as_trie_backend(&self) -> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
573573
match self {
574-
GenesisOrUnavailableState::Genesis(ref mut state) => state.as_trie_backend(),
574+
GenesisOrUnavailableState::Genesis(ref state) => state.as_trie_backend(),
575575
GenesisOrUnavailableState::Unavailable => None,
576576
}
577577
}

client/service/src/client/call_executor.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -212,29 +212,30 @@ where
212212
backend::changes_tries_state_at_block(at, self.backend.changes_trie_storage())?;
213213
let mut storage_transaction_cache = storage_transaction_cache.map(|c| c.borrow_mut());
214214

215-
let mut state = self.backend.state_at(*at)?;
215+
let state = self.backend.state_at(*at)?;
216216

217217
let changes = &mut *changes.borrow_mut();
218218

219219
let at_hash = self.backend.blockchain().block_hash_from_id(at)?.ok_or_else(|| {
220220
sp_blockchain::Error::UnknownBlock(format!("Could not find block hash for {:?}", at))
221221
})?;
222222

223+
// It is important to extract the runtime code here before we create the proof
224+
// recorder to not record it. We also need to fetch the runtime code from `state` to
225+
// make sure we use the caching layers.
226+
let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);
227+
228+
let runtime_code =
229+
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
230+
let runtime_code = self.check_override(runtime_code, at)?;
231+
223232
match recorder {
224233
Some(recorder) => {
225234
let trie_state = state.as_trie_backend().ok_or_else(|| {
226235
Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof)
227236
as Box<dyn sp_state_machine::Error>
228237
})?;
229238

230-
let state_runtime_code =
231-
sp_state_machine::backend::BackendRuntimeCode::new(trie_state);
232-
// It is important to extract the runtime code here before we create the proof
233-
// recorder.
234-
let runtime_code =
235-
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
236-
let runtime_code = self.check_override(runtime_code, at)?;
237-
238239
let backend = sp_state_machine::ProvingBackend::new_with_recorder(
239240
trie_state,
240241
recorder.clone(),
@@ -259,11 +260,6 @@ where
259260
)
260261
},
261262
None => {
262-
let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(&state);
263-
let runtime_code =
264-
state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?;
265-
let runtime_code = self.check_override(runtime_code, at)?;
266-
267263
let mut state_machine = StateMachine::new(
268264
&state,
269265
changes_trie_state,
@@ -309,7 +305,7 @@ where
309305
method: &str,
310306
call_data: &[u8],
311307
) -> sp_blockchain::Result<(Vec<u8>, StorageProof)> {
312-
let mut state = self.backend.state_at(*at)?;
308+
let state = self.backend.state_at(*at)?;
313309

314310
let trie_backend = state.as_trie_backend().ok_or_else(|| {
315311
Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof)

primitives/state-machine/src/backend.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ pub trait Backend<H: Hasher>: sp_std::fmt::Debug {
173173
}
174174

175175
/// Try convert into trie backend.
176-
fn as_trie_backend(&mut self) -> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
176+
fn as_trie_backend(&self) -> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
177177
None
178178
}
179179

primitives/state-machine/src/in_memory_backend.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ mod tests {
175175
let storage = new_in_mem::<BlakeTwo256>();
176176
let child_info = ChildInfo::new_default(b"1");
177177
let child_info = &child_info;
178-
let mut storage = storage
178+
let storage = storage
179179
.update(vec![(Some(child_info.clone()), vec![(b"2".to_vec(), Some(b"3".to_vec()))])]);
180180
let trie_backend = storage.as_trie_backend().unwrap();
181181
assert_eq!(trie_backend.child_storage(child_info, b"2").unwrap(), Some(b"3".to_vec()));

primitives/state-machine/src/lib.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ mod execution {
719719
}
720720

721721
/// Generate storage read proof.
722-
pub fn prove_read<B, H, I>(mut backend: B, keys: I) -> Result<StorageProof, Box<dyn Error>>
722+
pub fn prove_read<B, H, I>(backend: B, keys: I) -> Result<StorageProof, Box<dyn Error>>
723723
where
724724
B: Backend<H>,
725725
H: Hasher,
@@ -735,7 +735,7 @@ mod execution {
735735

736736
/// Generate range storage read proof.
737737
pub fn prove_range_read_with_size<B, H>(
738-
mut backend: B,
738+
backend: B,
739739
child_info: Option<&ChildInfo>,
740740
prefix: Option<&[u8]>,
741741
size_limit: usize,
@@ -794,7 +794,7 @@ mod execution {
794794

795795
/// Generate child storage read proof.
796796
pub fn prove_child_read<B, H, I>(
797-
mut backend: B,
797+
backend: B,
798798
child_info: &ChildInfo,
799799
keys: I,
800800
) -> Result<StorageProof, Box<dyn Error>>
@@ -1197,7 +1197,7 @@ mod tests {
11971197
b"abc".to_vec() => b"2".to_vec(),
11981198
b"bbb".to_vec() => b"3".to_vec()
11991199
];
1200-
let mut state = InMemoryBackend::<BlakeTwo256>::from(initial);
1200+
let state = InMemoryBackend::<BlakeTwo256>::from(initial);
12011201
let backend = state.as_trie_backend().unwrap();
12021202

12031203
let mut overlay = OverlayedChanges::default();
@@ -1350,7 +1350,7 @@ mod tests {
13501350
fn set_child_storage_works() {
13511351
let child_info = ChildInfo::new_default(b"sub1");
13521352
let child_info = &child_info;
1353-
let mut state = new_in_mem::<BlakeTwo256>();
1353+
let state = new_in_mem::<BlakeTwo256>();
13541354
let backend = state.as_trie_backend().unwrap();
13551355
let mut overlay = OverlayedChanges::default();
13561356
let mut cache = StorageTransactionCache::default();
@@ -1372,7 +1372,7 @@ mod tests {
13721372
fn append_storage_works() {
13731373
let reference_data = vec![b"data1".to_vec(), b"2".to_vec(), b"D3".to_vec(), b"d4".to_vec()];
13741374
let key = b"key".to_vec();
1375-
let mut state = new_in_mem::<BlakeTwo256>();
1375+
let state = new_in_mem::<BlakeTwo256>();
13761376
let backend = state.as_trie_backend().unwrap();
13771377
let mut overlay = OverlayedChanges::default();
13781378
let mut cache = StorageTransactionCache::default();
@@ -1427,7 +1427,7 @@ mod tests {
14271427

14281428
let key = b"events".to_vec();
14291429
let mut cache = StorageTransactionCache::default();
1430-
let mut state = new_in_mem::<BlakeTwo256>();
1430+
let state = new_in_mem::<BlakeTwo256>();
14311431
let backend = state.as_trie_backend().unwrap();
14321432
let mut overlay = OverlayedChanges::default();
14331433

@@ -1696,7 +1696,7 @@ mod tests {
16961696
b"aaa".to_vec() => b"0".to_vec(),
16971697
b"bbb".to_vec() => b"".to_vec()
16981698
];
1699-
let mut state = InMemoryBackend::<BlakeTwo256>::from(initial);
1699+
let state = InMemoryBackend::<BlakeTwo256>::from(initial);
17001700
let backend = state.as_trie_backend().unwrap();
17011701

17021702
let mut overlay = OverlayedChanges::default();

primitives/state-machine/src/proving_backend.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ mod tests {
433433
fn proof_recorded_and_checked() {
434434
let contents = (0..64).map(|i| (vec![i], Some(vec![i]))).collect::<Vec<_>>();
435435
let in_memory = InMemoryBackend::<BlakeTwo256>::default();
436-
let mut in_memory = in_memory.update(vec![(None, contents)]);
436+
let in_memory = in_memory.update(vec![(None, contents)]);
437437
let in_memory_root = in_memory.storage_root(::std::iter::empty()).0;
438438
(0..64).for_each(|i| assert_eq!(in_memory.storage(&[i]).unwrap().unwrap(), vec![i]));
439439

@@ -464,7 +464,7 @@ mod tests {
464464
(Some(child_info_2.clone()), (10..15).map(|i| (vec![i], Some(vec![i]))).collect()),
465465
];
466466
let in_memory = InMemoryBackend::<BlakeTwo256>::default();
467-
let mut in_memory = in_memory.update(contents);
467+
let in_memory = in_memory.update(contents);
468468
let child_storage_keys = vec![child_info_1.to_owned(), child_info_2.to_owned()];
469469
let in_memory_root = in_memory
470470
.full_storage_root(

primitives/state-machine/src/trie_backend.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ where
253253
(root, is_default, write_overlay)
254254
}
255255

256-
fn as_trie_backend(&mut self) -> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
256+
fn as_trie_backend(&self) -> Option<&TrieBackend<Self::TrieBackendStorage, H>> {
257257
Some(self)
258258
}
259259

0 commit comments

Comments
 (0)