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>
This commit is contained in:
Benjamin Kampmann
2020-03-04 20:26:16 +01:00
committed by GitHub
parent 67837c6233
commit 6ee39261c8
31 changed files with 480 additions and 183 deletions
+65
View File
@@ -98,6 +98,7 @@ pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static {
>(
&self,
ext: &mut E,
runtime_code: &RuntimeCode,
method: &str,
data: &[u8],
use_native: bool,
@@ -105,6 +106,70 @@ pub trait CodeExecutor: Sized + Send + Sync + CallInWasm + Clone + 'static {
) -> (Result<crate::NativeOrEncoded<R>, Self::Error>, bool);
}
/// The Wasm code of a Substrate runtime.
#[derive(Debug, Clone, codec::Encode, codec::Decode)]
pub struct RuntimeCode {
/// The actual Wasm code as binary blob.
pub code: Vec<u8>,
/// 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 PartialEq for RuntimeCode {
fn eq(&self, other: &Self) -> bool {
self.hash == other.hash
}
}
impl RuntimeCode {
/// Create an `RuntimeCode` instance from the given `Externalities`.
///
/// Extracts the code and the heap pages using the well known keys.
///
/// Returns an error if the code could not be found.
pub fn from_externalities(ext: &dyn Externalities) -> Result<Self, CodeNotFound> {
let code = ext.storage(sp_storage::well_known_keys::CODE).ok_or(CodeNotFound)?;
let hash = ext.storage_hash(sp_storage::well_known_keys::CODE).ok_or(CodeNotFound)?;
let heap_pages = ext.storage(sp_storage::well_known_keys::HEAP_PAGES)
.and_then(|hp| codec::Decode::decode(&mut &hp[..]).ok());
Ok(Self {
code,
hash,
heap_pages,
})
}
/// Create an empty instance.
///
/// This is only useful for tests that don't want to execute any code.
pub fn empty() -> Self {
Self {
code: Vec::new(),
hash: Vec::new(),
heap_pages: None,
}
}
}
/// 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)