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

            
17
//! Test utilities
18
#![allow(non_camel_case_types)]
19

            
20
use super::*;
21
use cumulus_pallet_parachain_system::{RelayChainState, RelaychainStateProvider};
22
use frame_support::{
23
	construct_runtime, parameter_types, sp_runtime::traits::IdentityLookup, traits::Everything,
24
	weights::Weight,
25
};
26
use pallet_evm::{EnsureAddressNever, EnsureAddressRoot, SubstrateBlockHashMapping};
27
use parity_scale_codec::Decode;
28
use precompile_utils::{precompile_set::*, testing::MockAccount};
29
use sp_core::{Get, U256};
30
use sp_runtime::{traits::BlakeTwo256, BuildStorage};
31

            
32
// Configure a mock runtime to test the pallet.
33
300
construct_runtime!(
34
	pub enum Runtime {
35
		System: frame_system,
36
		Balances: pallet_balances,
37
		Evm: pallet_evm,
38
		Timestamp: pallet_timestamp,
39
		RelayStorageRoots: pallet_relay_storage_roots,
40
		PrecompileBenchmarks: pallet_precompile_benchmarks
41
	}
42
978
);
43

            
44
pub type AccountId = MockAccount;
45

            
46
pub type Balance = u128;
47
type Block = frame_system::mocking::MockBlockU32<Runtime>;
48

            
49
parameter_types! {
50
	pub const BlockHashCount: u32 = 250;
51
	pub const SS58Prefix: u8 = 42;
52
}
53

            
54
impl frame_system::Config for Runtime {
55
	type BaseCallFilter = Everything;
56
	type DbWeight = ();
57
	type RuntimeOrigin = RuntimeOrigin;
58
	type RuntimeTask = RuntimeTask;
59
	type Nonce = u64;
60
	type Block = Block;
61
	type RuntimeCall = RuntimeCall;
62
	type Hash = H256;
63
	type Hashing = BlakeTwo256;
64
	type AccountId = AccountId;
65
	type Lookup = IdentityLookup<Self::AccountId>;
66
	type RuntimeEvent = RuntimeEvent;
67
	type BlockHashCount = BlockHashCount;
68
	type Version = ();
69
	type PalletInfo = PalletInfo;
70
	type AccountData = pallet_balances::AccountData<Balance>;
71
	type OnNewAccount = ();
72
	type OnKilledAccount = ();
73
	type SystemWeightInfo = ();
74
	type BlockWeights = ();
75
	type BlockLength = ();
76
	type SS58Prefix = ();
77
	type OnSetCode = ();
78
	type MaxConsumers = frame_support::traits::ConstU32<16>;
79
	type SingleBlockMigrations = ();
80
	type MultiBlockMigrator = ();
81
	type PreInherents = ();
82
	type PostInherents = ();
83
	type PostTransactions = ();
84
}
85

            
86
parameter_types! {
87
	pub const ExistentialDeposit: u128 = 1;
88
}
89

            
90
impl pallet_balances::Config for Runtime {
91
	type MaxReserves = ();
92
	type ReserveIdentifier = ();
93
	type MaxLocks = ();
94
	type Balance = Balance;
95
	type RuntimeEvent = RuntimeEvent;
96
	type DustRemoval = ();
97
	type ExistentialDeposit = ExistentialDeposit;
98
	type AccountStore = System;
99
	type WeightInfo = ();
100
	type RuntimeHoldReason = ();
101
	type FreezeIdentifier = ();
102
	type MaxFreezes = ();
103
	type RuntimeFreezeReason = ();
104
}
105

            
106
parameter_types! {
107
	pub const MinimumPeriod: u64 = 5;
108
}
109

            
110
impl pallet_timestamp::Config for Runtime {
111
	type Moment = u64;
112
	type OnTimestampSet = ();
113
	type MinimumPeriod = MinimumPeriod;
114
	type WeightInfo = ();
115
}
116

            
117
pub struct PersistedValidationDataGetter;
118

            
119
impl RelaychainStateProvider for PersistedValidationDataGetter {
120
48
	fn current_relay_chain_state() -> RelayChainState {
121
48
		frame_support::storage::unhashed::get(b"MOCK_PERSISTED_VALIDATION_DATA").unwrap()
122
48
	}
123

            
124
	#[cfg(feature = "runtime-benchmarks")]
125
	fn set_current_relay_chain_state(state: RelayChainState) {
126
		frame_support::storage::unhashed::put(b"MOCK_PERSISTED_VALIDATION_DATA", &state);
127
	}
128
}
129

            
130
27
pub fn set_current_relay_chain_state(block_number: u32, state_root: H256) {
131
27
	let state = RelayChainState {
132
27
		number: block_number,
133
27
		state_root,
134
27
	};
135
27
	frame_support::storage::unhashed::put(b"MOCK_PERSISTED_VALIDATION_DATA", &state);
136
27
	pallet_relay_storage_roots::Pallet::<Runtime>::set_relay_storage_root();
137
27
}
138

            
139
parameter_types! {
140
	pub const MaxStorageRoots: u32 = 3;
141
}
142

            
143
impl pallet_relay_storage_roots::Config for Runtime {
144
	type MaxStorageRoots = MaxStorageRoots;
145
	type RelaychainStateProvider = PersistedValidationDataGetter;
146
	type WeightInfo = ();
147
}
148

            
149
pub type Precompiles<R> =
150
	PrecompileSetBuilder<R, PrecompileAt<AddressU64<1>, RelayDataVerifierPrecompile<R>>>;
