sp_domains_fraud_proof/
execution_prover.rsuse crate::fraud_proof::ExecutionPhase;
use domain_block_builder::create_delta_backend;
use sc_client_api::backend::Backend;
use sp_api::StorageProof;
use sp_core::traits::CodeExecutor;
use sp_runtime::traits::{Block as BlockT, HashingFor};
use sp_state_machine::backend::AsTrieBackend;
use sp_state_machine::BackendTransaction;
use std::marker::PhantomData;
use std::sync::Arc;
pub struct ExecutionProver<Block, B, Exec> {
backend: Arc<B>,
executor: Arc<Exec>,
_phantom: PhantomData<Block>,
}
impl<Block, B, Exec> ExecutionProver<Block, B, Exec>
where
Block: BlockT,
B: Backend<Block>,
Exec: CodeExecutor + 'static,
{
pub fn new(backend: Arc<B>, executor: Arc<Exec>) -> Self {
Self {
backend,
executor,
_phantom: PhantomData::<Block>,
}
}
pub fn prove_execution(
&self,
at: Block::Hash,
execution_phase: &ExecutionPhase,
call_data: &[u8],
delta_changes: Option<(BackendTransaction<HashingFor<Block>>, Block::Hash)>,
) -> sp_blockchain::Result<StorageProof> {
let state = self.backend.state_at(at)?;
let trie_backend = state.as_trie_backend();
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)?;
if let Some((delta, post_delta_root)) = delta_changes {
let delta_backend = create_delta_backend(trie_backend, &delta, post_delta_root);
sp_state_machine::prove_execution_on_trie_backend(
&delta_backend,
&mut Default::default(),
&*self.executor,
execution_phase.execution_method(),
call_data,
&runtime_code,
&mut Default::default(),
)
.map(|(_ret, proof)| proof)
.map_err(Into::into)
} else {
sp_state_machine::prove_execution_on_trie_backend(
trie_backend,
&mut Default::default(),
&*self.executor,
execution_phase.execution_method(),
call_data,
&runtime_code,
&mut Default::default(),
)
.map(|(_ret, proof)| proof)
.map_err(Into::into)
}
}
}