diff --git a/Cargo.lock b/Cargo.lock index dc21689dc3..9bb0ef1336 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6315,17 +6315,12 @@ dependencies = [ "pallet-evm-chain-id", "pallet-evm-precompile-simple", "pallet-timestamp", - "pallet-xcm-transactor", "parity-scale-codec", "scale-info", "sp-core", "sp-io", "sp-runtime", "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.7.2)", - "staging-xcm", - "staging-xcm-builder", - "staging-xcm-executor", - "xcm-primitives", ] [[package]] @@ -8271,12 +8266,8 @@ dependencies = [ "frame-support", "frame-system", "hex", - "hex-literal", "orml-traits", - "pallet-balances", "parity-scale-codec", - "rand", - "runtime-common", "scale-info", "sp-core", "sp-io", diff --git a/pallets/liquidity-pools-gateway/Cargo.toml b/pallets/liquidity-pools-gateway/Cargo.toml index add2f09a3d..5f01d96284 100644 --- a/pallets/liquidity-pools-gateway/Cargo.toml +++ b/pallets/liquidity-pools-gateway/Cargo.toml @@ -34,11 +34,6 @@ cfg-utils = { workspace = true } [dev-dependencies] cfg-mocks = { workspace = true, default-features = true } -cfg-primitives = { workspace = true, default-features = true } -hex-literal = { workspace = true } -pallet-balances = { workspace = true, default-features = true } -rand = { workspace = true, default-features = true } -runtime-common = { workspace = true, default-features = true } sp-io = { workspace = true, default-features = true } [features] diff --git a/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs b/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs index fddc1fec92..d2fcec96b6 100644 --- a/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs +++ b/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs @@ -21,11 +21,7 @@ use fp_evm::{ExitError, PrecompileFailure, PrecompileHandle}; use frame_support::ensure; use precompile_utils::prelude::*; use sp_core::{bounded::BoundedVec, ConstU32, H256, U256}; -use sp_runtime::{ - traits::{BlakeTwo256, Hash}, - DispatchError, -}; -use sp_std::vec::Vec; +use sp_runtime::traits::{BlakeTwo256, Hash}; pub use crate::weights::WeightInfo; @@ -203,21 +199,6 @@ pub mod pallet { } } -impl cfg_traits::TryConvert<(Vec, Vec), DomainAddress> for Pallet { - type Error = DispatchError; - - fn try_convert(origin: (Vec, Vec)) -> Result { - let (source_chain, source_address) = origin; - - let domain_converter = SourceConversion::::get(BlakeTwo256::hash(&source_chain)) - .ok_or(Error::::NoConverterForSource)?; - - domain_converter - .try_convert(&source_address) - .ok_or(Error::::AccountBytesMismatchForDomain.into()) - } -} - #[precompile_utils::precompile] impl Pallet where @@ -287,16 +268,13 @@ where exit_status: ExitError::Other("account bytes mismatch for domain".into()), })?; - match pallet_liquidity_pools_gateway::Pallet::::receive_message( + pallet_liquidity_pools_gateway::Pallet::::receive_message( pallet_liquidity_pools_gateway::GatewayOrigin::Domain(domain_address).into(), msg, ) .map(|_| ()) .map_err(TryDispatchError::Substrate) - { - Err(e) => Err(e.into()), - Ok(()) => Ok(()), - } + .map_err(Into::into) } // Mimics: diff --git a/pallets/liquidity-pools-gateway/routers/Cargo.toml b/pallets/liquidity-pools-gateway/routers/Cargo.toml index 3fde07c088..0edfe84975 100644 --- a/pallets/liquidity-pools-gateway/routers/Cargo.toml +++ b/pallets/liquidity-pools-gateway/routers/Cargo.toml @@ -22,11 +22,6 @@ sp-std = { workspace = true } sp-core = { workspace = true } sp-runtime = { workspace = true } -# XCM -pallet-xcm-transactor = { workspace = true } -staging-xcm = { workspace = true } -xcm-primitives = { workspace = true } - # EVM ethabi = { workspace = true } pallet-ethereum = { workspace = true } @@ -44,9 +39,6 @@ lazy_static = { workspace = true } cumulus-primitives-core = { workspace = true, default-features = true } -staging-xcm-builder = { workspace = true, default-features = true } -staging-xcm-executor = { workspace = true, default-features = true } - pallet-evm-chain-id = { workspace = true, default-features = true } pallet-evm-precompile-simple = { workspace = true, default-features = true } pallet-timestamp = { workspace = true, default-features = true } @@ -71,11 +63,8 @@ std = [ "frame-system/std", "sp-std/std", "sp-core/std", - "staging-xcm/std", - "pallet-xcm-transactor/std", "pallet-ethereum/std", "pallet-ethereum-transaction/std", - "xcm-primitives/std", "ethabi/std", "scale-info/std", "pallet-evm/std", @@ -90,12 +79,9 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", "pallet-ethereum-transaction/runtime-benchmarks", - "pallet-xcm-transactor/runtime-benchmarks", - "xcm-primitives/runtime-benchmarks", "pallet-evm/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "sp-runtime/runtime-benchmarks", - "staging-xcm-builder/runtime-benchmarks", ] try-runtime = [ "frame-support/try-runtime", @@ -106,7 +92,6 @@ try-runtime = [ "cfg-mocks/try-runtime", "pallet-ethereum/try-runtime", "pallet-ethereum-transaction/try-runtime", - "pallet-xcm-transactor/try-runtime", "pallet-evm/try-runtime", "pallet-balances/try-runtime", "sp-runtime/try-runtime", diff --git a/pallets/liquidity-pools-gateway/routers/src/lib.rs b/pallets/liquidity-pools-gateway/routers/src/lib.rs index 7f004c3442..a731009fbb 100644 --- a/pallets/liquidity-pools-gateway/routers/src/lib.rs +++ b/pallets/liquidity-pools-gateway/routers/src/lib.rs @@ -22,38 +22,17 @@ //! Moonbeam - via XCM. #![cfg_attr(not(feature = "std"), no_std)] -// polkadot/blob/19f6665a6162e68cd2651f5fe3615d6676821f90/xcm/src/v3/mod.rs# -// L1193 Defensively we increase this value to allow UMP fragments through -// xcm-transactor to prepare our runtime for a relay upgrade where the xcm -// instruction weights are not ZERO hardcoded. If that happens stuff will break -// in our side. Rationale behind the value: e.g. staking unbond will go above -// 64kb and thus required_weight_at_most must be below overall weight but still -// above whatever value we decide to set. For this reason we set here a value -// that makes sense for the overall weight. -pub const DEFAULT_PROOF_SIZE: u64 = 256 * 1024; - -// See moonbeam docs: https://docs.moonbeam.network/builders/interoperability/xcm/fees/#:~:text=As%20previously%20mentioned%2C%20Polkadot%20currently,1%2C000%2C000%2C000%20weight%20units%20per%20instruction -pub const XCM_INSTRUCTION_WEIGHT: u64 = 1_000_000_000; - -/// Multiplier for converting a unit of gas into a unit of Substrate weight -pub const GAS_TO_WEIGHT_MULTIPLIER: u64 = 25_000; - use cfg_traits::{ethereum::EthereumTransactor, liquidity_pools::Router}; use frame_support::{ - dispatch::PostDispatchInfo, ensure, pallet_prelude::{DispatchError, DispatchResult, DispatchResultWithPostInfo}, - traits::OriginTrait, - weights::Weight, }; use frame_system::pallet_prelude::OriginFor; -use pallet_xcm_transactor::{Currency, CurrencyPayment, TransactWeights}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_core::{bounded::BoundedVec, ConstU32, H160, H256, U256}; +use sp_core::{H160, H256, U256}; use sp_runtime::traits::{BlakeTwo256, Hash}; -use sp_std::{boxed::Box, marker::PhantomData, vec::Vec}; -use staging_xcm::{latest::OriginKind, prelude::Limited, VersionedLocation}; +use sp_std::{marker::PhantomData, vec::Vec}; #[cfg(test)] mod mock; @@ -63,13 +42,9 @@ mod tests; pub mod routers { pub mod axelar_evm; - pub mod axelar_xcm; - pub mod ethereum_xcm; } -pub use routers::{ - axelar_evm::AxelarEVMRouter, axelar_xcm::AxelarXCMRouter, ethereum_xcm::EthereumXCMRouter, -}; +pub use routers::axelar_evm::AxelarEVMRouter; /// Maximum size allowed for a byte representation of an Axelar EVM chain /// string, as found below: @@ -77,9 +52,6 @@ pub use routers::{ /// pub const MAX_AXELAR_EVM_CHAIN_SIZE: u32 = 16; -const FUNCTION_NAME: &str = "handle"; -const MESSAGE_PARAM: &str = "message"; - const AXELAR_FUNCTION_NAME: &str = "callContract"; const AXELAR_DESTINATION_CHAIN_PARAM: &str = "destinationChain"; const AXELAR_DESTINATION_CONTRACT_ADDRESS_PARAM: &str = "destinationContractAddress"; @@ -89,19 +61,17 @@ const AXELAR_PAYLOAD_PARAM: &str = "payload"; #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] pub enum DomainRouter where - T: pallet_xcm_transactor::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, T::AccountId: AsRef<[u8; 32]>, OriginFor: From + Into>>, { - EthereumXCM(EthereumXCMRouter), AxelarEVM(AxelarEVMRouter), - AxelarXCM(AxelarXCMRouter), } impl Router for DomainRouter where - T: pallet_xcm_transactor::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, T::AccountId: AsRef<[u8; 32]>, OriginFor: From + Into>>, @@ -110,17 +80,13 @@ where fn init(&self) -> DispatchResult { match self { - DomainRouter::EthereumXCM(r) => r.do_init(), DomainRouter::AxelarEVM(r) => r.do_init(), - DomainRouter::AxelarXCM(r) => r.do_init(), } } fn send(&self, sender: Self::Sender, message: Vec) -> DispatchResultWithPostInfo { match self { - DomainRouter::EthereumXCM(r) => r.do_send(sender, message), DomainRouter::AxelarEVM(r) => r.do_send(sender, message), - DomainRouter::AxelarXCM(r) => r.do_send(sender, message), } } } @@ -219,127 +185,3 @@ pub struct FeeValues { /// The gas limit used when executing the EVM call. pub gas_limit: U256, } - -/// A generic router used for executing XCM calls. -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub struct XCMRouter { - pub xcm_domain: XcmDomain, -} - -impl XCMRouter { - /// Sets the weight information for the provided XCM domain location, and - /// the fee per second for the provided fee asset location. - pub fn do_init(&self) -> DispatchResult { - Ok(()) - } - - /// Encodes the message to the required format and executes the - /// call via the XCM transactor pallet. - pub fn do_send(&self, sender: T::AccountId, msg: Vec) -> DispatchResultWithPostInfo { - let ethereum_xcm_call = get_encoded_ethereum_xcm_call::(self.xcm_domain.clone(), msg) - .map_err(|_| DispatchError::Other("encoded ethereum xcm call retrieval"))?; - - pallet_xcm_transactor::Pallet::::transact_through_sovereign( - ::RuntimeOrigin::root(), - // The destination to which the message should be sent. - self.xcm_domain.location.clone(), - // The sender will pay for this transaction. - Some(sender), - // The currency in which we want to pay fees. - CurrencyPayment { - currency: Currency::AsCurrencyId(self.xcm_domain.fee_currency.clone()), - fee_amount: Some(self.xcm_domain.fee_amount), - }, - // The call to be executed in the destination chain. - ethereum_xcm_call, - OriginKind::SovereignAccount, - TransactWeights { - transact_required_weight_at_most: self.xcm_domain.transact_required_weight_at_most, - overall_weight: Some(Limited(self.xcm_domain.overall_weight)), - }, - // Opt-in on RefundSurplus - true, - )?; - - Ok(PostDispatchInfo { - actual_weight: Some(self.xcm_domain.overall_weight), - pays_fee: Default::default(), - }) - } -} - -pub(crate) fn get_encoded_ethereum_xcm_call( - xcm_domain: XcmDomain, - msg: Vec, -) -> Result, ()> -where - T: pallet_xcm_transactor::Config, -{ - let input = - BoundedVec::>::try_from(msg) - .map_err(|_| ())?; - - let mut encoded: Vec = Vec::new(); - - encoded.append(&mut xcm_domain.ethereum_xcm_transact_call_index.into_inner()); - - encoded.append( - &mut xcm_primitives::EthereumXcmTransaction::V1(xcm_primitives::EthereumXcmTransactionV1 { - gas_limit: U256::from(xcm_domain.max_gas_limit), - fee_payment: xcm_primitives::EthereumXcmFee::Auto, - action: pallet_ethereum::TransactionAction::Call(xcm_domain.contract_address), - value: U256::zero(), - input, - access_list: None, - }) - .encode(), - ); - - Ok(encoded) -} - -/// XcmDomain gathers all the required fields to build and send remote -/// calls to a specific XCM-based Domain. -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub struct XcmDomain { - /// The XCM multilocation of the domain. - pub location: Box, - - /// The ethereum_xcm::Call::transact call index on a given domain. - /// It should contain the pallet index + the `transact` call index, to which - /// we will append the eth_tx param. - /// - /// You can obtain this value by building an ethereum_xcm::transact call - /// with Polkadot JS on the target chain. - pub ethereum_xcm_transact_call_index: - BoundedVec>, - - /// The target contract address on a given domain. - pub contract_address: H160, - - /// The max gas limit for the execution of the EVM call - pub max_gas_limit: u64, - - /// The max weight we want to pay for the execution of the Transact call in - /// the destination chain - pub transact_required_weight_at_most: Weight, - - /// The overall max weight we want to pay for the whole XCM message (i.e, - /// all the instructions) - pub overall_weight: Weight, - - /// The currency in which execution fees will be paid on - pub fee_currency: CurrencyId, - - /// The fee we use to buy execution for the execution of the Transact call - pub fee_amount: u128, -} - -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -/// XcmTransactInfo hold all the weight related information required for the XCM -/// transactor pallet. -pub struct XcmTransactInfo { - pub transact_extra_weight: Weight, - pub max_weight: Weight, - pub transact_extra_weight_signed: Option, -} diff --git a/pallets/liquidity-pools-gateway/routers/src/mock.rs b/pallets/liquidity-pools-gateway/routers/src/mock.rs index c48a5563c9..40ab5abbb3 100644 --- a/pallets/liquidity-pools-gateway/routers/src/mock.rs +++ b/pallets/liquidity-pools-gateway/routers/src/mock.rs @@ -3,34 +3,15 @@ use std::str::FromStr; use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers}; use cfg_primitives::{BLOCK_STORAGE_LIMIT, MAX_POV_SIZE}; use cfg_types::domain_address::DomainAddress; -use cumulus_primitives_core::{Instruction, PalletInstance, Parachain, SendError, Xcm, XcmHash}; -use frame_support::{ - derive_impl, parameter_types, - traits::{FindAuthor, PalletInfo as PalletInfoTrait}, - weights::Weight, -}; -use frame_system::EnsureRoot; +use frame_support::{derive_impl, parameter_types, traits::FindAuthor, weights::Weight}; use pallet_ethereum::{IntermediateStateRoot, PostLogContent}; use pallet_evm::{ runner::stack::Runner, AddressMapping, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, FixedGasWeightMapping, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, SubstrateBlockHashMapping, }; -use parity_scale_codec::{Decode, Encode}; use sp_core::{crypto::AccountId32, ByteArray, ConstU32, H160, U256}; use sp_runtime::{traits::IdentityLookup, ConsensusEngineId}; -use sp_std::{cell::RefCell, marker::PhantomData}; -use staging_xcm::latest::{ - opaque, Asset, Assets, Error as XcmError, InteriorLocation, Junction, Location, NetworkId, - Result as XcmResult, SendResult, SendXcm, XcmContext, -}; -use staging_xcm_executor::{ - traits::{TransactAsset, WeightBounds}, - AssetsInHolding, -}; -use xcm_primitives::{ - HrmpAvailableCalls, HrmpEncodeCall, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact, -}; pub type Balance = u128; @@ -39,7 +20,6 @@ frame_support::construct_runtime!( System: frame_system, Balances: pallet_balances, MockLiquidityPools: pallet_mock_liquidity_pools, - XcmTransactor: pallet_xcm_transactor, EVM: pallet_evm, Timestamp: pallet_timestamp, Ethereum: pallet_ethereum, @@ -205,236 +185,6 @@ impl pallet_ethereum::Config for Runtime { type RuntimeEvent = RuntimeEvent; type StateRoot = IntermediateStateRoot; } -/////////////////////////// -// XCM transactor mocks. // -/////////////////////////// - -// Transactors for the mock runtime. Only relay chain -#[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, scale_info::TypeInfo)] -pub enum Transactors { - Relay, -} - -#[cfg(feature = "runtime-benchmarks")] -impl Default for Transactors { - fn default() -> Self { - Transactors::Relay - } -} - -impl XcmTransact for Transactors { - fn destination(self) -> Location { - match self { - Transactors::Relay => Location::parent(), - } - } -} - -impl UtilityEncodeCall for Transactors { - fn encode_call(self, call: UtilityAvailableCalls) -> Vec { - match self { - Transactors::Relay => match call { - UtilityAvailableCalls::AsDerivative(a, b) => { - let mut call = - RelayCall::Utility(UtilityCall::AsDerivative(a.clone())).encode(); - call.append(&mut b.clone()); - call - } - }, - } - } -} - -pub struct AccountIdToLocation; -impl sp_runtime::traits::Convert for AccountIdToLocation { - fn convert(_account: AccountId32) -> Location { - let as_h160: H160 = H160::repeat_byte(0xAA); - Location::new( - 0, - Junction::AccountKey20 { - network: None, - key: as_h160.as_fixed_bytes().clone(), - }, - ) - } -} - -pub struct DummyAssetTransactor; -impl TransactAsset for DummyAssetTransactor { - fn deposit_asset(_what: &Asset, _who: &Location, _context: Option<&XcmContext>) -> XcmResult { - Ok(()) - } - - fn withdraw_asset( - _what: &Asset, - _who: &Location, - _context: Option<&XcmContext>, - ) -> Result { - Ok(AssetsInHolding::default()) - } -} - -pub struct CurrencyIdToLocation; - -pub type AssetId = u128; - -#[derive(Clone, Eq, Debug, PartialEq, Ord, PartialOrd, Encode, Decode, scale_info::TypeInfo)] -pub enum CurrencyId { - SelfReserve, - OtherReserve(AssetId), -} - -impl sp_runtime::traits::Convert> for CurrencyIdToLocation { - fn convert(currency: CurrencyId) -> Option { - match currency { - CurrencyId::SelfReserve => { - let multi: Location = SelfReserve::get(); - Some(multi) - } - // To distinguish between relay and others, specially for reserve asset - CurrencyId::OtherReserve(asset) => { - if asset == 0 { - Some(Location::parent()) - } else { - Some(Location::new(1, Parachain(2))) - } - } - } - } -} - -pub struct MockHrmpEncoder; - -impl HrmpEncodeCall for MockHrmpEncoder { - fn hrmp_encode_call(call: HrmpAvailableCalls) -> Result, XcmError> { - match call { - HrmpAvailableCalls::InitOpenChannel(_, _, _) => { - Ok(RelayCall::Hrmp(HrmpCall::Init()).encode()) - } - HrmpAvailableCalls::AcceptOpenChannel(_) => { - Ok(RelayCall::Hrmp(HrmpCall::Accept()).encode()) - } - HrmpAvailableCalls::CloseChannel(_) => Ok(RelayCall::Hrmp(HrmpCall::Close()).encode()), - HrmpAvailableCalls::CancelOpenRequest(_, _) => { - Ok(RelayCall::Hrmp(HrmpCall::Close()).encode()) - } - } - } -} - -// Simulates sending a XCM message -thread_local! { - pub static SENT_XCM: RefCell> = RefCell::new(Vec::new()); -} -pub fn sent_xcm() -> Vec<(Location, opaque::Xcm)> { - SENT_XCM.with(|q| (*q.borrow()).clone()) -} -pub struct TestSendXcm; -impl SendXcm for TestSendXcm { - type Ticket = (); - - fn validate( - destination: &mut Option, - message: &mut Option, - ) -> SendResult { - SENT_XCM.with(|q| { - q.borrow_mut() - .push((destination.clone().unwrap(), message.clone().unwrap())) - }); - Ok(((), Assets::new())) - } - - fn deliver(_: Self::Ticket) -> Result { - Ok(XcmHash::default()) - } -} - -#[derive(Encode, Decode)] -pub enum RelayCall { - #[codec(index = 0u8)] - // the index should match the position of the module in `construct_runtime!` - Utility(UtilityCall), - #[codec(index = 1u8)] - // the index should match the position of the module in `construct_runtime!` - Hrmp(HrmpCall), -} - -#[derive(Encode, Decode)] -pub enum UtilityCall { - #[codec(index = 0u8)] - AsDerivative(u16), -} - -#[derive(Encode, Decode)] -pub enum HrmpCall { - #[codec(index = 0u8)] - Init(), - #[codec(index = 1u8)] - Accept(), - #[codec(index = 2u8)] - Close(), -} - -pub type MaxHrmpRelayFee = staging_xcm_builder::Case; - -pub struct DummyWeigher(PhantomData); - -impl WeightBounds for DummyWeigher { - fn weight(_message: &mut Xcm) -> Result { - Ok(Weight::zero()) - } - - fn instr_weight(_instruction: &Instruction) -> Result { - Ok(Weight::zero()) - } -} - -parameter_types! { - pub const RelayNetwork: NetworkId = NetworkId::Polkadot; - - pub ParachainId: cumulus_primitives_core::ParaId = 100.into(); - - pub SelfLocation: Location = - Location::new(1, Parachain(ParachainId::get().into())); - - pub SelfReserve: Location = Location::new( - 1, - [ - Parachain(ParachainId::get().into()), - PalletInstance( - ::PalletInfo::index::().unwrap() as u8 - ) - ] - ); - - pub const BaseXcmWeight: staging_xcm::latest::Weight = staging_xcm::latest::Weight::from_parts(1000, 0); - - pub MaxFee: Asset = (Location::parent(), 1_000_000_000_000u128).into(); - - pub UniversalLocation: InteriorLocation = RelayNetwork::get().into(); -} - -impl pallet_xcm_transactor::Config for Runtime { - type AccountIdToLocation = AccountIdToLocation; - type AssetTransactor = DummyAssetTransactor; - type Balance = Balance; - type BaseXcmWeight = BaseXcmWeight; - type CurrencyId = CurrencyId; - type CurrencyIdToLocation = CurrencyIdToLocation; - type DerivativeAddressRegistrationOrigin = EnsureRoot; - type HrmpManipulatorOrigin = EnsureRoot; - type HrmpOpenOrigin = EnsureRoot; - type MaxHrmpFee = MaxHrmpRelayFee; - type ReserveProvider = orml_traits::location::RelativeReserveProvider; - type RuntimeEvent = RuntimeEvent; - type SelfLocation = SelfLocation; - type SovereignAccountDispatcherOrigin = EnsureRoot; - type Transactor = Transactors; - type UniversalLocation = UniversalLocation; - type Weigher = DummyWeigher; - type WeightInfo = (); - type XcmSender = TestSendXcm; -} pub fn new_test_ext() -> sp_io::TestExternalities { System::externalities() diff --git a/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs b/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs deleted file mode 100644 index 4ec4003212..0000000000 --- a/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2021 Centrifuge Foundation (centrifuge.io). -// -// This file is part of the Centrifuge chain project. -// Centrifuge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version (see http://www.gnu.org/licenses). -// Centrifuge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -use frame_support::dispatch::{DispatchResult, DispatchResultWithPostInfo}; -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use scale_info::TypeInfo; -use sp_core::{bounded::BoundedVec, ConstU32, H160}; -use sp_runtime::DispatchError; -use sp_std::vec::Vec; - -use crate::{routers::axelar_evm::get_axelar_encoded_msg, XCMRouter, MAX_AXELAR_EVM_CHAIN_SIZE}; - -/// The router used for submitting a message using Axelar via -/// Moonbeam XCM. -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub struct AxelarXCMRouter { - pub router: XCMRouter, - pub axelar_target_chain: BoundedVec>, - pub axelar_target_contract: H160, -} - -impl AxelarXCMRouter { - /// Calls the init function on the EVM router. - pub fn do_init(&self) -> DispatchResult { - self.router.do_init() - } - - /// Encodes the message to the required format, - /// then executes the EVM call using the generic XCM router. - pub fn do_send(&self, sender: T::AccountId, msg: Vec) -> DispatchResultWithPostInfo { - let contract_call = get_axelar_encoded_msg( - msg, - self.axelar_target_chain.clone().into_inner(), - self.axelar_target_contract, - ) - .map_err(|_| DispatchError::Other("encoded contract call retrieval"))?; - - self.router.do_send(sender, contract_call) - } -} diff --git a/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs b/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs deleted file mode 100644 index 571cd5cfc0..0000000000 --- a/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2021 Centrifuge Foundation (centrifuge.io). -// -// This file is part of the Centrifuge chain project. -// Centrifuge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version (see http://www.gnu.org/licenses). -// Centrifuge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -use ethabi::{Bytes, Contract}; -use frame_support::{ - dispatch::{DispatchResult, DispatchResultWithPostInfo}, - sp_runtime::DispatchError, -}; -use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use scale_info::TypeInfo; -use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; - -use crate::{XCMRouter, FUNCTION_NAME, MESSAGE_PARAM}; - -/// The router used for submitting a message via Moonbeam XCM. -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub struct EthereumXCMRouter { - pub router: XCMRouter, -} - -impl EthereumXCMRouter { - /// Calls the init function on the EVM router. - pub fn do_init(&self) -> DispatchResult { - self.router.do_init() - } - - /// Executes the call via the XCM router. - pub fn do_send(&self, sender: T::AccountId, msg: Vec) -> DispatchResultWithPostInfo { - let contract_call = get_encoded_contract_call(msg) - .map_err(|_| DispatchError::Other("encoded contract call retrieval"))?; - - self.router.do_send(sender, contract_call) - } -} - -/// Return the encoded contract call, i.e, -/// LiquidityPoolsXcmRouter::handle(encoded_msg). -pub(crate) fn get_encoded_contract_call(encoded_msg: Vec) -> Result { - let contract = get_xcm_router_contract(); - let encoded_contract_call = contract - .function(FUNCTION_NAME) - .map_err(|_| ())? - .encode_input(&[ethabi::Token::Bytes(encoded_msg)]) - .map_err(|_| ())?; - - Ok(encoded_contract_call) -} - -/// The LiquidityPoolsXcmRouter Abi as in ethabi::Contract -/// Note: We only concern ourselves with the `handle` function of the -/// contract since that's all we need to build the calls for remote EVM -/// execution. -fn get_xcm_router_contract() -> Contract { - let mut functions = BTreeMap::new(); - #[allow(deprecated)] - functions.insert( - FUNCTION_NAME.into(), - vec![ethabi::Function { - name: FUNCTION_NAME.into(), - inputs: vec![ethabi::Param { - name: MESSAGE_PARAM.into(), - kind: ethabi::ParamType::Bytes, - internal_type: None, - }], - outputs: vec![], - constant: Some(false), - state_mutability: Default::default(), - }], - ); - - Contract { - constructor: None, - functions, - events: Default::default(), - errors: Default::default(), - receive: false, - fallback: false, - } -} diff --git a/pallets/liquidity-pools-gateway/routers/src/tests.rs b/pallets/liquidity-pools-gateway/routers/src/tests.rs index 7db8b6569d..02c165205a 100644 --- a/pallets/liquidity-pools-gateway/routers/src/tests.rs +++ b/pallets/liquidity-pools-gateway/routers/src/tests.rs @@ -1,22 +1,16 @@ use cfg_primitives::CFG; use cfg_traits::liquidity_pools::Router; -use frame_support::{assert_noop, assert_ok, traits::fungible::Mutate}; +use frame_support::{assert_noop, assert_ok, traits::fungible::Mutate, BoundedVec}; use lazy_static::lazy_static; use pallet_evm::AddressMapping; -use sp_core::{bounded_vec, crypto::AccountId32, H160, H256, U256}; +use sp_core::{crypto::AccountId32, H160, H256, U256}; use sp_runtime::{ - traits::{BlakeTwo256, Convert, Hash}, + traits::{BlakeTwo256, ConstU32, Hash}, DispatchError, }; -use staging_xcm::latest::{ - Asset, AssetId, Fungibility, Instruction::*, Location, OriginKind, WeightLimit, -}; use super::mock::*; -use crate::{ - routers::{axelar_evm::get_axelar_encoded_msg, ethereum_xcm::get_encoded_contract_call}, - *, -}; +use crate::*; lazy_static! { static ref TEST_EVM_CHAIN: BoundedVec> = @@ -176,133 +170,6 @@ mod evm_router { } } -mod xcm_router { - use util::*; - - use super::*; - - mod util { - use super::*; - - pub struct XCMRouterTestData { - pub currency_id: CurrencyId, - pub dest: Location, - pub xcm_domain: XcmDomain<::CurrencyId>, - pub sender: AccountId32, - pub msg: Vec, - } - - pub fn get_test_data() -> XCMRouterTestData { - let currency_id = CurrencyId::OtherReserve(1); - let dest = CurrencyIdToLocation::convert(currency_id.clone()).unwrap(); - - let xcm_domain = XcmDomain { - location: Box::new(dest.clone().into_versioned()), - ethereum_xcm_transact_call_index: bounded_vec![0], - contract_address: H160::from_slice([0; 20].as_slice()), - max_gas_limit: 10, - transact_required_weight_at_most: Default::default(), - overall_weight: Default::default(), - fee_currency: currency_id.clone(), - fee_amount: 200000000000000000, - }; - - let sender: AccountId32 = [0; 32].into(); - - let msg = vec![0, 1, 2]; - - XCMRouterTestData { - currency_id, - dest, - xcm_domain, - sender, - msg, - } - } - } - - mod init { - use super::*; - - #[test] - fn success() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let router = XCMRouter:: { - xcm_domain: test_data.xcm_domain.clone(), - }; - - assert_ok!(router.do_init()); - }); - } - } - - mod send { - use super::*; - - #[test] - fn success() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let router = XCMRouter:: { - xcm_domain: test_data.xcm_domain.clone(), - }; - - assert_ok!(router.do_send(test_data.sender, test_data.msg.clone())); - - let sent_messages = sent_xcm(); - assert_eq!(sent_messages.len(), 1); - - let (_, xcm) = sent_messages.first().unwrap(); - assert!(xcm.0.contains(&WithdrawAsset( - (Asset { - id: AssetId(Location::here()), - fun: Fungibility::Fungible(test_data.xcm_domain.fee_amount), - }) - .into() - ))); - - assert!(xcm.0.contains(&BuyExecution { - fees: Asset { - id: AssetId(Location::here()), - fun: Fungibility::Fungible(test_data.xcm_domain.fee_amount), - }, - weight_limit: WeightLimit::Limited(test_data.xcm_domain.overall_weight), - })); - - let expected_call = get_encoded_ethereum_xcm_call::( - test_data.xcm_domain.clone(), - test_data.msg, - ) - .unwrap(); - - assert!(xcm.0.contains(&Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: test_data.xcm_domain.transact_required_weight_at_most, - call: expected_call.into(), - })); - }); - } - - #[test] - fn success_with_init() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let router = XCMRouter:: { - xcm_domain: test_data.xcm_domain.clone(), - }; - - assert_ok!(router.do_init()); - - assert_ok!(router.do_send(test_data.sender, test_data.msg)); - }); - } - } -} - mod axelar_evm { use util::*; @@ -482,269 +349,3 @@ mod axelar_evm { } } } - -mod axelar_xcm { - use util::*; - - use super::*; - - mod util { - use super::*; - - pub struct AxelarXCMTestData { - pub currency_id: CurrencyId, - pub dest: Location, - pub xcm_domain: XcmDomain<::CurrencyId>, - pub axelar_target_chain: BoundedVec>, - pub axelar_target_contract: H160, - pub sender: AccountId32, - pub msg: Vec, - } - - pub fn get_test_data() -> AxelarXCMTestData { - let currency_id = CurrencyId::OtherReserve(1); - let dest = CurrencyIdToLocation::convert(currency_id.clone()).unwrap(); - - let xcm_domain = XcmDomain { - location: Box::new(dest.clone().into_versioned()), - ethereum_xcm_transact_call_index: bounded_vec![0], - contract_address: H160::from_slice([0; 20].as_slice()), - max_gas_limit: 10, - transact_required_weight_at_most: Default::default(), - overall_weight: Default::default(), - fee_currency: currency_id.clone(), - fee_amount: 200000000000000000, - }; - let axelar_target_chain = TEST_EVM_CHAIN.clone(); - let axelar_target_contract = H160::from_low_u64_be(1); - - let sender: AccountId32 = [0; 32].into(); - - let msg = vec![0x42]; - - AxelarXCMTestData { - currency_id, - dest, - xcm_domain, - axelar_target_chain, - axelar_target_contract, - sender, - msg, - } - } - } - - mod init { - use super::*; - - #[test] - fn success() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let domain_router = - DomainRouter::::AxelarXCM(AxelarXCMRouter:: { - router: XCMRouter { - xcm_domain: test_data.xcm_domain.clone(), - }, - axelar_target_chain: test_data.axelar_target_chain, - axelar_target_contract: test_data.axelar_target_contract, - }); - - assert_ok!(domain_router.init()); - }); - } - } - - mod send { - use super::*; - - #[test] - fn success() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let domain_router = - DomainRouter::::AxelarXCM(AxelarXCMRouter:: { - router: XCMRouter { - xcm_domain: test_data.xcm_domain.clone(), - }, - axelar_target_chain: test_data.axelar_target_chain.clone(), - axelar_target_contract: test_data.axelar_target_contract, - }); - - assert_ok!(domain_router.init()); - - assert_ok!(domain_router.send(test_data.sender, test_data.msg.clone())); - - let sent_messages = sent_xcm(); - assert_eq!(sent_messages.len(), 1); - - let sent_messages = sent_xcm(); - assert_eq!(sent_messages.len(), 1); - - let (_, xcm) = sent_messages.first().unwrap(); - assert!(xcm.0.contains(&WithdrawAsset( - (Asset { - id: AssetId(Location::here()), - fun: Fungibility::Fungible(test_data.xcm_domain.fee_amount), - }) - .into() - ))); - - assert!(xcm.0.contains(&BuyExecution { - fees: Asset { - id: AssetId(Location::here()), - fun: Fungibility::Fungible(test_data.xcm_domain.fee_amount), - }, - weight_limit: WeightLimit::Limited(test_data.xcm_domain.overall_weight), - })); - - let contract_call = get_axelar_encoded_msg( - test_data.msg, - test_data.axelar_target_chain.clone().into_inner(), - test_data.axelar_target_contract, - ) - .unwrap(); - let expected_call = get_encoded_ethereum_xcm_call::( - test_data.xcm_domain.clone(), - contract_call, - ) - .unwrap(); - - assert!(xcm.0.contains(&Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: test_data.xcm_domain.transact_required_weight_at_most, - call: expected_call.into(), - })); - }); - } - } -} - -mod ethereum_xcm { - use util::*; - - use super::*; - - mod util { - use super::*; - - pub struct EthereumXCMTestData { - pub currency_id: CurrencyId, - pub dest: Location, - pub xcm_domain: XcmDomain<::CurrencyId>, - pub axelar_target_chain: BoundedVec>, - pub axelar_target_contract: H160, - pub sender: AccountId32, - pub msg: Vec, - } - - pub fn get_test_data() -> EthereumXCMTestData { - let currency_id = CurrencyId::OtherReserve(1); - let dest = CurrencyIdToLocation::convert(currency_id.clone()).unwrap(); - - let xcm_domain = XcmDomain { - location: Box::new(dest.clone().into_versioned()), - ethereum_xcm_transact_call_index: bounded_vec![0], - contract_address: H160::from_slice([0; 20].as_slice()), - max_gas_limit: 10, - transact_required_weight_at_most: Default::default(), - overall_weight: Default::default(), - fee_currency: currency_id.clone(), - fee_amount: 200000000000000000, - }; - let axelar_target_chain = TEST_EVM_CHAIN.clone(); - let axelar_target_contract = H160::from_low_u64_be(1); - - let sender: AccountId32 = [0; 32].into(); - - let msg = vec![0x42]; - - EthereumXCMTestData { - currency_id, - dest, - xcm_domain, - axelar_target_chain, - axelar_target_contract, - sender, - msg, - } - } - } - - mod init { - use super::*; - - #[test] - fn success() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let domain_router = - DomainRouter::::EthereumXCM(EthereumXCMRouter:: { - router: XCMRouter { - xcm_domain: test_data.xcm_domain.clone(), - }, - }); - - assert_ok!(domain_router.init()); - }); - } - } - - mod send { - use super::*; - - #[test] - fn success_with_init() { - new_test_ext().execute_with(|| { - let test_data = get_test_data(); - - let domain_router = - DomainRouter::::EthereumXCM(EthereumXCMRouter:: { - router: XCMRouter { - xcm_domain: test_data.xcm_domain.clone(), - }, - }); - - assert_ok!(domain_router.init()); - - assert_ok!(domain_router.send(test_data.sender, test_data.msg.clone())); - - let sent_messages = sent_xcm(); - assert_eq!(sent_messages.len(), 1); - - let (_, xcm) = sent_messages.first().unwrap(); - assert!(xcm.0.contains(&WithdrawAsset( - (Asset { - id: AssetId(Location::here()), - fun: Fungibility::Fungible(test_data.xcm_domain.fee_amount), - }) - .into() - ))); - - assert!(xcm.0.contains(&BuyExecution { - fees: Asset { - id: AssetId(Location::here()), - fun: Fungibility::Fungible(test_data.xcm_domain.fee_amount), - }, - weight_limit: WeightLimit::Limited(test_data.xcm_domain.overall_weight), - })); - - let contract_call = get_encoded_contract_call(test_data.msg).unwrap(); - let expected_call = get_encoded_ethereum_xcm_call::( - test_data.xcm_domain.clone(), - contract_call, - ) - .unwrap(); - - assert!(xcm.0.contains(&Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: test_data.xcm_domain.transact_required_weight_at_most, - call: expected_call.into(), - })); - }); - } - } -} diff --git a/pallets/liquidity-pools-gateway/src/lib.rs b/pallets/liquidity-pools-gateway/src/lib.rs index db759ce7a3..2dfc01b85e 100644 --- a/pallets/liquidity-pools-gateway/src/lib.rs +++ b/pallets/liquidity-pools-gateway/src/lib.rs @@ -29,21 +29,18 @@ use core::fmt::Debug; use cfg_primitives::LP_DEFENSIVE_WEIGHT; -use cfg_traits::{ - liquidity_pools::{ - InboundMessageHandler, LPEncoding, MessageProcessor, MessageQueue, OutboundMessageHandler, - Router as DomainRouter, - }, - TryConvert, +use cfg_traits::liquidity_pools::{ + InboundMessageHandler, LPEncoding, MessageProcessor, MessageQueue, OutboundMessageHandler, + Router as DomainRouter, }; use cfg_types::domain_address::{Domain, DomainAddress}; -use frame_support::{dispatch::DispatchResult, pallet_prelude::*, PalletError}; +use frame_support::{dispatch::DispatchResult, pallet_prelude::*}; use frame_system::pallet_prelude::{ensure_signed, OriginFor}; use message::GatewayMessage; use orml_traits::GetByKey; pub use pallet::*; use parity_scale_codec::{EncodeLike, FullCodec}; -use sp_std::{convert::TryInto, vec::Vec}; +use sp_std::convert::TryInto; use crate::weights::WeightInfo; @@ -60,31 +57,9 @@ mod mock; #[cfg(test)] mod tests; -#[derive(Encode, Decode, TypeInfo, PalletError)] -pub enum RelayerMessageDecodingError { - MalformedSourceAddress, - MalformedSourceAddressLength, - MalformedSourceChain, - MalformedSourceChainLength, - MalformedMessage, -} - -impl From for Error { - fn from(value: RelayerMessageDecodingError) -> Self { - Error::RelayerMessageDecodingFailed { reason: value } - } -} - #[frame_support::pallet] pub mod pallet { - const BYTES_U32: usize = 4; - const BYTES_ACCOUNT_20: usize = 20; - use super::*; - use crate::RelayerMessageDecodingError::{ - MalformedMessage, MalformedSourceAddress, MalformedSourceAddressLength, - MalformedSourceChain, MalformedSourceChainLength, - }; const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); @@ -134,9 +109,6 @@ pub mod pallet { Message = Self::Message, >; - /// A way to recover a domain address from two byte slices - type OriginRecovery: TryConvert<(Vec, Vec), DomainAddress, Error = DispatchError>; - type WeightInfo: WeightInfo; /// Maximum size of an incoming message. @@ -164,12 +136,6 @@ pub mod pallet { /// An instance was removed from a domain. InstanceRemoved { instance: DomainAddress }, - /// A relayer was added. - RelayerAdded { relayer: DomainAddress }, - - /// A relayer was removed. - RelayerRemoved { relayer: DomainAddress }, - /// The domain hook address was initialized or updated. DomainHookAddressSet { domain: Domain, @@ -193,20 +159,11 @@ pub mod pallet { pub type Allowlist = StorageDoubleMap<_, Blake2_128Concat, Domain, Blake2_128Concat, DomainAddress, ()>; - /// Storage that contains a limited number of whitelisted instances of - /// deployed liquidity pools for a particular domain. - /// - /// This can only be modified by an admin. - #[pallet::storage] - #[pallet::getter(fn relayer)] - pub type RelayerList = - StorageDoubleMap<_, Blake2_128Concat, Domain, Blake2_128Concat, DomainAddress, ()>; - /// Stores the hook address of a domain required for particular LP messages. /// /// Lifetime: Indefinitely. /// - /// NOTE: Must only be changeable via root or `AdminOrigin`. + /// NOTE: Must only be changeable via `AdminOrigin`. #[pallet::storage] pub type DomainHookAddress = StorageMap<_, Blake2_128Concat, Domain, [u8; 20], OptionQuery>; @@ -232,30 +189,17 @@ pub mod pallet { /// Instance was already added to the domain. InstanceAlreadyAdded, - /// Relayer was already added to the domain - RelayerAlreadyAdded, - /// Maximum number of instances for a domain was reached. MaxDomainInstances, /// Unknown instance. UnknownInstance, - /// Unknown relayer - UnknownRelayer, - /// Router not found. RouterNotFound, - /// Relayer messages need to prepend the with - /// the original source chain and source address - /// that triggered the message. - /// Decoding that is essential and this error - /// signals malforming of the wrapping information. - RelayerMessageDecodingFailed { reason: RelayerMessageDecodingError }, - - /// Emitted when you call `start_batch_message()` but that was already - /// called. You should finalize the message with `end_batch_message()` + /// Emitted when you call `start_batch_messages()` but that was already + /// called. You should finalize the message with `end_batch_messages()` MessagePackingAlreadyStarted, /// Emitted when you can `end_batch_message()` but the packing process @@ -328,48 +272,6 @@ pub mod pallet { Ok(()) } - /// Add a known instance of a deployed liquidity pools integration for a - /// specific domain. - #[pallet::weight(T::WeightInfo::add_relayer())] - #[pallet::call_index(3)] - pub fn add_relayer(origin: OriginFor, relayer: DomainAddress) -> DispatchResult { - T::AdminOrigin::ensure_origin(origin)?; - - ensure!( - relayer.domain() != Domain::Centrifuge, - Error::::DomainNotSupported - ); - - ensure!( - !RelayerList::::contains_key(relayer.domain(), relayer.clone()), - Error::::RelayerAlreadyAdded, - ); - - RelayerList::::insert(relayer.domain(), relayer.clone(), ()); - - Self::deposit_event(Event::RelayerAdded { relayer }); - - Ok(()) - } - - /// Remove an instance from a specific domain. - #[pallet::weight(T::WeightInfo::remove_relayer())] - #[pallet::call_index(4)] - pub fn remove_relayer(origin: OriginFor, relayer: DomainAddress) -> DispatchResult { - T::AdminOrigin::ensure_origin(origin.clone())?; - - ensure!( - RelayerList::::contains_key(relayer.domain(), relayer.clone()), - Error::::UnknownRelayer, - ); - - RelayerList::::remove(relayer.domain(), relayer.clone()); - - Self::deposit_event(Event::RelayerRemoved { relayer }); - - Ok(()) - } - /// Process an inbound message. #[pallet::weight(T::WeightInfo::receive_message())] #[pallet::call_index(5)] @@ -377,57 +279,7 @@ pub mod pallet { origin: OriginFor, msg: BoundedVec, ) -> DispatchResult { - let (origin_address, incoming_msg) = match T::LocalEVMOrigin::ensure_origin(origin)? { - GatewayOrigin::Domain(domain_address) => (domain_address, msg), - GatewayOrigin::AxelarRelay(domain_address) => { - // Every axelar relay address has a separate storage - ensure!( - RelayerList::::contains_key(domain_address.domain(), domain_address), - Error::::UnknownRelayer - ); - - // Every axelar relay will prepend the (sourceChain, - // sourceAddress) from actual origination chain to the - // message bytes, with a length identifier - let mut input = cfg_utils::BufferReader(msg.as_slice()); - - let length_source_chain = match input.read_array::() { - Some(bytes) => u32::from_be_bytes(*bytes), - None => Err(Error::::from(MalformedSourceChainLength))?, - }; - - let source_chain = match input.read_bytes(length_source_chain as usize) { - Some(bytes) => bytes.to_vec(), - None => Err(Error::::from(MalformedSourceChain))?, - }; - - let length_source_address = match input.read_array::() { - Some(bytes) => u32::from_be_bytes(*bytes), - None => Err(Error::::from(MalformedSourceAddressLength))?, - }; - - let source_address = match input.read_bytes(length_source_address as usize) { - Some(bytes) => { - // NOTE: Axelar simply provides the hexadecimal string of an EVM - // address as the `sourceAddress` argument. Solidity does on - // the other side recognize the hex-encoding and - // encode the hex bytes to utf-8 bytes. - // - // Hence, we are reverting this process here. - cfg_utils::decode_var_source::(bytes) - .ok_or(Error::::from(MalformedSourceAddress))? - .to_vec() - } - None => Err(Error::::from(MalformedSourceAddress))?, - }; - - ( - T::OriginRecovery::try_convert((source_chain, source_address))?, - BoundedVec::try_from(input.0.to_vec()) - .map_err(|_| Error::::from(MalformedMessage))?, - ) - } - }; + let GatewayOrigin::Domain(origin_address) = T::LocalEVMOrigin::ensure_origin(origin)?; if let DomainAddress::Centrifuge(_) = origin_address { return Err(Error::::InvalidMessageOrigin.into()); @@ -440,7 +292,7 @@ pub mod pallet { let gateway_message = GatewayMessage::::Inbound { domain_address: origin_address, - message: T::Message::deserialize(&incoming_msg)?, + message: T::Message::deserialize(&msg)?, }; T::MessageQueue::submit(gateway_message) diff --git a/pallets/liquidity-pools-gateway/src/mock.rs b/pallets/liquidity-pools-gateway/src/mock.rs index 83d8e9b5da..348ccf8d91 100644 --- a/pallets/liquidity-pools-gateway/src/mock.rs +++ b/pallets/liquidity-pools-gateway/src/mock.rs @@ -5,21 +5,14 @@ use cfg_mocks::{ use cfg_traits::liquidity_pools::LPEncoding; use cfg_types::domain_address::DomainAddress; use frame_support::{derive_impl, weights::constants::RocksDbWeight}; +use frame_system::EnsureRoot; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; -use runtime_common::origin::EnsureAccountOrRoot; use scale_info::TypeInfo; use sp_core::{crypto::AccountId32, H256}; use sp_runtime::{traits::IdentityLookup, DispatchError, DispatchResult}; use crate::{pallet as pallet_liquidity_pools_gateway, EnsureLocal, GatewayMessage}; -pub const LENGTH_SOURCE_CHAIN: usize = 10; -pub const SOURCE_CHAIN: [u8; LENGTH_SOURCE_CHAIN] = *b"ethereum-2"; -pub const SOURCE_CHAIN_EVM_ID: u64 = 1; - -pub const LENGTH_SOURCE_ADDRESS: usize = 20; -pub const SOURCE_ADDRESS: [u8; LENGTH_SOURCE_ADDRESS] = [0u8; LENGTH_SOURCE_ADDRESS]; - pub const LP_ADMIN_ACCOUNT: AccountId32 = AccountId32::new([u8::MAX; 32]); pub const MAX_PACKED_MESSAGES_ERR: &str = "packed limit error"; @@ -89,7 +82,6 @@ frame_support::construct_runtime!( MockLiquidityPools: pallet_mock_liquidity_pools, MockLiquidityPoolsGatewayQueue: pallet_mock_liquidity_pools_gateway_queue, MockRouters: pallet_mock_routers, - MockOriginRecovery: cfg_mocks::converter::pallet, LiquidityPoolsGateway: pallet_liquidity_pools_gateway, } ); @@ -109,11 +101,6 @@ impl pallet_mock_liquidity_pools::Config for Runtime { impl pallet_mock_routers::Config for Runtime {} -impl cfg_mocks::converter::pallet::Config for Runtime { - type From = (Vec, Vec); - type To = DomainAddress; -} - impl pallet_mock_liquidity_pools_gateway_queue::Config for Runtime { type Message = GatewayMessage; } @@ -125,13 +112,12 @@ frame_support::parameter_types! { } impl pallet_liquidity_pools_gateway::Config for Runtime { - type AdminOrigin = EnsureAccountOrRoot; + type AdminOrigin = EnsureRoot; type InboundMessageHandler = MockLiquidityPools; type LocalEVMOrigin = EnsureLocal; type MaxIncomingMessageSize = MaxIncomingMessageSize; type Message = Message; type MessageQueue = MockLiquidityPoolsGatewayQueue; - type OriginRecovery = MockOriginRecovery; type Router = RouterMock; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; diff --git a/pallets/liquidity-pools-gateway/src/origin.rs b/pallets/liquidity-pools-gateway/src/origin.rs index f492d8c9ec..04a3157f9a 100644 --- a/pallets/liquidity-pools-gateway/src/origin.rs +++ b/pallets/liquidity-pools-gateway/src/origin.rs @@ -21,7 +21,6 @@ use sp_runtime::RuntimeDebug; #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)] pub enum GatewayOrigin { Domain(DomainAddress), - AxelarRelay(DomainAddress), } pub struct EnsureLocal; diff --git a/pallets/liquidity-pools-gateway/src/tests.rs b/pallets/liquidity-pools-gateway/src/tests.rs index 887137afdf..13afa3a3bc 100644 --- a/pallets/liquidity-pools-gateway/src/tests.rs +++ b/pallets/liquidity-pools-gateway/src/tests.rs @@ -45,7 +45,7 @@ mod set_domain_router { use super::*; #[test] - fn success_with_root() { + fn success() { new_test_ext().execute_with(|| { let domain = Domain::EVM(0); let router = RouterMock::::default(); @@ -64,25 +64,6 @@ mod set_domain_router { }); } #[test] - fn success_with_lp_admin_account() { - new_test_ext().execute_with(|| { - let domain = Domain::EVM(0); - let router = RouterMock::::default(); - router.mock_init(move || Ok(())); - - assert_ok!(LiquidityPoolsGateway::set_domain_router( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - domain.clone(), - router.clone(), - )); - - let storage_entry = DomainRouters::::get(domain.clone()); - assert_eq!(storage_entry.unwrap(), router); - - event_exists(Event::::DomainRouterSet { domain, router }); - }); - } - #[test] fn router_init_error() { new_test_ext().execute_with(|| { let domain = Domain::EVM(0); @@ -145,7 +126,7 @@ mod add_instance { use super::*; #[test] - fn success_with_root() { + fn success() { new_test_ext().execute_with(|| { let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); let domain_address = DomainAddress::EVM(0, address.into()); @@ -166,28 +147,6 @@ mod add_instance { }); } - #[test] - fn success_with_lp_admin_account() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::EVM(0, address.into()); - - assert_ok!(LiquidityPoolsGateway::add_instance( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - domain_address.clone(), - )); - - assert!(Allowlist::::contains_key( - domain_address.domain(), - domain_address.clone() - )); - - event_exists(Event::::InstanceAdded { - instance: domain_address, - }); - }); - } - #[test] fn bad_origin() { new_test_ext().execute_with(|| { @@ -243,7 +202,7 @@ mod add_instance { )); assert_noop!( - LiquidityPoolsGateway::add_instance(RuntimeOrigin::root(), domain_address,), + LiquidityPoolsGateway::add_instance(RuntimeOrigin::root(), domain_address), Error::::InstanceAlreadyAdded ); }); @@ -254,7 +213,7 @@ mod remove_instance { use super::*; #[test] - fn success_with_root() { + fn success() { new_test_ext().execute_with(|| { let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); let domain_address = DomainAddress::EVM(0, address.into()); @@ -280,33 +239,6 @@ mod remove_instance { }); } - #[test] - fn success_with_lp_admin_account() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::EVM(0, address.into()); - - assert_ok!(LiquidityPoolsGateway::add_instance( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - domain_address.clone(), - )); - - assert_ok!(LiquidityPoolsGateway::remove_instance( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - domain_address.clone(), - )); - - assert!(!Allowlist::::contains_key( - domain_address.domain(), - domain_address.clone() - )); - - event_exists(Event::::InstanceRemoved { - instance: domain_address.clone(), - }); - }); - } - #[test] fn bad_origin() { new_test_ext().execute_with(|| { @@ -340,290 +272,6 @@ mod remove_instance { } } -mod receive_message_axelar_relay { - use sp_core::bounded::BoundedVec; - - use super::*; - use crate::RelayerMessageDecodingError; - - #[test] - fn success_from_solidity_payload() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let source_address = hex_literal::hex!["8503b4452Bf6238cC76CdbEE223b46d7196b1c93"]; - let domain_address = DomainAddress::EVM(SOURCE_CHAIN_EVM_ID, source_address); - let relayer_address = DomainAddress::EVM(0, address.into()); - - assert_ok!(LiquidityPoolsGateway::add_instance( - RuntimeOrigin::root(), - domain_address.clone(), - )); - - assert_ok!(LiquidityPoolsGateway::add_relayer( - RuntimeOrigin::root(), - relayer_address.clone(), - )); - - - let expected_msg = Message::Simple; - let expected_domain_address = domain_address.clone(); - - let inbound_message = GatewayMessage::::Inbound { domain_address: expected_domain_address, message: expected_msg.clone() }; - - MockLiquidityPoolsGatewayQueue::mock_submit(move |mock_message| { - assert_eq!(mock_message, inbound_message); - Ok(()) - }); - - let expected_domain_address = domain_address.clone(); - - MockOriginRecovery::mock_try_convert(move |origin| { - let (source_chain, origin_source_address) = origin; - - assert_eq!(&source_chain, SOURCE_CHAIN.as_slice()); - assert_eq!(&origin_source_address, source_address.as_slice()); - - Ok(expected_domain_address.clone()) - }); - - let solidity_header = "0000000a657468657265756d2d320000002a307838353033623434353242663632333863433736436462454532323362343664373139366231633933"; - let payload = [hex::decode(solidity_header).unwrap(), expected_msg.serialize()].concat(); - - assert_ok!(LiquidityPoolsGateway::receive_message( - GatewayOrigin::AxelarRelay(relayer_address).into(), - BoundedVec::::try_from(payload).unwrap() - )); - }) - } - - #[test] - fn success_with_root() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::EVM(SOURCE_CHAIN_EVM_ID, SOURCE_ADDRESS); - let relayer_address = DomainAddress::EVM(0, address.into()); - let message = Message::Simple; - assert_ok!(LiquidityPoolsGateway::add_instance( - RuntimeOrigin::root(), - domain_address.clone(), - )); - - assert_ok!(LiquidityPoolsGateway::add_relayer( - RuntimeOrigin::root(), - relayer_address.clone(), - )); - - let gateway_message = GatewayMessage::::Inbound { - domain_address: domain_address.clone(), - message: message.clone(), - }; - - MockLiquidityPoolsGatewayQueue::mock_submit(move |mock_message| { - assert_eq!(mock_message, gateway_message); - Ok(()) - }); - - let expected_domain_address = domain_address.clone(); - - MockOriginRecovery::mock_try_convert(move |origin| { - let (source_chain, source_address) = origin; - - assert_eq!(&source_chain, SOURCE_CHAIN.as_slice()); - assert_eq!(&source_address, SOURCE_ADDRESS.as_slice()); - - Ok(expected_domain_address.clone()) - }); - - let mut msg = Vec::new(); - msg.extend_from_slice(&(LENGTH_SOURCE_CHAIN as u32).to_be_bytes()); - msg.extend_from_slice(&SOURCE_CHAIN); - msg.extend_from_slice(&(LENGTH_SOURCE_ADDRESS as u32).to_be_bytes()); - msg.extend_from_slice(&SOURCE_ADDRESS); - msg.extend_from_slice(&message.serialize()); - - assert_ok!(LiquidityPoolsGateway::receive_message( - GatewayOrigin::AxelarRelay(relayer_address).into(), - BoundedVec::::try_from(msg).unwrap() - )); - }); - } - - #[test] - fn success_with_lp_admin_account() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::EVM(SOURCE_CHAIN_EVM_ID, SOURCE_ADDRESS); - let relayer_address = DomainAddress::EVM(0, address.into()); - let message = Message::Simple; - - assert_ok!(LiquidityPoolsGateway::add_instance( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - domain_address.clone(), - )); - - assert_ok!(LiquidityPoolsGateway::add_relayer( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - relayer_address.clone(), - )); - - let gateway_message = GatewayMessage::::Inbound { - domain_address: domain_address.clone(), - message: message.clone(), - }; - - MockLiquidityPoolsGatewayQueue::mock_submit(move |mock_message| { - assert_eq!(mock_message, gateway_message); - Ok(()) - }); - - let expected_domain_address = domain_address.clone(); - - MockOriginRecovery::mock_try_convert(move |origin| { - let (source_chain, source_address) = origin; - - assert_eq!(&source_chain, SOURCE_CHAIN.as_slice()); - assert_eq!(&source_address, SOURCE_ADDRESS.as_slice()); - - Ok(expected_domain_address.clone()) - }); - - let mut msg = Vec::new(); - msg.extend_from_slice(&(LENGTH_SOURCE_CHAIN as u32).to_be_bytes()); - msg.extend_from_slice(&SOURCE_CHAIN); - msg.extend_from_slice(&(LENGTH_SOURCE_ADDRESS as u32).to_be_bytes()); - msg.extend_from_slice(&SOURCE_ADDRESS); - msg.extend_from_slice(&message.serialize()); - - assert_ok!(LiquidityPoolsGateway::receive_message( - GatewayOrigin::AxelarRelay(relayer_address).into(), - BoundedVec::::try_from(msg).unwrap() - )); - }); - } - - #[test] - fn invalid_message_origin() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::Centrifuge(get_test_account_id().into()); - let relayer_address = DomainAddress::EVM(0, address.into()); - - assert_ok!(LiquidityPoolsGateway::add_relayer( - RuntimeOrigin::root(), - relayer_address.clone(), - )); - - let expected_msg = Message::Simple; - - let mut msg = Vec::new(); - - // Need to prepend length signaler - msg.extend_from_slice(&(0 as u32).to_be_bytes()); - msg.extend_from_slice(&(0 as u32).to_be_bytes()); - msg.extend_from_slice(&expected_msg.serialize()); - - MockOriginRecovery::mock_try_convert(move |origin| { - let (source_chain, source_address) = origin; - - assert!(source_chain.is_empty()); - assert!(source_address.is_empty()); - - Ok(domain_address.clone()) - }); - - assert_noop!( - LiquidityPoolsGateway::receive_message( - GatewayOrigin::AxelarRelay(relayer_address).into(), - BoundedVec::::try_from(msg).unwrap() - ), - Error::::RelayerMessageDecodingFailed { - reason: RelayerMessageDecodingError::MalformedSourceAddress - }, - ); - }); - } - - #[test] - fn unknown_instance() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::EVM(SOURCE_CHAIN_EVM_ID, SOURCE_ADDRESS); - let relayer_address = DomainAddress::EVM(0, address.into()); - - assert_ok!(LiquidityPoolsGateway::add_relayer( - RuntimeOrigin::root(), - relayer_address.clone(), - )); - - let expected_msg = Message::Simple; - - let mut msg = Vec::new(); - msg.extend_from_slice(&(LENGTH_SOURCE_CHAIN as u32).to_be_bytes()); - msg.extend_from_slice(&SOURCE_CHAIN); - msg.extend_from_slice(&(LENGTH_SOURCE_ADDRESS as u32).to_be_bytes()); - msg.extend_from_slice(&SOURCE_ADDRESS); - msg.extend_from_slice(&expected_msg.serialize()); - - let expected_domain_address = domain_address.clone(); - - MockOriginRecovery::mock_try_convert(move |origin| { - let (source_chain, source_address) = origin; - - assert_eq!(&source_chain, SOURCE_CHAIN.as_slice()); - assert_eq!(&source_address, SOURCE_ADDRESS.as_slice()); - - Ok(expected_domain_address.clone()) - }); - - assert_noop!( - LiquidityPoolsGateway::receive_message( - GatewayOrigin::AxelarRelay(relayer_address).into(), - BoundedVec::::try_from(msg).unwrap() - ), - Error::::UnknownInstance - ); - }); - } - - #[test] - fn message_queue_error() { - new_test_ext().execute_with(|| { - let address = H160::from_slice(&get_test_account_id().as_slice()[..20]); - let domain_address = DomainAddress::EVM(SOURCE_CHAIN_EVM_ID, SOURCE_ADDRESS); - let relayer_address = DomainAddress::EVM(0, address.into()); - - assert_ok!(LiquidityPoolsGateway::add_instance( - RuntimeOrigin::root(), - domain_address.clone(), - )); - - assert_ok!(LiquidityPoolsGateway::add_relayer( - RuntimeOrigin::root(), - relayer_address.clone(), - )); - - let expected_msg = Message::Simple; - let encoded_msg = expected_msg.serialize(); - - let expected_domain_address = domain_address.clone(); - - MockOriginRecovery::mock_try_convert(move |_| Ok(expected_domain_address.clone())); - - let err = sp_runtime::DispatchError::from("message queue error"); - - MockLiquidityPoolsGatewayQueue::mock_submit(move |_| Err(err)); - - assert_noop!( - LiquidityPoolsGateway::receive_message( - GatewayOrigin::Domain(domain_address).into(), - BoundedVec::::try_from(encoded_msg).unwrap() - ), - err, - ); - }); - } -} - mod receive_message_domain { use super::*; @@ -665,7 +313,7 @@ mod receive_message_domain { assert_noop!( LiquidityPoolsGateway::receive_message( - RuntimeOrigin::root(), + RuntimeOrigin::signed(AccountId32::new([0u8; 32])), BoundedVec::::try_from(encoded_msg).unwrap() ), BadOrigin, @@ -831,7 +479,7 @@ mod set_domain_hook { use super::*; #[test] - fn success_with_root() { + fn success() { new_test_ext().execute_with(|| { let domain = Domain::EVM(0); @@ -843,19 +491,6 @@ mod set_domain_hook { }); } - #[test] - fn success_with_lp_admin_account() { - new_test_ext().execute_with(|| { - let domain = Domain::EVM(0); - - assert_ok!(LiquidityPoolsGateway::set_domain_hook_address( - RuntimeOrigin::signed(LP_ADMIN_ACCOUNT), - domain, - get_test_hook_bytes() - )); - }); - } - #[test] fn failure_bad_origin() { new_test_ext().execute_with(|| { diff --git a/runtime/altair/src/lib.rs b/runtime/altair/src/lib.rs index 00aeab74d3..fe0d5dd8f8 100644 --- a/runtime/altair/src/lib.rs +++ b/runtime/altair/src/lib.rs @@ -1766,7 +1766,6 @@ impl pallet_liquidity_pools_gateway::Config for Runtime { type MaxIncomingMessageSize = MaxIncomingMessageSize; type Message = pallet_liquidity_pools::Message; type MessageQueue = LiquidityPoolsGatewayQueue; - type OriginRecovery = LiquidityPoolsAxelarGateway; type Router = liquidity_pools_gateway_routers::DomainRouter; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/centrifuge/src/lib.rs b/runtime/centrifuge/src/lib.rs index aa64dc80a7..0d97bad678 100644 --- a/runtime/centrifuge/src/lib.rs +++ b/runtime/centrifuge/src/lib.rs @@ -1865,7 +1865,6 @@ impl pallet_liquidity_pools_gateway::Config for Runtime { type MaxIncomingMessageSize = MaxIncomingMessageSize; type Message = pallet_liquidity_pools::Message; type MessageQueue = LiquidityPoolsGatewayQueue; - type OriginRecovery = LiquidityPoolsAxelarGateway; type Router = liquidity_pools_gateway_routers::DomainRouter; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/centrifuge/src/xcm.rs b/runtime/centrifuge/src/xcm.rs index f454f5f695..c210642c73 100644 --- a/runtime/centrifuge/src/xcm.rs +++ b/runtime/centrifuge/src/xcm.rs @@ -26,7 +26,7 @@ use runtime_common::{ transfer_filter::PreXcmTransfer, xcm::{ AccountIdToLocation, Barrier, CanonicalNativePerSecond, FixedConversionRateProvider, - LocalOriginToLocation, LpInstanceRelayer, ToTreasury, + LocalOriginToLocation, ToTreasury, }, }; use sp_core::ConstU32; @@ -186,8 +186,6 @@ impl TryConvert for ParaToEvm { /// `Transact`. There is an `OriginKind` which can biases the kind of local /// `Origin` it will become. pub type XcmOriginToTransactDispatchOrigin = ( - // A matcher that catches all Moonbeam relaying contracts to generate the right Origin - LpInstanceRelayer, // Sovereign account converter; this attempts to derive an `AccountId` from the origin location // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for // foreign chains who want to have a local sovereign account on this chain which they control. diff --git a/runtime/common/src/xcm.rs b/runtime/common/src/xcm.rs index f41382e91b..27248f3d84 100644 --- a/runtime/common/src/xcm.rs +++ b/runtime/common/src/xcm.rs @@ -11,12 +11,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. use cfg_primitives::types::{AccountId, Balance}; -use cfg_traits::TryConvert; -use cfg_types::{ - domain_address::{Domain, DomainAddress}, - tokens::{CrossChainTransferability, CurrencyId, CustomMetadata}, - EVMChainId, ParaId, -}; +use cfg_types::tokens::{CrossChainTransferability, CurrencyId, CustomMetadata}; use frame_support::traits::{fungibles::Mutate, Everything, Get}; use frame_system::pallet_prelude::BlockNumberFor; use orml_traits::asset_registry::Inspect; @@ -26,8 +21,8 @@ use sp_std::marker::PhantomData; use staging_xcm::v4::{ Asset, AssetId, Fungibility::Fungible, - Junction::{AccountId32, AccountKey20, GeneralKey, Parachain}, - Location, NetworkId, OriginKind, + Junction::{AccountId32, GeneralKey, Parachain}, + Location, NetworkId, }; use staging_xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, @@ -95,42 +90,6 @@ impl> Convert for AccountIdToLoca } } -pub struct LpInstanceRelayer(PhantomData<(ParaAsEvmChain, Runtime)>); -impl - staging_xcm_executor::traits::ConvertOrigin<::RuntimeOrigin> - for LpInstanceRelayer -where - ParaAsEvmChain: TryConvert, - Runtime: pallet_liquidity_pools_gateway::Config, - ::RuntimeOrigin: - From, -{ - fn convert_origin( - origin: impl Into, - kind: OriginKind, - ) -> Result<::RuntimeOrigin, Location> { - let location = origin.into(); - match (kind, location.clone().unpack()) { - (OriginKind::SovereignAccount, (1, [Parachain(para), AccountKey20 { key, .. }])) => { - let evm_id = ParaAsEvmChain::try_convert(*para).map_err(|_| location.clone())?; - let domain_address = DomainAddress::EVM(evm_id, *key); - - pallet_liquidity_pools_gateway::Pallet::::relayer( - Domain::EVM(evm_id), - &domain_address, - ) - .ok_or(location.clone())?; - - Ok( - pallet_liquidity_pools_gateway::GatewayOrigin::AxelarRelay(domain_address) - .into(), - ) - } - _ => Err(location), - } - } -} - /// No local origins on this chain are allowed to dispatch XCM sends/executions. pub type LocalOriginToLocation = SignedToAccountId32< ::RuntimeOrigin, @@ -269,287 +228,3 @@ pub type LocationToAccountId = ( // Generate remote accounts according to polkadot standards HashedDescription>, ); - -#[cfg(test)] -mod test { - use cfg_mocks::{ - pallet_mock_liquidity_pools, pallet_mock_liquidity_pools_gateway_queue, - pallet_mock_routers, RouterMock, - }; - use frame_support::{assert_ok, derive_impl, traits::EnsureOrigin}; - use frame_system::EnsureRoot; - use pallet_liquidity_pools::Message; - use pallet_liquidity_pools_gateway::{message::GatewayMessage, EnsureLocal, GatewayOrigin}; - use sp_core::{ConstU32, ConstU64}; - use sp_runtime::DispatchError; - use staging_xcm_executor::traits::ConvertOrigin; - - use super::*; - - type AccountId = u64; - - // For testing the pallet, we construct a mock runtime. - frame_support::construct_runtime!( - pub enum Runtime { - System: frame_system, - Gateway: pallet_liquidity_pools_gateway, - MockLP: pallet_mock_liquidity_pools, - MockLiquidityPoolsGatewayQueue: pallet_mock_liquidity_pools_gateway_queue, - MockParaAsEvmChain: cfg_mocks::converter::pallet::, - MockOriginRecovery: cfg_mocks::converter::pallet::, - } - ); - - #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] - impl frame_system::Config for Runtime { - type Block = frame_system::mocking::MockBlock; - } - - impl cfg_mocks::converter::pallet::Config for Runtime { - type From = ParaId; - type To = EVMChainId; - } - - impl cfg_mocks::converter::pallet::Config for Runtime { - type From = (Vec, Vec); - type To = DomainAddress; - } - - impl pallet_mock_liquidity_pools::Config for Runtime { - type DomainAddress = DomainAddress; - type Message = Message; - } - - impl pallet_mock_routers::Config for Runtime {} - - impl pallet_mock_liquidity_pools_gateway_queue::Config for Runtime { - type Message = GatewayMessage; - } - - impl pallet_liquidity_pools_gateway::Config for Runtime { - type AdminOrigin = EnsureRoot; - type InboundMessageHandler = MockLP; - type LocalEVMOrigin = pallet_liquidity_pools_gateway::EnsureLocal; - type MaxIncomingMessageSize = ConstU32<1024>; - type Message = Message; - type MessageQueue = MockLiquidityPoolsGatewayQueue; - type OriginRecovery = MockOriginRecovery; - type Router = RouterMock; - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type Sender = ConstU64<11>; - type WeightInfo = (); - } - - const RELAYER_PARA_ID: u32 = 1000; - const RELAYER_EVM_ID: u64 = 1001; - const RELAYER_ADDRESS: [u8; 20] = [1u8; 20]; - - #[test] - fn lp_instance_relayer_converts_correctly() { - System::externalities().execute_with(|| { - let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); - - assert_ok!(Gateway::add_relayer( - RuntimeOrigin::root(), - expected_address.clone(), - )); - - MockParaAsEvmChain::mock_try_convert(|from| { - assert_eq!(from, RELAYER_PARA_ID); - Ok(RELAYER_EVM_ID) - }); - - let location = Location::new( - 1, - [ - Parachain(RELAYER_PARA_ID), - AccountKey20 { - network: None, - key: RELAYER_ADDRESS, - }, - ], - ); - - let origin = LpInstanceRelayer::::convert_origin( - location, - OriginKind::SovereignAccount, - ) - .expect("Origin conversion failed unexpectedly."); - - assert_eq!( - EnsureLocal::ensure_origin(origin).expect("Generate origin must be GatewayOrigin"), - GatewayOrigin::AxelarRelay(expected_address) - ) - }) - } - - #[test] - fn lp_instance_relayer_fails_with_wrong_location() { - System::externalities().execute_with(|| { - let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); - - assert_ok!(Gateway::add_relayer( - RuntimeOrigin::root(), - expected_address.clone(), - )); - - MockParaAsEvmChain::mock_try_convert(|from| { - assert_eq!(from, RELAYER_PARA_ID); - Ok(RELAYER_EVM_ID) - }); - - let location = Location::new(1, Parachain(RELAYER_PARA_ID)); - - assert_eq!( - LpInstanceRelayer::::convert_origin( - location.clone(), - OriginKind::SovereignAccount, - ) - .unwrap_err(), - location - ); - }) - } - - #[test] - fn lp_instance_relayer_fails_if_relayer_not_set() { - System::externalities().execute_with(|| { - MockParaAsEvmChain::mock_try_convert(|from| { - assert_eq!(from, RELAYER_PARA_ID); - Ok(RELAYER_EVM_ID) - }); - - let location = Location::new( - 1, - [ - Parachain(RELAYER_PARA_ID), - AccountKey20 { - network: None, - key: RELAYER_ADDRESS, - }, - ], - ); - - assert_eq!( - LpInstanceRelayer::::convert_origin( - location.clone(), - OriginKind::SovereignAccount, - ) - .unwrap_err(), - location - ); - }) - } - - #[test] - fn lp_instance_relayer_fails_if_para_to_evm_fails() { - System::externalities().execute_with(|| { - let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); - - assert_ok!(Gateway::add_relayer( - RuntimeOrigin::root(), - expected_address.clone(), - )); - - MockParaAsEvmChain::mock_try_convert(|from| { - assert_eq!(from, RELAYER_PARA_ID); - Err(DispatchError::Other("")) - }); - - let location = Location::new( - 1, - [ - Parachain(RELAYER_PARA_ID), - AccountKey20 { - network: None, - key: RELAYER_ADDRESS, - }, - ], - ); - - assert_eq!( - LpInstanceRelayer::::convert_origin( - location.clone(), - OriginKind::SovereignAccount, - ) - .unwrap_err(), - location - ); - }) - } - - #[test] - fn lp_instance_relayer_fails_if_wrong_para() { - System::externalities().execute_with(|| { - let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); - - assert_ok!(Gateway::add_relayer( - RuntimeOrigin::root(), - expected_address.clone(), - )); - - MockParaAsEvmChain::mock_try_convert(|from| { - assert_eq!(from, 1); - Err(DispatchError::Other("")) - }); - - let location = Location::new( - 1, - [ - Parachain(1), - AccountKey20 { - network: None, - key: RELAYER_ADDRESS, - }, - ], - ); - - assert_eq!( - LpInstanceRelayer::::convert_origin( - location.clone(), - OriginKind::SovereignAccount, - ) - .unwrap_err(), - location - ); - }) - } - - #[test] - fn lp_instance_relayer_fails_if_wrong_address() { - System::externalities().execute_with(|| { - let expected_address = DomainAddress::EVM(RELAYER_EVM_ID, RELAYER_ADDRESS); - - assert_ok!(Gateway::add_relayer( - RuntimeOrigin::root(), - expected_address.clone(), - )); - - MockParaAsEvmChain::mock_try_convert(|from| { - assert_eq!(from, RELAYER_PARA_ID); - Ok(RELAYER_EVM_ID) - }); - - let location = Location::new( - 1, - [ - Parachain(RELAYER_PARA_ID), - AccountKey20 { - network: None, - key: [0u8; 20], - }, - ], - ); - - assert_eq!( - LpInstanceRelayer::::convert_origin( - location.clone(), - OriginKind::SovereignAccount, - ) - .unwrap_err(), - location - ); - }) - } -} diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index a8f0e1e484..67bf57c52c 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -1871,7 +1871,6 @@ impl pallet_liquidity_pools_gateway::Config for Runtime { type MaxIncomingMessageSize = MaxIncomingMessageSize; type Message = pallet_liquidity_pools::Message; type MessageQueue = LiquidityPoolsGatewayQueue; - type OriginRecovery = LiquidityPoolsAxelarGateway; type Router = liquidity_pools_gateway_routers::DomainRouter; type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; diff --git a/runtime/development/src/xcm.rs b/runtime/development/src/xcm.rs index eaecd65851..ba88b8b0e6 100644 --- a/runtime/development/src/xcm.rs +++ b/runtime/development/src/xcm.rs @@ -25,7 +25,7 @@ use runtime_common::{ transfer_filter::PreXcmTransfer, xcm::{ AccountIdToLocation, Barrier, CanonicalNativePerSecond, FixedConversionRateProvider, - LocalOriginToLocation, LpInstanceRelayer, ToTreasury, + LocalOriginToLocation, ToTreasury, }, }; use sp_core::ConstU32; @@ -185,8 +185,6 @@ impl TryConvert for ParaToEvm { /// `Transact`. There is an `OriginKind` which can biases the kind of local /// `Origin` it will become. pub type XcmOriginToTransactDispatchOrigin = ( - // A matcher that catches all Moonbeam relaying contracts to generate the right Origin - LpInstanceRelayer, // Sovereign account converter; this attempts to derive an `AccountId` from the origin location // using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for // foreign chains who want to have a local sovereign account on this chain which they control. diff --git a/runtime/integration-tests/src/cases/liquidity_pools.rs b/runtime/integration-tests/src/cases/liquidity_pools.rs index 7df2c69353..29403cad52 100644 --- a/runtime/integration-tests/src/cases/liquidity_pools.rs +++ b/runtime/integration-tests/src/cases/liquidity_pools.rs @@ -22,9 +22,6 @@ use frame_support::{ OriginTrait, PalletInfo, }, }; -use liquidity_pools_gateway_routers::{ - DomainRouter, EthereumXCMRouter, XCMRouter, XcmDomain, DEFAULT_PROOF_SIZE, -}; use pallet_foreign_investments::ForeignInvestmentInfo; use pallet_investments::CollectOutcome; use pallet_liquidity_pools::Message; @@ -35,13 +32,13 @@ use runtime_common::{ account_conversion::AccountConverter, foreign_investments::IdentityPoolCurrencyConverter, xcm::general_key, }; -use sp_core::{Get, H160}; +use sp_core::Get; use sp_runtime::{ traits::{AccountIdConversion, Convert, EnsureAdd, One, Zero}, BoundedVec, DispatchError, FixedPointNumber, Perquintill, SaturatedConversion, }; use staging_xcm::{ - v4::{Junction, Junction::*, Location, NetworkId}, + v4::{Junction::*, Location, NetworkId}, VersionedLocation, }; @@ -85,7 +82,6 @@ pub type LiquidityPoolMessage = Message; mod utils { use cfg_types::oracles::OracleKey; - use frame_support::weights::Weight; use runtime_common::oracle::Feeder; use super::*; @@ -211,42 +207,6 @@ mod utils { )); } - pub fn set_test_domain_router( - evm_chain_id: u64, - xcm_domain_location: VersionedLocation, - currency_id: CurrencyId, - ) { - let ethereum_xcm_router = EthereumXCMRouter:: { - router: XCMRouter { - xcm_domain: XcmDomain { - location: Box::new(xcm_domain_location), - ethereum_xcm_transact_call_index: BoundedVec::truncate_from(vec![38, 0]), - contract_address: H160::from(DEFAULT_EVM_ADDRESS_MOONBEAM), - max_gas_limit: 500_000, - transact_required_weight_at_most: Weight::from_parts( - 12530000000, - DEFAULT_PROOF_SIZE.saturating_div(2), - ), - overall_weight: Weight::from_parts(15530000000, DEFAULT_PROOF_SIZE), - fee_currency: currency_id, - // 0.2 token - fee_amount: 200000000000000000, - }, - }, - }; - - let domain_router = DomainRouter::EthereumXCM(ethereum_xcm_router); - let domain = Domain::EVM(evm_chain_id); - - assert_ok!( - pallet_liquidity_pools_gateway::Pallet::::set_domain_router( - ::RuntimeOrigin::root(), - domain, - domain_router, - ) - ); - } - pub fn default_tranche_id(pool_id: u64) -> TrancheId { let pool_details = pallet_pool_system::pallet::Pool::::get(pool_id).expect("Pool should exist"); @@ -325,12 +285,6 @@ mod utils { DEFAULT_BALANCE_GLMR, 0, )); - - set_test_domain_router::( - MOONBEAM_EVM_CHAIN_ID, - Location::new(1, Junction::Parachain(SIBLING_ID)).into(), - GLMR_CURRENCY_ID, - ); }); } @@ -343,11 +297,6 @@ mod utils { .expect("ForeignAsset should convert into u128") } - /// Returns the investment_id of the given pool and tranche ids. - pub fn investment_id(pool_id: u64, tranche_id: TrancheId) -> InvestmentId { - (pool_id, tranche_id) - } - pub fn default_investment_id() -> InvestmentId { (POOL_ID, default_tranche_id::(POOL_ID)) } @@ -578,7 +527,7 @@ mod utils { // Verify order id is 0 assert_eq!( - pallet_investments::Pallet::::redeem_order_id(investment_id::( + pallet_investments::Pallet::::redeem_order_id(( pool_id, default_tranche_id::(pool_id) )), diff --git a/runtime/integration-tests/src/cases/routers.rs b/runtime/integration-tests/src/cases/routers.rs index b21ad4b80a..bdaef239f7 100644 --- a/runtime/integration-tests/src/cases/routers.rs +++ b/runtime/integration-tests/src/cases/routers.rs @@ -1,37 +1,22 @@ use cfg_primitives::Balance; use cfg_traits::liquidity_pools::MessageProcessor; -use cfg_types::{ - domain_address::Domain, - tokens::{AssetMetadata, CurrencyId}, -}; +use cfg_types::domain_address::Domain; use frame_support::{assert_ok, dispatch::RawOrigin}; use liquidity_pools_gateway_routers::{ - AxelarEVMRouter, AxelarXCMRouter, DomainRouter, EVMDomain, EVMRouter, EthereumXCMRouter, - FeeValues, XCMRouter, XcmDomain, + AxelarEVMRouter, DomainRouter, EVMDomain, EVMRouter, FeeValues, }; use pallet_liquidity_pools::Message; use pallet_liquidity_pools_gateway::message::GatewayMessage; use polkadot_core_primitives::BlakeTwo256; use runtime_common::gateway::get_gateway_h160_account; use sp_core::{Get, H160, U256}; -use sp_runtime::{traits::Hash, BoundedVec}; -use staging_xcm::v4::{Junction::*, Location}; +use sp_runtime::traits::Hash; use crate::{ config::Runtime, env::Env, - envs::{ - fudge_env::{handle::SIBLING_ID, FudgeEnv, FudgeSupport}, - runtime_env::RuntimeEnv, - }, - utils::{ - self, - accounts::Keyring, - currency::{cfg, CurrencyInfo, CustomCurrency}, - genesis, - genesis::Genesis, - xcm::{enable_para_to_sibling_communication, transferable_metadata}, - }, + envs::runtime_env::RuntimeEnv, + utils::{self, accounts::Keyring, currency::cfg, genesis, genesis::Genesis}, }; const INITIAL: Balance = 100; @@ -40,31 +25,6 @@ const TEST_DOMAIN: Domain = Domain::EVM(1); const AXELAR_CONTRACT_ADDRESS: H160 = H160::repeat_byte(1); const AXELAR_CONTRACT_CODE: &[u8] = &[0, 0, 0]; -lazy_static::lazy_static! { - static ref CURR: CustomCurrency = CustomCurrency( - CurrencyId::ForeignAsset(1), - AssetMetadata { - decimals: 18, - ..transferable_metadata(Some(SIBLING_ID)) - }, - ); -} - -fn xcm_router() -> XCMRouter { - XCMRouter { - xcm_domain: XcmDomain { - location: Box::new(Location::new(1, Parachain(SIBLING_ID)).into()), - ethereum_xcm_transact_call_index: BoundedVec::truncate_from(vec![38, 0]), - contract_address: H160::from_low_u64_be(11), - max_gas_limit: 700_000, - transact_required_weight_at_most: Default::default(), - overall_weight: Default::default(), - fee_currency: CURR.id(), - fee_amount: CURR.val(1), - }, - } -} - fn environment_for_evm() -> RuntimeEnv { let mut env = RuntimeEnv::::from_parachain_storage( Genesis::default() @@ -82,23 +42,6 @@ fn environment_for_evm() -> RuntimeEnv { env } -fn environment_for_xcm() -> FudgeEnv { - let mut env = FudgeEnv::::from_parachain_storage( - Genesis::default() - .add(genesis::balances::(cfg(1_000))) - .add(genesis::assets::([(CURR.id(), CURR.metadata())])) - .storage(), - ); - - enable_para_to_sibling_communication::(&mut env); - - env.parachain_state_mut(|| { - utils::give_tokens::(T::Sender::get(), CURR.id(), CURR.val(50)); - }); - - env -} - fn check_submission(mut env: impl Env, domain_router: DomainRouter) { env.parachain_state_mut(|| { assert_ok!( @@ -149,23 +92,3 @@ fn submit_by_axelar_evm() { check_submission(environment_for_evm::(), router); } - -#[test_runtimes(all)] -fn submit_by_ethereum_xcm() { - let router = DomainRouter::EthereumXCM(EthereumXCMRouter:: { - router: xcm_router(), - }); - - check_submission(environment_for_xcm::(), router); -} - -#[test_runtimes(all)] -fn submit_by_axelar_xcm() { - let router = DomainRouter::AxelarXCM(AxelarXCMRouter:: { - router: xcm_router(), - axelar_target_chain: Vec::from(b"ethereum").try_into().unwrap(), - axelar_target_contract: AXELAR_CONTRACT_ADDRESS, - }); - - check_submission(environment_for_xcm::(), router); -}