151

            
152
pub type PCall = RelayDataVerifierPrecompileCall<Runtime>;
153

            
154
const MAX_POV_SIZE: u64 = 5 * 1024 * 1024;
155
/// Block storage limit in bytes. Set to 40 KB.
156
const BLOCK_STORAGE_LIMIT: u64 = 40 * 1024;
157

            
158
parameter_types! {
159
	pub BlockGasLimit: U256 = U256::from(u64::MAX);
160
	pub PrecompilesValue: Precompiles<Runtime> = Precompiles::new();
161
	pub const WeightPerGas: Weight = Weight::from_parts(1, 0);
162
	pub GasLimitPovSizeRatio: u64 = {
163
		let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
164
		block_gas_limit.saturating_div(MAX_POV_SIZE)
165
	};
166
	pub GasLimitStorageGrowthRatio: u64 = {
167
		let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
168
		block_gas_limit.saturating_div(BLOCK_STORAGE_LIMIT)
169
	};
170
}
171

            
172
impl pallet_evm::Config for Runtime {
173
	type FeeCalculator = ();
174
	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
175
	type WeightPerGas = WeightPerGas;
176
	type CallOrigin = EnsureAddressRoot<AccountId>;
177
	type WithdrawOrigin = EnsureAddressNever<AccountId>;
178
	type AddressMapping = AccountId;
179
	type Currency = Balances;
180
	type RuntimeEvent = RuntimeEvent;
181
	type Runner = pallet_evm::runner::stack::Runner<Self>;
182
	type PrecompilesValue = PrecompilesValue;
183
	type PrecompilesType = Precompiles<Self>;
184
	type ChainId = ();
185
	type OnChargeTransaction = ();
186
	type BlockGasLimit = BlockGasLimit;
187
	type BlockHashMapping = SubstrateBlockHashMapping<Self>;
188
	type FindAuthor = ();
189
	type OnCreate = ();
190
	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
191
	type SuicideQuickClearLimit = ConstU32<0>;
192
	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
193
	type Timestamp = Timestamp;
194
	type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
195
}
196

            
197
impl pallet_precompile_benchmarks::Config for Runtime {
198
	type WeightInfo = WeightInfo<Runtime>;
199
}
200

            
201
pub(crate) struct ExtBuilder {
202
	// endowed accounts with balances
203
	balances: Vec<(AccountId, Balance)>,
204
}
205

            
206
impl Default for ExtBuilder {
207
11
	fn default() -> ExtBuilder {
208
11
		ExtBuilder { balances: vec![] }
209
11
	}
210
}
211

            
212
impl ExtBuilder {
213
8
	pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
214
8
		self.balances = balances;
215
8
		self
216
8
	}
