pub trait Backend<H: Hasher>: Debug {
    type Error: Error;
    type Transaction: Consolidate + Default + Send;
    type TrieBackendStorage: TrieBackendStorage<H, Overlay = Self::Transaction>;

Show 29 methods fn storage(&self, key: &[u8]) -> Result<Option<StorageValue>, Self::Error>; fn storage_hash(&self, key: &[u8]) -> Result<Option<H::Out>, Self::Error>; fn child_storage(
        &self,
        child_info: &ChildInfo,
        key: &[u8]
    ) -> Result<Option<StorageValue>, Self::Error>; fn child_storage_hash(
        &self,
        child_info: &ChildInfo,
        key: &[u8]
    ) -> Result<Option<H::Out>, Self::Error>; fn next_storage_key(
        &self,
        key: &[u8]
    ) -> Result<Option<StorageKey>, Self::Error>; fn next_child_storage_key(
        &self,
        child_info: &ChildInfo,
        key: &[u8]
    ) -> Result<Option<StorageKey>, Self::Error>; fn apply_to_key_values_while<F: FnMut(Vec<u8>, Vec<u8>) -> bool>(
        &self,
        child_info: Option<&ChildInfo>,
        prefix: Option<&[u8]>,
        start_at: Option<&[u8]>,
        f: F,
        allow_missing: bool
    ) -> Result<bool, Self::Error>; fn apply_to_keys_while<F: FnMut(&[u8]) -> bool>(
        &self,
        child_info: Option<&ChildInfo>,
        prefix: Option<&[u8]>,
        start_at: Option<&[u8]>,
        f: F
    ); fn for_key_values_with_prefix<F: FnMut(&[u8], &[u8])>(
        &self,
        prefix: &[u8],
        f: F
    ); fn for_child_keys_with_prefix<F: FnMut(&[u8])>(
        &self,
        child_info: &ChildInfo,
        prefix: &[u8],
        f: F
    ); fn storage_root<'a>(
        &self,
        delta: impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>,
        state_version: StateVersion
    ) -> (H::Out, Self::Transaction)
    where
        H::Out: Ord
; fn child_storage_root<'a>(
        &self,
        child_info: &ChildInfo,
        delta: impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>,
        state_version: StateVersion
    ) -> (H::Out, bool, Self::Transaction)
    where
        H::Out: Ord
; fn pairs(&self) -> Vec<(StorageKey, StorageValue)> ; fn register_overlay_stats(&self, _stats: &StateMachineStats); fn usage_info(&self) -> UsageInfo; fn exists_storage(&self, key: &[u8]) -> Result<bool, Self::Error> { ... } fn exists_child_storage(
        &self,
        child_info: &ChildInfo,
        key: &[u8]
    ) -> Result<bool, Self::Error> { ... } fn for_keys_with_prefix<F: FnMut(&[u8])>(&self, prefix: &[u8], f: F) { ... } fn keys(&self, prefix: &[u8]) -> Vec<StorageKey> { ... } fn child_keys(&self, child_info: &ChildInfo, prefix: &[u8]) -> Vec<StorageKey> { ... } fn full_storage_root<'a>(
        &self,
        delta: impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>,
        child_deltas: impl Iterator<Item = (&'a ChildInfo, impl Iterator<Item = (&'a [u8], Option<&'a [u8]>)>)>,
        state_version: StateVersion
    ) -> (H::Out, Self::Transaction)
    where
        H::Out: Ord + Encode
, { ... } fn wipe(&self) -> Result<(), Self::Error> { ... } fn commit(
        &self,
        _: H::Out,
        _: Self::Transaction,
        _: StorageCollection,
        _: ChildStorageCollection
    ) -> Result<(), Self::Error> { ... } fn read_write_count(&self) -> (u32, u32, u32, u32) { ... } fn reset_read_write_count(&self) { ... } fn get_whitelist(&self) -> Vec<TrackedStorageKey> { ... } fn set_whitelist(&self, _: Vec<TrackedStorageKey>) { ... } fn proof_size(&self) -> Option<u32> { ... } fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> { ... }
}
Expand description

