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
//! A minimal runtime including the multi block migrations pallet
18

            
19
use super::*;
20
use crate as pallet_xcm_weight_trader;
21
use frame_support::{
22
	construct_runtime, ord_parameter_types, parameter_types,
23
	traits::{Currency, Everything},
24
	weights::{constants::RocksDbWeight, IdentityFee},
25
};
26
use frame_system::EnsureSignedBy;
27
use sp_core::H256;
28
use sp_runtime::{
29
	traits::{BlakeTwo256, IdentityLookup},
30
	BuildStorage,
31
};
32
use xcm::v5::{Asset, Error as XcmError, Junction, Location, Result as XcmResult, XcmContext};
33

            
34
type AccountId = u64;
35
type Balance = u128;
36
type Block = frame_system::mocking::MockBlock<Test>;
37

            
38
// Configure a mock runtime to test the pallet.
39
464
construct_runtime!(
40
257
	pub enum Test
41
257
	{
42
257
		System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>},
43
257
		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
44
257
		XcmWeightTrader: pallet_xcm_weight_trader::{Pallet, Call, Storage, Event<T>},
45
257
	}
46
504
);
47

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

            
85
parameter_types! {
86
	pub const ExistentialDeposit: u128 = 0;
87
}
88
impl pallet_balances::Config for Test {
89
	type MaxReserves = ();
90
	type ReserveIdentifier = ();
91
	type MaxLocks = ();
92
	type Balance = Balance;
93
	type RuntimeEvent = RuntimeEvent;
94
	type DustRemoval = ();
95
	type ExistentialDeposit = ExistentialDeposit;
96
	type AccountStore = System;
97
	type WeightInfo = ();
98
	type RuntimeHoldReason = ();
99
	type FreezeIdentifier = ();
100
	type MaxFreezes = ();
101
	type RuntimeFreezeReason = ();
102
	type DoneSlashHandler = ();
103
}
104

            
105
pub struct AccountIdToLocation;
106
impl Convert<AccountId, Location> for AccountIdToLocation {
107
3
	fn convert(account: AccountId) -> Location {
108
3
		Location::new(
109
3
			0,
110
3
			[Junction::AccountIndex64 {
111
3
				network: None,
112
3
				index: account,
113
3
			}],
114
3
		)
115
3
	}
116
}
117

            
118
pub struct AssetLocationFilter;
119
impl Contains<Location> for AssetLocationFilter {
120
9
	fn contains(location: &Location) -> bool {
121
9
		*location == <Test as Config>::NativeLocation::get() || *location == Location::parent()
122
9
	}
123
}
124

            
125
1
pub fn get_parent_asset_deposited() -> Option<(AccountId, Balance)> {
126
1
	storage::unhashed::get_raw(b"____parent_asset_deposited")
127
1
		.map(|output| Decode::decode(&mut output.as_slice()).expect("Decoding should work"))
128
1
}
129

            
130
pub struct MockAssetTransactor;
131
impl TransactAsset for MockAssetTransactor {
132
3
	fn deposit_asset(asset: &Asset, who: &Location, _context: Option<&XcmContext>) -> XcmResult {
133
3
		match (asset.id.clone(), asset.fun.clone()) {
134
3
			(XcmAssetId(location), Fungibility::Fungible(amount)) => {
135
3
				let who = match who.interior.iter().next() {
136
3
					Some(Junction::AccountIndex64 { index, .. }) => index,
137
					_ => panic!("invalid location"),
138
				};
139
3
				if location == <Test as Config>::NativeLocation::get() {
140
2
					let _ = Balances::deposit_creating(who, amount);
141
2
					Ok(())
142
1
				} else if location == Location::parent() {
143
1
					storage::unhashed::put_raw(
144
1
						b"____parent_asset_deposited",
145
1
						(who, amount).encode().as_slice(),
146
1
					);
147
1
					Ok(())
148
				} else {
149
					Err(XcmError::AssetNotFound)
150
				}
151
			}
152
			_ => Err(XcmError::AssetNotFound),
153
		}
154
3
	}
155
}
156

            
157
ord_parameter_types! {
158
	pub const AddAccount: u64 = 1;
159
	pub const EditAccount: u64 = 2;
160
	pub const PauseAccount: u64 = 3;
161
	pub const ResumeAccount: u64 = 4;
162
	pub const RemoveAccount: u64 = 5;
163
}
164

            
165
parameter_types! {
166
	pub NativeLocation: Location = Location::here();
167
	pub XcmFeesAccount: AccountId = 101;
168
	pub NotFilteredLocation: Location = Location::parent();
169
}
170

            
171
impl Config for Test {
172
	type AccountIdToLocation = AccountIdToLocation;
173
	type AddSupportedAssetOrigin = EnsureSignedBy<AddAccount, AccountId>;
174
	type AssetLocationFilter = AssetLocationFilter;
175
	type AssetTransactor = MockAssetTransactor;
176
	type Balance = Balance;
177
	type EditSupportedAssetOrigin = EnsureSignedBy<EditAccount, AccountId>;
178
	type NativeLocation = NativeLocation;
179
	type PauseSupportedAssetOrigin = EnsureSignedBy<PauseAccount, AccountId>;
180
	type RemoveSupportedAssetOrigin = EnsureSignedBy<RemoveAccount, AccountId>;
181
	type RuntimeEvent = RuntimeEvent;
182
	type ResumeSupportedAssetOrigin = EnsureSignedBy<ResumeAccount, AccountId>;
183
	type WeightInfo = ();
184
	type WeightToFee = IdentityFee<Balance>;
185
	type XcmFeesAccount = XcmFeesAccount;
186
	#[cfg(feature = "runtime-benchmarks")]
187
	type NotFilteredLocation = NotFilteredLocation;
188
}
189

            
190
9
pub fn new_test_ext() -> sp_io::TestExternalities {
191
9
	sp_tracing::try_init_simple();
192
9
	let mut t = frame_system::GenesisConfig::<Test>::default()
193
9
		.build_storage()
194
9
		.unwrap();
195
9

            
196
9
	let balances = vec![(1, 100), (2, 100), (3, 100), (4, 100), (5, 100)];
197
9
	pallet_balances::GenesisConfig::<Test> { balances }
198
9
		.assimilate_storage(&mut t)
199
9
		.unwrap();
200
9

            
201
9
	t.into()
202
9
}