1use core::any::Any;
2
3pub mod api;
4pub mod client;
5pub mod 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::{
23 Bytes,
24 evm::{
25 CallLog,
26 CallTrace,
27 },
28};
29pub use macros::{
30 AssetIdForTrustBackedAssets,
31 BlockBuilder,
32 DefaultSandbox,
33 TrustBackedAssetsInstance,
34};
35use pallet_revive::{
36 ContractResult,
37 ExecReturnValue,
38 InstantiateReturnValue,
39};
40use sp_core::Get;
41pub use {
43 frame_support::sp_runtime::testing::H256,
44 frame_support::{
45 self,
46 sp_runtime::{
47 AccountId32,
48 DispatchError,
49 },
50 },
51 frame_system,
52 ink_precompiles,
53 pallet_assets,
54 pallet_assets_precompiles,
55 pallet_balances,
56 pallet_revive,
57 pallet_timestamp,
58 pallet_transaction_payment,
59 paste,
60 scale,
61 sp_core::crypto::Ss58Codec,
62 sp_externalities::{
63 self,
64 Extension,
65 },
66 sp_io::TestExternalities,
67};
68
69pub use client::{
70 Client as SandboxClient,
71 preset,
72};
73pub use error::E2EError;
74pub use ink_e2e_macro::test;
75
76#[derive(Clone, Debug)]
78pub struct Snapshot {
79 pub storage: RawStorage,
81 pub storage_root: StorageRoot,
83}
84
85pub type RawStorage = Vec<(Vec<u8>, (Vec<u8>, i32))>;
86pub type StorageRoot = H256;
87
88type BalanceOf<R> =
90 <<R as pallet_revive::Config>::Currency as Inspect<AccountIdFor<R>>>::Balance;
91
92pub type AccountIdFor<R> = <R as frame_system::Config>::AccountId;
94
95pub type RuntimeCall<R> = <R as frame_system::Config>::RuntimeCall;
97
98pub type EventRecordOf<Runtime> = EventRecord<
100 <Runtime as frame_system::Config>::RuntimeEvent,
101 <Runtime as frame_system::Config>::Hash,
102>;
103
104pub type ContractInstantiateResultFor<Runtime> =
106 ContractResult<OriginFor<Runtime>, BalanceOf<Runtime>>;
107
108pub type ContractResultFor<Runtime> = ContractResult<Runtime, BalanceOf<Runtime>>;
109
110pub type ContractResultInstantiate<Runtime> =
111 ContractResult<InstantiateReturnValue, BalanceOf<Runtime>>;
112
113pub type ContractExecResultFor<Runtime> =
115 ContractResult<ExecReturnValue, BalanceOf<Runtime>>;
116
117pub type MapAccountResultFor = Result<(), DispatchError>;
119
120pub type RuntimeOf<S> = <S as Sandbox>::Runtime;
122
123pub type RuntimeEventOf<S> = <RuntimeOf<S> as frame_system::Config>::RuntimeEvent;
125
126pub trait Sandbox {
128 type Runtime: frame_system::Config;
130
131 fn execute_with<T>(&mut self, execute: impl FnOnce() -> T) -> T;
133
134 fn dry_run<T>(&mut self, action: impl FnOnce(&mut Self) -> T) -> T;
136
137 fn register_extension<E: Any + Extension>(&mut self, ext: E);
139
140 fn initialize_block(
142 _height: BlockNumberFor<Self::Runtime>,
143 _parent_hash: <Self::Runtime as frame_system::Config>::Hash,
144 ) {
145 }
146
147 fn finalize_block(
149 _height: BlockNumberFor<Self::Runtime>,
150 ) -> <Self::Runtime as frame_system::Config>::Hash {
151 Default::default()
152 }
153
154 fn default_actor() -> AccountIdFor<Self::Runtime>;
156
157 fn default_gas_limit() -> Weight {
158 Weight::from_parts(100_000_000_000_000, 6 * 1024 * 1024)
159 }
160
161 fn get_metadata() -> RuntimeMetadataPrefixed;
163
164 fn convert_account_to_origin(
166 account: AccountIdFor<Self::Runtime>,
167 ) -> <<Self::Runtime as frame_system::Config>::RuntimeCall as Dispatchable>::RuntimeOrigin;
168
169 fn take_snapshot(&mut self) -> Snapshot;
171
172 fn restore_snapshot(&mut self, snapshot: Snapshot);
174}
175
176pub fn balance_to_evm_value<R>(value: BalanceOf<R>) -> U256
186where
187 R: pallet_revive::Config,
188 BalanceOf<R>: Into<U256>,
189 U256: From<u32>,
190{
191 let native_to_eth_ratio: U256 =
192 <R as pallet_revive::Config>::NativeToEthRatio::get().into();
193 let evm_value: U256 = value.into();
194 native_to_eth_ratio.saturating_mul(evm_value)
195}
196
197pub fn to_revive_trace(t: pallet_revive::evm::CallTrace) -> CallTrace {
200 CallTrace {
201 from: t.from,
202 gas: t.gas,
203 gas_used: t.gas_used,
204 to: t.to,
205 input: Bytes(t.input.0),
206 output: Bytes(t.output.0),
207 error: t.error,
208 revert_reason: t.revert_reason,
209 calls: t.calls.into_iter().map(to_revive_trace).collect(),
210 logs: t
211 .logs
212 .into_iter()
213 .map(|log| {
214 CallLog {
215 address: log.address,
216 topics: log.topics,
217 data: log.data.0,
218 ..Default::default()
219 }
220 })
221 .collect(),
222 value: t.value,
223 call_type: to_revive_call_type(t.call_type),
224 child_call_count: t.child_call_count,
225 }
226}
227
228fn to_revive_call_type(
230 ct: pallet_revive::evm::CallType,
231) -> ink_revive_types::evm::CallType {
232 match ct {
233 pallet_revive::evm::CallType::Call => ink_revive_types::evm::CallType::Call,
234 pallet_revive::evm::CallType::StaticCall => {
235 ink_revive_types::evm::CallType::StaticCall
236 }
237 pallet_revive::evm::CallType::DelegateCall => {
238 ink_revive_types::evm::CallType::DelegateCall
239 }
240 pallet_revive::evm::CallType::Create => ink_revive_types::evm::CallType::Create,
241 pallet_revive::evm::CallType::Create2 => ink_revive_types::evm::CallType::Create2,
242 }
243}
244
245pub fn to_revive_storage_deposit<B>(
247 sd: pallet_revive::StorageDeposit<B>,
248) -> ink_revive_types::StorageDeposit<B> {
249 match sd {
250 pallet_revive::StorageDeposit::Charge(b) => {
251 ink_revive_types::StorageDeposit::Charge(b)
252 }
253 pallet_revive::StorageDeposit::Refund(b) => {
254 ink_revive_types::StorageDeposit::Refund(b)
255 }
256 }
257}
258
259pub trait IntoAccountId<AccountId> {
264 fn into_account_id(self) -> AccountId;
265}
266
267impl IntoAccountId<AccountId32> for &AccountId32 {
268 fn into_account_id(self) -> AccountId32 {
269 self.clone()
270 }
271}
272
273impl IntoAccountId<AccountId32> for &ink_primitives::AccountId {
274 fn into_account_id(self) -> AccountId32 {
275 AccountId32::from(*AsRef::<[u8; 32]>::as_ref(self))
276 }
277}
278
279impl IntoAccountId<AccountId32> for &ink_e2e::Keypair {
280 fn into_account_id(self) -> AccountId32 {
281 AccountId32::from(self.public_key().0)
282 }
283}