A state backend is used to read state data and can have changes committed to it.

The clone operation (if implemented) should be cheap.

Required Associated Types§

An error type when fetching data is not possible.

Storage changes to be applied if committing

Type of trie backend storage.

Required Methods§

Get keyed storage or None if there is nothing associated.

Get keyed storage value hash or None if there is nothing associated.

Get keyed child storage or None if there is nothing associated.

Get child keyed storage value hash or None if there is nothing associated.

Return the next key in storage in lexicographic order or None if there is no value.

Return the next key in child storage in lexicographic order or None if there is no value.

Iterate over storage starting at key, for a given prefix and child trie. Aborts as soon as f returns false. Warning, this fails at first error when usual iteration skips errors. If allow_missing is true, iteration stops when it reaches a missing trie node. Otherwise an error is produced.

Returns true if trie end is reached.

Retrieve all entries keys of storage and call f for each of those keys. Aborts as soon as f returns false.

Retrieve all entries keys and values of which start with the given prefix and call f for each of those keys.

Retrieve all child entries keys which start with the given prefix and call f for each of those keys.

Calculate the storage root, with given delta over what is already stored in the backend, and produce a “transaction” that can be used to commit. Does not include child storage updates.

Calculate the child storage root, with given delta over what is already stored in the backend, and produce a “transaction” that can be used to commit. The second argument is true if child storage root equals default storage root.

Get all key/value pairs into a Vec.

Register stats from overlay of state machine.

By default nothing is registered.

Query backend usage statistics (i/o, memory)

Not all implementations are expected to be able to do this. In the case when they don’t, empty statistics is returned.

Provided Methods§

true if a key exists in storage.

Examples found in repository?
src/ext.rs (line 275)
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
	fn exists_storage(&self, key: &[u8]) -> bool {
		let _guard = guard();
		let result = match self.overlay.storage(key) {
			Some(x) => x.is_some(),
			_ => self.backend.exists_storage(key).expect(EXT_NOT_ALLOWED_TO_FAIL),
		};

		trace!(
			target: "state",
			method = "Exists",
			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
			key = %HexDisplay::from(&key),
			%result,
		);

		result
	}

true if a key exists in child storage.

Examples found in repository?
src/ext.rs (line 296)
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
	fn exists_child_storage(&self, child_info: &ChildInfo, key: &[u8]) -> bool {
		let _guard = guard();

		let result = match self.overlay.child_storage(child_info, key) {
			Some(x) => x.is_some(),
			_ => self
				.backend
				.exists_child_storage(child_info, key)
				.expect(EXT_NOT_ALLOWED_TO_FAIL),
		};

		trace!(
			target: "state",
			method = "ChildExists",
			ext_id = %HexDisplay::from(&self.id.to_le_bytes()),
			child_info = %HexDisplay::from(&child_info.storage_key()),
			key = %HexDisplay::from(&key),
			%result,
		);
		result
	}

Retrieve all entries keys which start with the given prefix and call f for each of those keys.

Examples found in repository?
src/backend.rs (line 165)
163
164
165
166
167
	fn keys(&self, prefix: &[u8]) -> Vec<StorageKey> {
		let mut all = Vec::new();
		self.for_keys_with_prefix(prefix, |k| all.push(k.to_vec()));
		all
	}

Get all keys with given prefix

Get all keys of child storage with given prefix

Calculate the storage root, with given delta over what is already stored in the backend, and produce a “transaction” that can be used to commit. Does include child storage updates.

Examples found in repository?
src/in_memory_backend.rs (lines 76-82)
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
	pub fn insert<T: IntoIterator<Item = (Option<ChildInfo>, StorageCollection)>>(
		&mut self,
		changes: T,
		state_version: StateVersion,
	) {
		let (top, child) = changes.into_iter().partition::<Vec<_>, _>(|v| v.0.is_none());
		let (root, transaction) = self.full_storage_root(
			top.iter().flat_map(|(_, v)| v).map(|(k, v)| (&k[..], v.as_deref())),
			child.iter().filter_map(|v| {
				v.0.as_ref().map(|c| (c, v.1.iter().map(|(k, v)| (&k[..], v.as_deref()))))
			}),
			state_version,
		);

		self.apply_transaction(root, transaction);
	}
