-
Notifications
You must be signed in to change notification settings - Fork 416
/
Copy pathsetup.rs
286 lines (244 loc) · 8.87 KB
/
setup.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
// This file is part of Astar.
// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later
// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.
//! Runtime integration tests setup & imports.
pub use frame_support::{
assert_noop, assert_ok,
traits::{OnFinalize, OnIdle, OnInitialize},
weights::Weight,
};
pub use pallet_evm::AddressMapping;
pub use sp_core::{H160, H256, U256};
pub use sp_io::hashing::keccak_256;
pub use sp_runtime::{AccountId32, MultiAddress};
pub use astar_primitives::{evm::UnifiedAddressMapper, BlockNumber};
#[cfg(feature = "shibuya")]
pub use shibuya::*;
#[cfg(feature = "shibuya")]
mod shibuya {
use super::*;
use parity_scale_codec::Decode;
pub use shibuya_runtime::*;
/// 1 SBY.
pub const UNIT: Balance = SBY;
pub fn alith_secret_key() -> libsecp256k1::SecretKey {
libsecp256k1::SecretKey::parse(&keccak_256(b"Alith")).unwrap()
}
/// H160 address mapped to `ALICE`.
pub fn alith() -> H160 {
UnifiedAccounts::eth_address(&alith_secret_key())
}
/// Convert `H160` to `AccountId32`.
pub fn account_id_from(address: H160) -> AccountId32 {
<Runtime as pallet_evm::Config>::AddressMapping::into_account_id(address)
}
/// Deploy an EVM contract with code via ALICE as origin.
pub fn deploy_evm_contract(code: &str) -> H160 {
assert_ok!(EVM::create2(
RuntimeOrigin::root(),
alith(),
hex::decode(code).expect("invalid code hex"),
H256::zero(),
U256::zero(),
1_000_000,
U256::from(DefaultBaseFeePerGas::get()),
None,
None,
vec![],
));
match System::events()
.iter()
.last()
.expect("no event found")
.event
{
RuntimeEvent::EVM(pallet_evm::Event::Created { address }) => address,
_ => panic!("Deploy failed."),
}
}
/// Deploy a WASM contract via ALICE as origin. (The code is in `../ink-contracts/`.)
/// Assumption: Contract constructor is called "new" and take no arguments
pub fn deploy_wasm_contract(name: &str) -> AccountId32 {
let (address, _) = astar_test_utils::deploy_wasm_contract::<Runtime>(
name,
ALICE,
0,
Weight::from_parts(10_000_000_000, 1024 * 1024),
None,
hex::decode("9bae9d5e").expect("invalid data hex"),
);
// On instantiation, the contract got existential deposit.
assert_eq!(Balances::free_balance(&address), ExistentialDeposit::get(),);
address
}
/// Call a wasm smart contract method
pub fn call_wasm_contract_method<V: Decode>(
origin: AccountId,
contract_id: AccountId,
data: Vec<u8>,
) -> V {
let (value, _, _) = astar_test_utils::call_wasm_contract_method::<Runtime, V>(
origin,
contract_id,
0,
Weight::from_parts(10_000_000_000, 1024 * 1024),
None,
data,
false,
);
value
}
/// Build the signature payload for given native account and eth private key
fn get_evm_signature(who: &AccountId32, secret: &libsecp256k1::SecretKey) -> [u8; 65] {
// sign the payload
UnifiedAccounts::eth_sign_prehash(&UnifiedAccounts::build_signing_payload(who), secret)
}
/// Create the mappings for the accounts
pub fn connect_accounts(who: &AccountId32, secret: &libsecp256k1::SecretKey) {
assert_ok!(UnifiedAccounts::claim_evm_address(
RuntimeOrigin::signed(who.clone()),
UnifiedAccounts::eth_address(secret),
get_evm_signature(who, secret)
));
}
}
#[cfg(feature = "shiden")]
pub use shiden::*;
#[cfg(feature = "shiden")]
mod shiden {
pub use shiden_runtime::*;
/// 1 SDN.
pub const UNIT: Balance = SDN;
}
#[cfg(feature = "astar")]
pub use astar::*;
#[cfg(feature = "astar")]
mod astar {
pub use astar_runtime::*;
/// 1 ASTR.
pub const UNIT: Balance = ASTR;
}
pub const ALICE: AccountId32 = AccountId32::new([1_u8; 32]);
pub const BOB: AccountId32 = AccountId32::new([2_u8; 32]);
pub const CAT: AccountId32 = AccountId32::new([3_u8; 32]);
pub const INITIAL_AMOUNT: u128 = 100_000 * UNIT;
pub type SystemError = frame_system::Error<Runtime>;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_dapp_staking_v3 as DappStakingCall;
pub use pallet_dapps_staking as DappsStakingCall;
pub use pallet_proxy::Event as ProxyEvent;
pub use pallet_utility::{Call as UtilityCall, Event as UtilityEvent};
pub struct ExtBuilder {
balances: Vec<(AccountId32, Balance)>,
}
impl Default for ExtBuilder {
fn default() -> Self {
Self { balances: vec![] }
}
}
impl ExtBuilder {
pub fn balances(mut self, balances: Vec<(AccountId32, Balance)>) -> Self {
self.balances = balances;
self
}
pub fn build(self) -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Runtime>::default()
.build_storage()
.unwrap();
pallet_balances::GenesisConfig::<Runtime> {
balances: self.balances,
}
.assimilate_storage(&mut t)
.unwrap();
#[cfg(any(feature = "shibuya"))]
// Needed to trigger initial inflation config setting.
<pallet_inflation::GenesisConfig<Runtime> as BuildStorage>::assimilate_storage(
&pallet_inflation::GenesisConfig::default(),
&mut t,
)
.unwrap();
let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
}
pub fn new_test_ext() -> sp_io::TestExternalities {
ExtBuilder::default()
.balances(vec![
(ALICE, INITIAL_AMOUNT),
(BOB, INITIAL_AMOUNT),
(CAT, INITIAL_AMOUNT),
])
.build()
}
// Block time: 12 seconds.
pub const BLOCK_TIME: u64 = 12_000;
pub fn run_to_block(n: BlockNumber) {
while System::block_number() < n {
let block_number = System::block_number();
TransactionPayment::on_finalize(block_number);
#[cfg(any(feature = "shibuya"))]
DappStaking::on_finalize(block_number);
#[cfg(any(feature = "astar", feature = "shiden"))]
DappsStaking::on_finalize(block_number);
Authorship::on_finalize(block_number);
Session::on_finalize(block_number);
AuraExt::on_finalize(block_number);
PolkadotXcm::on_finalize(block_number);
Ethereum::on_finalize(block_number);
DynamicEvmBaseFee::on_finalize(block_number);
#[cfg(any(feature = "shibuya"))]
Inflation::on_finalize(block_number);
System::set_block_number(block_number + 1);
let block_number = System::block_number();
#[cfg(any(feature = "shibuya"))]
Inflation::on_initialize(block_number);
Timestamp::set_timestamp(block_number as u64 * BLOCK_TIME);
TransactionPayment::on_initialize(block_number);
#[cfg(any(feature = "shibuya"))]
DappStaking::on_initialize(block_number);
#[cfg(any(feature = "astar", feature = "shiden"))]
DappsStaking::on_initialize(block_number);
Authorship::on_initialize(block_number);
Aura::on_initialize(block_number);
AuraExt::on_initialize(block_number);
Ethereum::on_initialize(block_number);
DynamicEvmBaseFee::on_initialize(block_number);
#[cfg(any(feature = "shibuya", feature = "shiden"))]
RandomnessCollectiveFlip::on_initialize(block_number);
XcmpQueue::on_idle(block_number, Weight::MAX);
DmpQueue::on_idle(block_number, Weight::MAX);
Contracts::on_idle(block_number, Weight::MAX);
}
}
pub fn run_for_blocks(n: BlockNumber) {
run_to_block(System::block_number() + n)
}
fn last_events(n: usize) -> Vec<RuntimeEvent> {
frame_system::Pallet::<Runtime>::events()
.into_iter()
.rev()
.take(n)
.rev()
.map(|e| e.event)
.collect()
}
pub fn expect_events(e: Vec<RuntimeEvent>) {
assert_eq!(last_events(e.len()), e);
}
/// Initialize `env_logger` for tests. It will enable logging like `DEBUG`
/// and `TRACE` in runtime.
#[allow(dead_code)]
pub fn init_env_logger() {
let _ = env_logger::builder().is_test(true).try_init();
}