mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-10 17:11:03 +00:00
Never panic during execution proof check (#3504)
* do not panic during execution proof check * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * BackendTrustLevel enum * up runtime version * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * Update core/state-machine/src/lib.rs Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com> * fixed some grumbles * Update core/state-machine/src/testing.rs Co-Authored-By: Gavin Wood <gavin@parity.io> * Update core/state-machine/src/lib.rs Co-Authored-By: Gavin Wood <gavin@parity.io> * mov where * spaces -> tabs (to restart build)
This commit is contained in:
committed by
GitHub
parent
9607afd629
commit
010395e620
@@ -111,7 +111,7 @@ fn prepare_extrinsics_input<'a, B, H, Number>(
|
||||
block: block.clone(),
|
||||
storage_key: storage_key.clone(),
|
||||
};
|
||||
|
||||
|
||||
let iter = prepare_extrinsics_input_inner(backend, block, changes, Some(storage_key))?;
|
||||
children_result.insert(child_index, iter);
|
||||
}
|
||||
@@ -120,7 +120,7 @@ fn prepare_extrinsics_input<'a, B, H, Number>(
|
||||
|
||||
Ok((top, children_result))
|
||||
}
|
||||
|
||||
|
||||
fn prepare_extrinsics_input_inner<'a, B, H, Number>(
|
||||
backend: &'a B,
|
||||
block: &Number,
|
||||
|
||||
@@ -100,7 +100,7 @@ impl<H: Hasher, Number: BlockNumber> InMemoryStorage<H, Number> {
|
||||
for (storage_key, child_input) in children_inputs {
|
||||
for (block, pairs) in child_input {
|
||||
let root = insert_into_memory_db::<H, _>(&mut mdb, pairs.into_iter().map(Into::into));
|
||||
|
||||
|
||||
if let Some(root) = root {
|
||||
let ix = if let Some(ix) = top_inputs.iter().position(|v| v.0 == block) {
|
||||
ix
|
||||
|
||||
@@ -174,13 +174,12 @@ where
|
||||
}
|
||||
|
||||
impl<'a, B, T, H, N, O> Externalities<H> for Ext<'a, H, N, B, T, O>
|
||||
where
|
||||
H: Hasher,
|
||||
where H: Hasher,
|
||||
B: 'a + Backend<H>,
|
||||
T: 'a + ChangesTrieStorage<H, N>,
|
||||
O: 'a + offchain::Externalities,
|
||||
H::Out: Ord + 'static,
|
||||
N: crate::changes_trie::BlockNumber,
|
||||
O: 'a + offchain::Externalities,
|
||||
{
|
||||
fn storage(&self, key: &[u8]) -> Option<Vec<u8>> {
|
||||
let _guard = panic_handler::AbortGuard::force_abort();
|
||||
@@ -371,6 +370,7 @@ where
|
||||
fn keystore(&self) -> Option<BareCryptoStorePtr> {
|
||||
self.keystore.clone()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -89,13 +89,26 @@ pub enum ExecutionStrategy {
|
||||
NativeElseWasm,
|
||||
}
|
||||
|
||||
/// Storage backend trust level.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum BackendTrustLevel {
|
||||
/// Panics from trusted backends are considered justified, and never caught.
|
||||
Trusted,
|
||||
/// Panics from untrusted backend are caught and interpreted as runtime error.
|
||||
/// Untrusted backend may be missing some parts of the trie, so panics are not considered
|
||||
/// fatal.
|
||||
Untrusted,
|
||||
}
|
||||
|
||||
/// Like `ExecutionStrategy` only it also stores a handler in case of consensus failure.
|
||||
#[derive(Clone)]
|
||||
pub enum ExecutionManager<F> {
|
||||
/// Execute with the native equivalent if it is compatible with the given wasm module; otherwise fall back to the wasm.
|
||||
NativeWhenPossible,
|
||||
/// Use the given wasm module.
|
||||
AlwaysWasm,
|
||||
/// Use the given wasm module. The backend on which code is executed code could be
|
||||
/// trusted to provide all storage or not (i.e. the light client cannot be trusted to provide
|
||||
/// for all storage queries since the storage entries it has come from an external node).
|
||||
AlwaysWasm(BackendTrustLevel),
|
||||
/// Run with both the wasm and the native variant (if compatible). Call `F` in the case of any discrepency.
|
||||
Both(F),
|
||||
/// First native, then if that fails or is not possible, wasm.
|
||||
@@ -106,7 +119,7 @@ impl<'a, F> From<&'a ExecutionManager<F>> for ExecutionStrategy {
|
||||
fn from(s: &'a ExecutionManager<F>) -> Self {
|
||||
match *s {
|
||||
ExecutionManager::NativeWhenPossible => ExecutionStrategy::NativeWhenPossible,
|
||||
ExecutionManager::AlwaysWasm => ExecutionStrategy::AlwaysWasm,
|
||||
ExecutionManager::AlwaysWasm(_) => ExecutionStrategy::AlwaysWasm,
|
||||
ExecutionManager::NativeElseWasm => ExecutionStrategy::NativeElseWasm,
|
||||
ExecutionManager::Both(_) => ExecutionStrategy::Both,
|
||||
}
|
||||
@@ -119,7 +132,7 @@ impl ExecutionStrategy {
|
||||
self,
|
||||
) -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
match self {
|
||||
ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm,
|
||||
ExecutionStrategy::AlwaysWasm => ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted),
|
||||
ExecutionStrategy::NativeWhenPossible => ExecutionManager::NativeWhenPossible,
|
||||
ExecutionStrategy::NativeElseWasm => ExecutionManager::NativeElseWasm,
|
||||
ExecutionStrategy::Both => ExecutionManager::Both(|wasm_result, native_result| {
|
||||
@@ -139,6 +152,16 @@ pub fn native_else_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>
|
||||
ExecutionManager::NativeElseWasm
|
||||
}
|
||||
|
||||
/// Evaluate to ExecutionManager::AlwaysWasm with trusted backend, without having to figure out the type.
|
||||
fn always_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
ExecutionManager::AlwaysWasm(BackendTrustLevel::Trusted)
|
||||
}
|
||||
|
||||
/// Evaluate ExecutionManager::AlwaysWasm with untrusted backend, without having to figure out the type.
|
||||
fn always_untrusted_wasm<E, R: Decode>() -> ExecutionManager<DefaultHandler<R, E>> {
|
||||
ExecutionManager::AlwaysWasm(BackendTrustLevel::Untrusted)
|
||||
}
|
||||
|
||||
/// The substrate state machine.
|
||||
pub struct StateMachine<'a, B, H, N, T, O, Exec> {
|
||||
backend: B,
|
||||
@@ -375,7 +398,11 @@ impl<'a, B, H, N, T, O, Exec> StateMachine<'a, B, H, N, T, O, Exec> where
|
||||
orig_prospective,
|
||||
)
|
||||
},
|
||||
ExecutionManager::AlwaysWasm => {
|
||||
ExecutionManager::AlwaysWasm(trust_level) => {
|
||||
let _abort_guard = match trust_level {
|
||||
BackendTrustLevel::Trusted => None,
|
||||
BackendTrustLevel::Untrusted => Some(panic_handler::AbortGuard::never_abort()),
|
||||
};
|
||||
let res = self.execute_aux(compute_tx, false, native_call);
|
||||
(res.0, res.2, res.3)
|
||||
},
|
||||
@@ -444,7 +471,7 @@ where
|
||||
);
|
||||
|
||||
let (result, _, _) = sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
native_else_wasm(),
|
||||
always_wasm(),
|
||||
false,
|
||||
None,
|
||||
)?;
|
||||
@@ -490,7 +517,7 @@ where
|
||||
);
|
||||
|
||||
sm.execute_using_consensus_failure_handler::<_, NeverNativeValue, fn() -> _>(
|
||||
native_else_wasm(),
|
||||
always_untrusted_wasm(),
|
||||
false,
|
||||
None,
|
||||
).map(|(result, _, _)| result.into_encoded())
|
||||
|
||||
@@ -142,11 +142,10 @@ impl<H: Hasher, N: ChangesTrieBlockNumber> From<StorageTuple> for TestExternalit
|
||||
}
|
||||
}
|
||||
|
||||
impl<H, N> Externalities<H> for TestExternalities<H, N>
|
||||
where
|
||||
H: Hasher,
|
||||
N: ChangesTrieBlockNumber,
|
||||
H::Out: Ord + 'static
|
||||
impl<H, N> Externalities<H> for TestExternalities<H, N> where
|
||||
H: Hasher,
|
||||
N: ChangesTrieBlockNumber,
|
||||
H::Out: Ord + 'static,
|
||||
{
|
||||
fn storage(&self, key: &[u8]) -> Option<Vec<u8>> {
|
||||
self.overlay.storage(key).map(|x| x.map(|x| x.to_vec())).unwrap_or_else(||
|
||||
|
||||
Reference in New Issue
Block a user