From aaa6bb67389737a8bbd3e6d485b2554065db8bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Enrique=20Mu=C3=B1oz=20Mart=C3=ADn?= Date: Fri, 28 Jun 2024 13:06:11 +0200 Subject: [PATCH] Refactor: Decoupling routers from gateway (#1891) * decoupling routers from gateway. Use Vec * gateway adapted * fix imports * move test msg to cfg-traits * fix imports --- Cargo.lock | 1 - libs/mocks/src/lib.rs | 2 +- libs/mocks/src/liquidity_pools.rs | 39 +------- .../src/liquidity_pools_gateway_routers.rs | 17 +--- libs/traits/src/liquidity_pools.rs | 28 +++++- .../routers/Cargo.toml | 4 - .../routers/src/lib.rs | 49 ++++------ .../routers/src/mock.rs | 41 +------- .../routers/src/routers/axelar_evm.rs | 24 ++--- .../routers/src/routers/axelar_xcm.rs | 27 ++---- .../routers/src/routers/ethereum_xcm.rs | 27 ++---- .../routers/src/routers/mod.rs | 18 ---- .../routers/src/tests.rs | 24 ++--- pallets/liquidity-pools-gateway/src/lib.rs | 4 +- pallets/liquidity-pools-gateway/src/mock.rs | 35 ++----- pallets/liquidity-pools-gateway/src/tests.rs | 93 ++++++------------- runtime/common/src/xcm.rs | 7 +- 17 files changed, 132 insertions(+), 308 deletions(-) delete mode 100644 pallets/liquidity-pools-gateway/routers/src/routers/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 7abc1104d7..b7346dfc0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6307,7 +6307,6 @@ dependencies = [ "pallet-evm", "pallet-evm-chain-id", "pallet-evm-precompile-simple", - "pallet-liquidity-pools-gateway", "pallet-timestamp", "pallet-xcm-transactor", "parity-scale-codec", diff --git a/libs/mocks/src/lib.rs b/libs/mocks/src/lib.rs index de52496021..34694093cc 100644 --- a/libs/mocks/src/lib.rs +++ b/libs/mocks/src/lib.rs @@ -25,7 +25,7 @@ pub use currency_conversion::pallet as pallet_mock_currency_conversion; pub use data::pallet as pallet_mock_data; pub use fees::pallet as pallet_mock_fees; pub use investment::pallet as pallet_mock_investment; -pub use liquidity_pools::{pallet as pallet_mock_liquidity_pools, MessageMock}; +pub use liquidity_pools::pallet as pallet_mock_liquidity_pools; pub use liquidity_pools_gateway_routers::{pallet as pallet_mock_routers, RouterMock}; pub use pay_fee::pallet as pallet_mock_pay_fee; pub use permissions::pallet as pallet_mock_permissions; diff --git a/libs/mocks/src/liquidity_pools.rs b/libs/mocks/src/liquidity_pools.rs index 0b94debc7a..59db34dd59 100644 --- a/libs/mocks/src/liquidity_pools.rs +++ b/libs/mocks/src/liquidity_pools.rs @@ -1,46 +1,9 @@ -use cfg_traits::liquidity_pools::Codec; -use parity_scale_codec::{Decode, Encode, Error, Input, MaxEncodedLen}; -use scale_info::TypeInfo; - -#[derive(Debug, Eq, PartialEq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub enum MessageMock { - First, - Second, -} - -impl MessageMock { - fn call_type(&self) -> u8 { - match self { - MessageMock::First => 0, - MessageMock::Second => 1, - } - } -} - -impl Codec for MessageMock { - fn serialize(&self) -> Vec { - vec![self.call_type()] - } - - fn deserialize(input: &mut I) -> Result { - let call_type = input.read_byte()?; - - match call_type { - 0 => Ok(MessageMock::First), - 1 => Ok(MessageMock::Second), - _ => Err("unsupported message".into()), - } - } -} - #[frame_support::pallet(dev_mode)] pub mod pallet { use cfg_traits::liquidity_pools::InboundQueue; use frame_support::pallet_prelude::*; use mock_builder::{execute_call, register_call}; - use crate::liquidity_pools::MessageMock; - #[pallet::config] pub trait Config: frame_system::Config { type DomainAddress; @@ -54,7 +17,7 @@ pub mod pallet { type CallIds = StorageMap<_, _, String, mock_builder::CallId>; impl Pallet { - pub fn mock_submit(f: impl Fn(T::DomainAddress, MessageMock) -> DispatchResult + 'static) { + pub fn mock_submit(f: impl Fn(T::DomainAddress, T::Message) -> DispatchResult + 'static) { register_call!(move |(sender, msg)| f(sender, msg)); } } diff --git a/libs/mocks/src/liquidity_pools_gateway_routers.rs b/libs/mocks/src/liquidity_pools_gateway_routers.rs index af00e0adc3..22bfdf1bb0 100644 --- a/libs/mocks/src/liquidity_pools_gateway_routers.rs +++ b/libs/mocks/src/liquidity_pools_gateway_routers.rs @@ -3,8 +3,6 @@ use frame_support::{dispatch::DispatchResult, pallet_prelude::*}; use mock_builder::{execute_call, register_call}; use sp_std::default::Default; -use crate::MessageMock; - #[frame_support::pallet(dev_mode)] pub mod pallet { use super::*; @@ -24,21 +22,20 @@ pub mod pallet { } pub fn mock_send( - f: impl Fn(T::AccountId, MessageMock) -> DispatchResultWithPostInfo + 'static, + f: impl Fn(T::AccountId, Vec) -> DispatchResultWithPostInfo + 'static, ) { register_call!(move |(sender, message)| f(sender, message)); } } impl MockedRouter for Pallet { - type Message = MessageMock; type Sender = T::AccountId; fn init() -> DispatchResult { execute_call!(()) } - fn send(sender: Self::Sender, message: MessageMock) -> DispatchResultWithPostInfo { + fn send(sender: Self::Sender, message: Vec) -> DispatchResultWithPostInfo { execute_call!((sender, message)) } } @@ -67,7 +64,7 @@ impl RouterMock { pub fn mock_send( &self, - f: impl Fn(T::AccountId, MessageMock) -> DispatchResultWithPostInfo + 'static, + f: impl Fn(T::AccountId, Vec) -> DispatchResultWithPostInfo + 'static, ) { pallet::Pallet::::mock_send(f) } @@ -76,14 +73,13 @@ impl RouterMock { /// Here we implement the actual Router trait for the `RouterMock` which in turn /// calls the `MockedRouter` trait implementation. impl Router for RouterMock { - type Message = MessageMock; type Sender = T::AccountId; fn init(&self) -> DispatchResult { pallet::Pallet::::init() } - fn send(&self, sender: Self::Sender, message: Self::Message) -> DispatchResultWithPostInfo { + fn send(&self, sender: Self::Sender, message: Vec) -> DispatchResultWithPostInfo { pallet::Pallet::::send(sender, message) } } @@ -98,12 +94,9 @@ trait MockedRouter { /// The sender type of the outbound message. type Sender; - /// The outbound message type. - type Message; - /// Initialize the router. fn init() -> DispatchResult; /// Send the message to the router's destination. - fn send(sender: Self::Sender, message: Self::Message) -> DispatchResultWithPostInfo; + fn send(sender: Self::Sender, message: Vec) -> DispatchResultWithPostInfo; } diff --git a/libs/traits/src/liquidity_pools.rs b/libs/traits/src/liquidity_pools.rs index d4aa0ae880..0397cbef0a 100644 --- a/libs/traits/src/liquidity_pools.rs +++ b/libs/traits/src/liquidity_pools.rs @@ -22,19 +22,39 @@ pub trait Codec: Sized { fn deserialize(input: &mut I) -> Result; } +#[cfg(any(test, feature = "std"))] +pub mod test_util { + use parity_scale_codec::{Decode, Encode, Input, MaxEncodedLen}; + use scale_info::TypeInfo; + + use super::Codec; + + #[derive(Debug, Eq, PartialEq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub struct Message; + impl Codec for Message { + fn serialize(&self) -> Vec { + vec![0x42] + } + + fn deserialize(input: &mut I) -> Result { + match input.read_byte()? { + 0x42 => Ok(Self), + _ => Err("unsupported message".into()), + } + } + } +} + /// The trait required for sending outbound messages. pub trait Router { /// The sender type of the outbound message. type Sender; - /// The outbound message type. - type Message; - /// Initialize the router. fn init(&self) -> DispatchResult; /// Send the message to the router's destination. - fn send(&self, sender: Self::Sender, message: Self::Message) -> DispatchResultWithPostInfo; + fn send(&self, sender: Self::Sender, message: Vec) -> DispatchResultWithPostInfo; } /// The trait required for processing outbound messages. diff --git a/pallets/liquidity-pools-gateway/routers/Cargo.toml b/pallets/liquidity-pools-gateway/routers/Cargo.toml index 7e5ba91264..3fde07c088 100644 --- a/pallets/liquidity-pools-gateway/routers/Cargo.toml +++ b/pallets/liquidity-pools-gateway/routers/Cargo.toml @@ -37,7 +37,6 @@ cfg-traits = { workspace = true } # Local pallets pallet-ethereum-transaction = { workspace = true } -pallet-liquidity-pools-gateway = { workspace = true } [dev-dependencies] cfg-types = { workspace = true, default-features = true } @@ -73,7 +72,6 @@ std = [ "sp-std/std", "sp-core/std", "staging-xcm/std", - "pallet-liquidity-pools-gateway/std", "pallet-xcm-transactor/std", "pallet-ethereum/std", "pallet-ethereum-transaction/std", @@ -90,7 +88,6 @@ runtime-benchmarks = [ "cfg-primitives/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", - "pallet-liquidity-pools-gateway/runtime-benchmarks", "pallet-ethereum/runtime-benchmarks", "pallet-ethereum-transaction/runtime-benchmarks", "pallet-xcm-transactor/runtime-benchmarks", @@ -107,7 +104,6 @@ try-runtime = [ "cfg-primitives/try-runtime", "cfg-types/try-runtime", "cfg-mocks/try-runtime", - "pallet-liquidity-pools-gateway/try-runtime", "pallet-ethereum/try-runtime", "pallet-ethereum-transaction/try-runtime", "pallet-xcm-transactor/try-runtime", diff --git a/pallets/liquidity-pools-gateway/routers/src/lib.rs b/pallets/liquidity-pools-gateway/routers/src/lib.rs index a2e9f4184c..7f004c3442 100644 --- a/pallets/liquidity-pools-gateway/routers/src/lib.rs +++ b/pallets/liquidity-pools-gateway/routers/src/lib.rs @@ -61,13 +61,15 @@ mod mock; #[cfg(test)] mod tests; -pub mod routers; - -pub use routers::*; +pub mod routers { + pub mod axelar_evm; + pub mod axelar_xcm; + pub mod ethereum_xcm; +} -type CurrencyIdOf = ::CurrencyId; -type MessageOf = ::Message; -type AccountIdOf = ::AccountId; +pub use routers::{ + axelar_evm::AxelarEVMRouter, axelar_xcm::AxelarXCMRouter, ethereum_xcm::EthereumXCMRouter, +}; /// Maximum size allowed for a byte representation of an Axelar EVM chain /// string, as found below: @@ -87,11 +89,7 @@ const AXELAR_PAYLOAD_PARAM: &str = "payload"; #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] pub enum DomainRouter where - T: frame_system::Config - + pallet_xcm_transactor::Config - + pallet_liquidity_pools_gateway::Config - + pallet_ethereum_transaction::Config - + pallet_evm::Config, + T: pallet_xcm_transactor::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, T::AccountId: AsRef<[u8; 32]>, OriginFor: From + Into>>, @@ -103,17 +101,12 @@ where impl Router for DomainRouter where - T: frame_system::Config - + pallet_xcm_transactor::Config - + pallet_liquidity_pools_gateway::Config - + pallet_ethereum_transaction::Config - + pallet_evm::Config, + T: pallet_xcm_transactor::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, T::AccountId: AsRef<[u8; 32]>, OriginFor: From + Into>>, { - type Message = MessageOf; - type Sender = AccountIdOf; + type Sender = T::AccountId; fn init(&self) -> DispatchResult { match self { @@ -123,7 +116,7 @@ where } } - fn send(&self, sender: Self::Sender, message: Self::Message) -> DispatchResultWithPostInfo { + 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), @@ -136,7 +129,7 @@ where #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] pub struct EVMRouter where - T: frame_system::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, OriginFor: From + Into>>, { @@ -146,7 +139,7 @@ where impl EVMRouter where - T: frame_system::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, OriginFor: From + Into>>, { @@ -160,7 +153,7 @@ where impl EVMRouter where - T: frame_system::Config + pallet_ethereum_transaction::Config + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, T::AccountId: AsRef<[u8; 32]>, OriginFor: From + Into>>, @@ -229,17 +222,11 @@ pub struct FeeValues { /// A generic router used for executing XCM calls. #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] -pub struct XCMRouter -where - T: frame_system::Config + pallet_xcm_transactor::Config, -{ +pub struct XCMRouter { pub xcm_domain: XcmDomain, } -impl XCMRouter -where - T: frame_system::Config + pallet_xcm_transactor::Config, -{ +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 { @@ -286,7 +273,7 @@ pub(crate) fn get_encoded_ethereum_xcm_call( msg: Vec, ) -> Result, ()> where - T: frame_system::Config + pallet_xcm_transactor::Config, + T: pallet_xcm_transactor::Config, { let input = BoundedVec::>::try_from(msg) diff --git a/pallets/liquidity-pools-gateway/routers/src/mock.rs b/pallets/liquidity-pools-gateway/routers/src/mock.rs index 7671f21263..c48a5563c9 100644 --- a/pallets/liquidity-pools-gateway/routers/src/mock.rs +++ b/pallets/liquidity-pools-gateway/routers/src/mock.rs @@ -1,8 +1,7 @@ use std::str::FromStr; -use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, MessageMock, RouterMock}; -use cfg_primitives::{OutboundMessageNonce, BLOCK_STORAGE_LIMIT, MAX_POV_SIZE}; -use cfg_traits::TryConvert; +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::{ @@ -17,10 +16,9 @@ use pallet_evm::{ FixedGasWeightMapping, IsPrecompileResult, Precompile, PrecompileHandle, PrecompileResult, PrecompileSet, SubstrateBlockHashMapping, }; -use pallet_liquidity_pools_gateway::EnsureLocal; use parity_scale_codec::{Decode, Encode}; -use sp_core::{crypto::AccountId32, ByteArray, ConstU32, H160, H256, U256}; -use sp_runtime::{traits::IdentityLookup, ConsensusEngineId, DispatchError}; +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, @@ -41,7 +39,6 @@ frame_support::construct_runtime!( System: frame_system, Balances: pallet_balances, MockLiquidityPools: pallet_mock_liquidity_pools, - LiquidityPoolsGateway: pallet_liquidity_pools_gateway, XcmTransactor: pallet_xcm_transactor, EVM: pallet_evm, Timestamp: pallet_timestamp, @@ -79,41 +76,13 @@ impl pallet_balances::Config for Runtime { impl pallet_mock_liquidity_pools::Config for Runtime { type DomainAddress = DomainAddress; - type Message = MessageMock; + type Message = (); } impl pallet_ethereum_transaction::Config for Runtime {} impl pallet_mock_routers::Config for Runtime {} -pub struct MockOriginRecovery; -impl TryConvert<(Vec, Vec), DomainAddress> for MockOriginRecovery { - type Error = DispatchError; - - fn try_convert(_: (Vec, Vec)) -> Result { - Err(DispatchError::Other("Unimplemented")) - } -} - -parameter_types! { - pub Sender: AccountId32 = AccountId32::from(H256::from_low_u64_be(1).to_fixed_bytes()); -} - -impl pallet_liquidity_pools_gateway::Config for Runtime { - type AdminOrigin = EnsureRoot; - type InboundQueue = MockLiquidityPools; - type LocalEVMOrigin = EnsureLocal; - type MaxIncomingMessageSize = MaxIncomingMessageSize; - type Message = MessageMock; - type OriginRecovery = MockOriginRecovery; - type OutboundMessageNonce = OutboundMessageNonce; - type Router = RouterMock; - type RuntimeEvent = RuntimeEvent; - type RuntimeOrigin = RuntimeOrigin; - type Sender = Sender; - type WeightInfo = (); -} - parameter_types! { pub const MinimumPeriod: u64 = 1000; } diff --git a/pallets/liquidity-pools-gateway/routers/src/routers/axelar_evm.rs b/pallets/liquidity-pools-gateway/routers/src/routers/axelar_evm.rs index 7aea971fc8..670bb8b4dd 100644 --- a/pallets/liquidity-pools-gateway/routers/src/routers/axelar_evm.rs +++ b/pallets/liquidity-pools-gateway/routers/src/routers/axelar_evm.rs @@ -9,7 +9,7 @@ // 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 cfg_traits::liquidity_pools::Codec; + use ethabi::{Contract, Function, Param, ParamType, Token}; use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, @@ -25,19 +25,15 @@ use sp_core::{bounded::BoundedVec, ConstU32, H160}; use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; use crate::{ - AccountIdOf, EVMRouter, MessageOf, AXELAR_DESTINATION_CHAIN_PARAM, - AXELAR_DESTINATION_CONTRACT_ADDRESS_PARAM, AXELAR_FUNCTION_NAME, AXELAR_PAYLOAD_PARAM, - MAX_AXELAR_EVM_CHAIN_SIZE, + EVMRouter, AXELAR_DESTINATION_CHAIN_PARAM, AXELAR_DESTINATION_CONTRACT_ADDRESS_PARAM, + AXELAR_FUNCTION_NAME, AXELAR_PAYLOAD_PARAM, MAX_AXELAR_EVM_CHAIN_SIZE, }; /// The router used for executing the LiquidityPools contract via Axelar. #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)] pub struct AxelarEVMRouter where - T: frame_system::Config - + pallet_liquidity_pools_gateway::Config - + pallet_ethereum_transaction::Config - + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, OriginFor: From + Into>>, { @@ -48,10 +44,7 @@ where impl AxelarEVMRouter where - T: frame_system::Config - + pallet_liquidity_pools_gateway::Config - + pallet_ethereum_transaction::Config - + pallet_evm::Config, + T: pallet_ethereum_transaction::Config + pallet_evm::Config, T::AccountId: AsRef<[u8; 32]>, OriginFor: From + Into>>, @@ -73,11 +66,10 @@ where self.router.do_init() } - /// Encodes the message to the required format, - /// then executes the EVM call using the generic EVM router. - pub fn do_send(&self, sender: AccountIdOf, msg: MessageOf) -> DispatchResultWithPostInfo { + /// Executes the EVM call using the generic EVM router. + pub fn do_send(&self, sender: T::AccountId, msg: Vec) -> DispatchResultWithPostInfo { let eth_msg = get_axelar_encoded_msg( - msg.serialize(), + msg, self.evm_chain.clone().into_inner(), self.liquidity_pools_contract_address, ) diff --git a/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs b/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs index fa245b0036..4ec4003212 100644 --- a/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs +++ b/pallets/liquidity-pools-gateway/routers/src/routers/axelar_xcm.rs @@ -10,40 +10,25 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -use cfg_traits::liquidity_pools::Codec; 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::{ - axelar_evm::get_axelar_encoded_msg, AccountIdOf, CurrencyIdOf, MessageOf, XCMRouter, XcmDomain, - MAX_AXELAR_EVM_CHAIN_SIZE, -}; - -pub type AxelarXcmDomain = XcmDomain>; +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 -where - T: frame_system::Config - + pallet_xcm_transactor::Config - + pallet_liquidity_pools_gateway::Config, -{ +pub struct AxelarXCMRouter { pub router: XCMRouter, pub axelar_target_chain: BoundedVec>, pub axelar_target_contract: H160, } -impl AxelarXCMRouter -where - T: frame_system::Config - + pallet_xcm_transactor::Config - + pallet_liquidity_pools_gateway::Config, -{ +impl AxelarXCMRouter { /// Calls the init function on the EVM router. pub fn do_init(&self) -> DispatchResult { self.router.do_init() @@ -51,9 +36,9 @@ where /// Encodes the message to the required format, /// then executes the EVM call using the generic XCM router. - pub fn do_send(&self, sender: AccountIdOf, msg: MessageOf) -> DispatchResultWithPostInfo { + pub fn do_send(&self, sender: T::AccountId, msg: Vec) -> DispatchResultWithPostInfo { let contract_call = get_axelar_encoded_msg( - msg.serialize(), + msg, self.axelar_target_chain.clone().into_inner(), self.axelar_target_contract, ) diff --git a/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs b/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs index 26aa2c7afc..571cd5cfc0 100644 --- a/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs +++ b/pallets/liquidity-pools-gateway/routers/src/routers/ethereum_xcm.rs @@ -9,7 +9,7 @@ // 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 cfg_traits::liquidity_pools::Codec; + use ethabi::{Bytes, Contract}; use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, @@ -19,34 +19,23 @@ use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec}; -use crate::{AccountIdOf, MessageOf, XCMRouter, FUNCTION_NAME, MESSAGE_PARAM}; +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 -where - T: frame_system::Config - + pallet_xcm_transactor::Config - + pallet_liquidity_pools_gateway::Config, -{ +pub struct EthereumXCMRouter { pub router: XCMRouter, } -impl EthereumXCMRouter -where - T: frame_system::Config - + pallet_xcm_transactor::Config - + pallet_liquidity_pools_gateway::Config, -{ +impl EthereumXCMRouter { /// 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 and executes the - /// call via the XCM router. - pub fn do_send(&self, sender: AccountIdOf, msg: MessageOf) -> DispatchResultWithPostInfo { - let contract_call = get_encoded_contract_call(msg.serialize()) + /// 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) @@ -70,7 +59,7 @@ pub(crate) fn get_encoded_contract_call(encoded_msg: Vec) -> Result Contract { +fn get_xcm_router_contract() -> Contract { let mut functions = BTreeMap::new(); #[allow(deprecated)] functions.insert( diff --git a/pallets/liquidity-pools-gateway/routers/src/routers/mod.rs b/pallets/liquidity-pools-gateway/routers/src/routers/mod.rs deleted file mode 100644 index 2f932293c9..0000000000 --- a/pallets/liquidity-pools-gateway/routers/src/routers/mod.rs +++ /dev/null @@ -1,18 +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. -pub mod axelar_evm; -pub mod axelar_xcm; -pub mod ethereum_xcm; - -pub use axelar_evm::*; -pub use axelar_xcm::*; -pub use ethereum_xcm::*; diff --git a/pallets/liquidity-pools-gateway/routers/src/tests.rs b/pallets/liquidity-pools-gateway/routers/src/tests.rs index 88dfdd17dd..7db8b6569d 100644 --- a/pallets/liquidity-pools-gateway/routers/src/tests.rs +++ b/pallets/liquidity-pools-gateway/routers/src/tests.rs @@ -1,6 +1,5 @@ -use cfg_mocks::MessageMock; use cfg_primitives::CFG; -use cfg_traits::liquidity_pools::{Codec, Router}; +use cfg_traits::liquidity_pools::Router; use frame_support::{assert_noop, assert_ok, traits::fungible::Mutate}; use lazy_static::lazy_static; use pallet_evm::AddressMapping; @@ -14,7 +13,10 @@ use staging_xcm::latest::{ }; use super::mock::*; -use crate::*; +use crate::{ + routers::{axelar_evm::get_axelar_encoded_msg, ethereum_xcm::get_encoded_contract_call}, + *, +}; lazy_static! { static ref TEST_EVM_CHAIN: BoundedVec> = @@ -318,7 +320,7 @@ mod axelar_evm { pub sender: AccountId32, pub sender_h160: H160, pub derived_sender: AccountId32, - pub msg: MessageMock, + pub msg: Vec, } pub fn get_test_data() -> AxelarEVMTestData { @@ -342,7 +344,7 @@ mod axelar_evm { H160::from_slice(&>::as_ref(&sender)[0..20]); let derived_sender = IdentityAddressMapping::into_account_id(sender_h160); - let msg = MessageMock::Second; + let msg = vec![0x42]; AxelarEVMTestData { axelar_contract_address, @@ -496,7 +498,7 @@ mod axelar_xcm { pub axelar_target_chain: BoundedVec>, pub axelar_target_contract: H160, pub sender: AccountId32, - pub msg: MessageMock, + pub msg: Vec, } pub fn get_test_data() -> AxelarXCMTestData { @@ -518,7 +520,7 @@ mod axelar_xcm { let sender: AccountId32 = [0; 32].into(); - let msg = MessageMock::First; + let msg = vec![0x42]; AxelarXCMTestData { currency_id, @@ -599,7 +601,7 @@ mod axelar_xcm { })); let contract_call = get_axelar_encoded_msg( - test_data.msg.serialize(), + test_data.msg, test_data.axelar_target_chain.clone().into_inner(), test_data.axelar_target_contract, ) @@ -635,7 +637,7 @@ mod ethereum_xcm { pub axelar_target_chain: BoundedVec>, pub axelar_target_contract: H160, pub sender: AccountId32, - pub msg: MessageMock, + pub msg: Vec, } pub fn get_test_data() -> EthereumXCMTestData { @@ -657,7 +659,7 @@ mod ethereum_xcm { let sender: AccountId32 = [0; 32].into(); - let msg = MessageMock::First; + let msg = vec![0x42]; EthereumXCMTestData { currency_id, @@ -730,7 +732,7 @@ mod ethereum_xcm { weight_limit: WeightLimit::Limited(test_data.xcm_domain.overall_weight), })); - let contract_call = get_encoded_contract_call(test_data.msg.serialize()).unwrap(); + 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, diff --git a/pallets/liquidity-pools-gateway/src/lib.rs b/pallets/liquidity-pools-gateway/src/lib.rs index c0b0ad13af..3e670ee000 100644 --- a/pallets/liquidity-pools-gateway/src/lib.rs +++ b/pallets/liquidity-pools-gateway/src/lib.rs @@ -125,7 +125,7 @@ pub mod pallet { type Message: Codec + Clone + Debug + PartialEq + MaxEncodedLen + TypeInfo + FullCodec; /// The message router type that is stored for each domain. - type Router: DomainRouter + type Router: DomainRouter + Clone + Debug + MaxEncodedLen @@ -744,7 +744,7 @@ pub mod pallet { } }; - match router.send(sender, message) { + match router.send(sender, message.serialize()) { Ok(dispatch_info) => Ok(post_dispatch_info_fn( dispatch_info.actual_weight, read_weight, diff --git a/pallets/liquidity-pools-gateway/src/mock.rs b/pallets/liquidity-pools-gateway/src/mock.rs index 4f0f2c78de..2c91a2a072 100644 --- a/pallets/liquidity-pools-gateway/src/mock.rs +++ b/pallets/liquidity-pools-gateway/src/mock.rs @@ -1,15 +1,14 @@ -use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, MessageMock, RouterMock}; +use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, RouterMock}; use cfg_primitives::OutboundMessageNonce; +use cfg_traits::liquidity_pools::test_util::Message; use cfg_types::domain_address::DomainAddress; use frame_support::derive_impl; use frame_system::EnsureRoot; -use sp_core::{crypto::AccountId32, ConstU128, H256}; -use sp_runtime::{traits::IdentityLookup, BuildStorage}; +use sp_core::{crypto::AccountId32, H256}; +use sp_runtime::traits::IdentityLookup; use crate::{pallet as pallet_liquidity_pools_gateway, EnsureLocal}; -pub type Balance = u128; - 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; @@ -17,10 +16,11 @@ 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 ENCODED_MESSAGE_MOCK: &str = "42"; + frame_support::construct_runtime!( pub enum Runtime { System: frame_system, - Balances: pallet_balances, MockLiquidityPools: pallet_mock_liquidity_pools, MockRouters: pallet_mock_routers, MockOriginRecovery: cfg_mocks::converter::pallet, @@ -30,24 +30,14 @@ frame_support::construct_runtime!( #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] impl frame_system::Config for Runtime { - type AccountData = pallet_balances::AccountData; type AccountId = AccountId32; type Block = frame_system::mocking::MockBlock; type Lookup = IdentityLookup; } -#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] -impl pallet_balances::Config for Runtime { - type AccountStore = System; - type Balance = Balance; - type DustRemoval = (); - type ExistentialDeposit = ConstU128<1>; - type RuntimeHoldReason = (); -} - impl pallet_mock_liquidity_pools::Config for Runtime { type DomainAddress = DomainAddress; - type Message = MessageMock; + type Message = Message; } impl pallet_mock_routers::Config for Runtime {} @@ -67,7 +57,7 @@ impl pallet_liquidity_pools_gateway::Config for Runtime { type InboundQueue = MockLiquidityPools; type LocalEVMOrigin = EnsureLocal; type MaxIncomingMessageSize = MaxIncomingMessageSize; - type Message = MessageMock; + type Message = Message; type OriginRecovery = MockOriginRecovery; type OutboundMessageNonce = OutboundMessageNonce; type Router = RouterMock; @@ -78,12 +68,5 @@ impl pallet_liquidity_pools_gateway::Config for Runtime { } pub fn new_test_ext() -> sp_io::TestExternalities { - let storage = frame_system::GenesisConfig::::default() - .build_storage() - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(storage); - ext.execute_with(|| frame_system::Pallet::::set_block_number(1)); - - ext + System::externalities() } diff --git a/pallets/liquidity-pools-gateway/src/tests.rs b/pallets/liquidity-pools-gateway/src/tests.rs index 60185de92f..24a86879ef 100644 --- a/pallets/liquidity-pools-gateway/src/tests.rs +++ b/pallets/liquidity-pools-gateway/src/tests.rs @@ -1,6 +1,6 @@ use cfg_mocks::*; use cfg_primitives::OutboundMessageNonce; -use cfg_traits::liquidity_pools::{Codec, OutboundQueue}; +use cfg_traits::liquidity_pools::{test_util::Message, Codec, OutboundQueue}; use cfg_types::domain_address::*; use frame_support::{ assert_noop, assert_ok, @@ -385,7 +385,7 @@ mod process_msg_axelar_relay { )); - let expected_msg = MessageMock::First; + let expected_msg = Message; let expected_domain_address = domain_address.clone(); MockLiquidityPools::mock_submit(move |domain, message| { @@ -405,10 +405,8 @@ mod process_msg_axelar_relay { Ok(expected_domain_address.clone()) }); - // NOTE: A solidity generated payload. The most important part about this is the new decoding of the address. - // The message was cut out and replaced with a single byte of value 0 in order to decode correctly to this - // mocks message type. - let payload = hex::decode("0000000a657468657265756d2d320000002a30783835303362343435324266363233386343373643646245453232336234366437313936623163393300").unwrap(); + let solidity_header = "0000000a657468657265756d2d320000002a307838353033623434353242663632333863433736436462454532323362343664373139366231633933"; + let payload = hex::decode(format!("{solidity_header}{ENCODED_MESSAGE_MOCK}")).unwrap(); assert_ok!(LiquidityPoolsGateway::process_msg( GatewayOrigin::AxelarRelay(relayer_address).into(), @@ -434,7 +432,7 @@ mod process_msg_axelar_relay { relayer_address.clone(), )); - let expected_msg = MessageMock::First; + let expected_msg = Message; let expected_domain_address = domain_address.clone(); let mut msg = Vec::new(); @@ -480,7 +478,7 @@ mod process_msg_axelar_relay { relayer_address.clone(), )); - let expected_msg = MessageMock::First; + let expected_msg = Message; let mut msg = Vec::new(); @@ -522,7 +520,7 @@ mod process_msg_axelar_relay { relayer_address.clone(), )); - let expected_msg = MessageMock::First; + let expected_msg = Message; let mut msg = Vec::new(); msg.extend_from_slice(&(LENGTH_SOURCE_CHAIN as u32).to_be_bytes()); @@ -570,13 +568,6 @@ mod process_msg_axelar_relay { )); let encoded_msg: Vec = vec![11]; - 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(&encoded_msg); - let expected_domain_address = domain_address.clone(); MockOriginRecovery::mock_try_convert(move |origin| { @@ -615,39 +606,21 @@ mod process_msg_axelar_relay { relayer_address.clone(), )); - let expected_msg = MessageMock::First; - - 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_msg = Message; + let encoded_msg = 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()) - }); + MockOriginRecovery::mock_try_convert(move |_| Ok(expected_domain_address.clone())); let err = sp_runtime::DispatchError::from("liquidity_pools error"); - let expected_domain_address = domain_address.clone(); - MockLiquidityPools::mock_submit(move |domain, message| { - assert_eq!(domain, expected_domain_address.clone()); - assert_eq!(message, expected_msg); - Err(err) - }); + MockLiquidityPools::mock_submit(move |_, _| Err(err)); assert_noop!( LiquidityPoolsGateway::process_msg( GatewayOrigin::Domain(domain_address).into(), - BoundedVec::::try_from(msg).unwrap() + BoundedVec::::try_from(encoded_msg).unwrap() ), err, ); @@ -671,7 +644,7 @@ mod process_msg_domain { domain_address.clone(), )); - let expected_msg = MessageMock::First; + let expected_msg = Message; let encoded_msg = expected_msg.serialize(); let expected_domain_address = domain_address.clone(); @@ -692,7 +665,7 @@ mod process_msg_domain { #[test] fn bad_origin() { new_test_ext().execute_with(|| { - let encoded_msg = MessageMock::First.serialize(); + let encoded_msg = Message.serialize(); assert_noop!( LiquidityPoolsGateway::process_msg( @@ -708,7 +681,7 @@ mod process_msg_domain { fn invalid_message_origin() { new_test_ext().execute_with(|| { let domain_address = DomainAddress::Centrifuge(get_test_account_id().into()); - let encoded_msg = MessageMock::First.serialize(); + let encoded_msg = Message.serialize(); assert_noop!( LiquidityPoolsGateway::process_msg( @@ -725,7 +698,7 @@ mod process_msg_domain { 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()); - let encoded_msg = MessageMock::First.serialize(); + let encoded_msg = Message.serialize(); assert_noop!( LiquidityPoolsGateway::process_msg( @@ -771,7 +744,7 @@ mod process_msg_domain { domain_address.clone(), )); - let expected_msg = MessageMock::First; + let expected_msg = Message; let encoded_msg = expected_msg.serialize(); let expected_domain_address = domain_address.clone(); @@ -813,7 +786,7 @@ mod process_outbound_message { )); let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; router.mock_send({ let sender = sender.clone(); @@ -821,7 +794,7 @@ mod process_outbound_message { move |mock_sender, mock_msg| { assert_eq!(sender, mock_sender); - assert_eq!(msg, mock_msg); + assert_eq!(msg.serialize(), mock_msg); Ok(PostDispatchInfo { actual_weight: Some(Weight::from_parts(100, 100)), @@ -881,18 +854,13 @@ mod process_outbound_message { )); let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; let err = DispatchError::Unavailable; router.mock_send({ - let sender = sender.clone(); - let msg = msg.clone(); let err = err.clone(); - move |mock_sender, mock_msg| { - assert_eq!(sender, mock_sender); - assert_eq!(msg, mock_msg); - + move |_, _| { Err(DispatchErrorWithPostInfo { post_info: PostDispatchInfo { actual_weight: Some(Weight::from_parts(100, 100)), @@ -954,7 +922,7 @@ mod process_failed_outbound_message { )); let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; let err = DispatchError::Unavailable; router.mock_send({ @@ -963,7 +931,7 @@ mod process_failed_outbound_message { move |mock_sender, mock_msg| { assert_eq!(sender, mock_sender); - assert_eq!(msg, mock_msg); + assert_eq!(msg.serialize(), mock_msg); Ok(PostDispatchInfo { actual_weight: Some(Weight::from_parts(100, 100)), @@ -1023,18 +991,13 @@ mod process_failed_outbound_message { )); let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; let err = DispatchError::Unavailable; router.mock_send({ - let sender = sender.clone(); - let msg = msg.clone(); let err = err.clone(); - move |mock_sender, mock_msg| { - assert_eq!(sender, mock_sender); - assert_eq!(msg, mock_msg); - + move |_, _| { Err(DispatchErrorWithPostInfo { post_info: PostDispatchInfo { actual_weight: Some(Weight::from_parts(100, 100)), @@ -1078,7 +1041,7 @@ mod outbound_queue_impl { new_test_ext().execute_with(|| { let domain = Domain::EVM(0); let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; let router = RouterMock::::default(); router.mock_init(move || Ok(())); @@ -1116,7 +1079,7 @@ mod outbound_queue_impl { new_test_ext().execute_with(|| { let domain = Domain::Centrifuge; let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; assert_noop!( LiquidityPoolsGateway::submit(sender, domain, msg), @@ -1130,7 +1093,7 @@ mod outbound_queue_impl { new_test_ext().execute_with(|| { let domain = Domain::EVM(0); let sender = get_test_account_id(); - let msg = MessageMock::First; + let msg = Message; assert_noop!( LiquidityPoolsGateway::submit(sender, domain, msg), diff --git a/runtime/common/src/xcm.rs b/runtime/common/src/xcm.rs index aa82c339de..2bf09a676d 100644 --- a/runtime/common/src/xcm.rs +++ b/runtime/common/src/xcm.rs @@ -272,8 +272,9 @@ pub type LocationToAccountId = ( #[cfg(test)] mod test { - use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, MessageMock, RouterMock}; + use cfg_mocks::{pallet_mock_liquidity_pools, pallet_mock_routers, RouterMock}; use cfg_primitives::OutboundMessageNonce; + use cfg_traits::liquidity_pools::test_util::Message; use frame_support::{assert_ok, derive_impl, traits::EnsureOrigin}; use frame_system::EnsureRoot; use pallet_liquidity_pools_gateway::{EnsureLocal, GatewayOrigin}; @@ -313,7 +314,7 @@ mod test { impl pallet_mock_liquidity_pools::Config for Runtime { type DomainAddress = DomainAddress; - type Message = MessageMock; + type Message = Message; } impl pallet_mock_routers::Config for Runtime {} @@ -323,7 +324,7 @@ mod test { type InboundQueue = MockLP; type LocalEVMOrigin = pallet_liquidity_pools_gateway::EnsureLocal; type MaxIncomingMessageSize = ConstU32<1024>; - type Message = MessageMock; + type Message = Message; type OriginRecovery = MockOriginRecovery; type OutboundMessageNonce = OutboundMessageNonce; type Router = RouterMock;