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::v4::{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
461
construct_runtime!(
40
	pub enum Test
41
	{
42
		System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>},
43
		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
44
		XcmWeightTrader: pallet_xcm_weight_trader::{Pallet, Call, Storage, Event<T>},
45
	}
46
718
);
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
}
83

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

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

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

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

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

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

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

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

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

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

            
199
9
	t.into()
200
9
}