Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: LP V2 message forwarding #1971

Merged
merged 25 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
db9996e
refactor: LpMessage
wischli Aug 16, 2024
93512ea
feat: extend LpMessage with forwarding
wischli Aug 16, 2024
b4c4eda
wip: forwarding pallet
wischli Aug 16, 2024
bd6b064
Merge remote-tracking branch 'origin/main' into feat/lp-msg-relay
wischli Aug 16, 2024
893736a
chore: apply domainaddress refactor
wischli Aug 16, 2024
e5dedb2
refactor: combine traits, cleanup, add docs
wischli Aug 16, 2024
006c5a3
chore: compile runtimes
wischli Aug 16, 2024
042b08a
tests: add UTs
wischli Aug 17, 2024
67d5c3f
Merge remote-tracking branch 'origin/main' into feat/lp-msg-relay
wischli Aug 17, 2024
ce64041
fix: remove RouterProvider from Forwarder
wischli Aug 17, 2024
b39fa47
feat: move serialization to runtime type
wischli Aug 17, 2024
30eae5c
chore: apply suggestions from @cdamian's review
wischli Aug 17, 2024
5cf3752
fix: release build
wischli Aug 17, 2024
6a5cb5f
refactor: unite Receiver|SenderMessage types in mock
wischli Aug 18, 2024
4a0f751
refactor: remove trait namespaces in forwarder test
wischli Aug 18, 2024
cd72182
fix: re-add RouterProvider to forwarder pallet
wischli Aug 18, 2024
9f433f0
fix: use source domain
wischli Aug 18, 2024
be1fc23
fix: use source domain
wischli Aug 18, 2024
047ebac
feat: instantiate mock_router
wischli Aug 18, 2024
a253a6f
refactor: add MessageDeserializer to Gateway config
wischli Aug 18, 2024
ba726f0
Revert "refactor: add MessageDeserializer to Gateway config"
wischli Aug 18, 2024
cbb75b4
refactor: remove receive_message gateway extrinsic
wischli Aug 18, 2024
b24a5d4
refactor: remove artifacts
wischli Aug 18, 2024
3a15a49
taplo: fmt
wischli Aug 18, 2024
acc6f39
fix: ensure multi-router-setup validity
wischli Aug 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions libs/mocks/src/router_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ pub mod pallet {
pub trait Config: frame_system::Config {
type Middleware;
type Origin;
type Message;
type ReceiverMessage;
type SenderMessage;
}

#[pallet::pallet]
Expand All @@ -19,29 +20,30 @@ pub mod pallet {

impl<T: Config> Pallet<T> {
pub fn mock_receive(
f: impl Fn(T::Middleware, T::Origin, Vec<u8>) -> DispatchResult + 'static,
f: impl Fn(T::Middleware, T::Origin, T::ReceiverMessage) -> DispatchResult + 'static,
) {
register_call!(move |(a, b, c)| f(a, b, c));
}

pub fn mock_send(
f: impl Fn(T::Middleware, T::Origin, T::Message) -> DispatchResult + 'static,
f: impl Fn(T::Middleware, T::Origin, T::SenderMessage) -> DispatchResult + 'static,
) -> CallHandler {
register_call!(move |(a, b, c)| f(a, b, c))
}
}

impl<T: Config> MessageReceiver for Pallet<T> {
type Message = T::ReceiverMessage;
type Middleware = T::Middleware;
type Origin = T::Origin;

fn receive(a: Self::Middleware, b: Self::Origin, c: Vec<u8>) -> DispatchResult {
fn receive(a: Self::Middleware, b: Self::Origin, c: Self::Message) -> DispatchResult {
execute_call!((a, b, c))
}
}

impl<T: Config> MessageSender for Pallet<T> {
type Message = T::Message;
type Message = T::SenderMessage;
type Middleware = T::Middleware;
type Origin = T::Origin;

Expand Down
4 changes: 3 additions & 1 deletion libs/traits/src/liquidity_pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,13 @@ pub trait MessageReceiver {
/// The originator of the received message
type Origin;

type Message;

/// Sends a message for origin to destination
fn receive(
middleware: Self::Middleware,
origin: Self::Origin,
message: Vec<u8>,
message: Self::Message,
) -> DispatchResult;
}

Expand Down
6 changes: 5 additions & 1 deletion pallets/axelar-router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ pub mod pallet {
type AdminOrigin: EnsureOrigin<Self::RuntimeOrigin>;

/// The target of the messages coming from other chains
type Receiver: MessageReceiver<Middleware = Self::Middleware, Origin = DomainAddress>;
type Receiver: MessageReceiver<
Middleware = Self::Middleware,
Origin = DomainAddress,
Message = Vec<u8>,
>;

/// Middleware used by the gateway
type Middleware: From<AxelarId>;
Expand Down
3 changes: 2 additions & 1 deletion pallets/axelar-router/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ impl frame_system::Config for Runtime {
}

impl cfg_mocks::router_message::pallet::Config for Runtime {
type Message = Vec<u8>;
type Middleware = Middleware;
type Origin = DomainAddress;
type ReceiverMessage = Vec<u8>;
type SenderMessage = Vec<u8>;
wischli marked this conversation as resolved.
Show resolved Hide resolved
}

impl cfg_mocks::ethereum_transactor::pallet::Config for Runtime {}
Expand Down
52 changes: 28 additions & 24 deletions pallets/liquidity-pools-forwarder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use frame_system::pallet_prelude::OriginFor;
pub use pallet::*;
use parity_scale_codec::FullCodec;
use sp_core::H160;
use sp_std::{convert::TryInto, vec::Vec};
use sp_std::convert::TryInto;

#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct ForwardInfo {
Expand Down Expand Up @@ -88,11 +88,15 @@ pub mod pallet {
type MessageSender: MessageSender<
Middleware = Self::RouterId,
Origin = DomainAddress,
Message = Vec<u8>,
Message = Self::Message,
>;

/// The entity which acts on unwrapped messages.
type MessageReceiver: MessageReceiver<Middleware = Self::RouterId, Origin = DomainAddress>;
type MessageReceiver: MessageReceiver<
Middleware = Self::RouterId,
Origin = DomainAddress,
Message = Self::Message,
>;

/// An identification of a router.
type RouterId: Parameter + MaxEncodedLen;
Expand Down Expand Up @@ -196,45 +200,45 @@ pub mod pallet {
origin: DomainAddress,
message: T::Message,
) -> DispatchResult {
let payload = if let Some(info) = RouterForwarding::<T>::get(&router_id) {
let wrapped =
T::Message::try_wrap_forward(info.source_domain, info.contract, message)?;
wrapped.serialize()
} else {
ensure!(!message.is_forwarded(), Error::<T>::ForwardInfoNotFound);
message.serialize()
};

T::MessageSender::send(router_id, origin, payload)
let msg = RouterForwarding::<T>::get(&router_id)
.map(|info| {
T::Message::try_wrap_forward(info.source_domain, info.contract, message.clone())
})
.unwrap_or({
ensure!(!message.is_forwarded(), Error::<T>::ForwardInfoNotFound);
Ok(message)
})?;

T::MessageSender::send(router_id, origin, msg)
}
}

impl<T: Config> MessageReceiver for Pallet<T> {
type Message = T::Message;
type Middleware = T::RouterId;
type Origin = DomainAddress;

fn receive(
router_id: T::RouterId,
domain_address: DomainAddress,
payload: Vec<u8>,
message: T::Message,
) -> DispatchResult {
let message = T::Message::deserialize(&payload)?;

// Message can be unwrapped iff it was forwarded
//
// NOTE: We can rely on EVM side to ensure forwarded messages are valid such
// that it suffices to filter for the existence of forwarding info
match (
let lp_message = match (
RouterForwarding::<T>::get(&router_id).is_some(),
message.unwrap_forwarded(),
message.clone().unwrap_forwarded(),
) {
(true, Some((_domain, _contract, lp_message))) => {
T::MessageReceiver::receive(router_id, domain_address, lp_message.serialize())
}
(true, None) => Err(Error::<T>::UnwrappingFailed.into()),
(false, Some((_, _, _))) => Err(Error::<T>::ForwardInfoNotFound.into()),
(false, None) => T::MessageReceiver::receive(router_id, domain_address, payload),
(false, None) => Ok(message),
(true, Some((_domain, _contract, lp_message))) => Ok(lp_message),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question. Why the _domain is not used?

Could make sense the new domain_addres to be: DomainAddress::Evm(domain, contract) or similar?

Copy link
Contributor Author

@wischli wischli Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the origin of the LP message was not _domain (say Celo) but the domain_address.domain() (say Ethereum). The gateway checks in the allowlist, if it contains Ethereum's domain_address.domain() in the allowlist. I don't believe that Celo's _domain should be in the allowlist because there is no direct connection configured for Celo, for that purpose we have the forwarder pallet which acts as an allowlist gatekeeper for forwarded domains whereas the gateway acts as gatekeeper for direct connections.

Copy link
Contributor Author

@wischli wischli Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though now I remember why I initially went with the RouterProvider! We cannot guarantee that the router_id of the receive signature here is the same for which we have stored forwarding info. Therefore, we actually need to iterate over all possible router ids!

cc @cdamian

Copy link
Contributor

@lemunozm lemunozm Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm... Ok, here we have two points:

First, I think we need to read _domain or _contract somehow because if the other side forwarder implementation works like ours, it will never forward a message.

Second, if we need to use the forwarder domain, how do we get the correct router?

Crazy idea. Could it makes sense that our chain never receives a Forwarder message? I mean, we're the final endpoint, right? The forwarder wrapper should have been unwrapped before reaching centrifuge. So, as a final endpoint, we should never receive a wrapped message.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my above crazy idea is not as crazy, and it's related to this thread above with Jeroen about not using the contract.

TLDR: I think we should not receive forwarded messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forwarder X -> Ethereum -> Centrifuge - message that comes through router A (pallet-axelar-router)
Forwarder X -> Ethereum -> Centrifuge - proof that comes through router B (some other router pallet)

This is the counterexample to the current implementation of the forwarder pallet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point now. The current design wouldn't handle messages and their proofs correclty as everything is mapped to the same router id. So we are on the same page.

Revisiting our inbound setup and my comment about correct forwarding configuration: Router -> Serializer -> Forwarder -> Gateway, it appears to me that we can actually rely on the correct router_id from the receive signature called by the Router and re-remove the RouterProvider from the forwarder pallet.

E.g., when we store the forwarding info for a router id, we need to do that for every supported router. This way, the forwarder pallet has no impact on handling proof- vs non-proof messages and leaves this up to the Gateway based on the router_id which is passed all the way from the MessageReceiver impl of the corresponding router.

WDYT @cdamian @lemunozm

Completely agree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy pasting here the flows for a 2-router-setup you broke down to make this more explicit:

Flow of a non-forwarded message

1) Ethereum -> Centrifuge Router A -> LP Forwarder::receive(router A, domain address, message) -> noop -> LP Gateway::receive(router A, domain address, message)

2) Ethereum -> Centrifuge Router B -> LP Forwarder::receive(router A, domain address, message) - >noop -> LP Gateway::receive(router A, domain address, message)

Flow of a forwarded message

1) Celo(Ethereum) -> Centrifuge Router A -> LP Forwarder::receive(router A, domain address, message) -> unwrap message to (source_domain, contract, unwrapped_message) -> LP Gateway::receive(router A, (source domain, contract), unwrapped_message)

2) Celo(Ethereum) -> Centrifuge Router B -> LP Forwarder::receive(router B, domain address, message) -> unwrap message to (source_domain, contract, unwrapped_message) -> LP Gateway::receive(router B, (source domain, contract), unwrapped_message)

Copy link
Contributor Author

@wischli wischli Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we all have found consensus on this matter, here's the corresponding code: acc6f39

I really hope this was the last raid boss to slay and that we can merge this beast.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the second line of non-forwaded message is router B in all places right? @wischli

(true, None) => Err(Error::<T>::UnwrappingFailed),
(false, Some((_, _, _))) => Err(Error::<T>::ForwardInfoNotFound),
}
.map_err(|e: Error<T>| e)?;

T::MessageReceiver::receive(router_id, domain_address, lp_message)
}
}
}
13 changes: 7 additions & 6 deletions pallets/liquidity-pools-forwarder/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ use sp_runtime::{traits::IdentityLookup, DispatchError};

use crate::pallet as pallet_liquidity_pools_forwarder;

pub const SOURCE_CHAIN_ID: u64 = 1;
pub const FORWARDER_CHAIN_ID: u64 = 42;
const SOURCE_CHAIN_ID: u64 = 1;
const FORWARDER_CHAIN_ID: u64 = 42;
pub const SOURCE_DOMAIN: Domain = Domain::Evm(SOURCE_CHAIN_ID);
pub const FORWARDER_ADAPTER_ADDRESS: H160 = H160::repeat_byte(1);
const FORWARDER_ADAPTER_ADDRESS: H160 = H160::repeat_byte(1);
pub const FORWARDER_DOMAIN_ADDRESS: DomainAddress =
DomainAddress::Evm(FORWARDER_CHAIN_ID, FORWARDER_ADAPTER_ADDRESS);
pub const FORWARD_CONTRACT: H160 = H160::repeat_byte(2);

pub const ROUTER_ID: RouterId = RouterId(1);
pub const FORWARD_SERIALIZED_MESSAGE_BYTES: [u8; 1] = [0x42];
pub const NON_FORWARD_SERIALIZED_MESSAGE_BYTES: [u8; 1] = [0x43];
const FORWARD_SERIALIZED_MESSAGE_BYTES: [u8; 1] = [0x42];
const NON_FORWARD_SERIALIZED_MESSAGE_BYTES: [u8; 1] = [0x43];
pub const ERROR_NESTING: DispatchError = DispatchError::Other("Nesting forward msg not allowed");

#[derive(Eq, PartialEq, Debug, Clone, Encode, Decode, TypeInfo, MaxEncodedLen, Hash)]
Expand Down Expand Up @@ -120,9 +120,10 @@ impl frame_system::Config for Runtime {
}

impl cfg_mocks::router_message::pallet::Config for Runtime {
type Message = Vec<u8>;
type Middleware = RouterId;
type Origin = DomainAddress;
type ReceiverMessage = Message;
type SenderMessage = Message;
}

impl pallet_liquidity_pools_forwarder::Config for Runtime {
Expand Down
22 changes: 11 additions & 11 deletions pallets/liquidity-pools-forwarder/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,15 @@ mod remove_forwarder {
}

mod send_message {
use cfg_traits::liquidity_pools::{LpMessage, MessageSender};
use cfg_traits::liquidity_pools::MessageSender;

use super::*;

fn config_mocks(msg: Message, set_forwarding_info: bool) {
MockSenderReceiver::mock_send(move |router_id, sender, message| {
assert_eq!(router_id, ROUTER_ID);
assert_eq!(sender, FORWARDER_DOMAIN_ADDRESS);
assert_eq!(&message, &msg.serialize());
assert_eq!(message, msg);

Ok(())
});
Expand Down Expand Up @@ -265,15 +265,15 @@ mod send_message {
}

mod receive_message {
use cfg_traits::liquidity_pools::{LpMessage, MessageReceiver};
use cfg_traits::liquidity_pools::MessageReceiver;

use super::*;

fn config_mocks(set_forwarding_info: bool) {
MockSenderReceiver::mock_receive(move |middleware, origin, message| {
assert_eq!(middleware, ROUTER_ID);
assert_eq!(origin, FORWARDER_DOMAIN_ADDRESS);
assert_eq!(&message, &NON_FORWARD_SERIALIZED_MESSAGE_BYTES);
assert_eq!(message, Message::NonForward);
Ok(())
});

Expand All @@ -288,7 +288,7 @@ mod receive_message {
}

mod success {
use cfg_traits::liquidity_pools::{LpMessage, MessageReceiver};
use cfg_traits::liquidity_pools::MessageReceiver;

use super::*;

Expand All @@ -300,7 +300,7 @@ mod receive_message {
assert_ok!(<LiquidityPoolsForwarder as MessageReceiver>::receive(
wischli marked this conversation as resolved.
Show resolved Hide resolved
ROUTER_ID,
FORWARDER_DOMAIN_ADDRESS,
Message::Forward.serialize()
Message::Forward
));
});
}
Expand All @@ -313,7 +313,7 @@ mod receive_message {
assert_ok!(<LiquidityPoolsForwarder as MessageReceiver>::receive(
ROUTER_ID,
FORWARDER_DOMAIN_ADDRESS,
Message::NonForward.serialize()
Message::NonForward
));
});
}
Expand All @@ -336,7 +336,7 @@ mod receive_message {
<LiquidityPoolsForwarder as MessageReceiver>::receive(
ROUTER_ID,
FORWARDER_DOMAIN_ADDRESS,
Message::Forward.serialize()
Message::Forward
),
Error::<Runtime>::ForwardInfoNotFound
);
Expand All @@ -352,7 +352,7 @@ mod receive_message {
<LiquidityPoolsForwarder as MessageReceiver>::receive(
ROUTER_ID,
FORWARDER_DOMAIN_ADDRESS,
Message::NonForward.serialize()
Message::NonForward
),
Error::<Runtime>::UnwrappingFailed
);
Expand All @@ -369,7 +369,7 @@ mod receive_message {
<LiquidityPoolsForwarder as MessageReceiver>::receive(
ROUTER_ID,
FORWARDER_DOMAIN_ADDRESS,
Message::Forward.serialize()
Message::Forward
),
ERROR
);
Expand All @@ -384,7 +384,7 @@ mod receive_message {
<LiquidityPoolsForwarder as MessageReceiver>::receive(
ROUTER_ID,
FORWARDER_DOMAIN_ADDRESS,
Message::NonForward.serialize()
Message::NonForward
),
ERROR
);
Expand Down
9 changes: 5 additions & 4 deletions pallets/liquidity-pools-gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub use pallet::*;
use parity_scale_codec::FullCodec;
use sp_arithmetic::traits::{BaseArithmetic, EnsureAddAssign, One};
use sp_runtime::SaturatedConversion;
use sp_std::{convert::TryInto, vec::Vec};
use sp_std::convert::TryInto;

use crate::{
message_processing::{InboundEntry, ProofEntry},
Expand Down Expand Up @@ -416,7 +416,7 @@ pub mod pallet {
return Err(Error::<T>::InvalidMessageOrigin.into());
}

Self::receive(router_id, origin_address, msg.into())
Self::receive(router_id, origin_address, T::Message::deserialize(&msg)?)
Copy link
Contributor

@lemunozm lemunozm Aug 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to move this out from the gateway. If not, the caller of this extrinsic will skip the forwarding logic.

Still not sure where. Maybe on pallet-axelar-router or pallet-liquidity-pool-forwarder (and using Message instead of Vec<u8>).

Or maybe just removing it, because it's no longer used...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch! I propose to add a MessageDeserializer AT to the Gateway config which is implemented by our runtime type MessageSerializer. This will deserialize the message and pass it to the forwarder pallet which will pass it back to the MessageReiver impl of the Gateway.

So from now:

  • process extrinsic -> Gateway impl of MessageReceiver

To

  • process in Gateway -> receive in MessagSerializer which deserializes -> receive in forward pallet which unwraps any forwarded message -> receive in Gateway which does its thing

WDYT?

Copy link
Contributor Author

@wischli wischli Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that htis requires instantiating the router_message mock pallet, which I am working on right now.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mmm... I am not sure about that walk...

As more I think on it as more I think we can remove this. We no longer need this since Axelar uses the trait to send message to the gateway. If we want to emulate receiving message explicitly, this extrinsic should be in axelar-router

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interested in your take on this @cdamian

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @lemunozm - the flow that you are describing above would mean that the forwarder can be called by the gateway, in an inbound context, which shouldn't happen? Also, this extrinsic can maybe ensure that no forwarded message is submitted since we have it for special cases?

Copy link
Contributor Author

@wischli wischli Aug 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See here for code changes if we added the MessageDeserializer to the Gateway: a253a6f

However, I have reverted that change and applied @lemunozm's proposal of removing the receive_message extrinsic which apparently was only used by the Axelar precompile. I have refactored the existing Gateway UTs for checking the MessageReceiver implementation which was not tested: cbb75b4

}

/// Set the address of the domain hook
Expand Down Expand Up @@ -687,13 +687,14 @@ pub mod pallet {
}

impl<T: Config> MessageReceiver for Pallet<T> {
type Message = T::Message;
type Middleware = T::RouterId;
type Origin = DomainAddress;

fn receive(
router_id: T::RouterId,
origin_address: DomainAddress,
message: Vec<u8>,
message: T::Message,
) -> DispatchResult {
ensure!(
Allowlist::<T>::contains_key(origin_address.domain(), origin_address.clone()),
Expand All @@ -702,7 +703,7 @@ pub mod pallet {

let gateway_message = GatewayMessage::<T::Message, T::RouterId>::Inbound {
domain_address: origin_address,
message: T::Message::deserialize(&message)?,
message,
router_id,
};

Expand Down
3 changes: 2 additions & 1 deletion pallets/liquidity-pools-gateway/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,10 @@ impl pallet_mock_liquidity_pools_gateway_queue::Config for Runtime {
}

impl cfg_mocks::router_message::pallet::Config for Runtime {
type Message = Message;
type Middleware = RouterId;
type Origin = DomainAddress;
type ReceiverMessage = Message;
type SenderMessage = Message;
}

frame_support::parameter_types! {
Expand Down
9 changes: 6 additions & 3 deletions runtime/altair/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ use runtime_common::{
permissions::{IsUnfrozenTrancheInvestor, PoolAdminCheck},
remarks::Remark,
rewards::SingleCurrencyMovement,
routing::{EvmAccountCodeChecker, LPGatewayRouterProvider, RouterDispatcher, RouterId},
routing::{
EvmAccountCodeChecker, LPGatewayRouterProvider, MessageSerializer, RouterDispatcher,
RouterId,
},
transfer_filter::{PreLpTransfer, PreNativeTransfer},
xcm::AccountIdToLocation,
xcm_transactor, AllowanceDeposit, CurrencyED,
Expand Down Expand Up @@ -1758,7 +1761,7 @@ impl pallet_liquidity_pools_forwarder::Config for Runtime {
type AdminOrigin = EnsureRootOr<HalfOfCouncil>;
type Message = pallet_liquidity_pools::Message;
type MessageReceiver = LiquidityPoolsGateway;
type MessageSender = RouterDispatcher<Runtime>;
type MessageSender = MessageSerializer<RouterDispatcher<Runtime>, LiquidityPoolsForwarder>;
type RouterId = RouterId;
type RuntimeEvent = RuntimeEvent;
}
Expand Down Expand Up @@ -1902,7 +1905,7 @@ impl pallet_axelar_router::Config for Runtime {
type AdminOrigin = EnsureRoot<AccountId>;
type EvmAccountCodeChecker = EvmAccountCodeChecker<Runtime>;
type Middleware = RouterId;
type Receiver = LiquidityPoolsForwarder;
type Receiver = MessageSerializer<RouterDispatcher<Runtime>, LiquidityPoolsForwarder>;
type RuntimeEvent = RuntimeEvent;
type Transactor = EthereumTransaction;
}
Expand Down
Loading
Loading