mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 03:58:04 +00:00
Remove requirement on Hash = H256, make Proposer return StorageChanges and Proof (#3860)
* Extend `Proposer` to optionally generate a proof of the proposal * Something * Refactor sr-api to not depend on client anymore * Fix benches * Apply suggestions from code review Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Apply suggestions from code review * Introduce new `into_storage_changes` function * Switch to runtime api for `execute_block` and don't require `H256` anywhere in the code * Put the `StorageChanges` into the `Proposal` * Move the runtime api error to its own trait * Adds `StorageTransactionCache` to the runtime api This requires that we add `type NodeBlock = ` to the `impl_runtime_apis!` macro to work around some bugs in rustc :( * Remove `type NodeBlock` and switch to a "better" hack * Start using the transaction cache from the runtime api * Make it compile * Move `InMemory` to its own file * Make all tests work again * Return block, storage_changes and proof from Blockbuilder::bake() * Make sure that we use/set `storage_changes` when possible * Add test * Fix deadlock * Remove accidentally added folders * Introduce `RecordProof` as argument type to be more explicit * Update client/src/client.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Update primitives/state-machine/src/ext.rs Co-Authored-By: Tomasz Drwięga <tomusdrw@users.noreply.github.com> * Integrates review feedback * Remove `unsafe` usage * Update client/block-builder/src/lib.rs Co-Authored-By: Benjamin Kampmann <ben@gnunicorn.org> * Update client/src/call_executor.rs * Bump versions Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com> Co-authored-by: Benjamin Kampmann <ben.kampmann@googlemail.com>
This commit is contained in:
@@ -339,9 +339,9 @@ fn prepare_digest_input<'a, H, Number>(
|
||||
mod test {
|
||||
use codec::Encode;
|
||||
use sp_core::Blake2Hasher;
|
||||
use sp_core::storage::well_known_keys::{EXTRINSIC_INDEX};
|
||||
use sp_core::storage::well_known_keys::EXTRINSIC_INDEX;
|
||||
use sp_core::storage::ChildInfo;
|
||||
use crate::backend::InMemory;
|
||||
use crate::InMemoryBackend;
|
||||
use crate::changes_trie::{RootsStorage, Configuration, storage::InMemoryStorage};
|
||||
use crate::changes_trie::build_cache::{IncompleteCacheAction, IncompleteCachedBuildData};
|
||||
use crate::overlayed_changes::{OverlayedValue, OverlayedChangeSet};
|
||||
@@ -351,20 +351,20 @@ mod test {
|
||||
const CHILD_INFO_2: ChildInfo<'static> = ChildInfo::new_default(b"unique_id_2");
|
||||
|
||||
fn prepare_for_build(zero: u64) -> (
|
||||
InMemory<Blake2Hasher>,
|
||||
InMemoryBackend<Blake2Hasher>,
|
||||
InMemoryStorage<Blake2Hasher, u64>,
|
||||
OverlayedChanges,
|
||||
Configuration,
|
||||
) {
|
||||
let config = Configuration { digest_interval: 4, digest_levels: 2 };
|
||||
let backend: InMemory<_> = vec![
|
||||
let backend: InMemoryBackend<_> = vec![
|
||||
(vec![100], vec![255]),
|
||||
(vec![101], vec![255]),
|
||||
(vec![102], vec![255]),
|
||||
(vec![103], vec![255]),
|
||||
(vec![104], vec![255]),
|
||||
(vec![105], vec![255]),
|
||||
].into_iter().collect::<::std::collections::BTreeMap<_, _>>().into();
|
||||
].into_iter().collect::<std::collections::BTreeMap<_, _>>().into();
|
||||
let child_trie_key1 = b"1".to_vec();
|
||||
let child_trie_key2 = b"2".to_vec();
|
||||
let storage = InMemoryStorage::with_inputs(vec![
|
||||
|
||||
@@ -84,37 +84,37 @@ pub const NO_EXTRINSIC_INDEX: u32 = 0xffffffff;
|
||||
/// Requirements for block number that can be used with changes tries.
|
||||
pub trait BlockNumber:
|
||||
Send + Sync + 'static +
|
||||
::std::fmt::Display +
|
||||
std::fmt::Display +
|
||||
Clone +
|
||||
From<u32> + TryInto<u32> + One + Zero +
|
||||
PartialEq + Ord +
|
||||
::std::hash::Hash +
|
||||
::std::ops::Add<Self, Output=Self> + ::std::ops::Sub<Self, Output=Self> +
|
||||
::std::ops::Mul<Self, Output=Self> + ::std::ops::Div<Self, Output=Self> +
|
||||
::std::ops::Rem<Self, Output=Self> +
|
||||
::std::ops::AddAssign<Self> +
|
||||
std::hash::Hash +
|
||||
std::ops::Add<Self, Output=Self> + ::std::ops::Sub<Self, Output=Self> +
|
||||
std::ops::Mul<Self, Output=Self> + ::std::ops::Div<Self, Output=Self> +
|
||||
std::ops::Rem<Self, Output=Self> +
|
||||
std::ops::AddAssign<Self> +
|
||||
num_traits::CheckedMul + num_traits::CheckedSub +
|
||||
Decode + Encode
|
||||
{}
|
||||
|
||||
impl<T> BlockNumber for T where T:
|
||||
Send + Sync + 'static +
|
||||
::std::fmt::Display +
|
||||
std::fmt::Display +
|
||||
Clone +
|
||||
From<u32> + TryInto<u32> + One + Zero +
|
||||
PartialEq + Ord +
|
||||
::std::hash::Hash +
|
||||
::std::ops::Add<Self, Output=Self> + ::std::ops::Sub<Self, Output=Self> +
|
||||
::std::ops::Mul<Self, Output=Self> + ::std::ops::Div<Self, Output=Self> +
|
||||
::std::ops::Rem<Self, Output=Self> +
|
||||
::std::ops::AddAssign<Self> +
|
||||
std::hash::Hash +
|
||||
std::ops::Add<Self, Output=Self> + ::std::ops::Sub<Self, Output=Self> +
|
||||
std::ops::Mul<Self, Output=Self> + ::std::ops::Div<Self, Output=Self> +
|
||||
std::ops::Rem<Self, Output=Self> +
|
||||
std::ops::AddAssign<Self> +
|
||||
num_traits::CheckedMul + num_traits::CheckedSub +
|
||||
Decode + Encode,
|
||||
{}
|
||||
|
||||
/// Block identifier that could be used to determine fork of this block.
|
||||
#[derive(Debug)]
|
||||
pub struct AnchorBlockId<Hash: ::std::fmt::Debug, Number: BlockNumber> {
|
||||
pub struct AnchorBlockId<Hash: std::fmt::Debug, Number: BlockNumber> {
|
||||
/// Hash of this block.
|
||||
pub hash: Hash,
|
||||
/// Number of this block.
|
||||
@@ -173,12 +173,14 @@ pub struct ConfigurationRange<'a, N> {
|
||||
/// Compute the changes trie root and transaction for given block.
|
||||
/// Returns Err(()) if unknown `parent_hash` has been passed.
|
||||
/// Returns Ok(None) if there's no data to perform computation.
|
||||
/// Panics if background storage returns an error OR if insert to MemoryDB fails.
|
||||
/// Panics if background storage returns an error (and `panic_on_storage_error` is `true`) OR
|
||||
/// if insert to MemoryDB fails.
|
||||
pub fn build_changes_trie<'a, B: Backend<H>, S: Storage<H, Number>, H: Hasher, Number: BlockNumber>(
|
||||
backend: &B,
|
||||
storage: Option<&'a S>,
|
||||
changes: &OverlayedChanges,
|
||||
parent_hash: H::Out,
|
||||
panic_on_storage_error: bool,
|
||||
) -> Result<Option<(MemoryDB<H>, H::Out, CacheAction<H::Out, Number>)>, ()>
|
||||
where
|
||||
H::Out: Ord + 'static + Encode,
|
||||
@@ -188,6 +190,19 @@ pub fn build_changes_trie<'a, B: Backend<H>, S: Storage<H, Number>, H: Hasher, N
|
||||
_ => return Ok(None),
|
||||
};
|
||||
|
||||
/// Panics when `res.is_err() && panic`, otherwise it returns `Err(())` on an error.
|
||||
fn maybe_panic<R, E: std::fmt::Debug>(
|
||||
res: std::result::Result<R, E>,
|
||||
panic: bool,
|
||||
) -> std::result::Result<R, ()> {
|
||||
res.map(Ok)
|
||||
.unwrap_or_else(|e| if panic {
|
||||
panic!("changes trie: storage access is not allowed to fail within runtime: {:?}", e)
|
||||
} else {
|
||||
Err(())
|
||||
})
|
||||
}
|
||||
|
||||
// FIXME: remove this in https://github.com/paritytech/substrate/pull/3201
|
||||
let config = ConfigurationRange {
|
||||
config,
|
||||
@@ -200,13 +215,16 @@ pub fn build_changes_trie<'a, B: Backend<H>, S: Storage<H, Number>, H: Hasher, N
|
||||
let block = parent.number.clone() + One::one();
|
||||
|
||||
// storage errors are considered fatal (similar to situations when runtime fetches values from storage)
|
||||
let (input_pairs, child_input_pairs, digest_input_blocks) = prepare_input::<B, H, Number>(
|
||||
backend,
|
||||
storage,
|
||||
config.clone(),
|
||||
changes,
|
||||
&parent,
|
||||
).expect("changes trie: storage access is not allowed to fail within runtime");
|
||||
let (input_pairs, child_input_pairs, digest_input_blocks) = maybe_panic(
|
||||
prepare_input::<B, H, Number>(
|
||||
backend,
|
||||
storage,
|
||||
config.clone(),
|
||||
changes,
|
||||
&parent,
|
||||
),
|
||||
panic_on_storage_error,
|
||||
)?;
|
||||
|
||||
// prepare cached data
|
||||
let mut cache_action = prepare_cached_build_data(config, block.clone());
|
||||
@@ -230,8 +248,7 @@ pub fn build_changes_trie<'a, B: Backend<H>, S: Storage<H, Number>, H: Hasher, N
|
||||
|
||||
let (key, value) = input_pair.into();
|
||||
not_empty = true;
|
||||
trie.insert(&key, &value)
|
||||
.expect("changes trie: insertion to trie is not allowed to fail within runtime");
|
||||
maybe_panic(trie.insert(&key, &value), panic_on_storage_error)?;
|
||||
}
|
||||
|
||||
cache_action = cache_action.insert(
|
||||
@@ -247,8 +264,7 @@ pub fn build_changes_trie<'a, B: Backend<H>, S: Storage<H, Number>, H: Hasher, N
|
||||
{
|
||||
let mut trie = TrieDBMut::<H>::new(&mut mdb, &mut root);
|
||||
for (key, value) in child_roots.into_iter().map(Into::into) {
|
||||
trie.insert(&key, &value)
|
||||
.expect("changes trie: insertion to trie is not allowed to fail within runtime");
|
||||
maybe_panic(trie.insert(&key, &value), panic_on_storage_error)?;
|
||||
}
|
||||
|
||||
let mut storage_changed_keys = HashSet::new();
|
||||
@@ -260,9 +276,9 @@ pub fn build_changes_trie<'a, B: Backend<H>, S: Storage<H, Number>, H: Hasher, N
|
||||
}
|
||||
|
||||
let (key, value) = input_pair.into();
|
||||
trie.insert(&key, &value)
|
||||
.expect("changes trie: insertion to trie is not allowed to fail within runtime");
|
||||
maybe_panic(trie.insert(&key, &value), panic_on_storage_error)?;
|
||||
}
|
||||
|
||||
cache_action = cache_action.insert(
|
||||
None,
|
||||
storage_changed_keys,
|
||||
|
||||
@@ -38,7 +38,7 @@ pub struct InMemoryStorage<H: Hasher, Number: BlockNumber> {
|
||||
/// Adapter for using changes trie storage as a TrieBackendEssence' storage.
|
||||
pub struct TrieBackendAdapter<'a, H: Hasher, Number: BlockNumber> {
|
||||
storage: &'a dyn Storage<H, Number>,
|
||||
_hasher: ::std::marker::PhantomData<(H, Number)>,
|
||||
_hasher: std::marker::PhantomData<(H, Number)>,
|
||||
}
|
||||
|
||||
struct InMemoryStorageData<H: Hasher, Number: BlockNumber> {
|
||||
|
||||
Reference in New Issue
Block a user