1use core::any::Any;
2
3pub mod api;
4pub mod client;
5mod error;
6pub mod macros;
7
8pub use frame_metadata::RuntimeMetadataPrefixed;
9pub use frame_support::weights::Weight;
10use frame_support::{
11 sp_runtime::traits::Dispatchable,
12 traits::fungible::Inspect,
13};
14use frame_system::{
15 EventRecord,
16 pallet_prelude::{
17 BlockNumberFor,
18 OriginFor,
19 },
20};
21use ink_primitives::U256;
22use ink_revive_types::evm::{
23 CallLog,
24 CallTrace,
25};
26pub use macros::{
27 BlockBuilder,
28 DefaultSandbox,
29};
30use pallet_revive::{
31 ContractResult,
32 ExecReturnValue,
33 InstantiateReturnValue,
34};
35use sp_core::Get;
36pub use {
38 frame_support::sp_runtime::testing::H256,
39 frame_support::{
40 self,
41 sp_runtime::{
42 AccountId32,
43 DispatchError,
44 },
45 },
46 frame_system,
47 pallet_balances,
48 pallet_revive,
49 pallet_timestamp,
50 paste,
51 sp_core::crypto::Ss58Codec,
52 sp_externalities::{
53 self,
54 Extension,
55 },
56 sp_io::TestExternalities,
57};
58
59pub use client::{
60 Client as SandboxClient,
61 preset,
62};
63pub use ink_e2e_macro::test;
64
65#[derive(Clone, Debug)]
67pub struct Snapshot {
68 pub storage: RawStorage,
70 pub storage_root: StorageRoot,
72}
73
74pub type RawStorage = Vec<(Vec<u8>, (Vec<u8>, i32))>;
75pub type StorageRoot = H256;
76
77type BalanceOf<R> =
79 <<R as pallet_revive::Config>::Currency as Inspect<AccountIdFor<R>>>::Balance;
80
81pub type AccountIdFor<R> = <R as frame_system::Config>::AccountId;
83
84pub type RuntimeCall<R> = <R as frame_system::Config>::RuntimeCall;
86
87pub type EventRecordOf<Runtime> = EventRecord<
89 <Runtime as frame_system::Config>::RuntimeEvent,
90 <Runtime as frame_system::Config>::Hash,
91>;
92
93pub type ContractInstantiateResultFor<Runtime> =
95 ContractResult<OriginFor<Runtime>, BalanceOf<Runtime>>;
96
97pub type ContractResultFor<Runtime> = ContractResult<Runtime, BalanceOf<Runtime>>;
98
99pub type ContractResultInstantiate<Runtime> =
100 ContractResult<InstantiateReturnValue, BalanceOf<Runtime>>;
101
102pub type ContractExecResultFor<Runtime> =
104 ContractResult<ExecReturnValue, BalanceOf<Runtime>>;
105
106pub type MapAccountResultFor = Result<(), DispatchError>;
108
109pub type RuntimeOf<S> = <S as Sandbox>::Runtime;
111
112pub type RuntimeEventOf<S> = <RuntimeOf<S> as frame_system::Config>::RuntimeEvent;
114
115pub trait Sandbox {
117 type Runtime: frame_system::Config;
119
120 fn execute_with<T>(&mut self, execute: impl FnOnce() -> T) -> T;
122
123 fn dry_run<T>(&mut self, action: impl FnOnce(&mut Self) -> T) -> T;
125
126 fn register_extension<E: Any + Extension>(&mut self, ext: E);
128
129 fn initialize_block(
131 _height: BlockNumberFor<Self::Runtime>,
132 _parent_hash: <Self::Runtime as frame_system::Config>::Hash,
133 ) {
134 }
135
136 fn finalize_block(
138 _height: BlockNumberFor<Self::Runtime>,
139 ) -> <Self::Runtime as frame_system::Config>::Hash {
140 Default::default()
141 }
142
143 fn default_actor() -> AccountIdFor<Self::Runtime>;
145
146 fn default_gas_limit() -> Weight {
147 Weight::from_parts(100_000_000_000_000, 6 * 1024 * 1024)
148 }
149
150 fn get_metadata() -> RuntimeMetadataPrefixed;
152
153 fn convert_account_to_origin(
155 account: AccountIdFor<Self::Runtime>,
156 ) -> <<Self::Runtime as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin;
157
158 fn take_snapshot(&mut self) -> Snapshot;
160
161 fn restore_snapshot(&mut self, snapshot: Snapshot);
163}
164
165pub fn balance_to_evm_value<R>(value: BalanceOf<R>) -> U256
175where
176 R: pallet_revive::Config,
177 BalanceOf<R>: Into<U256>,
178 U256: From<u32>,
179{
180 let native_to_eth_ratio: U256 =
181 <R as pallet_revive::Config>::NativeToEthRatio::get().into();
182 let evm_value: U256 = value.into();
183 native_to_eth_ratio.saturating_mul(evm_value)
184}
185
186pub fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace {
189 CallTrace {
190 from: t.from,
191 gas: t.gas,
192 gas_used: t.gas_used,
193 to: t.to,
194 input: t.input.0,
195 output: t.output.0,
196 error: t.error,
197 revert_reason: t.revert_reason,
198 calls: t.calls.into_iter().map(to_revive_trace).collect(),
199 logs: t
200 .logs
201 .into_iter()
202 .map(|log| {
203 CallLog {
204 address: log.address,
205 topics: log.topics,
206 data: log.data.0,
207 ..Default::default()
208 }
209 })
210 .collect(),
211 value: t.value,
212 call_type: to_revive_call_type(t.call_type),
213 }
214}
215
216fn to_revive_call_type(
218 ct: pallet_revive::evm::CallType,
219) -> ink_revive_types::evm::CallType {
220 match ct {
221 pallet_revive::evm::CallType::Call => ink_revive_types::evm::CallType::Call,
222 pallet_revive::evm::CallType::StaticCall => {
223 ink_revive_types::evm::CallType::StaticCall
224 }
225 pallet_revive::evm::CallType::DelegateCall => {
226 ink_revive_types::evm::CallType::DelegateCall
227 }
228 pallet_revive::evm::CallType::Create => ink_revive_types::evm::CallType::Create,
229 pallet_revive::evm::CallType::Create2 => ink_revive_types::evm::CallType::Create2,
230 }
231}
232
233pub fn to_revive_storage_deposit<B>(
235 sd: pallet_revive::StorageDeposit<B>,
236) -> ink_revive_types::StorageDeposit<B> {
237 match sd {
238 pallet_revive::StorageDeposit::Charge(b) => {
239 ink_revive_types::StorageDeposit::Charge(b)
240 }
241 pallet_revive::StorageDeposit::Refund(b) => {
242 ink_revive_types::StorageDeposit::Refund(b)
243 }
244 }
245}