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,
24
	sp_runtime::traits::IdentityLookup,
25
	traits::Everything,
26
	weights::{RuntimeDbWeight, Weight},
27
};
28
use pallet_evm::{EnsureAddressNever, EnsureAddressRoot, SubstrateBlockHashMapping};
29
use parity_scale_codec::Decode;
30
use precompile_utils::{precompile_set::*, testing::MockAccount};
31
use sp_core::{Get, U256};
32
use sp_runtime::{traits::BlakeTwo256, BuildStorage};
33

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

            
46
pub type AccountId = MockAccount;
47

            
48
pub type Balance = u128;
49
type Block = frame_system::mocking::MockBlockU32<Runtime>;
50

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

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

            
88
parameter_types! {
89
	pub const ExistentialDeposit: u128 = 1;
90
}
91

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

            
108
parameter_types! {
109
	pub const MinimumPeriod: u64 = 5;
110
}
111

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

            
119
pub struct PersistedValidationDataGetter;
120

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

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

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

            
141
parameter_types! {
142
	pub const MaxStorageRoots: u32 = 3;
143
}
144

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

            
151
pub struct MockWeightInfo;
152

            
153
impl pallet_precompile_benchmarks::WeightInfo for MockWeightInfo {
154
8
	fn verify_entry(x: u32) -> Weight {
155
8
		Weight::from_parts(76_430_000, 0)
156
8
			.saturating_add(Weight::from_parts(678_469, 0).saturating_mul(x.into()))
157
8
	}
158
4
	fn latest_relay_block() -> Weight {
159
4
		Weight::from_parts(4_641_000, 1606)
160
4
			.saturating_add(<() as Get<RuntimeDbWeight>>::get().reads(1_u64))
161
4
	}
162
	fn p256_verify() -> Weight {
163
		Weight::from_parts(1_580_914_000, 0).saturating_mul(1u64)
164
	}
165
}
166

            
167
pub type Precompiles<R> = PrecompileSetBuilder<
168
	R,
169
	PrecompileAt<AddressU64<1>, RelayDataVerifierPrecompile<R, MockWeightInfo>>,
