Skip to content

Commit

Permalink
LP Message with custom data format for serialization/deserialization (#…
Browse files Browse the repository at this point in the history
…1889)

* test compiling

* fix Domain serialization

* fix issues

* some reorganizations

* using bincode 2 with non-std support

* use custom trait

* tests passing for lp

* remove ENCODED_MSG constant

* fix runtimes compilation

* cargo fmt & taplo fmt

* cargo clippy

* minor change

* add custom serializer passing all tests

* no_std support

* minor renames

* cargo fmt

* cargo clippy

* minor comment change

* cargo fmt extra
  • Loading branch information
lemunozm authored Jul 4, 2024
1 parent 2f08ae7 commit df75508
Show file tree
Hide file tree
Showing 28 changed files with 896 additions and 868 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ version = "0.12.0"
hex-literal = { version = "0.4.1" }
hex = { version = "0.4.3", default-features = false }
smallvec = "1.11.0"
serde = { version = "1.0.195", default-features = false, features = ["derive"] }
serde = { version = "1.0.195", default-features = false, features = ["alloc", "derive"] }
serde_json = { version = "1.0.111" }
serde-big-array = { version = "0.5" }
parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] }
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
log = { version = "0.4.20", default-features = false }
Expand Down
21 changes: 11 additions & 10 deletions libs/traits/src/liquidity_pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,35 @@
// GNU General Public License for more details.

use frame_support::dispatch::{DispatchResult, DispatchResultWithPostInfo};
use parity_scale_codec::Input;
use sp_runtime::DispatchError;
use sp_std::vec::Vec;

