sc_simnode/
lib.rs

1// Copyright (C) 2023 Polytope Labs (Caymans) Ltd.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4// This program 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// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
16#![deny(missing_docs, unused_extern_crates)]
17
18//! ### sc-simnode
19
20use polkadot_sdk::*;
21
22use sc_client_api::ExecutorProvider;
23use sp_api::ConstructRuntimeApi;
24use sp_blockchain::HeaderBackend;
25use sp_runtime::traits::{Block as BlockT, TransactionExtension};
26use sp_state_machine::{Ext, OverlayedChanges};
27use std::sync::Arc;
28
29pub mod cli;
30pub mod client;
31pub mod overrides;
32pub mod rpc;
33pub mod sproof;
34
35pub use cli::*;
36pub use client::*;
37pub use overrides::*;
38pub use rpc::*;
39pub use sproof::*;
40
41/// Wrapper trait for concrete type required by this testing framework.
42pub trait ChainInfo: Sized {
43	/// Opaque block type
44	type Block: BlockT;
45
46	/// Runtime
47	type Runtime: frame_system::Config;
48
49	/// RuntimeApi
50	type RuntimeApi: ConstructRuntimeApi<Self::Block, FullClientFor<Self>> + Send + Sync + 'static;
51
52	/// The signed extras required by the runtime
53	type SignedExtras: TransactionExtension<<Self::Runtime as frame_system::Config>::RuntimeCall>;
54
55	/// This is for cases you don't yet have the simnode runtime api implemented.
56	/// this function is caled in an externalities provided environment, so feel free to read state.
57	fn signed_extras(
58		from: <Self::Runtime as frame_system::Config>::AccountId,
59	) -> Self::SignedExtras;
60}
61
62/// Runs the given closure in an externalities provided environment, over the blockchain state
63pub fn with_state<T: ChainInfo, R>(
64	client: Arc<FullClientFor<T>>,
65	id: Option<<T::Block as BlockT>::Hash>,
66	closure: impl FnOnce() -> R,
67) -> R {
68	let mut overlay = OverlayedChanges::default();
69	let id = id.unwrap_or_else(|| client.info().best_hash);
70	let block_number =
71		client.number(id).ok().flatten().unwrap_or_else(|| client.info().best_number);
72	let mut extensions = client.execution_extensions().extensions(id, block_number);
73	let state_backend = client.state_at(id).expect(&format!("State at block {} not found", id));
74
75	let mut ext = Ext::new(&mut overlay, &state_backend, Some(&mut extensions));
76	sp_externalities::set_and_run_with_externalities(&mut ext, closure)
77}