217

            
218
11
	pub(crate) fn build(self) -> sp_io::TestExternalities {
219
11
		let mut t = frame_system::GenesisConfig::<Runtime>::default()
220
11
			.build_storage()
221
11
			.expect("Frame system builds valid default genesis config");
222
11

            
223
11
		pallet_balances::GenesisConfig::<Runtime> {
224
11
			balances: self.balances,
225
11
		}
226
11
		.assimilate_storage(&mut t)
227
11
		.expect("Pallet balances storage can be assimilated");
228
11

            
229
11
		let mut ext = sp_io::TestExternalities::new(t);
230
11
		ext.execute_with(|| System::set_block_number(1));
231
11

            
232
11
		ext
233
11
	}
234
}
235

            
236
7
pub fn fill_relay_storage_roots<T: pallet_relay_storage_roots::Config>() {
237
21
	(1..=T::MaxStorageRoots::get()).for_each(|i| {
238
21
		set_current_relay_chain_state(i, H256::default());
239
21
		pallet_relay_storage_roots::Pallet::<T>::set_relay_storage_root();
240
21
	})
241
7
}
242

            
243
// Storage Root: 767caa877bcea0d34dd515a202b75efa41bffbc9f814ab59e2c1c96716d4c65d
244
pub const STORAGE_ROOT: &[u8] = &[
245
	118, 124, 170, 135, 123, 206, 160, 211, 77, 213, 21, 162, 2, 183, 94, 250, 65, 191, 251, 201,
246
	248, 20, 171, 89, 226, 193, 201, 103, 22, 212, 198, 93,
247
];
248

            
249
// Timestamp key: f0c365c3cf59d671eb72da0e7a4113c49f1f0515f462cdcf84e0f1d6045dfcbb
250
pub const TIMESTAMP_KEY: &[u8] = &[
251
	240, 195, 101, 195, 207, 89, 214, 113, 235, 114, 218, 14, 122, 65, 19, 196, 159, 31, 5, 21,
252
	244, 98, 205, 207, 132, 224, 241, 214, 4, 93, 252, 187,
253
];
254

            
255
// Total Issuance Key: c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80
256
pub const TOTAL_ISSUANCE_KEY: &[u8] = &[
257
	194, 38, 18, 118, 204, 157, 31, 133, 152, 234, 75, 106, 116, 177, 92, 47, 87, 200, 117, 228,
258
	207, 247, 65, 72, 228, 98, 143, 38, 75, 151, 76, 128,
259
];
260

            
261
// Treasury Approval Key: 89d139e01a5eb2256f222e5fc5dbe6b33c9c1284130706f5aea0c8b3d4c54d89
262
pub const TREASURY_APPROVALS_KEY: &[u8] = &[
263
	137, 209, 57, 224, 26, 94, 178, 37, 111, 34, 46, 95, 197, 219, 230, 179, 60, 156, 18, 132, 19,
264
	7, 6, 245, 174, 160, 200, 179, 212, 197, 77, 137,
265
];
266

            
267
// Mock a storage proof obtained from the relay chain using the
268
// state_getReadProof RPC call, for the following keys:
269
// TimeStamp:
270
// 0xf0c365c3cf59d671eb72da0e7a4113c49f1f0515f462cdcf84e0f1d6045dfcbb
271
// Balances (Total Issuance):
272
// 0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80
273
// Treasury Approvals
274
// 0x89d139e01a5eb2256f222e5fc5dbe6b33c9c1284130706f5aea0c8b3d4c54d89
275
// at Block Hash:
276
// 0x1272470f226fc0e955838262e8dd17a7d7bad6563739cc53a3b1744ddf0ea872
277

            
278
9
pub fn mocked_read_proof() -> ReadProof {
279
9
	// Mock a storage proof obtained from the relay chain using the
280
9
	// state_getReadProof RPC call, for the following
281
9
	let proof: Vec<Vec<u8>> = Vec::decode(&mut &include_bytes!("../proof").to_vec()[..]).unwrap();
282
9

            
283
9
	ReadProof {
284
9
		at: H256::default(),
285
9
		proof: BoundedVec::from(
286
9
			proof
287
9
				.iter()
288
72
				.map(|x| BoundedBytes::from(x.clone()))
289
9
				.collect::<Vec<_>>(),
290
9
		),
291
9
	}
292
9
}