1#[cfg(feature = "std")]
21use crate::overlayed_changes::OverlayedExtensions;
22use crate::{
23 backend::Backend, IndexOperation, IterArgs, OverlayedChanges, StorageKey, StorageValue,
24};
25use codec::{Compact, CompactLen, Decode, Encode};
26use hash_db::Hasher;
27#[cfg(feature = "std")]
28use sp_core::hexdisplay::HexDisplay;
29use sp_core::storage::{
30 well_known_keys::is_child_storage_key, ChildInfo, StateVersion, TrackedStorageKey,
31};
32#[cfg(feature = "std")]
33use sp_externalities::TransactionType;
34use sp_externalities::{Extension, ExtensionStore, Externalities, MultiRemovalResults};
35
36use crate::{trace, warn};
37use alloc::{boxed::Box, vec::Vec};
38use core::{
39 any::{Any, TypeId},
40 cmp::Ordering,
41};
42
43const EXT_NOT_ALLOWED_TO_FAIL: &str = "Externalities not allowed to fail within runtime";
44const BENCHMARKING_FN: &str = "\
45 This is a special fn only for benchmarking where a database commit happens from the runtime.
46 For that reason client started transactions before calling into runtime are not allowed.
47 Without client transactions the loop condition guarantees the success of the tx close.";
48
49#[cfg(feature = "std")]
50fn guard() -> sp_panic_handler::AbortGuard {
51 sp_panic_handler::AbortGuard::force_abort()
52}
53
54#[cfg(not(feature = "std"))]
55fn guard() -> () {
56 ()
57}
58
59pub struct Ext<'a, H, B>
61where
62 H: Hasher,
63 B: 'a + Backend<H>,
64{
65 overlay: &'a mut OverlayedChanges<H>,
67 backend: &'a B,
69 pub id: u16,
71 #[cfg(feature = "std")]
73 extensions: Option<OverlayedExtensions<'a>>,
74 state_version: StateVersion,
76}
77
78impl<'a, H, B> Ext<'a, H, B>
79where
80 H: Hasher,
81 B: Backend<H>,
82{
83 #[cfg(not(feature = "std"))]
85 pub fn new(
86 overlay: &'a mut OverlayedChanges<H>,
87 backend: &'a B,
88 state_version: StateVersion,
89 ) -> Self {
90 Ext { overlay, backend, id: 0, state_version }
91 }
92
93 #[cfg(feature = "std")]
95 pub fn new(
96 overlay: &'a mut OverlayedChanges<H>,
97 backend: &'a B,
98 extensions: Option<&'a mut sp_externalities::Extensions>,
99 state_version: StateVersion,
100 ) -> Self {
101 Self {
102 overlay,
103 backend,
104 id: rand::random(),
105 extensions: extensions.map(OverlayedExtensions::new),
106 state_version,
107 }
108 }
109}
110
111#[cfg(test)]
112impl<'a, H, B> Ext<'a, H, B>
113where
114 H: Hasher,
115 H::Out: Ord + 'static,
116 B: 'a + Backend<H>,
117{
118 pub fn storage_pairs(&mut self) -> Vec<(StorageKey, StorageValue)> {
120 use std::collections::HashMap;
121
122 self.backend
123 .pairs(Default::default())
124 .expect("never fails in tests; qed.")
125 .map(|key_value| key_value.expect("never fails in tests; qed."))
126 .map(|(k, v)| (k, Some(v)))
127 .chain(self.overlay.changes_mut().map(|(k, v)| (k.clone(), v.value().cloned())))
128 .collect::<HashMap<_, _>>()
129 .into_iter()
130 .filter_map(|(k, maybe_val)| maybe_val.map(|val| (k, val)))
131 .collect()
132 }
133}
134
135impl<'a, H, B> Externalities for Ext<'a, H, B>
136where
137 H: Hasher,
138 H::Out: Ord + 'static + codec::Codec,
139 B: Backend<H>,
140{
141 fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>) {
142 self.overlay.set_offchain_storage(key, value)
143 }
144
145 fn storage(&mut self, key: &[u8]) -> Option<StorageValue> {
146 let _guard = guard();
147 let result = self
148 .overlay
149 .storage(key)
150 .map(|x| x.map(|x| x.to_vec()))
151 .unwrap_or_else(|| self.backend.storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL));
152
153 trace!(
155 target: "state",
156 method = "Get",
157 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
158 key = %HexDisplay::from(&key),
159 result = ?result.as_ref().map(HexDisplay::from),
160 result_encoded = %HexDisplay::from(
161 &result
162 .as_ref()
163 .map(|v| EncodeOpaqueValue(v.clone()))
164 .encode()
165 ),
166 );
167
168 result
169 }
170
171 fn storage_hash(&mut self, key: &[u8]) -> Option<Vec<u8>> {
172 let _guard = guard();
173 let result = self
174 .overlay
175 .storage(key)
176 .map(|x| x.map(|x| H::hash(x)))
177 .unwrap_or_else(|| self.backend.storage_hash(key).expect(EXT_NOT_ALLOWED_TO_FAIL));
178
179 trace!(
180 target: "state",
181 method = "Hash",
182 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
183 key = %HexDisplay::from(&key),
184 ?result,
185 );
186 result.map(|r| r.encode())
187 }
188
189 fn child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<StorageValue> {
190 let _guard = guard();
191 let result = self
192 .overlay
193 .child_storage(child_info, key)
194 .map(|x| x.map(|x| x.to_vec()))
195 .unwrap_or_else(|| {
196 self.backend.child_storage(child_info, key).expect(EXT_NOT_ALLOWED_TO_FAIL)
197 });
198
199 trace!(
200 target: "state",
201 method = "ChildGet",
202 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
203 child_info = %HexDisplay::from(&child_info.storage_key()),
204 key = %HexDisplay::from(&key),
205 result = ?result.as_ref().map(HexDisplay::from)
206 );
207
208 result
209 }
210
211 fn child_storage_hash(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<Vec<u8>> {
212 let _guard = guard();
213 let result = self
214 .overlay
215 .child_storage(child_info, key)
216 .map(|x| x.map(|x| H::hash(x)))
217 .unwrap_or_else(|| {
218 self.backend.child_storage_hash(child_info, key).expect(EXT_NOT_ALLOWED_TO_FAIL)
219 });
220
221 trace!(
222 target: "state",
223 method = "ChildHash",
224 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
225 child_info = %HexDisplay::from(&child_info.storage_key()),
226 key = %HexDisplay::from(&key),
227 ?result,
228 );
229
230 result.map(|r| r.encode())
231 }
232
233 fn exists_storage(&mut self, key: &[u8]) -> bool {
234 let _guard = guard();
235 let result = match self.overlay.storage(key) {
236 Some(x) => x.is_some(),
237 _ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL),
238 };
239
240 trace!(
241 target: "state",
242 method = "Exists",
243 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
244 key = %HexDisplay::from(&key),
245 %result,
246 );
247
248 result
249 }
250
251 fn exists_child_storage(&mut self, child_info: &ChildInfo, key: &[u8]) -> bool {
252 let _guard = guard();
253
254 let result = match self.overlay.child_storage(child_info, key) {
255 Some(x) => x.is_some(),
256 _ => self
257 .backend
258 .exists_child_storage(child_info, key)
259 .expect(EXT_NOT_ALLOWED_TO_FAIL),
260 };
261
262 trace!(
263 target: "state",
264 method = "ChildExists",
265 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
266 child_info = %HexDisplay::from(&child_info.storage_key()),
267 key = %HexDisplay::from(&key),
268 %result,
269 );
270 result
271 }
272
273 fn next_storage_key(&mut self, key: &[u8]) -> Option<StorageKey> {
274 let mut next_backend_key =
275 self.backend.next_storage_key(key).expect(EXT_NOT_ALLOWED_TO_FAIL);
276 let mut overlay_changes = self.overlay.iter_after(key).peekable();
277
278 match (&next_backend_key, overlay_changes.peek()) {
279 (_, None) => next_backend_key,
280 (Some(_), Some(_)) => {
281 for overlay_key in overlay_changes {
282 let cmp = next_backend_key.as_deref().map(|v| v.cmp(overlay_key.0));
283
284 if cmp == Some(Ordering::Less) {
286 return next_backend_key;
287 } else if overlay_key.1.value().is_some() {
288 return Some(overlay_key.0.to_vec());
291 } else if cmp == Some(Ordering::Equal) {
292 next_backend_key = self
296 .backend
297 .next_storage_key(overlay_key.0)
298 .expect(EXT_NOT_ALLOWED_TO_FAIL);
299 }
300 }
301
302 next_backend_key
303 },
304 (None, Some(_)) => {
305 overlay_changes.find_map(|k| k.1.value().as_ref().map(|_| k.0.to_vec()))
307 },
308 }
309 }
310
311 fn next_child_storage_key(&mut self, child_info: &ChildInfo, key: &[u8]) -> Option<StorageKey> {
312 let mut next_backend_key = self
313 .backend
314 .next_child_storage_key(child_info, key)
315 .expect(EXT_NOT_ALLOWED_TO_FAIL);
316 let mut overlay_changes =
317 self.overlay.child_iter_after(child_info.storage_key(), key).peekable();
318
319 match (&next_backend_key, overlay_changes.peek()) {
320 (_, None) => next_backend_key,
321 (Some(_), Some(_)) => {
322 for overlay_key in overlay_changes {
323 let cmp = next_backend_key.as_deref().map(|v| v.cmp(overlay_key.0));
324
325 if cmp == Some(Ordering::Less) {
327 return next_backend_key;
328 } else if overlay_key.1.value().is_some() {
329 return Some(overlay_key.0.to_vec());
332 } else if cmp == Some(Ordering::Equal) {
333 next_backend_key = self
337 .backend
338 .next_child_storage_key(child_info, overlay_key.0)
339 .expect(EXT_NOT_ALLOWED_TO_FAIL);
340 }
341 }
342
343 next_backend_key
344 },
345 (None, Some(_)) => {
346 overlay_changes.find_map(|k| k.1.value().as_ref().map(|_| k.0.to_vec()))
348 },
349 }
350 }
351
352 fn place_storage(&mut self, key: StorageKey, value: Option<StorageValue>) {
353 let _guard = guard();
354 if is_child_storage_key(&key) {
355 warn!(target: "trie", "Refuse to directly set child storage key");
356 return;
357 }
358
359 trace!(
361 target: "state",
362 method = "Put",
363 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
364 key = %HexDisplay::from(&key),
365 value = ?value.as_ref().map(HexDisplay::from),
366 value_encoded = %HexDisplay::from(
367 &value
368 .as_ref()
369 .map(|v| EncodeOpaqueValue(v.clone()))
370 .encode()
371 ),
372 );
373
374 self.overlay.set_storage(key, value);
375 }
376
377 fn place_child_storage(
378 &mut self,
379 child_info: &ChildInfo,
380 key: StorageKey,
381 value: Option<StorageValue>,
382 ) {
383 trace!(
384 target: "state",
385 method = "ChildPut",
386 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
387 child_info = %HexDisplay::from(&child_info.storage_key()),
388 key = %HexDisplay::from(&key),
389 value = ?value.as_ref().map(HexDisplay::from),
390 );
391 let _guard = guard();
392
393 self.overlay.set_child_storage(child_info, key, value);
394 }
395
396 fn kill_child_storage(
397 &mut self,
398 child_info: &ChildInfo,
399 maybe_limit: Option<u32>,
400 maybe_cursor: Option<&[u8]>,
401 ) -> MultiRemovalResults {
402 trace!(
403 target: "state",
404 method = "ChildKill",
405 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
406 child_info = %HexDisplay::from(&child_info.storage_key()),
407 );
408 let _guard = guard();
409 let overlay = self.overlay.clear_child_storage(child_info);
410 let (maybe_cursor, backend, loops) =
411 self.limit_remove_from_backend(Some(child_info), None, maybe_limit, maybe_cursor);
412 MultiRemovalResults { maybe_cursor, backend, unique: overlay + backend, loops }
413 }
414
415 fn clear_prefix(
416 &mut self,
417 prefix: &[u8],
418 maybe_limit: Option<u32>,
419 maybe_cursor: Option<&[u8]>,
420 ) -> MultiRemovalResults {
421 trace!(
422 target: "state",
423 method = "ClearPrefix",
424 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
425 prefix = %HexDisplay::from(&prefix),
426 );
427 let _guard = guard();
428
429 if sp_core::storage::well_known_keys::starts_with_child_storage_key(prefix) {
430 warn!(
431 target: "trie",
432 "Refuse to directly clear prefix that is part or contains of child storage key",
433 );
434 return MultiRemovalResults { maybe_cursor: None, backend: 0, unique: 0, loops: 0 };
435 }
436
437 let overlay = self.overlay.clear_prefix(prefix);
438 let (maybe_cursor, backend, loops) =
439 self.limit_remove_from_backend(None, Some(prefix), maybe_limit, maybe_cursor);
440 MultiRemovalResults { maybe_cursor, backend, unique: overlay + backend, loops }
441 }
442
443 fn clear_child_prefix(
444 &mut self,
445 child_info: &ChildInfo,
446 prefix: &[u8],
447 maybe_limit: Option<u32>,
448 maybe_cursor: Option<&[u8]>,
449 ) -> MultiRemovalResults {
450 trace!(
451 target: "state",
452 method = "ChildClearPrefix",
453 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
454 child_info = %HexDisplay::from(&child_info.storage_key()),
455 prefix = %HexDisplay::from(&prefix),
456 );
457 let _guard = guard();
458
459 let overlay = self.overlay.clear_child_prefix(child_info, prefix);
460 let (maybe_cursor, backend, loops) = self.limit_remove_from_backend(
461 Some(child_info),
462 Some(prefix),
463 maybe_limit,
464 maybe_cursor,
465 );
466 MultiRemovalResults { maybe_cursor, backend, unique: overlay + backend, loops }
467 }
468
469 fn storage_append(&mut self, key: Vec<u8>, value: Vec<u8>) {
470 trace!(
471 target: "state",
472 method = "Append",
473 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
474 key = %HexDisplay::from(&key),
475 value = %HexDisplay::from(&value),
476 );
477
478 let _guard = guard();
479
480 let backend = &mut self.backend;
481 self.overlay.append_storage(key.clone(), value, || {
482 backend.storage(&key).expect(EXT_NOT_ALLOWED_TO_FAIL).unwrap_or_default()
483 });
484 }
485
486 fn storage_root(&mut self) -> Vec<u8> {
487 self.storage_root_with_version(self.state_version)
488 }
489
490 fn storage_root_with_version(&mut self, state_version: StateVersion) -> Vec<u8> {
491 let _guard = guard();
492
493 let (root, _cached) = self.overlay.storage_root(self.backend, state_version);
494
495 trace!(
496 target: "state",
497 method = "StorageRoot",
498 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
499 storage_root = %HexDisplay::from(&root.as_ref()),
500 cached = %_cached,
501 );
502
503 root.encode()
504 }
505
506 fn child_storage_root(&mut self, child_info: &ChildInfo) -> Vec<u8> {
507 self.child_storage_root_with_version(child_info, self.state_version)
508 }
509
510 fn child_storage_root_with_version(
511 &mut self,
512 child_info: &ChildInfo,
513 state_version: StateVersion,
514 ) -> Vec<u8> {
515 let _guard = guard();
516
517 let (root, _cached) = self
518 .overlay
519 .child_storage_root(child_info, self.backend, state_version)
520 .expect(EXT_NOT_ALLOWED_TO_FAIL);
521
522 trace!(
523 target: "state",
524 method = "ChildStorageRoot",
525 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
526 child_info = %HexDisplay::from(&child_info.storage_key()),
527 storage_root = %HexDisplay::from(&root.as_ref()),
528 cached = %_cached,
529 );
530
531 root.encode()
532 }
533
534 fn storage_index_transaction(&mut self, index: u32, hash: &[u8], size: u32) {
535 trace!(
536 target: "state",
537 method = "IndexTransaction",
538 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
539 %index,
540 tx_hash = %HexDisplay::from(&hash),
541 %size,
542 );
543
544 self.overlay.add_transaction_index(IndexOperation::Insert {
545 extrinsic: index,
546 hash: hash.to_vec(),
547 size,
548 });
549 }
550
551 fn storage_renew_transaction_index(&mut self, index: u32, hash: &[u8]) {
553 trace!(
554 target: "state",
555 method = "RenewTransactionIndex",
556 ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
557 %index,
558 tx_hash = %HexDisplay::from(&hash),
559 );
560
561 self.overlay
562 .add_transaction_index(IndexOperation::Renew { extrinsic: index, hash: hash.to_vec() });
563 }
564
565 fn storage_start_transaction(&mut self) {
566 self.overlay.start_transaction();
567
568 #[cfg(feature = "std")]
569 if let Some(exts) = self.extensions.as_mut() {
570 exts.start_transaction(TransactionType::Runtime);
571 }
572 }
573
574 fn storage_rollback_transaction(&mut self) -> Result<(), ()> {
575 self.overlay.rollback_transaction().map_err(|_| ())?;
576
577 #[cfg(feature = "std")]
578 if let Some(exts) = self.extensions.as_mut() {
579 exts.rollback_transaction(TransactionType::Runtime);
580 }
581
582 Ok(())
583 }
584
585 fn storage_commit_transaction(&mut self) -> Result<(), ()> {
586 self.overlay.commit_transaction().map_err(|_| ())?;
587
588 #[cfg(feature = "std")]
589 if let Some(exts) = self.extensions.as_mut() {
590 exts.commit_transaction(TransactionType::Runtime);
591 }
592
593 Ok(())
594 }
595
596 fn wipe(&mut self) {
597 for _ in 0..self.overlay.transaction_depth() {
598 self.overlay.rollback_transaction().expect(BENCHMARKING_FN);
599 }
600 self.overlay
601 .drain_storage_changes(self.backend, Default::default())
602 .expect(EXT_NOT_ALLOWED_TO_FAIL);
603 self.backend.wipe().expect(EXT_NOT_ALLOWED_TO_FAIL);
604 self.overlay
605 .enter_runtime()
606 .expect("We have reset the overlay above, so we can not be in the runtime; qed");
607 }
608
609 fn commit(&mut self) {
610 for _ in 0..self.overlay.transaction_depth() {
611 self.overlay.commit_transaction().expect(BENCHMARKING_FN);
612 }
613 let changes = self
614 .overlay
615 .drain_storage_changes(self.backend, self.state_version)
616 .expect(EXT_NOT_ALLOWED_TO_FAIL);
617 self.backend
618 .commit(
619 changes.transaction_storage_root,
620 changes.transaction,
621 changes.main_storage_changes,
622 changes.child_storage_changes,
623 )
624 .expect(EXT_NOT_ALLOWED_TO_FAIL);
625 self.overlay
626 .enter_runtime()
627 .expect("We have reset the overlay above, so we can not be in the runtime; qed");
628 }
629
630 fn read_write_count(&self) -> (u32, u32, u32, u32) {
631 self.backend.read_write_count()
632 }
633
634 fn reset_read_write_count(&mut self) {
635 self.backend.reset_read_write_count()
636 }
637
638 fn get_whitelist(&self) -> Vec<TrackedStorageKey> {
639 self.backend.get_whitelist()
640 }
641
642 fn set_whitelist(&mut self, new: Vec<TrackedStorageKey>) {
643 self.backend.set_whitelist(new)
644 }
645
646 fn proof_size(&self) -> Option<u32> {
647 self.backend.proof_size()
648 }
649
650 fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> {
651 self.backend.get_read_and_written_keys()
652 }
653}
654
655impl<'a, H, B> Ext<'a, H, B>
656where
657 H: Hasher,
658 H::Out: Ord + 'static + codec::Codec,
659 B: Backend<H>,
660{
661 fn limit_remove_from_backend(
662 &mut self,
663 child_info: Option<&ChildInfo>,
664 prefix: Option<&[u8]>,
665 maybe_limit: Option<u32>,
666 start_at: Option<&[u8]>,
667 ) -> (Option<Vec<u8>>, u32, u32) {
668 let iter = match self.backend.keys(IterArgs {
669 child_info: child_info.cloned(),
670 prefix,
671 start_at,
672 ..IterArgs::default()
673 }) {
674 Ok(iter) => iter,
675 Err(error) => {
676 log::debug!(target: "trie", "Error while iterating the storage: {}", error);
677 return (None, 0, 0);
678 },
679 };
680
681 let mut delete_count: u32 = 0;
682 let mut loop_count: u32 = 0;
683 let mut maybe_next_key = None;
684 for key in iter {
685 let key = match key {
686 Ok(key) => key,
687 Err(error) => {
688 log::debug!(target: "trie", "Error while iterating the storage: {}", error);
689 break;
690 },
691 };
692
693 if maybe_limit.map_or(false, |limit| loop_count == limit) {
694 maybe_next_key = Some(key);
695 break;
696 }
697 let overlay = match child_info {
698 Some(child_info) => self.overlay.child_storage(child_info, &key),
699 None => self.overlay.storage(&key),
700 };
701 if !matches!(overlay, Some(None)) {
702 if let Some(child_info) = child_info {
704 self.overlay.set_child_storage(child_info, key, None);
705 } else {
706 self.overlay.set_storage(key, None);
707 }
708 delete_count = delete_count.saturating_add(1);
709 }
710 loop_count = loop_count.saturating_add(1);
711 }
712
713 (maybe_next_key, delete_count, loop_count)
714 }
715}
716
717#[allow(dead_code)]
719struct EncodeOpaqueValue(Vec<u8>);
720
721impl Encode for EncodeOpaqueValue {
722 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
723 f(&self.0)
724 }
725}
726
727pub(crate) struct StorageAppend<'a>(&'a mut Vec<u8>);
729
730impl<'a> StorageAppend<'a> {
731 pub fn new(storage: &'a mut Vec<u8>) -> Self {
733 Self(storage)
734 }
735
736 pub fn extract_length(&self) -> Option<u32> {
738 Compact::<u32>::decode(&mut &self.0[..]).map(|c| c.0).ok()
739 }
740
741 pub fn replace_length(&mut self, old_length: Option<u32>, new_length: u32) {
745 let old_len_encoded_len = old_length.map(|l| Compact::<u32>::compact_len(&l)).unwrap_or(0);
746 let new_len_encoded = Compact::<u32>(new_length).encode();
747 self.0.splice(0..old_len_encoded_len, new_len_encoded);
748 }
749
750 #[cfg(any(test, feature = "fuzzing"))]
754 pub fn append(&mut self, value: Vec<u8>) -> bool {
755 use codec::EncodeAppend;
756 let mut result = true;
757 let value = vec![EncodeOpaqueValue(value)];
758
759 let item = core::mem::take(self.0);
760
761 *self.0 = match Vec::<EncodeOpaqueValue>::append_or_new(item, &value) {
762 Ok(item) => item,
763 Err(_) => {
764 result = false;
765 crate::log_error!(
766 target: "runtime",
767 "Failed to append value, resetting storage item to `[value]`.",
768 );
769 value.encode()
770 },
771 };
772 result
773 }
774
775 pub fn append_raw(&mut self, mut value: Vec<u8>) {
777 self.0.append(&mut value)
778 }
779}
780
781#[cfg(not(feature = "std"))]
782impl<'a, H, B> ExtensionStore for Ext<'a, H, B>
783where
784 H: Hasher,
785 H::Out: Ord + 'static + codec::Codec,
786 B: Backend<H>,
787{
788 fn extension_by_type_id(&mut self, _type_id: TypeId) -> Option<&mut dyn Any> {
789 None
790 }
791
792 fn register_extension_with_type_id(
793 &mut self,
794 _type_id: TypeId,
795 _extension: Box<dyn Extension>,
796 ) -> Result<(), sp_externalities::Error> {
797 Err(sp_externalities::Error::ExtensionsAreNotSupported)
798 }
799
800 fn deregister_extension_by_type_id(
801 &mut self,
802 _type_id: TypeId,
803 ) -> Result<(), sp_externalities::Error> {
804 Err(sp_externalities::Error::ExtensionsAreNotSupported)
805 }
806}
807
808#[cfg(feature = "std")]
809impl<'a, H, B> ExtensionStore for Ext<'a, H, B>
810where
811 H: Hasher,
812 B: 'a + Backend<H>,
813{
814 fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any> {
815 self.extensions.as_mut().and_then(|exts| exts.get_mut(type_id))
816 }
817
818 fn register_extension_with_type_id(
819 &mut self,
820 type_id: TypeId,
821 extension: Box<dyn Extension>,
822 ) -> Result<(), sp_externalities::Error> {
823 if let Some(ref mut extensions) = self.extensions {
824 extensions.register(type_id, extension)
825 } else {
826 Err(sp_externalities::Error::ExtensionsAreNotSupported)
827 }
828 }
829
830 fn deregister_extension_by_type_id(
831 &mut self,
832 type_id: TypeId,
833 ) -> Result<(), sp_externalities::Error> {
834 if let Some(ref mut extensions) = self.extensions {
835 if extensions.deregister(type_id) {
836 Ok(())
837 } else {
838 Err(sp_externalities::Error::ExtensionIsNotRegistered(type_id))
839 }
840 } else {
841 Err(sp_externalities::Error::ExtensionsAreNotSupported)
842 }
843 }
844}
845
846#[cfg(test)]
847mod tests {
848 use super::*;
849 use crate::InMemoryBackend;
850 use codec::{Decode, Encode};
851 use sp_core::{
852 map,
853 storage::{Storage, StorageChild},
854 Blake2Hasher,
855 };
856 use sp_trie::{LayoutV0, TrieConfiguration};
857
858 type TestBackend = InMemoryBackend<Blake2Hasher>;
859 type TestExt<'a> = Ext<'a, Blake2Hasher, TestBackend>;
860
861 #[test]
862 fn next_storage_key_works() {
863 let mut overlay = OverlayedChanges::default();
864 overlay.set_storage(vec![20], None);
865 overlay.set_storage(vec![30], Some(vec![31]));
866 let backend = (
867 Storage {
868 top: map![
869 vec![10] => vec![10],
870 vec![20] => vec![20],
871 vec![40] => vec![40]
872 ],
873 children_default: map![],
874 },
875 StateVersion::default(),
876 )
877 .into();
878
879 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
880
881 assert_eq!(ext.next_storage_key(&[5]), Some(vec![10]));
883
884 assert_eq!(ext.next_storage_key(&[10]), Some(vec![30]));
886
887 assert_eq!(ext.next_storage_key(&[20]), Some(vec![30]));
889
890 assert_eq!(ext.next_storage_key(&[30]), Some(vec![40]));
892
893 drop(ext);
894 overlay.set_storage(vec![50], Some(vec![50]));
895 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
896
897 assert_eq!(ext.next_storage_key(&[40]), Some(vec![50]));
899 }
900
901 #[test]
902 fn next_storage_key_works_with_a_lot_empty_values_in_overlay() {
903 let mut overlay = OverlayedChanges::default();
904 overlay.set_storage(vec![20], None);
905 overlay.set_storage(vec![21], None);
906 overlay.set_storage(vec![22], None);
907 overlay.set_storage(vec![23], None);
908 overlay.set_storage(vec![24], None);
909 overlay.set_storage(vec![25], None);
910 overlay.set_storage(vec![26], None);
911 overlay.set_storage(vec![27], None);
912 overlay.set_storage(vec![28], None);
913 overlay.set_storage(vec![29], None);
914 let backend = (
915 Storage {
916 top: map![
917 vec![30] => vec![30]
918 ],
919 children_default: map![],
920 },
921 StateVersion::default(),
922 )
923 .into();
924
925 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
926
927 assert_eq!(ext.next_storage_key(&[5]), Some(vec![30]));
928
929 drop(ext);
930 }
931
932 #[test]
933 fn next_child_storage_key_works() {
934 let child_info = ChildInfo::new_default(b"Child1");
935 let child_info = &child_info;
936
937 let mut overlay = OverlayedChanges::default();
938 overlay.set_child_storage(child_info, vec![20], None);
939 overlay.set_child_storage(child_info, vec![30], Some(vec![31]));
940 let backend = (
941 Storage {
942 top: map![],
943 children_default: map![
944 child_info.storage_key().to_vec() => StorageChild {
945 data: map![
946 vec![10] => vec![10],
947 vec![20] => vec![20],
948 vec![40] => vec![40]
949 ],
950 child_info: child_info.to_owned(),
951 }
952 ],
953 },
954 StateVersion::default(),
955 )
956 .into();
957
958 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
959
960 assert_eq!(ext.next_child_storage_key(child_info, &[5]), Some(vec![10]));
962
963 assert_eq!(ext.next_child_storage_key(child_info, &[10]), Some(vec![30]));
965
966 assert_eq!(ext.next_child_storage_key(child_info, &[20]), Some(vec![30]));
968
969 assert_eq!(ext.next_child_storage_key(child_info, &[30]), Some(vec![40]));
971
972 drop(ext);
973 overlay.set_child_storage(child_info, vec![50], Some(vec![50]));
974 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
975
976 assert_eq!(ext.next_child_storage_key(child_info, &[40]), Some(vec![50]));
978 }
979
980 #[test]
981 fn child_storage_works() {
982 let child_info = ChildInfo::new_default(b"Child1");
983 let child_info = &child_info;
984 let mut overlay = OverlayedChanges::default();
985 overlay.set_child_storage(child_info, vec![20], None);
986 overlay.set_child_storage(child_info, vec![30], Some(vec![31]));
987 let backend = (
988 Storage {
989 top: map![],
990 children_default: map![
991 child_info.storage_key().to_vec() => StorageChild {
992 data: map![
993 vec![10] => vec![10],
994 vec![20] => vec![20],
995 vec![30] => vec![40]
996 ],
997 child_info: child_info.to_owned(),
998 }
999 ],
1000 },
1001 StateVersion::default(),
1002 )
1003 .into();
1004
1005 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
1006
1007 assert_eq!(ext.child_storage(child_info, &[10]), Some(vec![10]));
1008 assert_eq!(
1009 ext.child_storage_hash(child_info, &[10]),
1010 Some(Blake2Hasher::hash(&[10]).as_ref().to_vec()),
1011 );
1012
1013 assert_eq!(ext.child_storage(child_info, &[20]), None);
1014 assert_eq!(ext.child_storage_hash(child_info, &[20]), None);
1015
1016 assert_eq!(ext.child_storage(child_info, &[30]), Some(vec![31]));
1017 assert_eq!(
1018 ext.child_storage_hash(child_info, &[30]),
1019 Some(Blake2Hasher::hash(&[31]).as_ref().to_vec()),
1020 );
1021 }
1022
1023 #[test]
1024 fn clear_prefix_cannot_delete_a_child_root() {
1025 let child_info = ChildInfo::new_default(b"Child1");
1026 let child_info = &child_info;
1027 let mut overlay = OverlayedChanges::default();
1028 let backend = (
1029 Storage {
1030 top: map![],
1031 children_default: map![
1032 child_info.storage_key().to_vec() => StorageChild {
1033 data: map![
1034 vec![30] => vec![40]
1035 ],
1036 child_info: child_info.to_owned(),
1037 }
1038 ],
1039 },
1040 StateVersion::default(),
1041 )
1042 .into();
1043
1044 let ext = TestExt::new(&mut overlay, &backend, None, StateVersion::default());
1045
1046 use sp_core::storage::well_known_keys;
1047 let mut ext = ext;
1048 let mut not_under_prefix = well_known_keys::CHILD_STORAGE_KEY_PREFIX.to_vec();
1049 not_under_prefix[4] = 88;
1050 not_under_prefix.extend(b"path");
1051 ext.set_storage(not_under_prefix.clone(), vec![10]);
1052
1053 let _ = ext.clear_prefix(&[], None, None);
1054 let _ = ext.clear_prefix(&well_known_keys::CHILD_STORAGE_KEY_PREFIX[..4], None, None);
1055 let mut under_prefix = well_known_keys::CHILD_STORAGE_KEY_PREFIX.to_vec();
1056 under_prefix.extend(b"path");
1057 let _ = ext.clear_prefix(&well_known_keys::CHILD_STORAGE_KEY_PREFIX[..4], None, None);
1058 assert_eq!(ext.child_storage(child_info, &[30]), Some(vec![40]));
1059 assert_eq!(ext.storage(not_under_prefix.as_slice()), Some(vec![10]));
1060 let _ = ext.clear_prefix(¬_under_prefix[..5], None, None);
1061 assert_eq!(ext.storage(not_under_prefix.as_slice()), None);
1062 }
1063
1064 #[test]
1065 fn storage_append_works() {
1066 let mut data = Vec::new();
1067 let mut append = StorageAppend::new(&mut data);
1068 append.append(1u32.encode());
1069 append.append(2u32.encode());
1070 drop(append);
1071
1072 assert_eq!(Vec::<u32>::decode(&mut &data[..]).unwrap(), vec![1, 2]);
1073
1074 let mut data = vec![1];
1076 let mut append = StorageAppend::new(&mut data);
1077 append.append(1u32.encode());
1078 append.append(2u32.encode());
1079 drop(append);
1080
1081 assert_eq!(Vec::<u32>::decode(&mut &data[..]).unwrap(), vec![1, 2]);
1082 }
1083
1084 #[test]
1085 fn state_version_is_used_for_root() {
1086 let backend = TestBackend::default();
1087 let mut overlay = OverlayedChanges::default();
1088 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::V1);
1089
1090 let key = b"key".to_vec();
1093 let value = vec![0x42; sp_core::storage::TRIE_VALUE_NODE_THRESHOLD as usize + 1];
1094 ext.set_storage(key.clone(), value.clone());
1095
1096 let root_v1 = ext.storage_root();
1097
1098 let mut ext = TestExt::new(&mut overlay, &backend, None, StateVersion::V0);
1099 let root_v0 = ext.storage_root();
1100 assert_ne!(root_v0, root_v1);
1101
1102 let expected_v0 = LayoutV0::<Blake2Hasher>::trie_root(
1103 vec![(key, value)].into_iter().collect::<std::collections::BTreeMap<_, _>>(),
1104 )
1105 .as_ref()
1106 .to_vec();
1107 assert_eq!(root_v0, expected_v0);
1108 }
1109}