170
>;
171

            
172
pub type PCall = RelayDataVerifierPrecompileCall<Runtime, MockWeightInfo>;
173

            
174
const MAX_POV_SIZE: u64 = 5 * 1024 * 1024;
175
/// Block storage limit in bytes. Set to 40 KB.
176
const BLOCK_STORAGE_LIMIT: u64 = 40 * 1024;
177

            
178
parameter_types! {
179
	pub BlockGasLimit: U256 = U256::from(u64::MAX);
180
	pub PrecompilesValue: Precompiles<Runtime> = Precompiles::new();
181
	pub const WeightPerGas: Weight = Weight::from_parts(1, 0);
182
	pub GasLimitPovSizeRatio: u64 = {
183
		let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
184
		block_gas_limit.saturating_div(MAX_POV_SIZE)
185
	};
186
	pub GasLimitStorageGrowthRatio: u64 = {
187
		let block_gas_limit = BlockGasLimit::get().min(u64::MAX.into()).low_u64();
188
		block_gas_limit.saturating_div(BLOCK_STORAGE_LIMIT)
189
	};
190
}
191

            
192
impl pallet_evm::Config for Runtime {
193
	type FeeCalculator = ();
194
	type GasWeightMapping = pallet_evm::FixedGasWeightMapping<Self>;
195
	type WeightPerGas = WeightPerGas;
196
	type CallOrigin = EnsureAddressRoot<AccountId>;
197
	type WithdrawOrigin = EnsureAddressNever<AccountId>;
198
	type AddressMapping = AccountId;
199
	type Currency = Balances;
200
	type RuntimeEvent = RuntimeEvent;
201
	type Runner = pallet_evm::runner::stack::Runner<Self>;
202
	type PrecompilesValue = PrecompilesValue;
203
	type PrecompilesType = Precompiles<Self>;
204
	type ChainId = ();
205
	type OnChargeTransaction = ();
206
	type BlockGasLimit = BlockGasLimit;
207
	type BlockHashMapping = SubstrateBlockHashMapping<Self>;
208
	type FindAuthor = ();
209
	type OnCreate = ();
210
	type GasLimitPovSizeRatio = GasLimitPovSizeRatio;
211
	type SuicideQuickClearLimit = ConstU32<0>;
212
	type GasLimitStorageGrowthRatio = GasLimitStorageGrowthRatio;
213
	type Timestamp = Timestamp;
214
	type WeightInfo = pallet_evm::weights::SubstrateWeight<Runtime>;
215
}
216

            
217
impl pallet_precompile_benchmarks::Config for Runtime {
218
	type WeightInfo = MockWeightInfo;
219
}
220

            
221
pub(crate) struct ExtBuilder {
222
	// endowed accounts with balances
223
	balances: Vec<(AccountId, Balance)>,
224
}
225

            
226
impl Default for ExtBuilder {
227
11
	fn default() -> ExtBuilder {
228
11
		ExtBuilder { balances: vec![] }
229
11
	}
230
}
231

            
232
impl ExtBuilder {
233
8
	pub(crate) fn with_balances(mut self, balances: Vec<(AccountId, Balance)>) -> Self {
234
8
		self.balances = balances;
235
8
		self
236
8
	}
237

            
238
11
	pub(crate) fn build(self) -> sp_io::TestExternalities {
239
11
		let mut t = frame_system::GenesisConfig::<Runtime>::default()
240
11
			.build_storage()
241
11
			.expect("Frame system builds valid default genesis config");
242
11

            
243
11
		pallet_balances::GenesisConfig::<Runtime> {
244
11
			balances: self.balances,
245
11
		}
246
11
		.assimilate_storage(&mut t)
247
11
		.expect("Pallet balances storage can be assimilated");
248
11

            
249
11
		let mut ext = sp_io::TestExternalities::new(t);
250
11
		ext.execute_with(|| System::set_block_number(1));
251
11

            
252
11
		ext
253
11
	}
254
}
255

            
256
7
pub fn fill_relay_storage_roots<T: pallet_relay_storage_roots::Config>() {
257
21
	(1..=T::MaxStorageRoots::get()).for_each(|i| {
258
21
		set_current_relay_chain_state(i, H256::default());
259
21
		pallet_relay_storage_roots::Pallet::<T>::set_relay_storage_root();
260
21
	})
261
7
}
262

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

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

            
275
// Total Issuance Key: c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80
276
pub const TOTAL_ISSUANCE_KEY: &[u8] = &[
277
	194, 38, 18, 118, 204, 157, 31, 133, 152, 234, 75, 106, 116, 177, 92, 47, 87, 200, 117, 228,
278
	207, 247, 65, 72, 228, 98, 143, 38, 75, 151, 76, 128,
279
];
280

            
281
// Treasury Approval Key: 89d139e01a5eb2256f222e5fc5dbe6b33c9c1284130706f5aea0c8b3d4c54d89
282
pub const TREASURY_APPROVALS_KEY: &[u8] = &[
283
	137, 209, 57, 224, 26, 94, 178, 37, 111, 34, 46, 95, 197, 219, 230, 179, 60, 156, 18, 132, 19,
284
	7, 6, 245, 174, 160, 200, 179, 212, 197, 77, 137,
285
];
286

            
287
// Mock a storage proof obtained from the relay chain using the
288
// state_getReadProof RPC call, for the following keys:
289
// TimeStamp:
290
// 0xf0c365c3cf59d671eb72da0e7a4113c49f1f0515f462cdcf84e0f1d6045dfcbb
291
// Balances (Total Issuance):
292
// 0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80
293
// Treasury Approvals
294
// 0x89d139e01a5eb2256f222e5fc5dbe6b33c9c1284130706f5aea0c8b3d4c54d89
295
// at Block Hash:
296
// 0x1272470f226fc0e955838262e8dd17a7d7bad6563739cc53a3b1744ddf0ea872
297

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

            
303
9
	ReadProof {
304
9
		at: H256::default(),
305
9
		proof: BoundedVec::from(
306
9
			proof
307
9
				.iter()
308
72
				.map(|x| BoundedBytes::from(x.clone()))
309
9
				.collect::<Vec<_>>(),
310
9
		),
311
9
	}
312
9
}