Skip to content

Commit

Permalink
refactor: combine traits, cleanup, add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
wischli committed Aug 16, 2024
1 parent 893736a commit e5dedb2
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 71 deletions.
3 changes: 2 additions & 1 deletion libs/mocks/src/router_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ pub mod pallet {
}

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

fn send(a: Self::Middleware, b: Self::Origin, c: Vec<u8>) -> DispatchResult {
fn send(a: Self::Middleware, b: Self::Origin, c: Self::Message) -> DispatchResult {
execute_call!((a, b, c))
}
}
Expand Down
50 changes: 10 additions & 40 deletions libs/traits/src/liquidity_pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ pub type Proof = [u8; 32];
/// LiquidityPools General Message Passing Format
pub trait LpMessage: Sized {
type Domain;
type SerializableDomain;

fn serialize(&self) -> Vec<u8>;
fn deserialize(input: &[u8]) -> Result<Self, DispatchError>;
Expand All @@ -43,10 +42,10 @@ pub trait LpMessage: Sized {
/// Converts the message into a message proof type.
fn to_proof_message(&self) -> Self;

/// Unwraps a forwarded message
/// Unwraps a forwarded message.
fn unwrap_forwarded(self) -> Option<(Self::Domain, H160, Self)>;

/// Attempts to wrap into a forwarded message
/// Attempts to wrap into a forwarded message.
fn try_wrap_forward(
domain: Self::Domain,
forwarding_contract: H160,
Expand All @@ -70,9 +69,15 @@ pub trait MessageSender {
/// The originator of the message to be sent
type Origin;

/// The type of the message
type Message;

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

/// The behavior of an entity that can receive messages
Expand Down Expand Up @@ -142,38 +147,3 @@ pub trait InboundMessageHandler {
/// Handle an inbound message.
fn handle(sender: Self::Sender, msg: Self::Message) -> DispatchResult;
}

/// The behavior of an entity that can forward outbound messages
pub trait ForwardMessageSender {
/// The middleware by where this message is sent
type Middleware;

/// The originator of the message to be sent
type Origin;

/// The message that will be forwarded
type Message;

/// Forwards a message for origin to destination
fn forward(
middleware: Self::Middleware,
origin: Self::Origin,
message: Self::Message,
) -> DispatchResult;
}

/// The behavior of an entity that can forward received messages
pub trait ForwardMessageReceiver {
/// The middleware by where this message is received
type Middleware;

/// The originator of the received message
type Origin;

/// Forwards a received message from origin
fn forward(
middleware: Self::Middleware,
origin: Self::Origin,
message: Vec<u8>,
) -> DispatchResult;
}
7 changes: 6 additions & 1 deletion pallets/axelar-router/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,15 @@ pub mod pallet {
}

impl<T: Config> MessageSender for Pallet<T> {
type Message = Vec<u8>;
type Middleware = AxelarId;
type Origin = DomainAddress;

fn send(axelar_id: AxelarId, origin: Self::Origin, message: Vec<u8>) -> DispatchResult {
fn send(
axelar_id: AxelarId,
origin: Self::Origin,
message: Self::Message,
) -> DispatchResult {
let chain_name = ChainNameById::<T>::get(axelar_id)
.ok_or(Error::<T>::RouterConfigurationNotFound)?;
let config = Configuration::<T>::get(&chain_name)
Expand Down
76 changes: 50 additions & 26 deletions pallets/liquidity-pools-forwarder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@
// GNU General Public License for more details.
//
//! # Liquidity Pools Forwarder Pallet.
//!
//! The Forwarder pallet acts as middleware for incoming and outgoing Liquidity
//! Pools messages by wrapping them, if they are forwarded ones.
//!
//! For incoming messages, it extracts the payload from forwarded messages.
//!
//! For outgoing messages, it wraps the payload based on the configured router
//! info.
//!
//! Assumptions: The EVM side ensures that incoming forwarded messages are
//! valid.
#![cfg_attr(not(feature = "std"), no_std)]

// TODO: Docs
use cfg_traits::liquidity_pools::{
ForwardMessageReceiver, ForwardMessageSender, LpMessage as LpMessageT, MessageReceiver,
MessageSender, RouterProvider,
LpMessage as LpMessageT, MessageReceiver, MessageSender, RouterProvider,
};
use cfg_types::domain_address::{Domain, DomainAddress};
use frame_support::{dispatch::DispatchResult, pallet_prelude::*};
Expand Down Expand Up @@ -70,13 +80,17 @@ pub mod pallet {
+ TypeInfo
+ FullCodec;

/// The target of the messages coming from this chain
type Sender: MessageSender<Middleware = Self::RouterId, Origin = DomainAddress>;
/// The entity of the messages coming from this chain.
type Sender: MessageSender<
Middleware = Self::RouterId,
Origin = DomainAddress,
Message = Vec<u8>,
>;

/// The target of the messages coming from other chains
/// The entity which acts on unwrapped messages.
type Receiver: MessageReceiver<Middleware = Self::RouterId, Origin = Domain>;

/// An identification of a router
/// An identification of a router.
type RouterId: Parameter + MaxEncodedLen;

/// The type that provides the router available for a domain.
Expand All @@ -88,33 +102,41 @@ pub mod pallet {
#[pallet::event]
#[pallet::generate_deposit(pub (super) fn deposit_event)]
pub enum Event<T: Config> {
/// Forwarding info was set
ForwarderSet {
router_id: T::RouterId,
source_domain: Domain,
forwarding_contract: H160,
},
/// Forwarding info was removed
ForwarderRemoved {
router_id: T::RouterId,
source_domain: Domain,
forwarding_contract: H160,
},
}

/// Maps a router id to its forwarding info.
///
/// Can only be mutated via admin origin.
#[pallet::storage]
pub type Forwarding<T: Config> =
pub type RouterForwarding<T: Config> =
StorageMap<_, Blake2_128Concat, T::RouterId, ForwardInfo, OptionQuery>;

#[pallet::error]
pub enum Error<T> {
/// The router id does not have any forwarder info stored
ForwardInfoNotFound,
/// The forwarder origin of the message is invalid
InvalidForwarderOrigin,
}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
/// Set forwarding info for the given router id.
///
/// Origin: Admin.
///
/// NOTE: Simple weight due to origin requirement.
#[pallet::weight(T::DbWeight::get().writes(1))]
#[pallet::call_index(0)]
pub fn set_forwarder(
origin: OriginFor<T>,
Expand All @@ -124,7 +146,7 @@ pub mod pallet {
) -> DispatchResult {
T::AdminOrigin::ensure_origin(origin)?;

Forwarding::<T>::insert(
RouterForwarding::<T>::insert(
&router_id,
ForwardInfo {
source_domain: source_domain.clone(),
Expand All @@ -141,12 +163,17 @@ pub mod pallet {
Ok(())
}

#[pallet::weight(0)]
/// Remove the forwarding info for the given router id.
///
/// Origin: Admin.
///
/// NOTE: Simple weight due to origin requirement.
#[pallet::weight(T::DbWeight::get().writes(1))]
#[pallet::call_index(1)]
pub fn remove_forwarder(origin: OriginFor<T>, router_id: T::RouterId) -> DispatchResult {
T::AdminOrigin::ensure_origin(origin)?;

if let Some(info) = Forwarding::<T>::take(&router_id) {
if let Some(info) = RouterForwarding::<T>::take(&router_id) {
Self::deposit_event(Event::<T>::ForwarderRemoved {
router_id,
source_domain: info.source_domain,
Expand All @@ -158,17 +185,17 @@ pub mod pallet {
}
}

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

fn forward(
fn send(
router_id: T::RouterId,
origin: DomainAddress,
message: T::Message,
) -> DispatchResult {
let payload = if let Some(info) = Forwarding::<T>::get(&router_id) {
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()
Expand All @@ -180,27 +207,24 @@ pub mod pallet {
}
}

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

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

// If message can be unwrapped, it was forwarded
if let Some((source_domain, _, lp_message)) = message.unwrap_forwarded() {
let router_ids = T::RouterProvider::routers_for_domain(source_domain);
for router_id in router_ids {
if let Some(info) = Forwarding::<T>::get(&router_id) {
ensure!(
// TODO: Ensure this condition can be assumed, info.contract could be
// Forwarder != Adapter which could be domain_address.h160()
info.contract == domain_address.h160(),
Error::<T>::InvalidForwarderOrigin
);
// 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
if RouterForwarding::<T>::get(&router_id).is_some() {
return T::Receiver::receive(
router_id,
domain_address.domain(),
Expand Down
7 changes: 5 additions & 2 deletions pallets/liquidity-pools/src/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl BatchMessages {
}
}

/// A message type that can not be forwarded.
/// A message type that cannot be forwarded.
#[derive(Encode, Decode, Serialize, Deserialize, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]

Expand Down Expand Up @@ -565,6 +565,10 @@ pub enum Message<BatchContent = BatchMessages, ForwardContent = NonForwardMessag
/// The amount of tranche tokens which should be redeemed.
amount: u128,
},
/// A wrapped Message which was forwarded from the source domain via the
/// contract.
///
/// Directionality: Centrifuge <-> EVM Domain.
Forwarded {
source_domain: SerializableDomain,
forwarding_contract: H160,
Expand All @@ -574,7 +578,6 @@ pub enum Message<BatchContent = BatchMessages, ForwardContent = NonForwardMessag

impl LpMessage for Message {
type Domain = Domain;
type SerializableDomain = SerializableDomain;

fn serialize(&self) -> Vec<u8> {
gmpf::to_vec(self).unwrap_or_default()
Expand Down
3 changes: 2 additions & 1 deletion runtime/common/src/routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ impl<Routers> MessageSender for RouterDispatcher<Routers>
where
Routers: pallet_axelar_router::Config,
{
type Message = Vec<u8>;
type Middleware = RouterId;
type Origin = DomainAddress;

fn send(router_id: RouterId, origin: Self::Origin, message: Vec<u8>) -> DispatchResult {
fn send(router_id: RouterId, origin: Self::Origin, message: Self::Message) -> DispatchResult {
match router_id {
RouterId::Axelar(axelar_id) => {
pallet_axelar_router::Pallet::<Routers>::send(axelar_id, origin, message)
Expand Down

0 comments on commit e5dedb2

Please sign in to comment.