/// An encoding & decoding trait for the purpose of meeting the
/// LiquidityPools General Message Passing Format
pub trait Codec: Sized {
pub trait LPEncoding: Sized {
fn serialize(&self) -> Vec<u8>;
fn deserialize<I: Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error>;
fn deserialize(input: &[u8]) -> Result<Self, DispatchError>;
}

#[cfg(any(test, feature = "std"))]
pub mod test_util {
use parity_scale_codec::{Decode, Encode, Input, MaxEncodedLen};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;

use super::Codec;
use super::*;

#[derive(Debug, Eq, PartialEq, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct Message;
impl Codec for Message {
impl LPEncoding for Message {
fn serialize(&self) -> Vec<u8> {
vec![0x42]
}

fn deserialize<I: Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
match input.read_byte()? {
0x42 => Ok(Self),
_ => Err("unsupported message".into()),
fn deserialize(input: &[u8]) -> Result<Self, DispatchError> {
match input.first() {
Some(0x42) => Ok(Self),
Some(_) => Err("unsupported message".into()),
None => Err("empty message".into()),
}
}
}
Expand Down
36 changes: 2 additions & 34 deletions libs/types/src/domain_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,15 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

use cfg_traits::liquidity_pools::Codec;
use cfg_utils::{decode_be_bytes, vec_to_fixed_array};
use cfg_utils::vec_to_fixed_array;
use frame_support::pallet_prelude::RuntimeDebug;
use parity_scale_codec::{Decode, Encode, Input, MaxEncodedLen};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_runtime::traits::AccountIdConversion;
use sp_std::{vec, vec::Vec};

use crate::EVMChainId;

/// A Domain is a chain or network we can send a message to.
/// The domain indices need to match those used in the EVM contracts and these
/// need to pass the Centrifuge domain to send tranche tokens from the other
/// domain here. Therefore, DO NOT remove or move variants around.
#[derive(Encode, Decode, Clone, Eq, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)]
pub enum Domain {
/// Referring to the Centrifuge Parachain. Will be used for handling
Expand All @@ -36,33 +31,6 @@ pub enum Domain {
EVM(EVMChainId),
}

impl Codec for Domain {
fn serialize(&self) -> Vec<u8> {
match self {
Self::Centrifuge => vec![0; 9],
Self::EVM(chain_id) => {
let mut output: Vec<u8> = 1u8.encode();
output.append(&mut chain_id.to_be_bytes().to_vec());

output
}
}
}

fn deserialize<I: Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
let variant = input.read_byte()?;

match variant {
0 => Ok(Self::Centrifuge),
1 => {
let chain_id = decode_be_bytes::<8, _, _>(input)?;
Ok(Self::EVM(chain_id))
}
_ => Err(parity_scale_codec::Error::from("Unknown Domain variant")),
}
}
}

impl Domain {
pub fn into_account<AccountId: Encode + Decode>(&self) -> AccountId {
DomainLocator {
Expand Down
32 changes: 2 additions & 30 deletions libs/utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// Ensure we're `no_std` when compiling for WebAssembly.
#![cfg_attr(not(feature = "std"), no_std)]

use parity_scale_codec::{Decode, Encode, Error, Input};
use sp_std::{cmp::min, vec::Vec};
use parity_scale_codec::Encode;
use sp_std::cmp::min;

/// Build a fixed-size array using as many elements from `src` as possible
/// without overflowing and ensuring that the array is 0 padded in the case
Expand All @@ -27,34 +27,6 @@ pub fn vec_to_fixed_array<const S: usize>(src: impl AsRef<[u8]>) -> [u8; S] {
dest
}

/// Encode a value in its big-endian representation of which all we know is that
/// it implements Encode. We use this for number types to make sure they are
/// encoded the way they are expected to be decoded on the Solidity side.
pub fn encode_be(x: impl Encode) -> Vec<u8> {
let mut output = x.encode();
output.reverse();
output
}

/// Decode a type O by reading S bytes from I. Those bytes are expected to be
/// encoded as big-endian and thus needs reversing to little-endian before
/// decoding to O.
pub fn decode_be_bytes<const S: usize, O: Decode, I: Input>(input: &mut I) -> Result<O, Error> {
let mut bytes = [0; S];
input.read(&mut bytes[..])?;
bytes.reverse();

O::decode(&mut bytes.as_slice())
}

/// Decode a type 0 by reading S bytes from I.
pub fn decode<const S: usize, O: Decode, I: Input>(input: &mut I) -> Result<O, Error> {
let mut bytes = [0; S];
input.read(&mut bytes[..])?;

O::decode(&mut bytes.as_slice())
}

/// Function that initializes the frame system & Aura, so a timestamp can be set
/// and pass validation
#[cfg(any(feature = "runtime-benchmarks", feature = "std"))]
Expand Down
6 changes: 3 additions & 3 deletions pallets/liquidity-pools-gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
use core::fmt::Debug;

use cfg_traits::{
liquidity_pools::{Codec, InboundQueue, OutboundQueue, Router as DomainRouter},
liquidity_pools::{InboundQueue, LPEncoding, OutboundQueue, Router as DomainRouter},
TryConvert,
};
use cfg_types::domain_address::{Domain, DomainAddress};
Expand Down Expand Up @@ -122,7 +122,7 @@ pub mod pallet {
///
/// NOTE - this `Codec` trait is the Centrifuge trait for liquidity
/// pools' messages.
type Message: Codec + Clone + Debug + PartialEq + MaxEncodedLen + TypeInfo + FullCodec;
type Message: LPEncoding + Clone + Debug + PartialEq + MaxEncodedLen + TypeInfo + FullCodec;

/// The message router type that is stored for each domain.
type Router: DomainRouter<Sender = Self::AccountId>
Expand Down Expand Up @@ -634,7 +634,7 @@ pub mod pallet {
Error::<T>::UnknownInstance,
);

let incoming_msg = T::Message::deserialize(&mut msg.as_slice())
let incoming_msg = T::Message::deserialize(msg.as_slice())
.map_err(|_| Error::<T>::MessageDecodingFailed)?;

Ok((address, incoming_msg))
Expand Down
2 changes: 0 additions & 2 deletions pallets/liquidity-pools-gateway/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ 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,
Expand Down
4 changes: 2 additions & 2 deletions pallets/liquidity-pools-gateway/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cfg_mocks::*;
use cfg_primitives::OutboundMessageNonce;
use cfg_traits::liquidity_pools::{test_util::Message, Codec, OutboundQueue};
use cfg_traits::liquidity_pools::{test_util::Message, LPEncoding, OutboundQueue};
use cfg_types::domain_address::*;
use frame_support::{
assert_noop, assert_ok,
Expand Down Expand Up @@ -406,7 +406,7 @@ mod process_msg_axelar_relay {
});

let solidity_header = "0000000a657468657265756d2d320000002a307838353033623434353242663632333863433736436462454532323362343664373139366231633933";
let payload = hex::decode(format!("{solidity_header}{ENCODED_MESSAGE_MOCK}")).unwrap();
let payload = [hex::decode(solidity_header).unwrap(), Message.serialize()].concat();

assert_ok!(LiquidityPoolsGateway::process_msg(
GatewayOrigin::AxelarRelay(relayer_address).into(),
Expand Down
3 changes: 3 additions & 0 deletions pallets/liquidity-pools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ hex = { workspace = true }
orml-traits = { workspace = true }
parity-scale-codec = { workspace = true }
scale-info = { workspace = true }
serde = { workspace = true }
serde-big-array = { workspace = true }
sp-core = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
Expand Down Expand Up @@ -50,6 +52,7 @@ std = [
"orml-traits/std",
"staging-xcm/std",
"scale-info/std",
"serde/std",
]
runtime-benchmarks = [
"orml-tokens/runtime-benchmarks",
Expand Down
Loading

0 comments on commit df75508

Please sign in to comment.