// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Substrate is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . //! A method call executor interface. use std::{panic::UnwindSafe, result, cell::RefCell}; use codec::{Encode, Decode}; use sp_runtime::{ generic::BlockId, traits::{Block as BlockT, HasherFor}, }; use sp_state_machine::{ OverlayedChanges, ExecutionManager, ExecutionStrategy, StorageProof, }; use sc_executor::{RuntimeVersion, NativeVersion}; use sp_externalities::Extensions; use sp_core::NativeOrEncoded; use sp_api::{ProofRecorder, InitializeBlock, StorageTransactionCache}; /// Method call executor. pub trait CallExecutor { /// Externalities error type. type Error: sp_state_machine::Error; /// The backend used by the node. type Backend: crate::backend::Backend; /// Execute a call to a contract on top of state in a block of given hash. /// /// No changes are made. fn call( &self, id: &BlockId, method: &str, call_data: &[u8], strategy: ExecutionStrategy, extensions: Option, ) -> Result, sp_blockchain::Error>; /// Execute a contextual call on top of state in a block of a given hash. /// /// No changes are made. /// Before executing the method, passed header is installed as the current header /// of the execution context. fn contextual_call< 'a, IB: Fn() -> sp_blockchain::Result<()>, EM: Fn( Result, Self::Error>, Result, Self::Error> ) -> Result, Self::Error>, R: Encode + Decode + PartialEq, NC: FnOnce() -> result::Result + UnwindSafe, >( &self, initialize_block_fn: IB, at: &BlockId, method: &str, call_data: &[u8], changes: &RefCell, storage_transaction_cache: Option<&RefCell< StorageTransactionCache>::State>, >>, initialize_block: InitializeBlock<'a, B>, execution_manager: ExecutionManager, native_call: Option, proof_recorder: &Option>, extensions: Option, ) -> sp_blockchain::Result> where ExecutionManager: Clone; /// Extract RuntimeVersion of given block /// /// No changes are made. fn runtime_version(&self, id: &BlockId) -> Result; /// Execute a call to a contract on top of given state, gathering execution proof. /// /// No changes are made. fn prove_at_state>>( &self, mut state: S, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] ) -> Result<(Vec, StorageProof), sp_blockchain::Error> { let trie_state = state.as_trie_backend() .ok_or_else(|| Box::new(sp_state_machine::ExecutionError::UnableToGenerateProof) as Box )?; self.prove_at_trie_state(trie_state, overlay, method, call_data) } /// Execute a call to a contract on top of given trie state, gathering execution proof. /// /// No changes are made. fn prove_at_trie_state>>( &self, trie_state: &sp_state_machine::TrieBackend>, overlay: &mut OverlayedChanges, method: &str, call_data: &[u8] ) -> Result<(Vec, StorageProof), sp_blockchain::Error>; /// Get runtime version if supported. fn native_runtime_version(&self) -> Option<&NativeVersion>; }