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

Connectors v1++ #1211

Merged
merged 38 commits into from
Mar 3, 2023
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
c1d52e1
connectors: Add POC `handle` extrinsic
NunoAlexandre Feb 20, 2023
70d3a11
xcm: Add AccountIdHash origin convert + dev 1013
NunoAlexandre Feb 22, 2023
640fc18
Fix Barrier, change handle API + dev spec 1015
NunoAlexandre Feb 22, 2023
3ab9815
fixup
NunoAlexandre Feb 22, 2023
bd1a402
Add allowlist logic guarding `handle`
NunoAlexandre Feb 23, 2023
0d32496
Implement and test Message::Transfer decoding
NunoAlexandre Feb 23, 2023
883b371
Clean up Message decoding
NunoAlexandre Feb 24, 2023
d2aa483
fixup! Add doc
NunoAlexandre Feb 24, 2023
461d9a2
Impl decoding for all message types
NunoAlexandre Feb 24, 2023
03d06db
Test identity decode . encode property for all messages
NunoAlexandre Feb 24, 2023
ab3f295
Clean and improve all encoding / decoding tests
NunoAlexandre Feb 24, 2023
b25b538
Dry message encoding with encoded_message
NunoAlexandre Feb 24, 2023
633698a
Use decode_be_bytes in Decode for Domain
NunoAlexandre Feb 24, 2023
939834c
Clean up imports
NunoAlexandre Feb 24, 2023
7e9cbee
Decode message in handle
NunoAlexandre Feb 24, 2023
5ab1c68
fmt
NunoAlexandre Feb 24, 2023
f81f205
nix
NunoAlexandre Feb 24, 2023
ab3fce1
Rename to_be to encode_be
NunoAlexandre Feb 24, 2023
8cb1a7c
Add weight fns for add_connector and handle
NunoAlexandre Feb 24, 2023
c2dda1b
type alias for Message type in message tests
NunoAlexandre Feb 24, 2023
4a325d5
Doc Message enum
NunoAlexandre Feb 27, 2023
9e3eff0
Merge branch 'main' into connectors-v1++
NunoAlexandre Feb 27, 2023
912002d
Use Account32Hash and drop custom AccountIdHash
NunoAlexandre Feb 27, 2023
0e1d3fb
Document Account32Hash
NunoAlexandre Feb 27, 2023
7fa50a4
fix clippy
NunoAlexandre Feb 27, 2023
bc83193
Merge branch 'main' into connectors-v1++
NunoAlexandre Feb 27, 2023
80eb025
dev: spec_version 1016
NunoAlexandre Feb 27, 2023
a32829b
Merge branch 'main' into connectors-v1++
NunoAlexandre Feb 27, 2023
75b4aa6
Option A
NunoAlexandre Feb 28, 2023
7dd0a16
dev: spec_version 1017
NunoAlexandre Feb 28, 2023
28cb551
Bump development runtime cargo version
NunoAlexandre Feb 28, 2023
b48e6d0
nix
NunoAlexandre Feb 28, 2023
d0973c8
Fix Domain codec issues with custom Codec trait
NunoAlexandre Mar 2, 2023
33cdf32
dev: spec_version 1018
NunoAlexandre Mar 2, 2023
0ac9ee5
fmt
NunoAlexandre Mar 2, 2023
d961d44
Merge branch 'main' into connectors-v1++
NunoAlexandre Mar 3, 2023
f6e8bc4
fix encoded_ethereum_xcm_add_pool
NunoAlexandre Mar 3, 2023
e45a0c7
fmt
NunoAlexandre Mar 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
};

# This is a hash of all the Cargo dependencies, for reproducibility.
cargoSha256 = "sha256-FgnJKi1LfSw+JX/2dx7uXClb3hkdCwoWTefZ83x6Tf4=";
cargoSha256 = "sha256-qFvobNDYPRfjHTyfF0KsqBCp+vhls0d8d6BcqKlhiek=";