More examples
Hide additional examples
src/overlayed_changes/mod.rs (line 593)
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
	pub fn storage_root<H: Hasher, B: Backend<H>>(
		&self,
		backend: &B,
		cache: &mut StorageTransactionCache<B::Transaction, H>,
		state_version: StateVersion,
	) -> H::Out
	where
		H::Out: Ord + Encode,
	{
		let delta = self.changes().map(|(k, v)| (&k[..], v.value().map(|v| &v[..])));
		let child_delta = self.children().map(|(changes, info)| {
			(info, changes.map(|(k, v)| (&k[..], v.value().map(|v| &v[..]))))
		});

		let (root, transaction) = backend.full_storage_root(delta, child_delta, state_version);

		cache.transaction = Some(transaction);
		cache.transaction_storage_root = Some(root);

		root
	}

Wipe the state database.

Examples found in repository?
src/ext.rs (line 688)
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
	fn wipe(&mut self) {
		for _ in 0..self.overlay.transaction_depth() {
			self.overlay.rollback_transaction().expect(BENCHMARKING_FN);
		}
		self.overlay
			.drain_storage_changes(
				self.backend,
				self.storage_transaction_cache,
				Default::default(), // using any state
			)
			.expect(EXT_NOT_ALLOWED_TO_FAIL);
		self.backend.wipe().expect(EXT_NOT_ALLOWED_TO_FAIL);
		self.mark_dirty();
		self.overlay
			.enter_runtime()
			.expect("We have reset the overlay above, so we can not be in the runtime; qed");
	}

Commit given transaction to storage.

Examples found in repository?
src/ext.rs (lines 706-711)
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
	fn commit(&mut self) {
		// Bench always use latest state.
		let state_version = StateVersion::default();
		for _ in 0..self.overlay.transaction_depth() {
			self.overlay.commit_transaction().expect(BENCHMARKING_FN);
		}
		let changes = self
			.overlay
			.drain_storage_changes(self.backend, self.storage_transaction_cache, state_version)
			.expect(EXT_NOT_ALLOWED_TO_FAIL);
		self.backend
			.commit(
				changes.transaction_storage_root,
				changes.transaction,
				changes.main_storage_changes,
				changes.child_storage_changes,
			)
			.expect(EXT_NOT_ALLOWED_TO_FAIL);
		self.mark_dirty();
		self.overlay
			.enter_runtime()
			.expect("We have reset the overlay above, so we can not be in the runtime; qed");
	}

Get the read/write count of the db

Examples found in repository?
src/ext.rs (line 720)
719
720
721
	fn read_write_count(&self) -> (u32, u32, u32, u32) {
		self.backend.read_write_count()
	}

Get the read/write count of the db

Examples found in repository?
src/ext.rs (line 724)
723
724
725
	fn reset_read_write_count(&mut self) {
		self.backend.reset_read_write_count()
	}

Get the whitelist for tracking db reads/writes

Examples found in repository?
src/ext.rs (line 728)
727
728
729
	fn get_whitelist(&self) -> Vec<TrackedStorageKey> {
		self.backend.get_whitelist()
	}

Update the whitelist for tracking db reads/writes

Examples found in repository?
src/ext.rs (line 732)
731
732
733
	fn set_whitelist(&mut self, new: Vec<TrackedStorageKey>) {
		self.backend.set_whitelist(new)
	}

Estimate proof size

Examples found in repository?
src/ext.rs (line 736)
735
736
737
	fn proof_size(&self) -> Option<u32> {
		self.backend.proof_size()
	}

Extend storage info for benchmarking db

Examples found in repository?
src/ext.rs (line 740)
739
740
741
	fn get_read_and_written_keys(&self) -> Vec<(Vec<u8>, u32, u32, bool)> {
		self.backend.get_read_and_written_keys()
	}

Implementors§