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: add connectors v2 extrinsics & inbound msg handlers #1364

Merged
merged 56 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
333baa1
refactor: move connectors codec to traits
wischli May 4, 2023
c1c07d0
refactor: move TypeId for DomainAddress
wischli May 4, 2023
d825bf3
Revert "fix: remove new extrinsics"
wischli May 4, 2023
a444162
refactor: move TypeId impl for DomainLocator
wischli May 4, 2023
f7d7bed
chore: add sanity checks to transfer_tranche_tokens
wischli May 5, 2023
2c67d1d
wip: invest & redeem handlers
wischli May 8, 2023
ffc8522
feat: add foreign investment traits
wischli May 24, 2023
f1246d7
feat: add u128 conv for GeneralCurrencyPrefix
wischli May 24, 2023
0cb33b1
refactor: normalize message codec vars
wischli May 24, 2023
78badd0
feat: add v2 extrinsics + inbound handlers
wischli May 24, 2023
9e9013a
docs: minor inv improvements
wischli May 24, 2023
21587ef
tests: apply add_member changes
wischli May 25, 2023
9c3947d
ci: disable on draft PRs
wischli May 25, 2023
ac05f8b
Merge remote-tracking branch 'origin/main' into feat/connectors-v2-ex…
wischli Jun 6, 2023
20c6af2
feat: add CurrencyInspect trait
wischli Jun 7, 2023
6630451
feat: apply CurrencyInspect
wischli Jun 7, 2023
04ade36
tests: add transfer_non_tranche_tokens
wischli Jun 7, 2023
61209a4
tests: add add_currency, allow_pool_currency
wischli Jun 9, 2023
740067b
chore: finish tests, fix inbound handlers
wischli Jun 14, 2023
6158fca
fix: order id storage in do_collect_redeem
wischli Jun 14, 2023
4c99a90
Merge remote-tracking branch 'origin/main' into feat/connectors-v2-ex…
wischli Jun 15, 2023
c3c9d0a
chore: various fixes and cleanups
wischli Jun 16, 2023
fa64b45
tests: add inbound tranche token transfer
wischli Jun 16, 2023
ccb88f9
tests: add non tranche transfers to local
wischli Jun 16, 2023
46cafd4
chore: apply clippy
wischli Jun 16, 2023
3c52de6
Revert "ci: disable on draft PRs"
wischli Jun 16, 2023
4f56811
fix: revert creep changes
wischli Jun 16, 2023
0e83682
refactor: apply suggestions from review
wischli Jun 19, 2023
b3eea35
fix: apply evm meta derivation from asset
wischli Jun 19, 2023
24c3952
refactor: normalize token, currency
wischli Jun 19, 2023
6d59c69
docs: apply suggestion from code review
wischli Jun 19, 2023
59ba987
fix: cleanup
wischli Jun 19, 2023
f8d7fab
tests: extend allow_pool_currency fails
wischli Jun 20, 2023
abc0ed9
clippy: fix
wischli Jun 20, 2023
40cd1f6
docs: add pallets config types
wischli Jun 20, 2023
4ba010b
refactor: apply suggestions from review
wischli Jun 20, 2023
4589410
refactor: rename to ConnectorsWrappedToken
wischli Jun 21, 2023
5396f5f
docs: improve update_asset in con tests
wischli Jun 21, 2023
44469c9
fix: derive tranche decimals from registry
wischli Jun 21, 2023
c04a1fe
refactor: investments trait
wischli Jun 25, 2023
cbba52c
fix: use DomainLocator
wischli Jun 26, 2023
dbb0502
refactor: apply suggestions from code review
wischli Jun 27, 2023
714cfd9
refactor: extend try_get_wrapped_token
wischli Jun 28, 2023
d4e382d
refactor: remove wrapped token conversions
wischli Jun 28, 2023
bd7ed80
docs: add subsequent pr todos
wischli Jun 28, 2023
a04aef7
feat: add connectors queue traits
wischli Jun 29, 2023
a8d9748
refactor: cleanup
wischli Jun 29, 2023
4b82591
refactor: rm local transfer checks
wischli Jun 29, 2023
78e58a3
chore: apply clippy to connectors tests
wischli Jun 29, 2023
2860526
Merge remote-tracking branch 'origin/main' into feat/connectors-v2-ex…
wischli Jun 29, 2023
2165341
fix: issues after rebasing
wischli Jun 29, 2023
de64a54
refactor: apply suggestions from code review
wischli Jun 30, 2023
a588972
Merge remote-tracking branch 'origin/main' into feat/connectors-v2-ex…
wischli Jun 30, 2023
a8d8ad7
tests: fix after rebase
wischli Jun 30, 2023
fe841c0
fix: remove burn, normalize inbound handlers
wischli Jun 30, 2023
036d16a
Merge branch 'main' into feat/connectors-v2-extrinsics
wischli Jun 30, 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
2 changes: 1 addition & 1 deletion Cargo.lock

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

