Skip to content

Commit

Permalink
use concrete InvestmentInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Sep 27, 2023
1 parent 2a345c5 commit 62174b5
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 80 deletions.
52 changes: 13 additions & 39 deletions libs/test-utils/src/mocks/accountant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@

/// Exposes a struct $name that implements the `trait Accountant`. The struct
/// expects one generic parameter that implements the fungibles traits
/// `Inspect`, `Mutate` and `Transfer`. Furthermore, there exists a struct
/// `GenesisConfig` that implements `trait GenesisBuild` that can be used
/// like any other `GenesisConfig` to initialize state in the
/// `TestExternalities`.
///
/// Also exports a `struct InvestmentInfo` to be used in the `GenesisConfig`
/// `Inspect`, `Mutate` and `Transfer`.
///
/// * E.g.: `MockAccountant<Tokens:
/// frame_support::traits::tokens::fungibles::{Inspect, Mutate, Transfer}>`
Expand Down Expand Up @@ -54,7 +49,7 @@
///
/// // Using the `GenesisConfig`
/// use accountant_mock::InvestmentInfo;
/// let storage = GenesisBuild::build_storage(&accountant_mock::GenesisConfig {
/// let storage = GenesisBuild::init(&accountant_mock::Genesis {
/// infos: vec![
/// (
/// InvestmentId::Tranche(0, [0;16]),
Expand All @@ -79,32 +74,28 @@ macro_rules! impl_mock_accountant {

use super::*;

#[derive(Default, serde::Serialize, serde::Deserialize)]
pub struct GenesisConfig {
pub type InvestmentInfo =
cfg_types::investments::InvestmentInfo<$account_id, $currency_id, $investment_id>;

#[derive(Default)]
pub struct Genesis {
pub infos: Vec<($investment_id, InvestmentInfo)>,
}

impl frame_support::traits::GenesisBuild<()> for GenesisConfig {
fn build(&self) {
pub struct $name<Tokens>(sp_std::marker::PhantomData<Tokens>);

impl<Tokens> $name<Tokens> {
pub fn init(genesis: Genesis) {
__private_STATE.with(|s| {
let mut state = s.borrow_mut();

for (id, info) in &self.infos {
for (id, info) in &genesis.infos {
state.add(id.clone(), info.clone())
}
})
}
}

pub struct $name<Tokens>(sp_std::marker::PhantomData<Tokens>);

#[derive(Clone, serde::Serialize, serde::Deserialize)]
pub struct InvestmentInfo {
pub owner: $account_id,
pub id: $investment_id,
pub payment_currency: $currency_id,
}

impl<Tokens> cfg_traits::investments::InvestmentAccountant<$account_id> for $name<Tokens>
where
Tokens: frame_support::traits::tokens::fungibles::Mutate<$account_id>
Expand Down Expand Up @@ -187,23 +178,6 @@ macro_rules! impl_mock_accountant {
}
}

impl cfg_traits::investments::InvestmentProperties<$account_id> for InvestmentInfo {
type Currency = $currency_id;
type Id = $investment_id;

fn owner(&self) -> $account_id {
self.owner
}

fn id(&self) -> Self::Id {
self.id
}

fn payment_currency(&self) -> Self::Currency {
self.payment_currency
}
}

mod __private {
use super::*;

Expand Down Expand Up @@ -235,7 +209,7 @@ macro_rules! impl_mock_accountant {

pub fn add(&mut self, investment_id: $investment_id, info: InvestmentInfo) {
// NOTE: We deliberately update the info here as add() is only called
// upon GenesisConfig.build(). We assume, if we are running in the
// upon init(). We assume, if we are running in the
// same thread this means a new initialization is wanted.
for (curr_id, curr_info) in &mut self.infos {
if *curr_id == investment_id {
Expand Down
56 changes: 22 additions & 34 deletions pallets/investments/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
use cfg_primitives::OrderId;
use cfg_traits::{
investments::{
Investment, InvestmentAccountant, InvestmentCollector, InvestmentProperties,
InvestmentsPortfolio, OrderManager,
Investment, InvestmentAccountant, InvestmentCollector, InvestmentsPortfolio, OrderManager,
},
PreConditions, StatusNotificationHook,
};
Expand Down Expand Up @@ -109,7 +108,7 @@ pub enum CollectType {

#[frame_support::pallet]
pub mod pallet {
use cfg_types::investments::ForeignInvestmentInfo;
use cfg_types::investments::{ForeignInvestmentInfo, InvestmentInfo};
use sp_runtime::{traits::AtLeast32BitUnsigned, FixedPointNumber, FixedPointOperand};

use super::*;
Expand All @@ -125,21 +124,14 @@ pub mod pallet {
/// The underlying investments one can invest into
type InvestmentId: Member + Parameter + Copy + MaxEncodedLen + Into<CurrencyOf<Self>>;

/// Properties used for the Accountant type
type InvestmentInfo: InvestmentProperties<
Self::AccountId,
Id = Self::InvestmentId,
Currency = CurrencyOf<Self>,
>;

/// Something that knows how to handle accounting for the given
/// investments and provides metadata about them
type Accountant: InvestmentAccountant<
Self::AccountId,
Error = DispatchError,
InvestmentId = Self::InvestmentId,
Amount = Self::Amount,
InvestmentInfo = Self::InvestmentInfo,
InvestmentInfo = InvestmentInfo<Self::AccountId, CurrencyOf<Self>, Self::InvestmentId>,
>;

/// A representation for an investment or redemption. Usually this
Expand Down Expand Up @@ -541,7 +533,7 @@ impl<T: Config> Pallet<T> {
total_order,
&who,
investment_id,
info,
info.payment_currency,
order,
amount,
)?;
Expand Down Expand Up @@ -580,7 +572,7 @@ impl<T: Config> Pallet<T> {
amount,
})?;

let info = T::Accountant::info(investment_id).map_err(|_| Error::<T>::UnknownInvestment)?;
let _ = T::Accountant::info(investment_id).map_err(|_| Error::<T>::UnknownInvestment)?;
let cur_order_id = ActiveRedeemOrders::<T>::try_mutate(
investment_id,
|total_order| -> Result<OrderId, DispatchError> {
Expand All @@ -603,7 +595,6 @@ impl<T: Config> Pallet<T> {
total_order,
&who,
investment_id,
info,
order,
amount,
)?;
Expand Down Expand Up @@ -647,7 +638,7 @@ impl<T: Config> Pallet<T> {
who: T::AccountId,
investment_id: T::InvestmentId,
) -> DispatchResultWithPostInfo {
let info = T::Accountant::info(investment_id).map_err(|_| Error::<T>::UnknownInvestment)?;
let _ = T::Accountant::info(investment_id).map_err(|_| Error::<T>::UnknownInvestment)?;
let (collected_investment, post_dispatch_info) = InvestOrders::<T>::try_mutate(
&who,
investment_id,
Expand All @@ -663,8 +654,7 @@ impl<T: Config> Pallet<T> {
who: who.clone(),
investment_id,
});
// TODO: Return correct weight
// - Accountant::info() + Storage::read() + Storage::write()
// TODO: Return correct weight + Storage::read() + Storage::write()
return Ok((Default::default(), ().into()));
};

Expand All @@ -684,8 +674,7 @@ impl<T: Config> Pallet<T> {
who: who.clone(),
investment_id,
});
// TODO: Return correct weight
// - Accountant::info() + 2 * Storage::read() + Storage::write()
// TODO: Return correct weight 2 * Storage::read() + Storage::write()
return Ok((Default::default(), ().into()));
}

Expand Down Expand Up @@ -713,7 +702,7 @@ impl<T: Config> Pallet<T> {
);

T::Accountant::transfer(
info.id(),
investment_id,
&InvestmentAccount { investment_id }.into_account_truncating(),
&who,
collection.payout_investment_invest,
Expand Down Expand Up @@ -847,7 +836,7 @@ impl<T: Config> Pallet<T> {
let investment_account =
InvestmentAccount { investment_id }.into_account_truncating();
T::Tokens::transfer(
info.payment_currency(),
info.payment_currency,
&investment_account,
&who,
collection.payout_investment_redeem,
Expand Down Expand Up @@ -907,7 +896,7 @@ impl<T: Config> Pallet<T> {
total_order: &mut TotalOrder<T::Amount>,
who: &T::AccountId,
investment_id: T::InvestmentId,
info: impl InvestmentProperties<T::AccountId, Currency = CurrencyOf<T>, Id = T::InvestmentId>,
payment_currency: CurrencyOf<T>,
order: &mut OrderOf<T>,
amount: T::Amount,
) -> DispatchResult {
Expand All @@ -920,14 +909,13 @@ impl<T: Config> Pallet<T> {
&mut total_order.amount,
)?;

T::Tokens::transfer(info.payment_currency(), send, recv, transfer_amount, false).map(|_| ())
T::Tokens::transfer(payment_currency, send, recv, transfer_amount, false).map(|_| ())
}

pub(crate) fn do_update_redeem_order(
total_order: &mut TotalOrder<T::Amount>,
who: &T::AccountId,
investment_id: T::InvestmentId,
info: impl InvestmentProperties<T::AccountId, Currency = CurrencyOf<T>, Id = T::InvestmentId>,
order: &mut OrderOf<T>,
amount: T::Amount,
) -> DispatchResult {
Expand All @@ -940,7 +928,7 @@ impl<T: Config> Pallet<T> {
&mut total_order.amount,
)?;

T::Accountant::transfer(info.id(), send, recv, transfer_amount)
T::Accountant::transfer(investment_id, send, recv, transfer_amount)
}

#[allow(clippy::type_complexity)]
Expand Down Expand Up @@ -1121,7 +1109,7 @@ impl<T: Config> InvestmentsPortfolio<T::AccountId> for Pallet<T> {
investment_id: T::InvestmentId,
) -> Result<CurrencyOf<T>, DispatchError> {
let info = T::Accountant::info(investment_id).map_err(|_| Error::<T>::UnknownInvestment)?;
Ok(info.payment_currency())
Ok(info.payment_currency)
}

/// Get the investments and associated payment currencies and balances for
Expand Down Expand Up @@ -1159,7 +1147,7 @@ impl<T: Config> Investment<T::AccountId> for Pallet<T> {
currency: Self::CurrencyId,
) -> bool {
T::Accountant::info(investment_id)
.map(|info| info.payment_currency() == currency)
.map(|info| info.payment_currency == currency)
.unwrap_or(false)
}

Expand All @@ -1184,7 +1172,7 @@ impl<T: Config> Investment<T::AccountId> for Pallet<T> {
currency: Self::CurrencyId,
) -> bool {
T::Accountant::info(investment_id)
.map(|info| info.payment_currency() == currency)
.map(|info| info.payment_currency == currency)
.unwrap_or(false)
}

Expand Down Expand Up @@ -1354,9 +1342,9 @@ impl<T: Config> OrderManager for Pallet<T> {
let info = T::Accountant::info(investment_id)?;

T::Tokens::transfer(
info.payment_currency(),
info.payment_currency,
&investment_account,
&info.payment_account(),
&info.owner,
invest_amount,
false,
)?;
Expand All @@ -1371,7 +1359,7 @@ impl<T: Config> OrderManager for Pallet<T> {
.checked_mul_int(invest_amount)
.ok_or(ArithmeticError::Overflow)?;

T::Accountant::deposit(&investment_account, info.id(), amount_of_investment_units)?;
T::Accountant::deposit(&investment_account, info.id, amount_of_investment_units)?;

// The previous OrderId is always 1 away
//
Expand Down Expand Up @@ -1446,14 +1434,14 @@ impl<T: Config> OrderManager for Pallet<T> {
let info = T::Accountant::info(investment_id)?;

T::Tokens::transfer(
info.payment_currency(),
&info.payment_account(),
info.payment_currency,
&info.owner,
&investment_account,
redeem_amount_payment,
false,
)?;

T::Accountant::withdraw(&investment_account, info.id(), redeem_amount)?;
T::Accountant::withdraw(&investment_account, info.id, redeem_amount)?;

// The previous OrderId is always 1 away
//
Expand Down
10 changes: 3 additions & 7 deletions pallets/investments/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use cfg_primitives::*;
use cfg_traits::{investments::OrderManager, PreConditions};
use cfg_types::{
fixed_point::Rate,
investments::InvestmentAccount,
investments::{InvestmentAccount, InvestmentInfo},
orders::{FulfillmentWithPrice, TotalOrder},
tokens::CurrencyId,
};
Expand Down Expand Up @@ -162,7 +162,6 @@ impl pallet_investments::Config for MockRuntime {
type CollectedInvestmentHook = NoopCollectHook;
type CollectedRedemptionHook = NoopCollectHook;
type InvestmentId = InvestmentId;
type InvestmentInfo = accountant_mock::InvestmentInfo;
type MaxOutstandingCollects = MaxOutstandingCollect;
type PreConditions = Always;
type RuntimeEvent = RuntimeEvent;
Expand Down Expand Up @@ -295,8 +294,7 @@ impl TestExternalitiesBuilder {
.assimilate_storage(&mut storage)
.unwrap();

use accountant_mock::InvestmentInfo;
accountant_mock::GenesisConfig {
MockAccountant::<OrmlTokens>::init(accountant_mock::Genesis {
infos: vec![
(
INVESTMENT_0_0,
Expand All @@ -315,9 +313,7 @@ impl TestExternalitiesBuilder {
},
),
],
}
.assimilate_storage(&mut storage)
.unwrap();
});

let mut externalities = TestExternalities::new(storage);
externalities.execute_with(|| {
Expand Down

0 comments on commit 62174b5

Please sign in to comment.