1
// Copyright 2019-2022 PureStake Inc.
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
//! Precompile to xcm transactor runtime methods via the EVM
18

            
19
use crate::functions::{CurrencyIdOf, GetDataLimit, TransactorOf, XcmTransactorWrapper};
20
use fp_evm::PrecompileHandle;
21
use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo};
22
use precompile_utils::prelude::*;
23
use sp_core::{H160, U256};
24
use sp_runtime::traits::Dispatchable;
25
use sp_std::{convert::TryFrom, marker::PhantomData};
26
use xcm::latest::Location;
27
use xcm_primitives::AccountIdToCurrencyId;
28

            
29
/// A precompile to wrap the functionality from xcm transactor
30
pub struct XcmTransactorPrecompileV2<Runtime>(PhantomData<Runtime>);
31

            
32
138
#[precompile_utils::precompile]
33
impl<Runtime> XcmTransactorPrecompileV2<Runtime>
34
where
35
	Runtime: pallet_xcm_transactor::Config + pallet_evm::Config + frame_system::Config,
36
	Runtime::RuntimeCall: Dispatchable<PostInfo = PostDispatchInfo> + GetDispatchInfo,
37
	Runtime::RuntimeCall: From<pallet_xcm_transactor::Call<Runtime>>,
38
	<Runtime::RuntimeCall as Dispatchable>::RuntimeOrigin: From<Option<Runtime::AccountId>>,
39
	TransactorOf<Runtime>: TryFrom<u8>,
40
	Runtime::AccountId: Into<H160>,
41
	Runtime: AccountIdToCurrencyId<Runtime::AccountId, CurrencyIdOf<Runtime>>,
42
{
43
	#[precompile::public("indexToAccount(uint16)")]
44
	#[precompile::view]
45
	fn index_to_account(handle: &mut impl PrecompileHandle, index: u16) -> EvmResult<Address> {
46
		XcmTransactorWrapper::<Runtime>::account_index(handle, index)
47
	}
48

            
49
	#[precompile::public("transactInfoWithSigned((uint8,bytes[]))")]
50
	#[precompile::view]
51
	fn transact_info_with_signed(
52
		handle: &mut impl PrecompileHandle,
53
		location: Location,
54
	) -> EvmResult<(u64, u64, u64)> {
55
		XcmTransactorWrapper::<Runtime>::transact_info_with_signed(handle, location)
56
	}
57

            
58
	#[precompile::public("feePerSecond((uint8,bytes[]))")]
59
	#[precompile::view]
60
	fn fee_per_second(handle: &mut impl PrecompileHandle, location: Location) -> EvmResult<U256> {
61
		XcmTransactorWrapper::<Runtime>::fee_per_second(handle, location)
62
	}
63

            
64
	#[precompile::public(
65
		"transactThroughDerivativeMultilocation(\
66
		uint8,\
67
		uint16,\
68
		(uint8,bytes[]),\
69
		uint64,bytes,\
70
		uint256,\
71
		uint64)"
72
	)]
73
1
	fn transact_through_derivative_multilocation(
74
1
		handle: &mut impl PrecompileHandle,
75
1
		transactor: u8,
76
1
		index: u16,
77
1
		fee_asset: Location,
78
1
		weight: u64,
79
1
		inner_call: BoundedBytes<GetDataLimit>,
80
1
		fee_amount: Convert<U256, u128>,
81
1
		overall_weight: u64,
82
1
	) -> EvmResult {
83
1
		XcmTransactorWrapper::<Runtime>::transact_through_derivative_multilocation_fee_weight(
84
1
			handle,
85
1
			transactor,
86
1
			index,
87
1
			fee_asset,
88
1
			weight,
89
1
			inner_call,
90
1
			fee_amount.converted(),
91
1
			overall_weight,
92
1
		)
93
1
	}
94

            
95
	#[precompile::public(
96
		"transactThroughDerivative(\
97
		uint8,\
98
		uint16,\
99
		address,\
100
		uint64,\
101
		bytes,\
102
		uint256,\
103
		uint64)"
104
	)]
105
1
	fn transact_through_derivative(
106
1
		handle: &mut impl PrecompileHandle,
107
1
		transactor: u8,
108
1
		index: u16,
109
1
		fee_asset: Address,
110
1
		weight: u64,
111
1
		inner_call: BoundedBytes<GetDataLimit>,
112
1
		fee_amount: Convert<U256, u128>,
113
1
		overall_weight: u64,
114
1
	) -> EvmResult {
115
1
		XcmTransactorWrapper::<Runtime>::transact_through_derivative_fee_weight(
116
1
			handle,
117
1
			transactor,
118
1
			index,
119
1
			fee_asset,
120
1
			weight,
121
1
			inner_call,
122
1
			fee_amount.converted(),
123
1
			overall_weight,
124
1
		)
125
1
	}
126

            
127
	#[precompile::public(
128
		"transactThroughSignedMultilocation(\
129
		(uint8,bytes[]),\
130
		(uint8,bytes[]),\
131
		uint64,\
132
		bytes,\
133
		uint256,\
134
		uint64)"
135
	)]
136
7
	fn transact_through_signed_multilocation(
137
7
		handle: &mut impl PrecompileHandle,
138
7
		dest: Location,
139
7
		fee_asset: Location,
140
7
		weight: u64,
141
7
		call: BoundedBytes<GetDataLimit>,
142
7
		fee_amount: Convert<U256, u128>,
143
7
		overall_weight: u64,
144
7
	) -> EvmResult {
145
7
		XcmTransactorWrapper::<Runtime>::transact_through_signed_multilocation_fee_weight(
146
7
			handle,
147
7
			dest,
148
7
			fee_asset,
149
7
			weight,
150
7
			call,
151
7
			fee_amount.converted(),
152
7
			overall_weight,
153
7
		)
154
7
	}
155

            
156
	#[precompile::public(
157
		"transactThroughSigned((uint8,bytes[]),address,uint64,bytes,uint256,uint64)"
158
	)]
159
1
	fn transact_through_signed(
160
1
		handle: &mut impl PrecompileHandle,
161
1
		dest: Location,
162
1
		fee_asset: Address,
163
1
		weight: u64,
164
1
		call: BoundedBytes<GetDataLimit>,
165
1
		fee_amount: Convert<U256, u128>,
166
1
		overall_weight: u64,
167
1
	) -> EvmResult {
168
1
		XcmTransactorWrapper::<Runtime>::transact_through_signed_fee_weight(
169
1
			handle,
170
1
			dest,
171
1
			fee_asset,
172
1
			weight,
173
1
			call,
174
1
			fee_amount.converted(),
175
1
			overall_weight,
176
1
		)
177
1
	}
178

            
179
	#[precompile::public("encodeUtilityAsDerivative(uint8,uint16,bytes)")]
180
	#[precompile::public("encode_utility_as_derivative(uint8,uint16,bytes)")]
181
	#[precompile::view]
182
	fn encode_utility_as_derivative(
183
		handle: &mut impl PrecompileHandle,
184
		transactor: u8,
185
		index: u16,
186
		inner_call: BoundedBytes<GetDataLimit>,
187
	) -> EvmResult<UnboundedBytes> {
188
		XcmTransactorWrapper::<Runtime>::encode_utility_as_derivative(
189
			handle, transactor, index, inner_call,
190
		)
191
	}
192
}