moonbeam_service/lazy_loading/
call_executor.rs

1// Copyright 2024 Moonbeam foundation
2// This file is part of Moonbeam.
3
4// Moonbeam is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Moonbeam is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16
17use sc_client_api::execution_extensions::ExecutionExtensions;
18use sc_executor::{RuntimeVersion, RuntimeVersionOf};
19use sp_api::ProofRecorder;
20use sp_core::traits::{CallContext, Externalities};
21use sp_runtime::traits::{Block as BlockT, HashingFor};
22use sp_state_machine::{OverlayedChanges, StorageProof};
23use std::cell::RefCell;
24use std::marker::PhantomData;
25
26/// Call executor that executes methods locally, querying all required
27/// data from local backend.
28#[derive(Clone)]
29pub struct LazyLoadingCallExecutor<Block, Executor> {
30	inner: Executor,
31	_phantom_data: PhantomData<Block>,
32}
33
34impl<Block: BlockT, Executor> LazyLoadingCallExecutor<Block, Executor>
35where
36	Executor: sc_client_api::CallExecutor<Block> + Clone + 'static,
37{
38	/// Creates new instance of local call executor.
39	pub fn new(executor: Executor) -> sp_blockchain::Result<Self> {
40		Ok(LazyLoadingCallExecutor {
41			inner: executor,
42			_phantom_data: Default::default(),
43		})
44	}
45}
46
47impl<Block, Executor> sc_client_api::CallExecutor<Block>
48	for LazyLoadingCallExecutor<Block, Executor>
49where
50	Executor: sc_client_api::CallExecutor<Block>,
51	Block: BlockT,
52{
53	type Error = Executor::Error;
54
55	type Backend = Executor::Backend;
56
57	fn execution_extensions(&self) -> &ExecutionExtensions<Block> {
58		&self.inner.execution_extensions()
59	}
60
61	fn call(
62		&self,
63		at_hash: Block::Hash,
64		method: &str,
65		call_data: &[u8],
66		context: CallContext,
67	) -> sp_blockchain::Result<Vec<u8>> {
68		self.inner.call(at_hash, method, call_data, context)
69	}
70
71	fn contextual_call(
72		&self,
73		at_hash: Block::Hash,
74		method: &str,
75		call_data: &[u8],
76		changes: &RefCell<OverlayedChanges<HashingFor<Block>>>,
77		// not used in lazy loading
78		_recorder: &Option<ProofRecorder<Block>>,
79		call_context: CallContext,
80		extensions: &RefCell<sp_externalities::Extensions>,
81	) -> Result<Vec<u8>, sp_blockchain::Error> {
82		self.inner.contextual_call(
83			at_hash,
84			method,
85			call_data,
86			changes,
87			&None,
88			call_context,
89			extensions,
90		)
91	}
92
93	fn runtime_version(&self, at_hash: Block::Hash) -> sp_blockchain::Result<RuntimeVersion> {
94		sc_client_api::CallExecutor::runtime_version(&self.inner, at_hash)
95	}
96
97	fn prove_execution(
98		&self,
99		at_hash: Block::Hash,
100		method: &str,
101		call_data: &[u8],
102	) -> sp_blockchain::Result<(Vec<u8>, StorageProof)> {
103		self.inner.prove_execution(at_hash, method, call_data)
104	}
105}
106
107impl<Block, Executor> RuntimeVersionOf for LazyLoadingCallExecutor<Block, Executor>
108where
109	Executor: RuntimeVersionOf,
110	Block: BlockT,
111{
112	fn runtime_version(
113		&self,
114		ext: &mut dyn Externalities,
115		runtime_code: &sp_core::traits::RuntimeCode,
116	) -> Result<RuntimeVersion, sc_executor::error::Error> {
117		self.inner.runtime_version(ext, runtime_code)
118	}
119}