From 8ce691dcc163c4ca3fe90a33f87c8821d1a73412 Mon Sep 17 00:00:00 2001 From: Liu-Cheng Xu Date: Sun, 6 Mar 2022 19:59:51 +0800 Subject: [PATCH] Add `verify_execution_proof` to ProofProvider --- client/api/src/call_executor.rs | 14 ++++++++ client/api/src/proof_provider.rs | 12 +++++++ client/service/src/client/call_executor.rs | 41 ++++++++++++++++++++++ client/service/src/client/client.rs | 13 +++++++ 4 files changed, 80 insertions(+) diff --git a/client/api/src/call_executor.rs b/client/api/src/call_executor.rs index 15088a573600d..c3973fedd7184 100644 --- a/client/api/src/call_executor.rs +++ b/client/api/src/call_executor.rs @@ -107,4 +107,18 @@ pub trait CallExecutor: RuntimeVersionOf { call_data: &[u8], overlay: Option, ) -> Result<(Vec, StorageProof), sp_blockchain::Error>; + + /// Verify the execution of the given `method`. + /// + /// No changes are made. + fn verify_execution<'a>( + &'a self, + root: sp_core::H256, + proof: StorageProof, + at: &'a BlockId, + method: &'a str, + call_data: &'a [u8], + overlay: sp_api::OverlayedChanges, + runtime_code: Option>, + ) -> Result, sp_blockchain::Error>; } diff --git a/client/api/src/proof_provider.rs b/client/api/src/proof_provider.rs index 4fe145edcd575..4d2e8627266f3 100644 --- a/client/api/src/proof_provider.rs +++ b/client/api/src/proof_provider.rs @@ -52,6 +52,18 @@ pub trait ProofProvider { overlay: Option, ) -> sp_blockchain::Result<(Vec, StorageProof)>; + /// Verify the execution proof produced by [`execution_proof`]. + fn verify_execution_proof<'a>( + &'a self, + root: sp_core::H256, + proof: StorageProof, + id: &'a BlockId, + method: &'a str, + call_data: &'a [u8], + overlay: sp_api::OverlayedChanges, + runtime_code: Option>, + ) -> sp_blockchain::Result>; + /// Given a `BlockId` iterate over all storage values starting at `start_keys`. /// Last `start_keys` element contains last accessed key value. /// With multiple `start_keys`, first `start_keys` element is diff --git a/client/service/src/client/call_executor.rs b/client/service/src/client/call_executor.rs index 1dc513176f966..5addc1d23a5a2 100644 --- a/client/service/src/client/call_executor.rs +++ b/client/service/src/client/call_executor.rs @@ -318,6 +318,47 @@ where ) .map_err(Into::into) } + + fn verify_execution<'a>( + &self, + root: sp_core::H256, + proof: StorageProof, + at: &'a BlockId, + method: &'a str, + call_data: &'a [u8], + overlay: sp_api::OverlayedChanges, + maybe_runtime_code: Option>, + ) -> sp_blockchain::Result> { + let state = self.backend.state_at(*at)?; + + let trie_backend = state.as_trie_backend().ok_or_else(|| { + Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) + as Box + })?; + + let state_runtime_code = sp_state_machine::backend::BackendRuntimeCode::new(trie_backend); + let runtime_code = state_runtime_code.runtime_code().map_err(sp_blockchain::Error::RuntimeCode)?; + let runtime_code = self.check_override(runtime_code, at)?; + + // TODO: unwrap_or_else and then fix the lifetime issue. + let runtime_code = match maybe_runtime_code { + Some(runtime_code) => runtime_code, + None => runtime_code + }; + + let mut overlay = overlay; + sp_state_machine::execution_proof_check::( + root, + proof, + &mut overlay, + &self.executor, + self.spawn_handle.clone(), + method, + call_data, + &runtime_code, + ) + .map_err(Into::into) + } } impl RuntimeVersionOf for LocalCallExecutor diff --git a/client/service/src/client/client.rs b/client/service/src/client/client.rs index e312d14f34d44..bb68cf46395d8 100644 --- a/client/service/src/client/client.rs +++ b/client/service/src/client/client.rs @@ -1172,6 +1172,19 @@ where self.executor.prove_execution(id, method, call_data, overlay) } + fn verify_execution_proof<'a>( + &self, + root: sp_core::H256, + proof: StorageProof, + id: &'a BlockId, + method: &'a str, + call_data: &'a [u8], + overlay: sp_api::OverlayedChanges, + runtime_code: Option> + ) -> sp_blockchain::Result> { + self.executor.verify_execution(root, proof, id, method, call_data, overlay, runtime_code) + } + fn read_proof_collection( &self, id: &BlockId,