anvil_polkadot/substrate_node/service/
executor.rs1use crate::substrate_node::{
2 host::{PublicKeyToHashOverride, SenderAddressRecoveryOverride},
3 service::{Backend, backend::StorageOverrides},
4};
5use parking_lot::Mutex;
6use polkadot_sdk::{
7 parachains_common::{Hash, opaque::Block},
8 sc_client_api::{Backend as _, CallExecutor, execution_extensions::ExecutionExtensions},
9 sc_executor::{self, RuntimeVersion, RuntimeVersionOf},
10 sc_service,
11 sp_api::{CallContext, ProofRecorder},
12 sp_blockchain::{self, HeaderBackend},
13 sp_core, sp_externalities, sp_io,
14 sp_runtime::{generic::BlockId, traits::HashingFor},
15 sp_state_machine::{OverlayedChanges, StorageProof},
16 sp_storage::ChildInfo,
17 sp_version,
18 sp_wasm_interface::ExtendedHostFunctions,
19};
20use std::{cell::RefCell, sync::Arc};
21
22pub type WasmExecutor = sc_executor::WasmExecutor<
24 ExtendedHostFunctions<
25 ExtendedHostFunctions<sp_io::SubstrateHostFunctions, SenderAddressRecoveryOverride>,
26 PublicKeyToHashOverride,
27 >,
28>;
29
30type InnerLocalCallExecutor = sc_service::client::LocalCallExecutor<Block, Backend, WasmExecutor>;
31
32#[derive(Clone)]
33pub struct Executor {
35 inner: InnerLocalCallExecutor,
36 storage_overrides: Arc<Mutex<StorageOverrides>>,
37 backend: Arc<Backend>,
38}
39
40impl Executor {
41 pub fn new(
42 inner: InnerLocalCallExecutor,
43 storage_overrides: Arc<Mutex<StorageOverrides>>,
44 backend: Arc<Backend>,
45 ) -> Self {
46 Self { inner, storage_overrides, backend }
47 }
48
49 fn apply_overrides(&self, hash: &Hash, overlay: &mut OverlayedChanges<HashingFor<Block>>) {
50 let overrides = { self.storage_overrides.lock().get(hash) };
51 let Some(overrides) = overrides else { return };
52
53 for (key, val) in overrides.top {
54 overlay.set_storage(key, val);
55 }
56
57 for (child_key, child_map) in overrides.children {
58 let child_info = ChildInfo::new_default_from_vec(child_key);
59
60 for (key, val) in child_map {
61 overlay.set_child_storage(&child_info, key, val);
62 }
63 }
64 }
65}
66
67impl CallExecutor<Block> for Executor {
68 type Error = <InnerLocalCallExecutor as CallExecutor<Block>>::Error;
69
70 type Backend = Backend;
71
72 fn execution_extensions(&self) -> &ExecutionExtensions<Block> {
73 self.inner.execution_extensions()
74 }
75
76 fn call(
77 &self,
78 at_hash: Hash,
79 method: &str,
80 call_data: &[u8],
81 context: CallContext,
82 ) -> sp_blockchain::Result<Vec<u8>> {
83 let at_number =
84 self.backend.blockchain().expect_block_number_from_id(&BlockId::Hash(at_hash))?;
85 let extensions = self.execution_extensions().extensions(at_hash, at_number);
86
87 let mut changes = OverlayedChanges::default();
88
89 self.apply_overrides(&at_hash, &mut changes);
90
91 self.contextual_call(
92 at_hash,
93 method,
94 call_data,
95 &RefCell::new(changes),
96 &None,
97 context,
98 &RefCell::new(extensions),
99 )
100 }
101
102 fn contextual_call(
103 &self,
104 at_hash: Hash,
105 method: &str,
106 call_data: &[u8],
107 changes: &RefCell<OverlayedChanges<HashingFor<Block>>>,
108 recorder: &Option<ProofRecorder<Block>>,
109 call_context: CallContext,
110 extensions: &RefCell<sp_externalities::Extensions>,
111 ) -> Result<Vec<u8>, sp_blockchain::Error> {
112 let apply_overrides = (method == "Core_initialize_block"
113 && call_context == CallContext::Onchain)
114 || call_context == CallContext::Offchain;
115
116 if apply_overrides {
117 self.apply_overrides(&at_hash, &mut changes.borrow_mut());
118 }
119
120 self.inner.contextual_call(
121 at_hash,
122 method,
123 call_data,
124 changes,
125 recorder,
126 call_context,
127 extensions,
128 )
129 }
130
131 fn runtime_version(&self, at_hash: Hash) -> sp_blockchain::Result<RuntimeVersion> {
132 CallExecutor::runtime_version(&self.inner, at_hash)
133 }
134
135 fn prove_execution(
136 &self,
137 at_hash: Hash,
138 method: &str,
139 call_data: &[u8],
140 ) -> sp_blockchain::Result<(Vec<u8>, StorageProof)> {
141 self.inner.prove_execution(at_hash, method, call_data)
142 }
143}
144
145impl RuntimeVersionOf for Executor {
146 fn runtime_version(
147 &self,
148 ext: &mut dyn sp_externalities::Externalities,
149 runtime_code: &sp_core::traits::RuntimeCode<'_>,
150 ) -> Result<sp_version::RuntimeVersion, sc_executor::error::Error> {
151 RuntimeVersionOf::runtime_version(&self.inner, ext, runtime_code)
152 }
153}