nativeBuildInputs = with pkgs; [ clang git-mock pkg-config ];
buildInputs = with pkgs; [ openssl ] ++ (
Expand Down
31 changes: 30 additions & 1 deletion libs/utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// Ensure we're `no_std` when compiling for WebAssembly.
#![cfg_attr(not(feature = "std"), no_std)]

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

/// Build a fixed-size array using as many elements from `src` as possible without
Expand All @@ -26,13 +27,41 @@ pub fn vec_to_fixed_array<const S: usize>(src: Vec<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, codec::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, codec::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"))]
pub fn set_block_number_timestamp<T>(block_number: T::BlockNumber, timestamp: T::Moment)
where
T: pallet_aura::Config + frame_system::Config + pallet_timestamp::Config,
{
use codec::Encode;
use frame_support::traits::Hooks;
use sp_consensus_aura::AURA_ENGINE_ID;
use sp_runtime::{Digest, DigestItem};
Expand Down
55 changes: 50 additions & 5 deletions pallets/connectors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use core::convert::TryFrom;

use cfg_traits::PoolInspect;
use cfg_utils::vec_to_fixed_array;
use cfg_utils::{decode_be_bytes, vec_to_fixed_array};
use codec::{Decode, Encode, EncodeLike, Input, MaxEncodedLen};
use frame_support::traits::{
fungibles::{Inspect, Mutate, Transfer},
Expand Down Expand Up @@ -83,10 +83,7 @@ impl Decode for Domain {
match variant {
0 => Ok(Self::Centrifuge),
1 => {
let mut chain_id_be_bytes = [0; 8];
input.read(&mut chain_id_be_bytes[..])?;

let chain_id = EVMChainId::from_be_bytes(chain_id_be_bytes);
let chain_id = decode_be_bytes::<8, _, _>(input)?;
Ok(Self::EVM(chain_id))
}
_ => Err(codec::Error::from("Unknown Domain variant")),
Expand Down Expand Up @@ -242,12 +239,22 @@ pub mod pallet {
domain: Domain,
router: Router<CurrencyIdOf<T>>,
},

IncomingMessage {
sender: T::AccountId,
message: Vec<u8>,
},
}

#[pallet::storage]
pub(crate) type DomainRouter<T: Config> =
StorageMap<_, Blake2_128Concat, Domain, Router<CurrencyIdOf<T>>>;

/// The set of known connectors. This set is used as an allow-list when authorizing
/// the origin of incoming messages through the `handle` extrinsic.
#[pallet::storage]
pub(crate) type KnownConnectors<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, ()>;

#[pallet::error]
pub enum Error<T> {
/// A pool could not be found
Expand All @@ -268,6 +275,10 @@ pub mod pallet {
UnauthorizedTransfer,
/// Failed to build Ethereum_Xcm call
FailedToBuildEthereumXcmCall,
/// The origin of an incoming message is not in the allow-list
InvalidIncomingMessageOrigin,
/// Failed to decode an incoming message
InvalidIncomingMessage,
}

#[pallet::call]
Expand All @@ -287,6 +298,16 @@ pub mod pallet {
Ok(())
}

/// Add an AccountId to the set of known connectors, allowing that origin
/// to send incoming messages.
#[pallet::weight(< T as Config >::WeightInfo::add_connector())]
pub fn add_connector(origin: OriginFor<T>, connector: T::AccountId) -> DispatchResult {
T::AdminOrigin::ensure_origin(origin)?;
<KnownConnectors<T>>::insert(connector, ());

Ok(())
}

/// Add a pool to a given domain
#[pallet::weight(< T as Config >::WeightInfo::add_pool())]
pub fn add_pool(
Expand Down Expand Up @@ -473,6 +494,30 @@ pub mod pallet {

Ok(())
}

/// Handle an incoming message
/// TODO(nuno): we probably need a custom origin type for these messages to ensure they have
/// come in through XCM. Probably even handle it in a separate pallet? For now, let's have a
NunoAlexandre marked this conversation as resolved.
Show resolved Hide resolved
/// POC here to test the pipeline Ethereum ---> Moonbeam ---> Centrifuge::connectors
#[pallet::call_index(99)]
#[pallet::weight(< T as Config >::WeightInfo::handle())]
pub fn handle(origin: OriginFor<T>, bytes: Vec<u8>) -> DispatchResult {
let sender = ensure_signed(origin.clone())?;
ensure!(
<KnownConnectors<T>>::contains_key(&sender),
Error::<T>::InvalidIncomingMessageOrigin
);

Self::deposit_event(Event::IncomingMessage {
sender,
message: bytes.clone(),
});
// todo: do someting with the decoded message later on
let _: MessageOf<T> = Message::decode(&mut bytes.as_slice())
.map_err(|_| Error::<T>::InvalidIncomingMessage)?;

Ok(())
}
}

impl<T: Config> Pallet<T> {
Expand Down