mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 08:51:09 +00:00
Don't include :code by default in storage proofs (#5179)
* Don't include `:code` by default in storage proofs (#5060) * Adds test to verify that the runtime currently is always contained in the proof * Start passing the runtime wasm code from the outside * Fix compilation * More build fixes * Make the test work as expected now :) * Last fixes * Fixes benchmarks * Review feedback * Apply suggestions from code review Co-Authored-By: Sergei Pepyakin <sergei@parity.io> * Review feedback * Fix compilation Co-authored-by: Sergei Pepyakin <s.pepyakin@gmail.com> * Fix compilation and change the way `RuntimeCode` works * Fix tests * Switch to `Cow` Co-authored-by: Benjamin Kampmann <ben@gnunicorn.org> Co-authored-by: Sergei Pepyakin <s.pepyakin@gmail.com>
This commit is contained in:
@@ -19,9 +19,7 @@
|
||||
use crate::{crypto::KeyTypeId, ed25519, sr25519};
|
||||
|
||||
use std::{
|
||||
fmt::{Debug, Display},
|
||||
panic::UnwindSafe,
|
||||
sync::Arc,
|
||||
fmt::{Debug, Display}, panic::UnwindSafe, sync::Arc, borrow::Cow,
|
||||
};
|
||||
|
||||
pub use sp_externalities::{Externalities, ExternalitiesExt};
|
||||
@@ -97,6 +95,7 @@ pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static {
|
||||
>(
|
||||
&self,
|
||||
ext: &mut dyn Externalities,
|
||||
runtime_code: &RuntimeCode,
|
||||
method: &str,
|
||||
data: &[u8],
|
||||
use_native: bool,
|
||||
@@ -104,15 +103,98 @@ pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static {
|
||||
) -> (Result<crate::NativeOrEncoded<R>, Self::Error>, bool);
|
||||
}
|
||||
|
||||
/// Something that can fetch the runtime `:code`.
|
||||
pub trait FetchRuntimeCode {
|
||||
/// Fetch the runtime `:code`.
|
||||
///
|
||||
/// If the `:code` could not be found/not available, `None` should be returned.
|
||||
fn fetch_runtime_code<'a>(&'a self) -> Option<Cow<'a, [u8]>>;
|
||||
}
|
||||
|
||||
/// Wrapper to use a `u8` slice or `Vec` as [`FetchRuntimeCode`].
|
||||
pub struct WrappedRuntimeCode<'a>(pub std::borrow::Cow<'a, [u8]>);
|
||||
|
||||
impl<'a> FetchRuntimeCode for WrappedRuntimeCode<'a> {
|
||||
fn fetch_runtime_code<'b>(&'b self) -> Option<Cow<'b, [u8]>> {
|
||||
Some(self.0.as_ref().into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Type that implements [`FetchRuntimeCode`] and always returns `None`.
|
||||
pub struct NoneFetchRuntimeCode;
|
||||
|
||||
impl FetchRuntimeCode for NoneFetchRuntimeCode {
|
||||
fn fetch_runtime_code<'a>(&'a self) -> Option<Cow<'a, [u8]>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// The Wasm code of a Substrate runtime.
|
||||
#[derive(Clone)]
|
||||
pub struct RuntimeCode<'a> {
|
||||
/// The code fetcher that can be used to lazily fetch the code.
|
||||
pub code_fetcher: &'a dyn FetchRuntimeCode,
|
||||
/// The optional heap pages this `code` should be executed with.
|
||||
///
|
||||
/// If `None` are given, the default value of the executor will be used.
|
||||
pub heap_pages: Option<u64>,
|
||||
/// The SCALE encoded hash of `code`.
|
||||
///
|
||||
/// The hashing algorithm isn't that important, as long as all runtime
|
||||
/// code instances use the same.
|
||||
pub hash: Vec<u8>,
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for RuntimeCode<'a> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.hash == other.hash
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> RuntimeCode<'a> {
|
||||
/// Create an empty instance.
|
||||
///
|
||||
/// This is only useful for tests that don't want to execute any code.
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
code_fetcher: &NoneFetchRuntimeCode,
|
||||
hash: Vec::new(),
|
||||
heap_pages: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FetchRuntimeCode for RuntimeCode<'a> {
|
||||
fn fetch_runtime_code<'b>(&'b self) -> Option<Cow<'b, [u8]>> {
|
||||
self.code_fetcher.fetch_runtime_code()
|
||||
}
|
||||
}
|
||||
|
||||
/// Could not find the `:code` in the externalities while initializing the [`RuntimeCode`].
|
||||
#[derive(Debug)]
|
||||
pub struct CodeNotFound;
|
||||
|
||||
impl std::fmt::Display for CodeNotFound {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
write!(f, "the storage entry `:code` doesn't have any code")
|
||||
}
|
||||
}
|
||||
|
||||
/// Something that can call a method in a WASM blob.
|
||||
pub trait CallInWasm: Send + Sync {
|
||||
/// Call the given `method` in the given `wasm_blob` using `call_data` (SCALE encoded arguments)
|
||||
/// to decode the arguments for the method.
|
||||
///
|
||||
/// Returns the SCALE encoded return value of the method.
|
||||
///
|
||||
/// # Note
|
||||
///
|
||||
/// If `code_hash` is `Some(_)` the `wasm_code` module and instance will be cached internally,
|
||||
/// otherwise it is thrown away after the call.
|
||||
fn call_in_wasm(
|
||||
&self,
|
||||
wasm_blob: &[u8],
|
||||
wasm_code: &[u8],
|
||||
code_hash: Option<Vec<u8>>,
|
||||
method: &str,
|
||||
call_data: &[u8],
|
||||
ext: &mut dyn Externalities,
|
||||
|
||||
Reference in New Issue
Block a user