Struct sp_state_machine::Ext
source · Expand description
Wraps a read-only backend, call executor, and current overlayed changes.
Fields§
§id: u16
Pseudo-unique id used for tracing.
Implementations§
source§impl<'a, H, B> Ext<'a, H, B>where
H: Hasher,
B: Backend<H>,
impl<'a, H, B> Ext<'a, H, B>where
H: Hasher,
B: Backend<H>,
sourcepub fn new(
overlay: &'a mut OverlayedChanges,
storage_transaction_cache: &'a mut StorageTransactionCache<B::Transaction, H>,
backend: &'a B,
extensions: Option<&'a mut Extensions>
) -> Self
pub fn new(
overlay: &'a mut OverlayedChanges,
storage_transaction_cache: &'a mut StorageTransactionCache<B::Transaction, H>,
backend: &'a B,
extensions: Option<&'a mut Extensions>
) -> Self
Create a new Ext
from overlayed changes and read-only backend
Examples found in repository?
src/testing.rs (lines 69-74)
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
pub fn ext(&mut self) -> Ext<H, InMemoryBackend<H>> {
Ext::new(
&mut self.overlay,
&mut self.storage_transaction_cache,
&self.backend,
Some(&mut self.extensions),
)
}
/// Create a new instance of `TestExternalities` with storage.
pub fn new(storage: Storage) -> Self {
Self::new_with_code_and_state(&[], storage, Default::default())
}
/// Create a new instance of `TestExternalities` with storage for a given state version.
pub fn new_with_state_version(storage: Storage, state_version: StateVersion) -> Self {
Self::new_with_code_and_state(&[], storage, state_version)
}
/// New empty test externalities.
pub fn new_empty() -> Self {
Self::new_with_code_and_state(&[], Storage::default(), Default::default())
}
/// Create a new instance of `TestExternalities` with code and storage.
pub fn new_with_code(code: &[u8], storage: Storage) -> Self {
Self::new_with_code_and_state(code, storage, Default::default())
}
/// Create a new instance of `TestExternalities` with code and storage for a given state
/// version.
pub fn new_with_code_and_state(
code: &[u8],
mut storage: Storage,
state_version: StateVersion,
) -> Self {
assert!(storage.top.keys().all(|key| !is_child_storage_key(key)));
storage.top.insert(CODE.to_vec(), code.to_vec());
let mut extensions = Extensions::default();
extensions.register(TaskExecutorExt::new(TaskExecutor::new()));
let offchain_db = TestPersistentOffchainDB::new();
let backend = (storage, state_version).into();
TestExternalities {
overlay: OverlayedChanges::default(),
offchain_db,
extensions,
backend,
storage_transaction_cache: Default::default(),
state_version,
}
}
/// Returns the overlayed changes.
pub fn overlayed_changes(&self) -> &OverlayedChanges {
&self.overlay
}
/// Move offchain changes from overlay to the persistent store.
pub fn persist_offchain_overlay(&mut self) {
self.offchain_db.apply_offchain_changes(self.overlay.offchain_drain_committed());
}
/// A shared reference type around the offchain worker storage.
pub fn offchain_db(&self) -> TestPersistentOffchainDB {
self.offchain_db.clone()
}
/// Insert key/value into backend
pub fn insert(&mut self, k: StorageKey, v: StorageValue) {
self.backend.insert(vec![(None, vec![(k, Some(v))])], self.state_version);
}
/// Insert key/value into backend.
///
/// This only supports inserting keys in child tries.
pub fn insert_child(&mut self, c: sp_core::storage::ChildInfo, k: StorageKey, v: StorageValue) {
self.backend.insert(vec![(Some(c), vec![(k, Some(v))])], self.state_version);
}
/// Registers the given extension for this instance.
pub fn register_extension<E: Any + Extension>(&mut self, ext: E) {
self.extensions.register(ext);
}
/// Return a new backend with all pending changes.
///
/// In contrast to [`commit_all`](Self::commit_all) this will not panic if there are open
/// transactions.
pub fn as_backend(&self) -> InMemoryBackend<H> {
let top: Vec<_> =
self.overlay.changes().map(|(k, v)| (k.clone(), v.value().cloned())).collect();
let mut transaction = vec![(None, top)];
for (child_changes, child_info) in self.overlay.children() {
transaction.push((
Some(child_info.clone()),
child_changes.map(|(k, v)| (k.clone(), v.value().cloned())).collect(),
))
}
self.backend.update(transaction, self.state_version)
}
/// Commit all pending changes to the underlying backend.
///
/// # Panic
///
/// This will panic if there are still open transactions.
pub fn commit_all(&mut self) -> Result<(), String> {
let changes = self.overlay.drain_storage_changes::<_, _>(
&self.backend,
&mut Default::default(),
self.state_version,
)?;
self.backend
.apply_transaction(changes.transaction_storage_root, changes.transaction);
Ok(())
}
/// Execute the given closure while `self` is set as externalities.
///
/// Returns the result of the given closure.
pub fn execute_with<R>(&mut self, execute: impl FnOnce() -> R) -> R {
let mut ext = self.ext();
sp_externalities::set_and_run_with_externalities(&mut ext, execute)
}
/// Execute the given closure while `self`, with `proving_backend` as backend, is set as
/// externalities.
///
/// This implementation will wipe the proof recorded in between calls. Consecutive calls will
/// get their own proof from scratch.
pub fn execute_and_prove<R>(&mut self, execute: impl FnOnce() -> R) -> (R, StorageProof) {
let proving_backend = TrieBackendBuilder::wrap(&self.backend)
.with_recorder(Default::default())
.build();
let mut proving_ext = Ext::new(
&mut self.overlay,
&mut self.storage_transaction_cache,
&proving_backend,
Some(&mut self.extensions),
);
let outcome = sp_externalities::set_and_run_with_externalities(&mut proving_ext, execute);
let proof = proving_backend.extract_proof().expect("Failed to extract storage proof");
(outcome, proof)
}
More examples
src/lib.rs (line 392)
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
fn execute_aux(&mut self, use_native: bool) -> (CallResult<Exec::Error>, bool) {
let mut cache = StorageTransactionCache::default();
let cache = match self.storage_transaction_cache.as_mut() {
Some(cache) => cache,
None => &mut cache,
};
self.overlay
.enter_runtime()
.expect("StateMachine is never called from the runtime; qed");
let mut ext = Ext::new(self.overlay, cache, self.backend, Some(&mut self.extensions));
let ext_id = ext.id;
trace!(
target: "state",
ext_id = %HexDisplay::from(&ext_id.to_le_bytes()),
method = %self.method,
parent_hash = %self.parent_hash.map(|h| format!("{:?}", h)).unwrap_or_else(|| String::from("None")),
input = ?HexDisplay::from(&self.call_data),
"Call",
);
let (result, was_native) = self.exec.call(
&mut ext,
self.runtime_code,
self.method,
self.call_data,
use_native,
);
self.overlay
.exit_runtime()
.expect("Runtime is not able to call this function in the overlay; qed");
trace!(
target: "state",
ext_id = %HexDisplay::from(&ext_id.to_le_bytes()),
?was_native,
?result,
"Return",
);
(result, was_native)
}
Trait Implementations§
source§impl<'a, H, B> ExtensionStore for Ext<'a, H, B>where
H: Hasher,
B: 'a + Backend<H>,
impl<'a, H, B> ExtensionStore for Ext<'a, H, B>where
H: Hasher,
B: 'a + Backend<H>,
source§fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>
fn extension_by_type_id(&mut self, type_id: TypeId) -> Option<&mut dyn Any>
Tries to find a registered extension by the given
type_id
and returns it as a &mut dyn Any
. Read moresource§impl<'a, H, B> Externalities for Ext<'a, H, B>where
H: Hasher,
H::Out: Ord + 'static + Codec,
B: Backend<H>,
impl<'a, H, B> Externalities for Ext<'a, H, B>where
H: Hasher,
H::Out: Ord + 'static + Codec,
B: Backend<H>,
source§fn storage_renew_transaction_index(&mut self, index: u32, hash: &[u8])
fn storage_renew_transaction_index(&mut self, index: u32, hash: &[u8])
Renew existing piece of data storage.
source§fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>)
fn set_offchain_storage(&mut self, key: &[u8], value: Option<&[u8]>)
Write a key value pair to the offchain storage database.
source§fn child_storage(
&self,
child_info: &ChildInfo,
key: &[u8]
) -> Option<StorageValue>
fn child_storage(
&self,
child_info: &ChildInfo,
key: &[u8]
) -> Option<StorageValue>
Read child runtime storage. Read more
source§fn child_storage_hash(
&self,
child_info: &ChildInfo,
key: &[u8]
) -> Option<Vec<u8>>
fn child_storage_hash(
&self,
child_info: &ChildInfo,
key: &[u8]
) -> Option<Vec<u8>>
Get child storage value hash. Read more
source§fn exists_storage(&self, key: &[u8]) -> bool
fn exists_storage(&self, key: &[u8]) -> bool
Whether a storage entry exists.
source§fn exists_child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> bool
fn exists_child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> bool
Whether a child storage entry exists.
source§fn next_storage_key(&self, key: &[u8]) -> Option<StorageKey>
fn next_storage_key(&self, key: &[u8]) -> Option<StorageKey>
Returns the key immediately following the given key, if it exists.
source§fn next_child_storage_key(
&self,
child_info: &ChildInfo,
key: &[u8]
) -> Option<StorageKey>
fn next_child_storage_key(
&self,
child_info: &ChildInfo,
key: &[u8]
) -> Option<StorageKey>
Returns the key immediately following the given key, if it exists, in child storage.
source§fn place_storage(&mut self, key: StorageKey, value: Option<StorageValue>)
fn place_storage(&mut self, key: StorageKey, value: Option<StorageValue>)
Set or clear a storage entry (
key
) of current contract being called (effective
immediately).source§fn place_child_storage(
&mut self,
child_info: &ChildInfo,
key: StorageKey,
value: Option<StorageValue>
)
fn place_child_storage(
&mut self,
child_info: &ChildInfo,
key: StorageKey,
value: Option<StorageValue>
)
Set or clear a child storage entry.
source§fn kill_child_storage(
&mut self,
child_info: &ChildInfo,
maybe_limit: Option<u32>,
maybe_cursor: Option<&[u8]>
) -> MultiRemovalResults
fn kill_child_storage(
&mut self,
child_info: &ChildInfo,
maybe_limit: Option<u32>,
maybe_cursor: Option<&[u8]>
) -> MultiRemovalResults
Clear an entire child storage. Read more
source§fn clear_prefix(
&mut self,
prefix: &[u8],
maybe_limit: Option<u32>,
maybe_cursor: Option<&[u8]>
) -> MultiRemovalResults
fn clear_prefix(
&mut self,
prefix: &[u8],
maybe_limit: Option<u32>,
maybe_cursor: Option<&[u8]>
) -> MultiRemovalResults
Clear storage entries which keys are start with the given prefix. Read more
source§fn clear_child_prefix(
&mut self,
child_info: &ChildInfo,
prefix: &[u8],
maybe_limit: Option<u32>,
maybe_cursor: Option<&[u8]>
) -> MultiRemovalResults
fn clear_child_prefix(
&mut self,
child_info: &ChildInfo,
prefix: &[u8],
maybe_limit: Option<u32>,
maybe_cursor: Option<&[u8]>
) -> MultiRemovalResults
Clear child storage entries which keys are start with the given prefix. Read more
source§fn storage_root(&mut self, state_version: StateVersion) -> Vec<u8> ⓘ
fn storage_root(&mut self, state_version: StateVersion) -> Vec<u8> ⓘ
Get the trie root of the current storage map. Read more
source§fn child_storage_root(
&mut self,
child_info: &ChildInfo,
state_version: StateVersion
) -> Vec<u8> ⓘ
fn child_storage_root(
&mut self,
child_info: &ChildInfo,
state_version: StateVersion
) -> Vec<u8> ⓘ
Get the trie root of a child storage map. Read more
source§fn storage_index_transaction(&mut self, index: u32, hash: &[u8], size: u32)
fn storage_index_transaction(&mut self, index: u32, hash: &[u8], size: u32)
Index specified transaction slice and store it.
source§fn storage_start_transaction(&mut self)
fn storage_start_transaction(&mut self)
Start a new nested transaction. Read more
source§fn storage_rollback_transaction(&mut self) -> Result<(), ()>
fn storage_rollback_transaction(&mut self) -> Result<(), ()>
Rollback the last transaction started by
storage_start_transaction
. Read moresource§fn storage_commit_transaction(&mut self) -> Result<(), ()>
fn storage_commit_transaction(&mut self) -> Result<(), ()>
Commit the last transaction started by
storage_start_transaction
. Read moresource§fn wipe(&mut self)
fn wipe(&mut self)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn commit(&mut self)
fn commit(&mut self)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn read_write_count(&self) -> (u32, u32, u32, u32)
fn read_write_count(&self) -> (u32, u32, u32, u32)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn reset_read_write_count(&mut self)
fn reset_read_write_count(&mut self)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn get_whitelist(&self) -> Vec<TrackedStorageKey> ⓘ
fn get_whitelist(&self) -> Vec<TrackedStorageKey> ⓘ
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn set_whitelist(&mut self, new: Vec<TrackedStorageKey>)
fn set_whitelist(&mut self, new: Vec<TrackedStorageKey>)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn proof_size(&self) -> Option<u32>
fn proof_size(&self) -> Option<u32>
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> ⓘ
fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> ⓘ
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Benchmarking related functionality and shouldn’t be used anywhere else!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Read more
source§fn set_storage(&mut self, key: Vec<u8, Global>, value: Vec<u8, Global>)
fn set_storage(&mut self, key: Vec<u8, Global>, value: Vec<u8, Global>)
Set storage entry
key
of current contract being called (effective immediately).source§fn set_child_storage(
&mut self,
child_info: &ChildInfo,
key: Vec<u8, Global>,
value: Vec<u8, Global>
)
fn set_child_storage(
&mut self,
child_info: &ChildInfo,
key: Vec<u8, Global>,
value: Vec<u8, Global>
)
Set child storage entry
key
of current contract being called (effective immediately).source§fn clear_storage(&mut self, key: &[u8])
fn clear_storage(&mut self, key: &[u8])
Clear a storage entry (
key
) of current contract being called (effective immediately).source§fn clear_child_storage(&mut self, child_info: &ChildInfo, key: &[u8])
fn clear_child_storage(&mut self, child_info: &ChildInfo, key: &[u8])
Clear a child storage entry (
key
) of current contract being called (effective
immediately).Auto Trait Implementations§
impl<'a, H, B> !RefUnwindSafe for Ext<'a, H, B>
impl<'a, H, B> Send for Ext<'a, H, B>where
B: Sync,
impl<'a, H, B> !Sync for Ext<'a, H, B>
impl<'a, H, B> Unpin for Ext<'a, H, B>
impl<'a, H, B> !UnwindSafe for Ext<'a, H, B>
Blanket Implementations§
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T, Global>) -> Box<dyn Any + 'static, Global>
fn into_any(self: Box<T, Global>) -> Box<dyn Any + 'static, Global>
Convert
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any + 'static>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any + 'static>
Convert
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
Convert
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
Convert
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T, Outer> IsWrappedBy<Outer> for Twhere
Outer: AsRef<T> + AsMut<T> + From<T>,
T: From<Outer>,
impl<T, Outer> IsWrappedBy<Outer> for Twhere
Outer: AsRef<T> + AsMut<T> + From<T>,
T: From<Outer>,
source§impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
impl<S, T> UncheckedInto<T> for Swhere
T: UncheckedFrom<S>,
source§fn unchecked_into(self) -> T
fn unchecked_into(self) -> T
The counterpart to
unchecked_from
.