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