8 changes: 8 additions & 0 deletions libs/mocks/src/pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ pub mod pallet {
register_call!(f);
}

pub fn mock_currency_for(f: impl Fn(T::PoolId) -> Option<T::CurrencyId> + 'static) {
register_call!(f);
}

pub fn mock_withdraw(
f: impl Fn(T::PoolId, T::AccountId, T::Balance) -> DispatchResult + 'static,
) {
Expand Down Expand Up @@ -102,6 +106,10 @@ pub mod pallet {
fn account_for(a: T::PoolId) -> T::AccountId {
execute_call!(a)
}

fn currency_for(a: T::PoolId) -> Option<T::CurrencyId> {
execute_call!(a)
}
}

impl<T: Config> PoolReserve<T::AccountId, T::CurrencyId> for Pallet<T> {
Expand Down
19 changes: 19 additions & 0 deletions libs/test-utils/src/mocks/order_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ pub mod pallet {
InvestmentProperties<T::AccountId, Currency = CurrencyOf<T>>,
{
type Amount = BalanceOf<T>;
type CurrencyId = CurrencyOf<T>;
type Error = DispatchError;
type InvestmentId = T::InvestmentId;

Expand All @@ -233,6 +234,15 @@ pub mod pallet {
Self::update_invest_order(investment_id, amount)
}

fn accepted_payment_currency(
investment_id: Self::InvestmentId,
currency: Self::CurrencyId,
) -> bool {
T::Accountant::info(investment_id)
.map(|info| info.payment_currency() == currency)
.unwrap_or(false)
}

fn investment(
_: &T::AccountId,
investment_id: Self::InvestmentId,
Expand All @@ -250,6 +260,15 @@ pub mod pallet {
Self::update_redeem_order(investment_id, amount)
}

fn accepted_payout_currency(
investment_id: Self::InvestmentId,
currency: Self::CurrencyId,
) -> bool {
T::Accountant::info(investment_id)
.map(|info| info.payment_currency() == currency)
.unwrap_or(false)
}

fn redemption(
_: &T::AccountId,
investment_id: Self::InvestmentId,
Expand Down
58 changes: 58 additions & 0 deletions libs/traits/src/connectors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2021 Centrifuge GmbH (centrifuge.io).
// This file is part of 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.

use codec::Input;
use frame_support::dispatch::DispatchResult;
use sp_std::vec::Vec;

/// An encoding & decoding trait for the purpose of meeting the
/// Connectors General Message Passing Format
pub trait Codec: Sized {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Moved from pallets/connectors/src as requested.

fn serialize(&self) -> Vec<u8>;
fn deserialize<I: Input>(input: &mut I) -> Result<Self, codec::Error>;
}

/// The trait required for processing outbound connectors messages.
pub trait OutboundQueue {
// pub trait OutboundQueue<Sender, Message, Destination> {
wischli marked this conversation as resolved.
Show resolved Hide resolved
/// The sender type of the outgoing message.
type Sender;

/// The message type that is processed.
type Message;

/// The destination this message should go to.
type Destination;

/// Submit a message to the outbound queue.
fn submit(
// destination: Destination,
// sender: Sender,
// msg: Message,
wischli marked this conversation as resolved.
Show resolved Hide resolved
destination: Self::Destination,
sender: Self::Sender,
msg: Self::Message,
wischli marked this conversation as resolved.
Show resolved Hide resolved
) -> DispatchResult;
}

/// The trait required for processing incoming connectors messages.
pub trait InboundQueue {
/// The sender type of the incoming message.
type Sender;

/// The connector message enum.
type Message;

/// Process a message from the inbound queue.
fn process(sender: Self::Sender, msg: Self::Message) -> DispatchResult;
wischli marked this conversation as resolved.
Show resolved Hide resolved
}
69 changes: 58 additions & 11 deletions libs/traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ use sp_runtime::{
};
use sp_std::{fmt::Debug, hash::Hash, str::FromStr, vec::Vec};

/// Traits related to rewards.
pub mod rewards;

/// Traits related to data registry & collections.
pub mod data;

/// Traits related to checked changes.
pub mod changes;
/// Traits related to connectors.
pub mod connectors;
/// Traits related to data registry and collection.
pub mod data;
/// Traits related to rewards.
pub mod rewards;

/// A trait used for loosely coupling the claim pallet with a reward mechanism.
///
Expand Down Expand Up @@ -142,6 +142,9 @@ pub trait PoolInspect<AccountId, CurrencyId> {

/// Get the account used for the given `pool_id`.
fn account_for(pool_id: Self::PoolId) -> AccountId;

// Get the currency used for the given `pool_id`.
fn currency_for(pool_id: Self::PoolId) -> Option<CurrencyId>;
}

/// Variants for valid Pool updates to send out as events
Expand Down Expand Up @@ -377,9 +380,10 @@ pub trait TrancheCurrency<PoolId, TrancheId> {
/// A trait, when implemented allows to invest into
/// investment classes
pub trait Investment<AccountId> {
type Error: Debug;
type InvestmentId;
type Amount;
type CurrencyId;
type Error: Debug;
type InvestmentId: Into<Self::CurrencyId>;
wischli marked this conversation as resolved.
Show resolved Hide resolved

/// Updates the current investment amount of who into the
/// investment class to amount.
Expand All @@ -391,6 +395,12 @@ pub trait Investment<AccountId> {
amount: Self::Amount,
) -> Result<(), Self::Error>;

/// Checks whether a currency can be used for buying `InvestmentId`
fn accepted_payment_currency(
investment_id: Self::InvestmentId,
currency: Self::CurrencyId,
) -> bool;

/// Returns, if possible, the current investment amount of who into the
/// given investment class
fn investment(
Expand All @@ -408,6 +418,12 @@ pub trait Investment<AccountId> {
amount: Self::Amount,
) -> Result<(), Self::Error>;

/// Checks whether a currency is accepted as a payout for an `InvestmentId`
fn accepted_payout_currency(
investment_id: Self::InvestmentId,
currency: Self::CurrencyId,
) -> bool;

/// Returns, if possible, the current redemption amount of who into the
/// given investment class
fn redemption(
Expand All @@ -416,6 +432,29 @@ pub trait Investment<AccountId> {
) -> Result<Self::Amount, Self::Error>;
}

/// A trait which allows to collect existing investments and redemptions.
pub trait InvestmentCollector<AccountId> {
type Error: Debug;
type InvestmentId;
type Result: Debug;

/// Collect the results of a user's invest orders for the given
/// investment. If any amounts are not fulfilled they are directly
/// appended to the next active order for this investment.
fn collect_investment(
who: AccountId,
investment_id: Self::InvestmentId,
) -> Result<Self::Result, Self::Error>;

/// Collect the results of a users redeem orders for the given
/// investment. If any amounts are not fulfilled they are directly
/// appended to the next active order for this investment.
fn collect_redemption(
who: AccountId,
investment_id: Self::InvestmentId,
) -> Result<Self::Result, Self::Error>;
}

/// A trait, when implemented must take care of
/// collecting orders (invest & redeem) for a given investment class.
/// When being asked it must return the current orders and
Expand Down Expand Up @@ -626,16 +665,24 @@ pub mod fees {
}

/// Trait to determine whether a sending account and currency have a
/// restriction, and if so is there an allowance for the reciever location.
/// restriction, and if so is there an allowance for the receiver location.
pub trait TransferAllowance<AccountId> {
type CurrencyId;
type Location: Member + Debug + Eq + PartialEq + TypeInfo + Encode + Decode + MaxEncodedLen;
/// Determines whether the `send` account is allowed to make a transfer to
/// the `receive` location with `currency` type currency. Returns result
/// the `receive` location with `currency` type currency. Returns result
/// wrapped bool for whether allowance is allowed.
fn allowance(
send: AccountId,
recieve: Self::Location,
receive: Self::Location,
currency: Self::CurrencyId,
) -> DispatchResult;
}

/// Trait to retrieve information about currencies.
pub trait CurrencyInspect {
type CurrencyId;

/// Checks whether the provided currency is a tranche token.
fn is_tranche_token(currency: Self::CurrencyId) -> bool;
wischli marked this conversation as resolved.
Show resolved Hide resolved
}
38 changes: 31 additions & 7 deletions libs/types/src/domain_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

use cfg_utils::vec_to_fixed_array;
use codec::{Decode, Encode, MaxEncodedLen};
use cfg_traits::connectors::Codec;
use cfg_utils::{decode_be_bytes, vec_to_fixed_array};
use codec::{Decode, Encode, Input, MaxEncodedLen};
use scale_info::TypeInfo;
use sp_core::TypeId;
use sp_std::{vec, vec::Vec};

use crate::EVMChainId;

Expand All @@ -32,15 +33,38 @@ pub enum Domain {
EVM(EVMChainId),
}

impl Codec for Domain {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Moved from pallets/connectors/src as requested.

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, 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(codec::Error::from("Unknown Domain variant")),
}
}
}

#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo)]
pub struct DomainLocator<Domain> {
pub domain: Domain,
}

impl<Domain> TypeId for DomainLocator<Domain> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

NOTE: Moved to libs/types/src/ids.rs as requested.

const TYPE_ID: [u8; 4] = *b"domn";
}

#[derive(Encode, Decode, Clone, PartialEq, Eq, TypeInfo, MaxEncodedLen)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum DomainAddress {
Expand Down
13 changes: 12 additions & 1 deletion libs/types/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
use frame_support::PalletId;
use sp_runtime::TypeId;

use crate::investments::InvestmentAccount;
use crate::{
domain_address::{DomainAddress, DomainLocator},
investments::InvestmentAccount,
};

// The TypeId impl we derive pool-accounts from
impl<InvestmentId> TypeId for InvestmentAccount<InvestmentId> {
Expand All @@ -41,3 +44,11 @@ pub const CHAIN_BRIDGE_NATIVE_TOKEN_ID: [u8; 4] = *b"xCFG";
// Reward related
/// The identifier of the group eligible to receive block rewards.
pub const COLLATOR_GROUP_ID: u32 = 1;

impl TypeId for DomainAddress {
const TYPE_ID: [u8; 4] = *b"dadr";
}

impl<Domain> TypeId for DomainLocator<Domain> {
const TYPE_ID: [u8; 4] = *b"domn";
}
25 changes: 25 additions & 0 deletions libs/types/src/tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ impl From<StakingCurrency> for CurrencyId {
}
}

impl cfg_traits::CurrencyInspect for CurrencyId {
type CurrencyId = CurrencyId;

fn is_tranche_token(currency: Self::CurrencyId) -> bool {
matches!(currency, CurrencyId::Tranche(_, _))
}
}

/// A general index wrapper for a given currency representation which is the
/// concatenation of the generic prefix and the identifier of the respective
/// currency.
Expand Down Expand Up @@ -138,6 +146,19 @@ where
}
}

impl<Index, Prefix> From<u128> for GeneralCurrencyIndex<Index, Prefix>
where
Index: From<u128>,
Prefix: Get<[u8; 12]>,
{
fn from(value: u128) -> Self {
GeneralCurrencyIndex {
index: value.into(),
_phantom: Default::default(),
}
}
}

/// A Currency that is solely used by tranches.
///
/// We distinguish here between the enum variant CurrencyId::Tranche(PoolId,
Expand Down Expand Up @@ -253,6 +274,10 @@ impl CrossChainTransferability {
pub fn includes_xcm(self) -> bool {
matches!(self, Self::Xcm(..) | Self::All(..))
}

pub fn includes_connectors(self) -> bool {
matches!(self, Self::Connectors | Self::All(..))
}
}

/// Connectors-wrapped tokens
Expand Down