1
// Copyright 2021 Parity Technologies (UK) Ltd.
2
// This file is part of Polkadot.
3

            
4
// Polkadot 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
// Polkadot 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 Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
pub mod parachain;
18
pub mod relay_chain;
19
pub mod statemint_like;
20

            
21
use cumulus_primitives_core::ParaId;
22
use pallet_xcm_transactor::chain_indices::*;
23
use sp_runtime::traits::AccountIdConversion;
24
use sp_runtime::{AccountId32, BuildStorage};
25
use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt};
26

            
27
use parachain::MockTransactors;
28

            
29
use polkadot_runtime_parachains::configuration::{
30
	GenesisConfig as ConfigurationGenesisConfig, HostConfiguration,
31
};
32
use polkadot_runtime_parachains::paras::{
33
	GenesisConfig as ParasGenesisConfig, ParaGenesisArgs, ParaKind,
34
};
35
use sp_core::{H160, U256};
36
use std::{collections::BTreeMap, str::FromStr};
37

            
38
pub const PARAALICE: [u8; 20] = [1u8; 20];
39
pub const PARABOB: [u8; 20] = [2u8; 20];
40
pub const RELAYALICE: AccountId32 = AccountId32::new([0u8; 32]);
41
pub const RELAYBOB: AccountId32 = AccountId32::new([2u8; 32]);
42

            
43
39
pub fn para_a_account() -> AccountId32 {
44
39
	ParaId::from(1).into_account_truncating()
45
39
}
46

            
47
1
pub fn para_b_account() -> AccountId32 {
48
1
	ParaId::from(2).into_account_truncating()
49
1
}
50

            
51
9
pub fn para_a_account_20() -> parachain::AccountId {
52
9
	ParaId::from(1).into_account_truncating()
53
9
}
54

            
55
238
pub fn evm_account() -> H160 {
56
238
	H160::from_str("1000000000000000000000000000000000000001").unwrap()
57
238
}
58

            
59
312
pub fn mock_para_genesis_info() -> ParaGenesisArgs {
60
312
	ParaGenesisArgs {
61
312
		genesis_head: vec![1u8].into(),
62
312
		validation_code: vec![1u8].into(),
63
312
		para_kind: ParaKind::Parachain,
64
312
	}
65
312
}
66

            
67
78
pub fn mock_relay_config() -> HostConfiguration<relay_chain::BlockNumber> {
68
78
	HostConfiguration::<relay_chain::BlockNumber> {
69
78
		hrmp_channel_max_capacity: u32::MAX,
70
78
		hrmp_channel_max_total_size: u32::MAX,
71
78
		hrmp_max_parachain_inbound_channels: 10,
72
78
		hrmp_max_parachain_outbound_channels: 10,
73
78
		hrmp_channel_max_message_size: u32::MAX,
74
78
		// Changed to avoid arithmetic errors within hrmp_close
75
78
		max_downward_message_size: 100_000u32,
76
78
		..Default::default()
77
78
	}
78
78
}
79

            
80
decl_test_parachain! {
81
	pub struct ParaA {
82
		Runtime = parachain::Runtime,
83
		XcmpMessageHandler = parachain::MsgQueue,
84
		DmpMessageHandler = parachain::MsgQueue,
85
		new_ext = para_ext(1),
86
	}
87
}
88

            
89
decl_test_parachain! {
90
	pub struct ParaB {
91
		Runtime = parachain::Runtime,
92
		XcmpMessageHandler = parachain::MsgQueue,
93
		DmpMessageHandler = parachain::MsgQueue,
94
		new_ext = para_ext(2),
95
	}
96
}
97

            
98
decl_test_parachain! {
99
	pub struct ParaC {
100
		Runtime = parachain::Runtime,
101
		XcmpMessageHandler = parachain::MsgQueue,
102
		DmpMessageHandler = parachain::MsgQueue,
103
		new_ext = para_ext(3),
104
	}
105
}
106

            
107
decl_test_parachain! {
108
	pub struct Statemint {
109
		Runtime = statemint_like::Runtime,
110
		XcmpMessageHandler = statemint_like::MsgQueue,
111
		DmpMessageHandler = statemint_like::MsgQueue,
112
		new_ext = statemint_ext(1000),
113
	}
114
}
115

            
116
decl_test_relay_chain! {
117
	pub struct Relay {
118
		Runtime = relay_chain::Runtime,
119
		RuntimeCall = relay_chain::RuntimeCall,
120
		RuntimeEvent = relay_chain::RuntimeEvent,
121
		XcmConfig = relay_chain::XcmConfig,
122
		MessageQueue = relay_chain::MessageQueue,
123
		System = relay_chain::System,
124
		new_ext = relay_ext(vec![1, 2, 3, 1000]),
125
	}
126
}
127

            
128
decl_test_network! {
129
	pub struct MockNet {
130
		relay_chain = Relay,
131
		parachains = vec![
132
			(1, ParaA),
133
			(2, ParaB),
134
			(3, ParaC),
135
			(1000, Statemint),
136
		],
137
	}
138
}
139

            
140
pub const INITIAL_BALANCE: u128 = 10_000_000_000_000_000;
141

            
142
pub const INITIAL_EVM_BALANCE: u128 = 0;
143
pub const INITIAL_EVM_NONCE: u32 = 1;
144

            
145
234
pub fn para_ext(para_id: u32) -> sp_io::TestExternalities {
146
	use parachain::{MsgQueue, Runtime, System};
147

            
148
234
	let mut t = frame_system::GenesisConfig::<Runtime>::default()
149
234
		.build_storage()
150
234
		.unwrap();
151
234

            
152
234
	pallet_balances::GenesisConfig::<Runtime> {
153
234
		balances: vec![(PARAALICE.into(), INITIAL_BALANCE)],
154
234
		dev_accounts: None,
155
234
	}
156
234
	.assimilate_storage(&mut t)
157
234
	.unwrap();
158
234

            
159
234
	pallet_xcm_transactor::GenesisConfig::<Runtime> {
160
234
		// match relay runtime construct_runtime order in xcm_mock::relay_chain
161
234
		chain_indices_map: vec![(
162
234
			MockTransactors::Relay,
163
234
			pallet_xcm_transactor::chain_indices::ChainIndices::Relay(RelayChainIndices {
164
234
				hrmp: 6u8,
165
234
				init_open_channel: 0u8,
166
234
				accept_open_channel: 1u8,
167
234
				close_channel: 2u8,
168
234
				cancel_open_request: 6u8,
169
234
				..Default::default()
170
234
			}),
171
234
		)],
172
234
		..Default::default()
173
234
	}
174
234
	.assimilate_storage(&mut t)
175
234
	.unwrap();
176
234

            
177
234
	// EVM accounts are self-sufficient.
178
234
	let mut evm_accounts = BTreeMap::new();
179
234
	evm_accounts.insert(
180
234
		evm_account(),
181
234
		fp_evm::GenesisAccount {
182
234
			nonce: U256::from(INITIAL_EVM_NONCE),
183
234
			balance: U256::from(INITIAL_EVM_BALANCE),
184
234
			storage: Default::default(),
185
234
			code: vec![
186
234
				0x00, // STOP
187
234
			],
188
234
		},
189
234
	);
190
234

            
191
234
	let genesis_config = pallet_evm::GenesisConfig::<Runtime> {
192
234
		accounts: evm_accounts,
193
234
		..Default::default()
194
234
	};
195
234
	genesis_config.assimilate_storage(&mut t).unwrap();
196
234

            
197
234
	let mut ext = sp_io::TestExternalities::new(t);
198
234
	ext.execute_with(|| {
199
234
		System::set_block_number(1);
200
234
		MsgQueue::set_para_id(para_id.into());
201
234
	});
202
234
	ext
203
234
}
204

            
205
78
pub fn statemint_ext(para_id: u32) -> sp_io::TestExternalities {
206
	use statemint_like::{MsgQueue, Runtime, System};
207

            
208
78
	let mut t = frame_system::GenesisConfig::<Runtime>::default()
209
78
		.build_storage()
210
78
		.unwrap();
211
78

            
212
78
	pallet_balances::GenesisConfig::<Runtime> {
213
78
		balances: vec![
214
78
			(RELAYALICE.into(), INITIAL_BALANCE),
215
78
			(RELAYBOB.into(), INITIAL_BALANCE),
216
78
		],
217
78
		dev_accounts: None,
218
78
	}
219
78
	.assimilate_storage(&mut t)
220
78
	.unwrap();
221
78

            
222
78
	let mut ext = sp_io::TestExternalities::new(t);
223
78
	ext.execute_with(|| {
224
78
		System::set_block_number(1);
225
78
		MsgQueue::set_para_id(para_id.into());
226
78
	});
227
78
	ext
228
78
}
229

            
230
78
pub fn relay_ext(paras: Vec<u32>) -> sp_io::TestExternalities {
231
	use relay_chain::{Runtime, System};
232

            
233
78
	let mut t = frame_system::GenesisConfig::<Runtime>::default()
234
78
		.build_storage()
235
78
		.unwrap();
236
78

            
237
78
	pallet_balances::GenesisConfig::<Runtime> {
238
78
		balances: vec![(RELAYALICE, INITIAL_BALANCE)],
239
78
		dev_accounts: None,
240
78
	}
241
78
	.assimilate_storage(&mut t)
242
78
	.unwrap();
243
78

            
244
78
	let para_genesis: Vec<(ParaId, ParaGenesisArgs)> = paras
245
78
		.iter()
246
312
		.map(|&para_id| (para_id.into(), mock_para_genesis_info()))
247
78
		.collect();
248
78

            
249
78
	let genesis_config = ConfigurationGenesisConfig::<Runtime> {
250
78
		config: mock_relay_config(),
251
78
	};
252
78
	genesis_config.assimilate_storage(&mut t).unwrap();
253
78

            
254
78
	let genesis_config = ParasGenesisConfig::<Runtime> {
255
78
		paras: para_genesis,
256
78
		..Default::default()
257
78
	};
258
78
	genesis_config.assimilate_storage(&mut t).unwrap();
259
78

            
260
78
	let mut ext = sp_io::TestExternalities::new(t);
261
78
	ext.execute_with(|| {
262
78
		System::set_block_number(1);
263
78
	});
264
78
	ext
265
78
}
266

            
267
pub type RelayChainPalletXcm = pallet_xcm::Pallet<relay_chain::Runtime>;
268
pub type Hrmp = polkadot_runtime_parachains::hrmp::Pallet<relay_chain::Runtime>;
269

            
270
pub type StatemintBalances = pallet_balances::Pallet<statemint_like::Runtime>;
271
pub type StatemintChainPalletXcm = pallet_xcm::Pallet<statemint_like::Runtime>;
272
pub type StatemintAssets = pallet_assets::Pallet<statemint_like::Runtime>;
273

            
274
pub type RelayBalances = pallet_balances::Pallet<relay_chain::Runtime>;
275
pub type ParaBalances = pallet_balances::Pallet<parachain::Runtime>;
276
pub type XcmTransactor = pallet_xcm_transactor::Pallet<parachain::Runtime>;