From d0ecc24f32acee6a4e7eb575cabebb519098d0c9 Mon Sep 17 00:00:00 2001 From: mustermeiszer Date: Tue, 6 Dec 2022 13:07:06 +0100 Subject: [PATCH 01/12] WIP: Removed macro, fixing max encoded len info missing --- libs/types/src/orders.rs | 2 +- pallets/anchors/src/lib.rs | 5 ++--- pallets/bridge/src/lib.rs | 1 - pallets/claims/src/lib.rs | 1 - pallets/collator-allowlist/src/lib.rs | 3 +-- pallets/connectors/src/lib.rs | 1 - pallets/crowdloan-claim/src/lib.rs | 4 ++-- pallets/crowdloan-reward/src/lib.rs | 1 - pallets/fees/src/lib.rs | 3 +-- pallets/interest-accrual/src/lib.rs | 10 +++++----- pallets/investments/src/lib.rs | 6 +++--- pallets/keystore/src/lib.rs | 7 +++---- pallets/loans/src/lib.rs | 1 - pallets/migration/src/lib.rs | 7 ++++--- pallets/nft-sales/src/lib.rs | 1 - pallets/nft/src/lib.rs | 1 - pallets/permissions/src/lib.rs | 9 ++++++--- pallets/pool-registry/src/lib.rs | 1 - pallets/pool-system/src/lib.rs | 1 - pallets/pool-system/src/pool_types.rs | 16 ++++++++-------- pallets/restricted-tokens/src/lib.rs | 1 - 21 files changed, 36 insertions(+), 46 deletions(-) diff --git a/libs/types/src/orders.rs b/libs/types/src/orders.rs index 87374624b1..d206332d28 100644 --- a/libs/types/src/orders.rs +++ b/libs/types/src/orders.rs @@ -21,7 +21,7 @@ use sp_std::{ vec::Vec, }; -#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct FulfillmentWithPrice { pub of_amount: Perquintill, pub price: BalanceRatio, diff --git a/pallets/anchors/src/lib.rs b/pallets/anchors/src/lib.rs index 80d7acd97c..afc5486ae2 100644 --- a/pallets/anchors/src/lib.rs +++ b/pallets/anchors/src/lib.rs @@ -19,7 +19,7 @@ #![allow(clippy::all)] use cfg_traits::fees::{Fee, Fees}; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ dispatch::{DispatchError, DispatchResult}, storage::child, @@ -81,7 +81,7 @@ const ANCHOR_PREFIX: &[u8; 6] = b"anchor"; const EVICT_PRE_COMMIT_LIST_SIZE: u32 = 100; /// The data structure for storing pre-committed anchors. -#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub struct PreCommitData { signing_root: Hash, @@ -112,7 +112,6 @@ pub mod pallet { // method. #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] diff --git a/pallets/bridge/src/lib.rs b/pallets/bridge/src/lib.rs index 8d8d2d5216..273fc66a7e 100644 --- a/pallets/bridge/src/lib.rs +++ b/pallets/bridge/src/lib.rs @@ -77,7 +77,6 @@ pub mod pallet { // for the pallet. #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); // ------------------------------------------------------------------------ diff --git a/pallets/claims/src/lib.rs b/pallets/claims/src/lib.rs index 0ef4030a02..e326fe3149 100644 --- a/pallets/claims/src/lib.rs +++ b/pallets/claims/src/lib.rs @@ -156,7 +156,6 @@ pub mod pallet { // for the pallet. #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); // ------------------------------------------------------------------------ diff --git a/pallets/collator-allowlist/src/lib.rs b/pallets/collator-allowlist/src/lib.rs index 4a5f9936e0..a40993dc68 100644 --- a/pallets/collator-allowlist/src/lib.rs +++ b/pallets/collator-allowlist/src/lib.rs @@ -37,7 +37,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] @@ -49,7 +48,7 @@ pub mod pallet { type WeightInfo: WeightInfo; /// The Validator Id type - type ValidatorId: Member + Parameter + MaybeSerializeDeserialize; + type ValidatorId: Member + Parameter + MaybeSerializeDeserialize + MaxEncodedLen; /// Type representing the underlying validator registration center. /// It offers us the API we need to check whether a collator diff --git a/pallets/connectors/src/lib.rs b/pallets/connectors/src/lib.rs index 8d7dcb9bb3..37f23492e2 100644 --- a/pallets/connectors/src/lib.rs +++ b/pallets/connectors/src/lib.rs @@ -117,7 +117,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] diff --git a/pallets/crowdloan-claim/src/lib.rs b/pallets/crowdloan-claim/src/lib.rs index e24428f686..52f62ae5a7 100644 --- a/pallets/crowdloan-claim/src/lib.rs +++ b/pallets/crowdloan-claim/src/lib.rs @@ -202,7 +202,6 @@ pub mod pallet { // for the pallet. #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); // ------------------------------------------------------------------------ @@ -233,7 +232,8 @@ pub mod pallet { + Member + Ord + Parameter - + Into; + + Into + + MaxEncodedLen; /// The maximum length (i.e. depth of the tree) we allow a proof to have. /// This mitigates DDoS attacks solely. We choose 30, which by a base 2 merkle-tree diff --git a/pallets/crowdloan-reward/src/lib.rs b/pallets/crowdloan-reward/src/lib.rs index f9de92655e..bf4d507a27 100644 --- a/pallets/crowdloan-reward/src/lib.rs +++ b/pallets/crowdloan-reward/src/lib.rs @@ -144,7 +144,6 @@ pub mod pallet { // Declare pallet structure placeholder #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); // ---------------------------------------------------------------------------- diff --git a/pallets/fees/src/lib.rs b/pallets/fees/src/lib.rs index d5e557f1c1..ee9b165051 100644 --- a/pallets/fees/src/lib.rs +++ b/pallets/fees/src/lib.rs @@ -46,13 +46,12 @@ pub mod pallet { // method. #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] pub trait Config: frame_system::Config + pallet_authorship::Config { /// Key type used for storing and identifying fees. - type FeeKey: FeeKey + EncodeLike; + type FeeKey: FeeKey + EncodeLike + MaxEncodedLen; /// The currency mechanism. type Currency: Currency; diff --git a/pallets/interest-accrual/src/lib.rs b/pallets/interest-accrual/src/lib.rs index 9ce31b072f..a426a5eda4 100644 --- a/pallets/interest-accrual/src/lib.rs +++ b/pallets/interest-accrual/src/lib.rs @@ -56,7 +56,7 @@ use cfg_primitives::{Moment, SECONDS_PER_YEAR}; use cfg_traits::InterestAccrual; use cfg_types::adjustments::Adjustment; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::UnixTime; use scale_info::TypeInfo; use sp_arithmetic::traits::{checked_pow, One, Zero}; @@ -89,14 +89,14 @@ pub struct RateDetailsV0 { pub last_updated: Moment, } -#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub struct RateDetails { pub accumulated_rate: InterestRate, pub reference_count: u32, } -#[derive(Encode, Decode, TypeInfo, PartialEq)] +#[derive(Encode, Decode, TypeInfo, PartialEq, MaxEncodedLen)] #[repr(u32)] pub enum Release { V0, @@ -119,7 +119,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] @@ -145,7 +144,8 @@ pub mod pallet { + Default + Copy + TypeInfo - + FixedPointNumber; + + FixedPointNumber + + MaxEncodedLen; type Time: UnixTime; diff --git a/pallets/investments/src/lib.rs b/pallets/investments/src/lib.rs index 11edcd04d7..beed3c210f 100644 --- a/pallets/investments/src/lib.rs +++ b/pallets/investments/src/lib.rs @@ -187,7 +187,7 @@ pub mod pallet { type Event: From> + IsType<::Event>; /// The underlying investments one can invest into - type InvestmentId: Member + Parameter + Copy; + type InvestmentId: Member + Parameter + Copy + MaxEncodedLen; /// Something that knows how to handle accounting for the given investments /// and provides metadata about them @@ -218,7 +218,8 @@ pub mod pallet { + Default + Copy + FixedPointNumber - + FixedPointNumberExtension; + + FixedPointNumberExtension + + MaxEncodedLen; /// The bound on how many fulfilled orders we cache until /// the user needs to collect them. @@ -243,7 +244,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::hooks] diff --git a/pallets/keystore/src/lib.rs b/pallets/keystore/src/lib.rs index 484459d9fa..3dab185df1 100644 --- a/pallets/keystore/src/lib.rs +++ b/pallets/keystore/src/lib.rs @@ -27,19 +27,19 @@ mod tests; pub mod weights; -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum KeyPurpose { P2PDiscovery, P2PDocumentSigning, } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum KeyType { ECDSA, EDDSA, } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct Key { purpose: KeyPurpose, key_type: KeyType, @@ -98,7 +98,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); /// Keys that are currently stored. diff --git a/pallets/loans/src/lib.rs b/pallets/loans/src/lib.rs index 0518136359..a204c29de3 100644 --- a/pallets/loans/src/lib.rs +++ b/pallets/loans/src/lib.rs @@ -84,7 +84,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] diff --git a/pallets/migration/src/lib.rs b/pallets/migration/src/lib.rs index 27b5cd877c..a7361b6dc1 100644 --- a/pallets/migration/src/lib.rs +++ b/pallets/migration/src/lib.rs @@ -7,7 +7,9 @@ #![allow(clippy::type_complexity)] use codec::{Decode, Encode}; -use frame_support::{dispatch::DispatchResult, ensure, traits::Currency}; +use frame_support::{ + dispatch::DispatchResult, ensure, pallet_prelude::MaxEncodedLen, traits::Currency, +}; pub use pallet::*; use scale_info::TypeInfo; pub use weights::*; @@ -27,7 +29,7 @@ type BalanceOf = <::Currency as Currency< ::AccountId, >>::Balance; -#[derive(Encode, Decode, PartialEq, Clone, TypeInfo)] +#[derive(Encode, Decode, PartialEq, Clone, TypeInfo, MaxEncodedLen)] pub enum MigrationStatus { Inactive, Ongoing, @@ -57,7 +59,6 @@ pub mod pallet { // method. #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] diff --git a/pallets/nft-sales/src/lib.rs b/pallets/nft-sales/src/lib.rs index ed0d4c9996..e2716d1e94 100644 --- a/pallets/nft-sales/src/lib.rs +++ b/pallets/nft-sales/src/lib.rs @@ -72,7 +72,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub (super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::config] diff --git a/pallets/nft/src/lib.rs b/pallets/nft/src/lib.rs index 45483801fe..6d8d3818b5 100644 --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -75,7 +75,6 @@ pub mod pallet { // for the pallet. #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); // ------------------------------------------------------------------------ diff --git a/pallets/permissions/src/lib.rs b/pallets/permissions/src/lib.rs index 0cffdaa0eb..2c7f285105 100644 --- a/pallets/permissions/src/lib.rs +++ b/pallets/permissions/src/lib.rs @@ -48,11 +48,15 @@ pub mod pallet { /// Because this pallet emits events, it depends on the runtime's definition of an event. type Event: From> + IsType<::Event>; - type Scope: Member + Parameter; + type Scope: Member + Parameter + MaxEncodedLen; type Role: Member + Parameter; - type Storage: Member + Parameter + Properties + Default; + type Storage: Member + + Parameter + + Properties + + Default + + MaxEncodedLen; type Editors: Contains<(Self::AccountId, Option, Self::Scope, Self::Role)>; @@ -66,7 +70,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::storage] diff --git a/pallets/pool-registry/src/lib.rs b/pallets/pool-registry/src/lib.rs index b72eca24ce..e944d752fc 100644 --- a/pallets/pool-registry/src/lib.rs +++ b/pallets/pool-registry/src/lib.rs @@ -158,7 +158,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::storage] diff --git a/pallets/pool-system/src/lib.rs b/pallets/pool-system/src/lib.rs index 43abbbce6e..5d4fc24878 100644 --- a/pallets/pool-system/src/lib.rs +++ b/pallets/pool-system/src/lib.rs @@ -331,7 +331,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::storage] diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index e279a62870..b0fe55ee96 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -12,7 +12,7 @@ use cfg_primitives::Moment; use cfg_types::epoch::EpochState; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ dispatch::{DispatchError, DispatchResult}, traits::Get, @@ -37,7 +37,7 @@ impl TypeId for PoolLocator { const TYPE_ID: [u8; 4] = *b"pool"; } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ReserveDetails { /// Investments will be allowed up to this amount. pub max: Balance, @@ -84,7 +84,7 @@ where } } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct ScheduledUpdateDetails where MaxTokenNameLength: Get, @@ -101,7 +101,7 @@ pub struct PoolLocator { pub pool_id: PoolId, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct PoolDetails< CurrencyId, TrancheCurrency, @@ -133,12 +133,12 @@ pub struct PoolDetails< pub reserve: ReserveDetails, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum PoolStatus { Open, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct PoolParameters { /// Minimum duration for an epoch. pub min_epoch_time: Moment, @@ -146,7 +146,7 @@ pub struct PoolParameters { pub max_nav_age: Moment, } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct PoolChanges where MaxTokenNameLength: Get, @@ -161,7 +161,7 @@ where } /// Information about the deposit that has been taken to create a pool -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, Default, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] pub struct PoolDepositInfo { pub depositor: AccountId, pub deposit: Balance, diff --git a/pallets/restricted-tokens/src/lib.rs b/pallets/restricted-tokens/src/lib.rs index 7bf81f3de4..817817f53d 100644 --- a/pallets/restricted-tokens/src/lib.rs +++ b/pallets/restricted-tokens/src/lib.rs @@ -212,7 +212,6 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] - #[pallet::without_storage_info] pub struct Pallet(_); #[pallet::event] From 6b350a53c2a68ba3fadcce556ba3eecbccb8a98a Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Thu, 5 Jan 2023 18:01:49 +0100 Subject: [PATCH 02/12] wip: derive MaxEncodedLen --- libs/traits/src/lib.rs | 2 +- libs/types/src/epoch.rs | 4 ++-- pallets/nft-sales/src/lib.rs | 12 ++++++----- pallets/pool-registry/src/lib.rs | 4 ++-- pallets/pool-system/src/lib.rs | 5 +++-- pallets/pool-system/src/pool_types.rs | 29 ++++++++++++++++++++++++++- pallets/pool-system/src/solution.rs | 11 +++++----- pallets/pool-system/src/tranches.rs | 20 ++++++++++-------- 8 files changed, 61 insertions(+), 26 deletions(-) diff --git a/libs/traits/src/lib.rs b/libs/traits/src/lib.rs index 92890dfcb5..ecc620f4ad 100644 --- a/libs/traits/src/lib.rs +++ b/libs/traits/src/lib.rs @@ -145,7 +145,7 @@ pub trait PoolMutate { type MaxTokenSymbolLength: Get; type MaxTranches: Get; type TrancheInput: Encode + Decode + Clone + TypeInfo + Debug + PartialEq; - type PoolChanges: Encode + Decode + Clone + TypeInfo + Debug + PartialEq; + type PoolChanges: Encode + Decode + Clone + TypeInfo + Debug + PartialEq + MaxEncodedLen; fn create( admin: AccountId, diff --git a/libs/types/src/epoch.rs b/libs/types/src/epoch.rs index 7ec3e2f69b..059c96ba63 100644 --- a/libs/types/src/epoch.rs +++ b/libs/types/src/epoch.rs @@ -11,11 +11,11 @@ // GNU General Public License for more details. use cfg_primitives::Moment; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::RuntimeDebug; use scale_info::TypeInfo; -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct EpochState { /// Current epoch that is ongoing. pub current: EpochId, diff --git a/pallets/nft-sales/src/lib.rs b/pallets/nft-sales/src/lib.rs index e2716d1e94..18f9091a59 100644 --- a/pallets/nft-sales/src/lib.rs +++ b/pallets/nft-sales/src/lib.rs @@ -11,7 +11,7 @@ //! To buy an NFT, users will call `buy`. //! #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::{ fungibles::{self, Transfer as FungiblesTransfer}, tokens::nonfungibles::{self, Inspect as _, Transfer as _}, @@ -48,14 +48,14 @@ type CollectionIdOf = type ItemIdOf = <::NonFungibles as nonfungibles::Inspect>>::ItemId; // Storage types -#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub struct Sale { pub seller: AccountId, pub price: Price, } -#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub struct Price { pub currency: CurrencyId, @@ -94,7 +94,8 @@ pub mod pallet { + Copy + Default + TypeInfo - + IsType>; + + IsType> + + MaxEncodedLen; /// The NFT ItemId type type ItemId: Parameter @@ -103,7 +104,8 @@ pub mod pallet { + Copy + TypeInfo + From - + IsType>; + + IsType> + + MaxEncodedLen; /// The Id of this pallet #[pallet::constant] diff --git a/pallets/pool-registry/src/lib.rs b/pallets/pool-registry/src/lib.rs index e944d752fc..4381604149 100644 --- a/pallets/pool-registry/src/lib.rs +++ b/pallets/pool-registry/src/lib.rs @@ -15,7 +15,7 @@ use cfg_primitives::Moment; use cfg_traits::{Permissions, PoolMutate, UpdateState}; use cfg_types::permissions::{PermissionScope, PoolRole, Role}; -use codec::HasCompact; +use codec::{HasCompact, MaxEncodedLen}; use frame_support::{pallet_prelude::*, scale_info::TypeInfo, transactional, BoundedVec}; use frame_system::pallet_prelude::*; pub use pallet::*; @@ -34,7 +34,7 @@ mod mock; mod tests; pub mod weights; -#[derive(Debug, Encode, PartialEq, Eq, Decode, Clone, TypeInfo)] +#[derive(Debug, Encode, PartialEq, Eq, Decode, Clone, TypeInfo, MaxEncodedLen)] pub struct TrancheMetadata where MaxTokenNameLength: Get, diff --git a/pallets/pool-system/src/lib.rs b/pallets/pool-system/src/lib.rs index 5d4fc24878..05e0c8058f 100644 --- a/pallets/pool-system/src/lib.rs +++ b/pallets/pool-system/src/lib.rs @@ -190,7 +190,8 @@ pub mod pallet { + Default + Copy + TypeInfo - + FixedPointNumber; + + FixedPointNumber + + MaxEncodedLen; #[pallet::constant] type PalletId: Get; @@ -226,7 +227,7 @@ pub mod pallet { + TypeInfo + Into; - type CurrencyId: Parameter + Copy; + type CurrencyId: Parameter + Copy + MaxEncodedLen; type PoolCurrency: Contains; diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index b0fe55ee96..8491c42b66 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -146,7 +146,7 @@ pub struct PoolParameters { pub max_nav_age: Moment, } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] pub struct PoolChanges where MaxTokenNameLength: Get, @@ -160,6 +160,33 @@ where pub max_nav_age: Change, } +// TODO: Check whether macro can be used instead of custom impl. +// Unfortunately, `Change` is the root as it does not impl MaxEncodedLen. +// Could open PR on ORML. +impl MaxEncodedLen + for PoolChanges +where + MaxTokenNameLength: Get, + MaxTokenSymbolLength: Get, + MaxTranches: Get, + PoolChanges: Encode, + BoundedVec, MaxTranches>: MaxEncodedLen, + BoundedVec, MaxTranches>: + MaxEncodedLen, + Moment: MaxEncodedLen, +{ + fn max_encoded_len() -> usize { + BoundedVec::, MaxTranches>::max_encoded_len() + .saturating_add(BoundedVec::< + TrancheMetadata, + MaxTranches, + >::max_encoded_len()) + // From 4x Change Enum + .saturating_add(4) + .saturating_add(Moment::max_encoded_len().saturating_mul(2)) + } +} + /// Information about the deposit that has been taken to create a pool #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, Default, TypeInfo, MaxEncodedLen)] pub struct PoolDepositInfo { diff --git a/pallets/pool-system/src/solution.rs b/pallets/pool-system/src/solution.rs index a5b3c0ebdf..4e1737333e 100644 --- a/pallets/pool-system/src/solution.rs +++ b/pallets/pool-system/src/solution.rs @@ -10,6 +10,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. +use codec::MaxEncodedLen; use frame_support::sp_runtime::traits::Convert; use sp_arithmetic::traits::Unsigned; use sp_runtime::ArithmeticError; @@ -85,7 +86,7 @@ impl PoolState { } } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum UnhealthyState { MaxReserveViolated, @@ -93,7 +94,7 @@ pub enum UnhealthyState { } /// The solutions struct for epoch solution -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum EpochSolution { Healthy(HealthySolution), @@ -101,7 +102,7 @@ pub enum EpochSolution { } /// The information for a currently executing epoch -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct EpochExecutionInfo { pub epoch: EpochId, @@ -315,7 +316,7 @@ where } } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct HealthySolution { pub solution: Vec, @@ -331,7 +332,7 @@ where } } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct UnhealthySolution { pub state: Vec, diff --git a/pallets/pool-system/src/tranches.rs b/pallets/pool-system/src/tranches.rs index ee22ad6cbb..706510a840 100644 --- a/pallets/pool-system/src/tranches.rs +++ b/pallets/pool-system/src/tranches.rs @@ -17,7 +17,7 @@ use cfg_traits::TrancheCurrency as TrancheCurrencyT; #[cfg(test)] use cfg_types::{fixed_point::Rate, tokens::TrancheCurrency}; use cfg_types::{tokens::CustomMetadata, xcm::XcmMetadata}; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ dispatch::DispatchResult, ensure, @@ -46,7 +46,7 @@ use xcm::{ /// Type that indicates the seniority of a tranche pub type Seniority = u32; -#[derive(Debug, Encode, PartialEq, Eq, Decode, Clone, TypeInfo)] +#[derive(Debug, Encode, PartialEq, Eq, Decode, Clone, TypeInfo, MaxEncodedLen)] pub struct TrancheInput where MaxTokenNameLength: Get, @@ -57,7 +57,7 @@ where pub metadata: TrancheMetadata, } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct TrancheUpdate { pub tranche_type: TrancheType, pub seniority: Option, @@ -85,7 +85,7 @@ where pub metadata: TrancheMetadata, } -#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum TrancheType { Residual, NonResidual { @@ -126,7 +126,8 @@ where } } -#[derive(Debug, Encode, PartialEq, Eq, Decode, Clone, TypeInfo)] +#[derive(Debug, Encode, PartialEq, Eq, Decode, Clone, TypeInfo, MaxEncodedLen)] +// TODO: Why same struct twice? pool-registry and pool-system. Maybe because of circular dependencies? pub struct TrancheMetadata where MaxTokenNameLength: Get, @@ -308,9 +309,11 @@ pub type TrancheIndex = u64; /// are not reusable! pub type TrancheSalt = (TrancheIndex, PoolId); -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct Tranches { + // FIXME: Move to BoundedVec pub tranches: Vec>, + // FIXME: Move to BoundedVec pub ids: Vec, pub salt: TrancheSalt, } @@ -994,7 +997,7 @@ where } } -#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct EpochExecutionTranche { pub currency: TrancheCurrency, pub supply: Balance, @@ -1023,8 +1026,9 @@ impl Default for EpochExecutionTranche { + // FIXME: Convert to BoundedVec pub tranches: Vec>, } From 9619e9b17e0fefb48085d79c1531ef9871ea0a78 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Fri, 6 Jan 2023 15:25:01 +0100 Subject: [PATCH 03/12] feat: bound pool-system --- pallets/pool-system/src/impls.rs | 1 + pallets/pool-system/src/lib.rs | 48 +++-- pallets/pool-system/src/pool_types.rs | 34 +++- pallets/pool-system/src/solution.rs | 248 +++++++++++++++++++------- pallets/pool-system/src/tranches.rs | 175 ++++++++++-------- runtime/common/src/apis/pools.rs | 6 +- 6 files changed, 344 insertions(+), 168 deletions(-) diff --git a/pallets/pool-system/src/impls.rs b/pallets/pool-system/src/impls.rs index cc232619d4..aadb641ea7 100644 --- a/pallets/pool-system/src/impls.rs +++ b/pallets/pool-system/src/impls.rs @@ -126,6 +126,7 @@ impl PoolMutate for Pallet { T::TrancheCurrency, T::TrancheId, T::PoolId, + T::MaxTranches, >::from_input::( pool_id, tranche_inputs.clone(), diff --git a/pallets/pool-system/src/lib.rs b/pallets/pool-system/src/lib.rs index 05e0c8058f..ff49d7b90d 100644 --- a/pallets/pool-system/src/lib.rs +++ b/pallets/pool-system/src/lib.rs @@ -88,6 +88,7 @@ pub type EpochExecutionTranchesOf = EpochExecutionTranches< ::Rate, ::TrancheWeight, ::TrancheCurrency, + ::MaxEpocExecutionTranches, >; /// Types alias for Tranches @@ -98,6 +99,7 @@ pub type TranchesOf = Tranches< ::TrancheCurrency, ::TrancheId, ::PoolId, + ::MaxTranches, >; #[allow(dead_code)] @@ -120,6 +122,7 @@ type PoolDetailsOf = PoolDetails< ::TrancheWeight, ::TrancheId, ::PoolId, + ::MaxTranches, >; /// Type alias for `struct EpochExecutionInfo` @@ -130,6 +133,8 @@ type EpochExecutionInfoOf = EpochExecutionInfo< ::TrancheWeight, ::BlockNumber, ::TrancheCurrency, + ::MaxEpocExecutionTranches, + ::MaxTranches, >; /// Type alias for `struct PoolDepositInfo` @@ -317,12 +322,16 @@ pub mod pallet { /// Max number of Tranches #[pallet::constant] - type MaxTranches: Get + Member + scale_info::TypeInfo; + type MaxTranches: Get + Member + PartialOrd + scale_info::TypeInfo; /// The amount that must be reserved to create a pool #[pallet::constant] type PoolDeposit: Get; + /// The maximum amount of execution tranches of an epoch. + #[pallet::constant] + type MaxEpocExecutionTranches: Get + scale_info::TypeInfo; + /// The origin permitted to create pools type PoolCreateOrigin: EnsureOrigin; @@ -373,7 +382,7 @@ pub mod pallet { SolutionSubmitted { pool_id: T::PoolId, epoch_id: T::EpochId, - solution: EpochSolution, + solution: EpochSolution, }, /// An epoch was executed. EpochExecuted { @@ -897,7 +906,7 @@ pub mod pallet { pool_id: &PoolDetailsOf, epoch: &EpochExecutionInfoOf, solution: &[TrancheSolution], - ) -> Result, DispatchError> { + ) -> Result, DispatchError> { match Self::inspect_solution(pool_id, epoch, solution)? { PoolState::Healthy => { EpochSolution::score_solution_healthy(solution, &epoch.tranches) @@ -923,21 +932,24 @@ pub mod pallet { Error::::InvalidSolution ); - let (acc_invest, acc_redeem, risk_buffers) = - calculate_solution_parameters::<_, _, T::Rate, _, T::TrancheCurrency>( - &epoch.tranches, - solution, - ) - .map_err(|e| { - // In case we have an underflow in the calculation, there - // is not enough balance in the tranches to realize the redeemptions. - // We convert this at the pool level into an InsufficientCurrency error. - if e == DispatchError::Arithmetic(ArithmeticError::Underflow) { - Error::::InsufficientCurrency - } else { - Error::::InvalidSolution - } - })?; + let (acc_invest, acc_redeem, risk_buffers) = calculate_solution_parameters::< + _, + _, + T::Rate, + _, + T::TrancheCurrency, + T::MaxEpocExecutionTranches, + >(&epoch.tranches, solution) + .map_err(|e| { + // In case we have an underflow in the calculation, there + // is not enough balance in the tranches to realize the redeemptions. + // We convert this at the pool level into an InsufficientCurrency error. + if e == DispatchError::Arithmetic(ArithmeticError::Underflow) { + Error::::InsufficientCurrency + } else { + Error::::InvalidSolution + } + })?; let currency_available: T::Balance = acc_invest .checked_add(&epoch.reserve) diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index 8491c42b66..4e59821cf9 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -51,14 +51,21 @@ impl ReserveDetails where Balance: AtLeast32BitUnsigned + Copy + From, { - pub fn deposit_from_epoch( + pub fn deposit_from_epoch( &mut self, - epoch_tranches: &EpochExecutionTranches, + epoch_tranches: &EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + TrancheCurrency, + MaxExecutionTranches, + >, solution: &[TrancheSolution], ) -> DispatchResult where Weight: Copy + From, BalanceRatio: Copy, + MaxExecutionTranches: Get, { let executed_amounts = epoch_tranches.fulfillment_cash_flows(solution)?; @@ -112,15 +119,17 @@ pub struct PoolDetails< Weight, TrancheId, PoolId, + MaxTranches, > where MetaSize: Get + Copy, Rate: FixedPointNumber, Balance: FixedPointOperand, + MaxTranches: Get, { /// Currency that the pool is denominated in (immutable). pub currency: CurrencyId, /// List of tranches, ordered junior to senior. - pub tranches: Tranches, + pub tranches: Tranches, /// Details about the parameters of the pool. pub parameters: PoolParameters, /// Metadata that specifies the pool. @@ -181,8 +190,8 @@ where TrancheMetadata, MaxTranches, >::max_encoded_len()) - // From 4x Change Enum - .saturating_add(4) + // from 4x `Value` enum + .saturating_add(8 * 4) .saturating_add(Moment::max_encoded_len().saturating_mul(2)) } } @@ -221,7 +230,18 @@ pub struct PoolEssence< Vec>, } -impl +impl< + CurrencyId, + TrancheCurrency, + EpochId, + Balance, + Rate, + MetaSize, + Weight, + TrancheId, + PoolId, + MaxTranches, + > PoolDetails< CurrencyId, TrancheCurrency, @@ -232,6 +252,7 @@ impl where Balance: FixedPointOperand + BaseArithmetic + Unsigned + From, CurrencyId: Copy, @@ -242,6 +263,7 @@ impl, TrancheId: Clone + From<[u8; 16]> + PartialEq, Weight: Copy + From, + MaxTranches: Get, { pub fn start_next_epoch(&mut self, now: Moment) -> DispatchResult { self.epoch.current += One::one(); diff --git a/pallets/pool-system/src/solution.rs b/pallets/pool-system/src/solution.rs index 4e1737333e..95681383b3 100644 --- a/pallets/pool-system/src/solution.rs +++ b/pallets/pool-system/src/solution.rs @@ -14,7 +14,7 @@ use codec::MaxEncodedLen; use frame_support::sp_runtime::traits::Convert; use sp_arithmetic::traits::Unsigned; use sp_runtime::ArithmeticError; -use sp_std::vec; +use sp_std::{ops::Deref, vec}; use super::*; use crate::tranches::{calculate_risk_buffers, EpochExecutionTranches, TrancheSolution}; @@ -96,25 +96,48 @@ pub enum UnhealthyState { /// The solutions struct for epoch solution #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub enum EpochSolution { - Healthy(HealthySolution), - Unhealthy(UnhealthySolution), +pub enum EpochSolution +where + MaxTranches: Get, +{ + Healthy(HealthySolution), + Unhealthy(UnhealthySolution), } /// The information for a currently executing epoch #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct EpochExecutionInfo +pub struct EpochExecutionInfo< + Balance, + BalanceRatio, + EpochId, + Weight, + BlockNumber, + TrancheCurrency, + MaxEpocExecutionTranches, + MaxTranches, +> where + MaxEpocExecutionTranches: Get, + MaxTranches: Get, { pub epoch: EpochId, pub nav: Balance, pub reserve: Balance, pub max_reserve: Balance, - pub tranches: EpochExecutionTranches, - pub best_submission: Option>, + pub tranches: EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + TrancheCurrency, + MaxEpocExecutionTranches, + >, + pub best_submission: Option>, pub challenge_period_end: Option, } -impl EpochSolution { +impl EpochSolution +where + MaxTranches: Get, +{ /// Calculates the score for a given solution. Should only be called inside the /// `fn score_solution()` from the runtime, as there are no checks if solution /// length matches tranche length. @@ -131,14 +154,21 @@ impl EpochSolution { /// score = ||X||1 /// /// Returns error upon overflow of `Balances`. - pub fn calculate_score( + pub fn calculate_score( solution: &[TrancheSolution], - tranches: &EpochExecutionTranches, + tranches: &EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + TrancheCurrency, + MaxExecutionTranches, + >, ) -> Result where Balance: Zero + Copy + BaseArithmetic + Unsigned + From, Weight: Copy + From + Convert, BalanceRatio: Copy, + MaxExecutionTranches: Get, { let (invest_score, redeem_score) = solution .iter() @@ -174,36 +204,50 @@ impl EpochSolution { } /// Scores a solution and returns a healthy solution as a result. - pub fn score_solution_healthy( + pub fn score_solution_healthy( solution: &[TrancheSolution], - tranches: &EpochExecutionTranches, - ) -> Result, DispatchError> + tranches: &EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + TrancheCurrency, + MaxExecutionTranches, + >, + ) -> Result, DispatchError> where Balance: Zero + Copy + BaseArithmetic + Unsigned + From, Weight: Copy + From + Convert, BalanceRatio: Copy, + MaxExecutionTranches: Get, { let score = Self::calculate_score(solution, tranches)?; Ok(EpochSolution::Healthy(HealthySolution { - solution: solution.to_vec(), + solution: BoundedVec::truncate_from(solution.to_vec()), score, })) } /// Scores an solution, that would bring a pool into an unhealthy state. /// - pub fn score_solution_unhealthy( + pub fn score_solution_unhealthy( solution: &[TrancheSolution], - tranches: &EpochExecutionTranches, + tranches: &EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + TrancheCurrency, + MaxExecutionTranches, + >, reserve: Balance, max_reserve: Balance, state: &[UnhealthyState], - ) -> Result, DispatchError> + ) -> Result, DispatchError> where Weight: Copy + From, BalanceRatio: Copy + FixedPointNumber, Balance: Copy + BaseArithmetic + FixedPointOperand + Unsigned + From, + MaxExecutionTranches: Get, { let risk_buffer_improvement_scores = if state.contains(&UnhealthyState::MinRiskBufferViolated) { @@ -275,17 +319,19 @@ impl EpochSolution { }; Ok(EpochSolution::Unhealthy(UnhealthySolution { - state: state.to_vec(), - solution: solution.to_vec(), - risk_buffer_improvement_scores, + state: BoundedVec::truncate_from(state.to_vec()), + solution: BoundedVec::truncate_from(solution.to_vec()), + risk_buffer_improvement_scores: risk_buffer_improvement_scores + .map(|v| BoundedVec::truncate_from(v)), reserve_improvement_score, })) } } -impl EpochSolution +impl EpochSolution where Balance: Copy, + MaxTranches: Get, { pub fn healthy(&self) -> bool { match self { @@ -302,9 +348,10 @@ where } } -impl PartialOrd for EpochSolution +impl PartialOrd for EpochSolution where Balance: PartialOrd, + MaxTranches: Get + PartialOrd, { fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { @@ -318,14 +365,16 @@ where #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct HealthySolution { - pub solution: Vec, +pub struct HealthySolution> { + // TODO: Check depedency of Tranches, Solutions and States. E.g. can we use the same max bounds for multiple different bounded vecs? + pub solution: BoundedVec, pub score: Balance, } -impl PartialOrd for HealthySolution +impl PartialOrd for HealthySolution where Balance: PartialOrd, + MaxTranches: Get + PartialOrd, { fn partial_cmp(&self, other: &Self) -> Option { self.score.partial_cmp(&other.score) @@ -334,24 +383,29 @@ where #[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct UnhealthySolution { - pub state: Vec, - pub solution: Vec, +pub struct UnhealthySolution> { + // TODO: Check depedency of Tranches, Solutions and States. E.g. can we use the same max bounds for multiple different bounded vecs? + pub state: BoundedVec, + pub solution: BoundedVec, // The risk buffer score per tranche (less junior tranche) for this solution - pub risk_buffer_improvement_scores: Option>, + pub risk_buffer_improvement_scores: Option>, // The reserve buffer score for this solution pub reserve_improvement_score: Option, } -impl UnhealthySolution { +impl UnhealthySolution +where + MaxTranches: Get, +{ fn has_state(&self, state: &UnhealthyState) -> bool { - self.state.contains(state) + self.state.deref().contains(state) } } -impl PartialOrd for UnhealthySolution +impl PartialOrd for UnhealthySolution where Balance: PartialOrd, + MaxTranches: Get + PartialOrd, { fn partial_cmp(&self, other: &Self) -> Option { // We check if any of the risk buffer scores are higher. @@ -401,14 +455,28 @@ where } } -pub fn calculate_solution_parameters( - epoch_tranches: &EpochExecutionTranches, +pub fn calculate_solution_parameters< + Balance, + BalanceRatio, + Rate, + Weight, + Currency, + MaxEpocExecutionTranches, +>( + epoch_tranches: &EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + Currency, + MaxEpocExecutionTranches, + >, solution: &[TrancheSolution], ) -> Result<(Balance, Balance, Vec), DispatchError> where BalanceRatio: Copy + FixedPointNumber, Balance: Copy + BaseArithmetic + FixedPointOperand + Unsigned + From, Weight: Copy + From, + MaxEpocExecutionTranches: Get, { let acc_invest: Balance = epoch_tranches .residual_top_slice() @@ -450,17 +518,17 @@ mod test { } } - fn get_solution(fulfillments: Vec<(f64, f64)>) -> Vec { + fn get_solution(fulfillments: Vec<(f64, f64)>) -> BoundedVec> { let mut solutions = Vec::new(); fulfillments .into_iter() .for_each(|(invest, redeem)| solutions.push(get_tranche_solution(invest, redeem))); - solutions + BoundedVec::<_, ConstU32<10>>::truncate_from(solutions) } - fn get_full_solution() -> Vec { + fn get_full_solution() -> BoundedVec> { let mut solutions = Vec::new(); solutions.push(get_tranche_solution(1.0, 1.0)); @@ -468,7 +536,7 @@ mod test { solutions.push(get_tranche_solution(1.0, 1.0)); solutions.push(get_tranche_solution(1.0, 1.0)); - solutions + BoundedVec::<_, ConstU32<10>>::truncate_from(solutions) } #[test] @@ -564,7 +632,9 @@ mod test { assert!(solution.healthy()); let solution = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, @@ -581,7 +651,9 @@ mod test { assert!(solution.solution() == get_full_solution()); let solution = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, @@ -625,7 +697,9 @@ mod test { assert!(solution_1 != solution_2); let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, @@ -637,13 +711,17 @@ mod test { assert!(solution_1 != solution_2); let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, @@ -651,13 +729,17 @@ mod test { assert!(solution_1 == solution_2); let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, @@ -665,13 +747,17 @@ mod test { assert!(solution_1 != solution_2); let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_solution(vec![(0.0, 0.0), (1.0, 0.7), (0.7, 0.7)]), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, @@ -682,7 +768,9 @@ mod test { #[test] fn unhealthy_solution_has_state_works() { let unhealthy = UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: get_full_solution(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, @@ -711,13 +799,15 @@ mod test { #[test] fn healthy_always_above_unhealthy() { let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![ + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ UnhealthyState::MinRiskBufferViolated, UnhealthyState::MaxReserveViolated, - ], + ]), solution: Default::default(), reserve_improvement_score: Some(1000), - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); let solution_2 = EpochSolution::::Healthy(HealthySolution { @@ -730,14 +820,18 @@ mod test { #[test] fn reserve_improvement_better() { let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: Default::default(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: Default::default(), reserve_improvement_score: Some(6), risk_buffer_improvement_scores: None, @@ -749,7 +843,9 @@ mod test { #[test] fn no_reserve_violation_better() { let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: Default::default(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, @@ -768,17 +864,21 @@ mod test { #[test] fn no_risk_buff_violation_better() { let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![ + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, UnhealthyState::MinRiskBufferViolated, - ], + ]), solution: Default::default(), reserve_improvement_score: Some(5), - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MaxReserveViolated], + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + UnhealthyState::MaxReserveViolated, + ]), solution: Default::default(), reserve_improvement_score: Some(1000), risk_buffer_improvement_scores: None, @@ -790,23 +890,27 @@ mod test { #[test] fn reserve_improvement_decides_over_equal_min_risk_buff() { let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![ + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, UnhealthyState::MinRiskBufferViolated, - ], + ]), solution: Default::default(), reserve_improvement_score: Some(5), - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![ + state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, UnhealthyState::MinRiskBufferViolated, - ], + ]), solution: Default::default(), reserve_improvement_score: Some(6), - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); assert!(solution_1 < solution_2); @@ -818,7 +922,9 @@ mod test { state: vec![UnhealthyState::MinRiskBufferViolated], solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { @@ -834,7 +940,9 @@ mod test { state: vec![UnhealthyState::MinRiskBufferViolated], solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { @@ -850,14 +958,18 @@ mod test { state: vec![UnhealthyState::MinRiskBufferViolated], solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 4u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 2u128, 3u128, 4u128], + )), // 4 tranches }); let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { state: vec![UnhealthyState::MinRiskBufferViolated], solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(vec![1u128, 3u128, 3u128, 5u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + vec![1u128, 3u128, 3u128, 5u128], + )), // 4 tranches }); assert!(solution_1 < solution_2); diff --git a/pallets/pool-system/src/tranches.rs b/pallets/pool-system/src/tranches.rs index 706510a840..641f66597e 100644 --- a/pallets/pool-system/src/tranches.rs +++ b/pallets/pool-system/src/tranches.rs @@ -36,7 +36,7 @@ use sp_runtime::{ traits::{ConstU32, Member, One, Zero}, DispatchError, FixedPointNumber, FixedPointOperand, Perquintill, WeakBoundedVec, }; -use sp_std::{marker::PhantomData, vec::Vec}; +use sp_std::{marker::PhantomData, ops::Deref, vec::Vec}; use xcm::{ latest::MultiLocation, prelude::{GeneralKey, PalletInstance, Parachain, X3}, @@ -137,7 +137,7 @@ where pub token_symbol: BoundedVec, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct Tranche { pub tranche_type: TrancheType, pub seniority: Seniority, @@ -310,11 +310,12 @@ pub type TrancheIndex = u64; pub type TrancheSalt = (TrancheIndex, PoolId); #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct Tranches { - // FIXME: Move to BoundedVec - pub tranches: Vec>, - // FIXME: Move to BoundedVec - pub ids: Vec, +pub struct Tranches +where + MaxTranches: Get, +{ + pub tranches: BoundedVec, MaxTranches>, + pub ids: BoundedVec, pub salt: TrancheSalt, } @@ -345,23 +346,25 @@ impl Tranches } Ok(Self { - tranches, - ids, + tranches: BoundedVec::, MaxTranches>::truncate_from(tranches), + ids: BoundedVec::::truncate_from(ids), salt, }) } } // The solution struct for a specific tranche -#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Default, RuntimeDebug, TypeInfo)] +#[derive( + Encode, Decode, Copy, Clone, Eq, PartialEq, Default, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct TrancheSolution { pub invest_fulfillment: Perquintill, pub redeem_fulfillment: Perquintill, } -impl - Tranches +impl + Tranches where TrancheCurrency: Copy + TrancheCurrencyT, Balance: Zero + Copy + BaseArithmetic + FixedPointOperand + Unsigned + From, @@ -369,6 +372,7 @@ where Rate: One + Copy + FixedPointNumber, TrancheId: Clone + From<[u8; 16]> + sp_std::cmp::PartialEq, PoolId: Copy + Encode, + MaxTranches: Get, { pub fn from_input( pool: PoolId, @@ -379,8 +383,8 @@ where MaxTokenNameLength: Get, MaxTokenSymbolLength: Get, { - let tranches = Vec::with_capacity(tranche_inputs.len()); - let ids = Vec::with_capacity(tranche_inputs.len()); + let tranches = BoundedVec::with_bounded_capacity(tranche_inputs.len()); + let ids = BoundedVec::with_bounded_capacity(tranche_inputs.len()); let salt = (0, pool); let mut tranches = Tranches { tranches, @@ -409,7 +413,7 @@ where TrancheLoc::Index(index) => index .try_into() .ok() - .and_then(|index: usize| self.ids.get(index).cloned()), + .and_then(|index: usize| self.ids.deref().get(index).cloned()), } } @@ -461,7 +465,7 @@ where TrancheLoc::Index(index) => { let index: Option = index.try_into().ok(); if let Some(index) = index { - self.tranches.get(index) + self.tranches.deref().get(index) } else { None } @@ -471,7 +475,7 @@ where if let Some(index) = index { let index: Option = index.try_into().ok(); if let Some(index) = index { - self.tranches.get(index) + self.tranches.deref().get(index) } else { None } @@ -496,7 +500,7 @@ where /// -> tranche id = Twox128::hash(salt) fn next_id(&mut self) -> Result { let id = - Tranches::::id_from_salt( + Tranches::::id_from_salt( self.salt, ); self.salt = ( @@ -560,7 +564,7 @@ where let at_idx = at; let at: usize = at.try_into().map_err(|_| ArithmeticError::Overflow)?; ensure!( - at <= self.tranches.len(), + at <= self.tranches.deref().len(), DispatchError::Other( "Must add tranches either in between others or at the end. This should be catched somewhere else." ) @@ -593,8 +597,12 @@ where ) ); } - self.tranches.insert(at, new_tranche); - self.ids.insert(at, id); + self.tranches + .try_insert(at, new_tranche) + .expect("at is < len and either 0 or a previous element must exist. qed."); + self.ids + .try_insert(at, id) + .expect("at is < len and either 0 or a previous element must exist. qed."); Ok(()) } @@ -602,7 +610,7 @@ where pub fn remove(&mut self, at: TrancheIndex) -> DispatchResult { let at: usize = at.try_into().map_err(|_| ArithmeticError::Overflow)?; ensure!( - at < self.tranches.len(), + at < self.tranches.deref().len(), DispatchError::Other( "Invalid tranche index. Exceeding number of tranches. This should be catched somewhere else." ) @@ -615,7 +623,7 @@ where } pub fn ids_non_residual_top(&self) -> Vec { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); self.ids.iter().rev().for_each(|id| res.push(id.clone())); res } @@ -628,8 +636,8 @@ where where F: FnMut(&Tranche) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); - for tranche in self.tranches.iter().rev() { + let mut res = Vec::with_capacity(self.tranches.deref().len()); + for tranche in self.tranches.deref().iter().rev() { let r = f(tranche)?; res.push(r) } @@ -640,7 +648,7 @@ where where F: FnMut(&mut Tranche) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); for tranche in self.tranches.iter_mut().rev() { let r = f(tranche)?; res.push(r) @@ -657,7 +665,7 @@ where F: FnMut(&Tranche, W) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); let iter = self.tranches.iter().rev().zip(with.into_iter()); for (tranche, w) in iter { @@ -680,7 +688,7 @@ where ) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); let iter = self.tranches.iter_mut().rev().zip(with.into_iter()); for (tranche, w) in iter { @@ -692,15 +700,15 @@ where } pub fn ids_residual_top(&self) -> Vec { - self.ids.clone() + self.ids.clone().into_inner() } pub fn combine_residual_top(&self, mut f: F) -> Result, DispatchError> where F: FnMut(&Tranche) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); - for tranche in self.tranches.iter() { + let mut res = Vec::with_capacity(self.tranches.deref().len()); + for tranche in self.tranches.deref().iter() { let r = f(tranche)?; res.push(r) } @@ -711,7 +719,7 @@ where where F: FnMut(&mut Tranche) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); for tranche in self.tranches.iter_mut() { let r = f(tranche)?; res.push(r) @@ -728,8 +736,8 @@ where F: FnMut(&Tranche, W) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); - let iter = self.tranches.iter().zip(with.into_iter()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); + let iter = self.tranches.deref().iter().zip(with.into_iter()); for (tranche, w) in iter { let r = f(tranche, w)?; @@ -751,7 +759,7 @@ where ) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); // TODO: Would be nice to error out when with is larger than tranches... let iter = self.tranches.iter_mut().zip(with.into_iter()); @@ -815,17 +823,19 @@ where } pub fn num_tranches(&self) -> usize { - self.tranches.len() + self.tranches.deref().len() } - pub fn into_tranches(self) -> Vec> { + pub fn into_tranches( + self, + ) -> BoundedVec, MaxTranches> { self.tranches } pub fn non_residual_tranches( &self, ) -> Option<&[Tranche]> { - if let Some((_head, tail)) = self.tranches.as_slice().split_first() { + if let Some((_head, tail)) = self.tranches.deref().as_slice().split_first() { Some(tail) } else { None @@ -835,7 +845,7 @@ where pub fn non_residual_tranches_mut( &mut self, ) -> Option<&mut [Tranche]> { - if let Some((_head, tail)) = self.tranches.as_mut_slice().split_first_mut() { + if let Some((_head, tail)) = self.tranches.as_mut().split_first_mut() { Some(tail) } else { None @@ -843,7 +853,7 @@ where } pub fn residual_tranche(&self) -> Option<&Tranche> { - if let Some((head, _tail)) = self.tranches.as_slice().split_first() { + if let Some((head, _tail)) = self.tranches.deref().as_slice().split_first() { Some(head) } else { None @@ -853,7 +863,7 @@ where pub fn residual_tranche_mut( &mut self, ) -> Option<&mut Tranche> { - if let Some((head, _tail)) = self.tranches.as_mut_slice().split_first_mut() { + if let Some((head, _tail)) = self.tranches.as_mut().split_first_mut() { Some(head) } else { None @@ -863,23 +873,23 @@ where pub fn non_residual_top_slice( &self, ) -> &RevSlice> { - self.tranches.rev() + self.tranches.deref().rev() } pub fn non_residual_top_slice_mut( &mut self, ) -> &mut RevSlice> { - self.tranches.rev_mut() + self.tranches.as_mut().rev_mut() } pub fn residual_top_slice(&self) -> &[Tranche] { - self.tranches.as_slice() + self.tranches.deref().as_slice() } pub fn residual_top_slice_mut( &mut self, ) -> &mut [Tranche] { - self.tranches.as_mut_slice() + self.tranches.as_mut() } pub fn supplies(&self) -> Result, DispatchError> { @@ -1027,29 +1037,42 @@ impl Default for EpochExecutionTranche { - // FIXME: Convert to BoundedVec - pub tranches: Vec>, +pub struct EpochExecutionTranches< + Balance, + BalanceRatio, + Weight, + TrancheCurrency, + MaxEpocExecutionTranches, +> where + MaxEpocExecutionTranches: Get, +{ + pub tranches: BoundedVec< + EpochExecutionTranche, + MaxEpocExecutionTranches, + >, } /// Utility implementations for `EpochExecutionTranches` -impl - EpochExecutionTranches +impl + EpochExecutionTranches where Balance: Zero + Copy + BaseArithmetic + Unsigned + From, Weight: Copy + From, BalanceRatio: Copy, + MaxEpocExecutionTranches: Get, { pub fn new( tranches: Vec>, ) -> Self { - Self { tranches } + Self { + tranches: BoundedVec::truncate_from(tranches), + } } pub fn non_residual_tranches( &self, ) -> Option<&[EpochExecutionTranche]> { - if let Some((_head, tail)) = self.tranches.as_slice().split_first() { + if let Some((_head, tail)) = self.tranches.deref().as_slice().split_first() { Some(tail) } else { None @@ -1059,7 +1082,7 @@ where pub fn non_residual_tranches_mut( &mut self, ) -> Option<&mut [EpochExecutionTranche]> { - if let Some((_head, tail)) = self.tranches.as_mut_slice().split_first_mut() { + if let Some((_head, tail)) = self.tranches.as_mut().split_first_mut() { Some(tail) } else { None @@ -1069,7 +1092,7 @@ where pub fn residual_tranche( &self, ) -> Option<&EpochExecutionTranche> { - if let Some((head, _tail)) = self.tranches.as_slice().split_first() { + if let Some((head, _tail)) = self.tranches.deref().as_slice().split_first() { Some(head) } else { None @@ -1079,7 +1102,7 @@ where pub fn residual_tranche_mut( &mut self, ) -> Option<&mut EpochExecutionTranche> { - if let Some((head, _tail)) = self.tranches.as_mut_slice().split_first_mut() { + if let Some((head, _tail)) = self.tranches.as_mut().split_first_mut() { Some(head) } else { None @@ -1087,37 +1110,40 @@ where } pub fn num_tranches(&self) -> usize { - self.tranches.len() + self.tranches.deref().len() } pub fn into_tranches( self, - ) -> Vec> { + ) -> BoundedVec< + EpochExecutionTranche, + MaxEpocExecutionTranches, + > { self.tranches } pub fn non_residual_top_slice( &self, ) -> &RevSlice> { - self.tranches.rev() + self.tranches.deref().rev() } pub fn non_residual_top_slice_mut( &mut self, ) -> &mut RevSlice> { - self.tranches.rev_mut() + self.tranches.as_mut().rev_mut() } pub fn residual_top_slice( &self, ) -> &[EpochExecutionTranche] { - self.tranches.as_slice() + self.tranches.deref().as_slice() } pub fn residual_top_slice_mut( &mut self, ) -> &mut [EpochExecutionTranche] { - self.tranches.as_mut_slice() + self.tranches.as_mut() } pub fn combine_non_residual_top(&self, mut f: F) -> Result, DispatchError> @@ -1126,8 +1152,8 @@ where &EpochExecutionTranche, ) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); - for tranche in self.tranches.iter().rev() { + let mut res = Vec::with_capacity(self.tranches.deref().len()); + for tranche in self.tranches.deref().iter().rev() { let r = f(tranche)?; res.push(r) } @@ -1140,7 +1166,7 @@ where &mut EpochExecutionTranche, ) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); for tranche in &mut self.tranches.iter_mut().rev() { let r = f(tranche)?; res.push(r) @@ -1160,7 +1186,7 @@ where ) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); let iter = self.tranches.iter().rev().zip(with.into_iter()); for (tranche, w) in iter { @@ -1183,7 +1209,7 @@ where ) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); let iter = self.tranches.iter_mut().rev().zip(with.into_iter()); for (tranche, w) in iter { @@ -1200,8 +1226,8 @@ where &EpochExecutionTranche, ) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); - for tranche in self.tranches.iter() { + let mut res = Vec::with_capacity(self.tranches.deref().len()); + for tranche in self.tranches.deref().iter() { let r = f(tranche)?; res.push(r) } @@ -1214,7 +1240,7 @@ where &mut EpochExecutionTranche, ) -> Result, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); for tranche in self.tranches.iter_mut() { let r = f(tranche)?; res.push(r) @@ -1234,8 +1260,8 @@ where ) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); - let iter = self.tranches.iter().zip(with.into_iter()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); + let iter = self.tranches.deref().iter().zip(with.into_iter()); for (tranche, w) in iter { let r = f(tranche, w)?; @@ -1257,7 +1283,7 @@ where ) -> Result, I: IntoIterator, { - let mut res = Vec::with_capacity(self.tranches.len()); + let mut res = Vec::with_capacity(self.tranches.deref().len()); let iter = self.tranches.iter_mut().zip(with.into_iter()); for (tranche, w) in iter { @@ -1270,12 +1296,13 @@ where } /// Business logic implementations for `EpochExecutionTranches` -impl - EpochExecutionTranches +impl + EpochExecutionTranches where Balance: Zero + Copy + BaseArithmetic + Unsigned + From, Weight: Copy + From, BalanceRatio: Copy, + MaxEpocExecutionTranches: Get, { pub fn prices(&self) -> Vec { self.tranches.iter().map(|tranche| tranche.price).collect() diff --git a/runtime/common/src/apis/pools.rs b/runtime/common/src/apis/pools.rs index 958b4bdf44..c370c03a32 100644 --- a/runtime/common/src/apis/pools.rs +++ b/runtime/common/src/apis/pools.rs @@ -16,6 +16,7 @@ use pallet_pool_system::{ EpochSolution, }; use sp_api::decl_runtime_apis; +use sp_runtime::traits::Get; use sp_std::vec::Vec; decl_runtime_apis! { @@ -23,17 +24,18 @@ decl_runtime_apis! { /// /// Note: The runtime api is pallet specific, while the RPC methods /// are more focused on domain-specific logic - pub trait PoolsApi + pub trait PoolsApi where PoolId: Codec, TrancheId: Codec, Balance: Codec, Currency: Codec, BalanceRatio: Codec, + MaxTranches: Get, { fn currency(pool_id: PoolId) -> Option; - fn inspect_epoch_solution(pool_id: PoolId, solution: Vec) -> Option>; + fn inspect_epoch_solution(pool_id: PoolId, solution: Vec) -> Option>; fn tranche_token_price(pool_id: PoolId, tranche: TrancheLoc) -> Option; From c759b7614110ddec4b054b5a9e65ac70b62ac40c Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Mon, 9 Jan 2023 12:03:57 +0100 Subject: [PATCH 04/12] fix: make it compile for default features --- libs/traits/src/lib.rs | 12 +++- libs/types/src/fee_keys.rs | 4 +- libs/types/src/fixed_point.rs | 3 +- libs/types/src/permissions.rs | 55 +++++++++++-------- pallets/connectors/src/lib.rs | 13 +++-- pallets/connectors/src/routers.rs | 31 +++++++++-- pallets/loans/src/lib.rs | 15 +++-- pallets/loans/src/loan_type.rs | 9 +-- pallets/loans/src/mock.rs | 4 +- pallets/loans/src/types.rs | 25 ++++++--- pallets/permissions/src/lib.rs | 4 ++ pallets/pool-registry/src/lib.rs | 4 +- pallets/pool-system/src/mock.rs | 4 +- runtime/altair/src/lib.rs | 14 +++-- runtime/common/src/apis/pools.rs | 2 +- runtime/development/src/lib.rs | 14 +++-- .../src/xcm/development/tests/connectors.rs | 4 +- src/rpc/pools.rs | 22 +++++--- 18 files changed, 163 insertions(+), 76 deletions(-) diff --git a/libs/traits/src/lib.rs b/libs/traits/src/lib.rs index ecc620f4ad..3fd1931348 100644 --- a/libs/traits/src/lib.rs +++ b/libs/traits/src/lib.rs @@ -114,8 +114,16 @@ pub trait PoolNAV { /// A trait that support pool inspection operations such as pool existence checks and pool admin of permission set. pub trait PoolInspect { - type PoolId: Parameter + Member + Debug + Copy + Default + TypeInfo + Encode + Decode; - type TrancheId: Parameter + Member + Debug + Copy + Default + TypeInfo; + type PoolId: Parameter + + Member + + Debug + + Copy + + Default + + TypeInfo + + Encode + + Decode + + MaxEncodedLen; + type TrancheId: Parameter + Member + Debug + Copy + Default + TypeInfo + MaxEncodedLen; type Rate; type Moment; diff --git a/libs/types/src/fee_keys.rs b/libs/types/src/fee_keys.rs index b1c8294bb3..def3c0bb53 100644 --- a/libs/types/src/fee_keys.rs +++ b/libs/types/src/fee_keys.rs @@ -10,7 +10,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::RuntimeDebug; use scale_info::TypeInfo; #[cfg(feature = "std")] @@ -19,7 +19,7 @@ use sp_std::cmp::PartialEq; /// Different fees keys available. /// Each variant represents a balance previously determined and configured. -#[derive(Encode, Decode, Clone, Copy, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Clone, Copy, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum FeeKey { /// Key to identify the balance reserved for the author. diff --git a/libs/types/src/fixed_point.rs b/libs/types/src/fixed_point.rs index cd57d82fea..5362b34c73 100644 --- a/libs/types/src/fixed_point.rs +++ b/libs/types/src/fixed_point.rs @@ -18,7 +18,7 @@ //! Decimal Fixed Point implementations for Substrate runtime. //! Copied over from sp_arithmetic -use codec::{CompactAs, Decode, Encode}; +use codec::{CompactAs, Decode, Encode, MaxEncodedLen}; #[cfg(feature = "std")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use sp_arithmetic::{ @@ -430,6 +430,7 @@ pub trait FixedPointNumberExtension: FixedPointNumber { PartialOrd, Ord, scale_info::TypeInfo, + MaxEncodedLen, )] pub struct Rate(u128); diff --git a/libs/types/src/permissions.rs b/libs/types/src/permissions.rs index 755e44b45a..e28b5c548e 100644 --- a/libs/types/src/permissions.rs +++ b/libs/types/src/permissions.rs @@ -11,10 +11,11 @@ // GNU General Public License for more details. use cfg_traits::Properties; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ sp_runtime::traits::Saturating, traits::{Get, UnixTime}, + BoundedVec, }; use scale_info::TypeInfo; #[cfg(feature = "std")] @@ -22,7 +23,6 @@ use serde::{Deserialize, Serialize}; use sp_std::{ cmp::{Ord, PartialEq, PartialOrd}, marker::PhantomData, - vec::Vec, }; /// PoolRole can hold any type of role specific functions a user can do on a given pool. @@ -64,7 +64,7 @@ pub enum Role { PermissionedCurrencyRole(PermissionedCurrencyRole), } -#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, TypeInfo, Debug)] +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, TypeInfo, Debug, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum PermissionScope { Pool(PoolId), @@ -85,7 +85,7 @@ where bitflags::bitflags! { /// The current admin roles we support - #[derive(codec::Encode, codec::Decode, TypeInfo)] + #[derive(codec::Encode, codec::Decode, TypeInfo, MaxEncodedLen)] pub struct PoolAdminRoles: u32 { const POOL_ADMIN = 0b00000001; const BORROWER = 0b00000010; @@ -96,44 +96,44 @@ bitflags::bitflags! { } /// The current admin roles we support - #[derive(codec::Encode, codec::Decode, TypeInfo)] + #[derive(codec::Encode, codec::Decode, TypeInfo, MaxEncodedLen)] pub struct CurrencyAdminRoles: u32 { const PERMISSIONED_ASSET_MANAGER = 0b00000001; const PERMISSIONED_ASSET_ISSUER = 0b00000010; } } -#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq)] +#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq, MaxEncodedLen)] pub struct PermissionedCurrencyHolderInfo { permissioned_till: Moment, } -#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq)] +#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq, MaxEncodedLen)] pub struct TrancheInvestorInfo { tranche_id: TrancheId, permissioned_till: Moment, } -#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq)] +#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq, MaxEncodedLen)] pub struct PermissionedCurrencyHolders { info: Option>, _phantom: PhantomData<(Now, MinDelay)>, } -#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq)] -pub struct TrancheInvestors { - info: Vec>, +#[derive(Encode, Decode, TypeInfo, Debug, Clone, Eq, PartialEq, MaxEncodedLen)] +pub struct TrancheInvestors> { + info: BoundedVec, MaxTranches>, _phantom: PhantomData<(Now, MinDelay)>, } /// The structure that we store in the pallet-permissions storage /// This here implements trait Properties. -#[derive(Encode, Decode, TypeInfo, Clone, Eq, PartialEq, Debug)] -pub struct PermissionRoles { +#[derive(Encode, Decode, TypeInfo, Clone, Eq, PartialEq, Debug, MaxEncodedLen)] +pub struct PermissionRoles, Moment = u64> { pool_admin: PoolAdminRoles, currency_admin: CurrencyAdminRoles, permissioned_asset_holder: PermissionedCurrencyHolders, - tranche_investor: TrancheInvestors, + tranche_investor: TrancheInvestors, } impl Default for PermissionedCurrencyHolders @@ -150,28 +150,31 @@ where } } -impl Default - for TrancheInvestors +impl Default + for TrancheInvestors where Now: UnixTime, MinDelay: Get, Moment: From + PartialEq + PartialOrd + Saturating + Ord, TrancheId: PartialEq + PartialOrd, + MaxTranches: Get, { fn default() -> Self { Self { - info: Vec::default(), + info: BoundedVec::default(), _phantom: Default::default(), } } } -impl Default for PermissionRoles +impl Default + for PermissionRoles where Now: UnixTime, MinDelay: Get, Moment: From + PartialEq + PartialOrd + Saturating + Ord, TrancheId: PartialEq + PartialOrd, + MaxTranches: Get, { fn default() -> Self { Self { @@ -179,7 +182,8 @@ where currency_admin: CurrencyAdminRoles::empty(), permissioned_asset_holder: PermissionedCurrencyHolders::::default(), - tranche_investor: TrancheInvestors::::default(), + tranche_investor: + TrancheInvestors::::default(), } } } @@ -189,13 +193,14 @@ where /// This UNION shall reflect that and explain to the reader why it is passed here. pub const UNION: u64 = 0; -impl Properties - for PermissionRoles +impl Properties + for PermissionRoles where Now: UnixTime, MinDelay: Get, Moment: From + PartialEq + PartialOrd + Saturating + Ord + Copy, TrancheId: PartialEq + PartialOrd, + MaxTranches: Get, { type Error = (); type Ok = (); @@ -373,12 +378,14 @@ where } } -impl TrancheInvestors +impl + TrancheInvestors where Now: UnixTime, MinDelay: Get, Moment: From + PartialEq + PartialOrd + Saturating + Ord + Copy, TrancheId: PartialEq + PartialOrd, + MaxTranches: Get, { pub fn empty() -> Self { Self::default() @@ -435,10 +442,10 @@ where Ok(self.info[index].permissioned_till = validity) } } else { - Ok(self.info.push(TrancheInvestorInfo { + self.info.try_push(TrancheInvestorInfo { tranche_id: tranche, permissioned_till: validity, - })) + }) } } } diff --git a/pallets/connectors/src/lib.rs b/pallets/connectors/src/lib.rs index 37f23492e2..ed62dcb571 100644 --- a/pallets/connectors/src/lib.rs +++ b/pallets/connectors/src/lib.rs @@ -15,7 +15,7 @@ use core::convert::TryFrom; use cfg_traits::PoolInspect; use cfg_utils::vec_to_fixed_array; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::traits::{ fungibles::{Inspect, Mutate, Transfer}, OriginTrait, @@ -38,7 +38,7 @@ mod contract; pub use contract::*; /// The Parachains that Centrifuge Connectors support. -#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub enum ParachainId { /// Moonbeam - It may be Moonbeam on Polkadot, Moonriver on Kusama, or Moonbase on a testnet. @@ -53,7 +53,7 @@ type EVMChainId = u64; /// 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, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub enum Domain { /// An EVM domain, identified by its EVM Chain Id @@ -456,7 +456,12 @@ pub mod pallet { ) -> Vec { let mut encoded: Vec = Vec::new(); - encoded.append(&mut xcm_domain.ethereum_xcm_transact_call_index.clone()); + encoded.append( + &mut xcm_domain + .ethereum_xcm_transact_call_index + .clone() + .into_inner(), + ); encoded.append( &mut xcm_primitives::EthereumXcmTransaction::V1( xcm_primitives::EthereumXcmTransactionV1 { diff --git a/pallets/connectors/src/routers.rs b/pallets/connectors/src/routers.rs index 5f1d170f6a..b138cd9d9c 100644 --- a/pallets/connectors/src/routers.rs +++ b/pallets/connectors/src/routers.rs @@ -1,10 +1,10 @@ -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; use sp_core::H160; -use sp_std::vec::Vec; +use sp_runtime::{traits::ConstU32, BoundedVec}; use xcm::VersionedMultiLocation; -#[derive(Encode, Decode, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Debug))] pub enum Router { // An XCM-based router @@ -22,9 +22,32 @@ pub struct XcmDomain { /// It should contain the pallet index + the `transact` call index, to which /// we will append the eth_tx param. You can obtain this value by building /// an ethereum_xcm::transact call with Polkadot JS on the target chain. - pub ethereum_xcm_transact_call_index: Vec, + pub ethereum_xcm_transact_call_index: + BoundedVec>, /// The ConnectorsXcmRouter contract address on a given domain pub contract_address: H160, /// The currency in which execution fees will be paid on pub fee_currency: CurrencyId, } + +/// FIXME: Remove this custom implementation once the following underlying data implements MaxEncodedLen: +/// * Polkadot Repo: xcm::VersionedMultiLocation +/// * PureStake Repo: pallet_xcm_transactor::Config::CurrencyId +impl MaxEncodedLen for XcmDomain +where + XcmDomain: Encode, +{ + fn max_encoded_len() -> usize { + // custom mel bound for `VersionedMultiLocation` + xcm::v1::MultiLocation::max_encoded_len() + // VersionedMultiLocation is binary enum + .saturating_add(2) + .saturating_add(BoundedVec::< + u8, + ConstU32<{ xcm_primitives::MAX_ETHEREUM_XCM_INPUT_SIZE }>, + >::max_encoded_len()) + // custom mel bound for CurrencyId + .saturating_add(cfg_types::tokens::CurrencyId::max_encoded_len()) + .saturating_add(H160::max_encoded_len()) + } +} diff --git a/pallets/loans/src/lib.rs b/pallets/loans/src/lib.rs index a204c29de3..f986424097 100644 --- a/pallets/loans/src/lib.rs +++ b/pallets/loans/src/lib.rs @@ -98,7 +98,8 @@ pub mod pallet { + Copy + Default + TypeInfo - + IsType>; + + IsType> + + MaxEncodedLen; /// The LoanId/InstanceId type type LoanId: Parameter @@ -107,10 +108,16 @@ pub mod pallet { + Copy + TypeInfo + From - + IsType>; + + IsType> + + MaxEncodedLen; /// the rate type - type Rate: Parameter + Member + MaybeSerializeDeserialize + FixedPointNumber + TypeInfo; + type Rate: Parameter + + Member + + MaybeSerializeDeserialize + + FixedPointNumber + + TypeInfo + + MaxEncodedLen; type Balance: Member + Parameter @@ -137,7 +144,7 @@ pub mod pallet { /// Pool reserve type type Pool: PoolReserve; - type CurrencyId: Parameter + Copy; + type CurrencyId: Parameter + Copy + MaxEncodedLen; /// Permission type that verifies permissions of users type Permission: PermissionsT< diff --git a/pallets/loans/src/loan_type.rs b/pallets/loans/src/loan_type.rs index d4d0a63d11..819ccbcf5f 100644 --- a/pallets/loans/src/loan_type.rs +++ b/pallets/loans/src/loan_type.rs @@ -12,12 +12,13 @@ // GNU General Public License for more details. //! Module provides functionality for different loan types +use codec::MaxEncodedLen; use scale_info::TypeInfo; use super::*; /// different types of loans -#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(any(feature = "std", feature = "runtime-benchmarks"), derive(Debug))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum LoanType { @@ -49,7 +50,7 @@ where } /// The data structure for Bullet loan type -#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(any(feature = "std", feature = "runtime-benchmarks"), derive(Debug))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct BulletLoan { @@ -127,7 +128,7 @@ where } /// The data structure for Credit line loan type -#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(any(feature = "std", feature = "runtime-benchmarks"), derive(Debug))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct CreditLine { @@ -169,7 +170,7 @@ impl CreditLine { } /// The data structure for Credit line with maturity loan type -#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(any(feature = "std", feature = "runtime-benchmarks"), derive(Debug))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct CreditLineWithMaturity { diff --git a/pallets/loans/src/mock.rs b/pallets/loans/src/mock.rs index d7655c6de8..c882e4a28f 100644 --- a/pallets/loans/src/mock.rs +++ b/pallets/loans/src/mock.rs @@ -339,9 +339,11 @@ impl pallet_permissions::Config for Runtime { type Editors = Everything; type Event = Event; type MaxRolesPerScope = MaxRoles; + type MaxTranches = MaxTranches; type Role = Role; type Scope = PermissionScope; - type Storage = PermissionRoles, MinDelay, TrancheId, Moment>; + type Storage = + PermissionRoles, MinDelay, TrancheId, MaxTranches, Moment>; type WeightInfo = (); } diff --git a/pallets/loans/src/types.rs b/pallets/loans/src/types.rs index 89dc1a9dc7..ce02496f0c 100644 --- a/pallets/loans/src/types.rs +++ b/pallets/loans/src/types.rs @@ -13,6 +13,7 @@ //! Module provides base types and their functions use cfg_traits::PoolInspect; +use codec::MaxEncodedLen; use frame_support::RuntimeDebug; use scale_info::TypeInfo; use sp_arithmetic::traits::Zero; @@ -20,7 +21,7 @@ use sp_arithmetic::traits::Zero; use super::*; /// Asset that represents a non fungible -#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, Default, Debug, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, Default, Debug, TypeInfo, MaxEncodedLen)] pub struct Asset(pub ClassId, pub InstanceId); impl Asset { @@ -37,7 +38,9 @@ pub(crate) struct ClosedLoan { } /// The data structure for storing pool nav details -#[derive(Encode, Decode, Copy, Clone, PartialEq, Default, RuntimeDebug, TypeInfo)] +#[derive( + Encode, Decode, Copy, Clone, PartialEq, Default, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct NAVDetails { // this is the latest nav for the given pool. @@ -54,7 +57,9 @@ pub struct NAVDetails { } /// The data structure for storing a specific write off group -#[derive(Encode, Decode, Copy, Clone, PartialEq, Default, RuntimeDebug, TypeInfo)] +#[derive( + Encode, Decode, Copy, Clone, PartialEq, Default, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct WriteOffGroup { /// percentage of outstanding debt we are going to write off on a loan @@ -68,7 +73,9 @@ pub struct WriteOffGroup { } /// The data structure as input for creating a write-off group -#[derive(Encode, Decode, Copy, Clone, PartialEq, Default, RuntimeDebug, TypeInfo)] +#[derive( + Encode, Decode, Copy, Clone, PartialEq, Default, RuntimeDebug, TypeInfo, MaxEncodedLen, +)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub struct WriteOffGroupInput { /// percentage of outstanding debt we are going to write off on a loan @@ -81,7 +88,7 @@ pub struct WriteOffGroupInput { pub(crate) penalty_interest_rate_per_year: Rate, } -#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(any(feature = "std", feature = "runtime-benchmarks"), derive(Debug))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum WriteOffStatus { @@ -111,7 +118,7 @@ pub enum WriteOffAction { } /// The data structure for storing loan status -#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, PartialEq, TypeInfo, MaxEncodedLen)] #[cfg_attr(any(feature = "std", feature = "runtime-benchmarks"), derive(Debug))] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] pub enum LoanStatus { @@ -136,14 +143,14 @@ pub enum NAVUpdateType { } /// The data structure for storing loan info -#[derive(Encode, Decode, Copy, Clone, RuntimeDebug, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct LoanDetails { +pub struct LoanDetails { pub(crate) collateral: Asset, pub(crate) status: LoanStatus, } -#[derive(Encode, Decode, Copy, Clone, TypeInfo)] +#[derive(Encode, Decode, Copy, Clone, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))] pub struct PricedLoanDetails { pub(crate) loan_id: LoanId, diff --git a/pallets/permissions/src/lib.rs b/pallets/permissions/src/lib.rs index 2c7f285105..d9544b1578 100644 --- a/pallets/permissions/src/lib.rs +++ b/pallets/permissions/src/lib.rs @@ -65,6 +65,10 @@ pub mod pallet { #[pallet::constant] type MaxRolesPerScope: Get; + /// The maximum number of tranche investors. + #[pallet::constant] + type MaxTranches: Get; + type WeightInfo: WeightInfo; } diff --git a/pallets/pool-registry/src/lib.rs b/pallets/pool-registry/src/lib.rs index 4381604149..f98516d409 100644 --- a/pallets/pool-registry/src/lib.rs +++ b/pallets/pool-registry/src/lib.rs @@ -44,7 +44,7 @@ where pub token_symbol: BoundedVec, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub struct PoolMetadata where MetaSize: Get, @@ -52,7 +52,7 @@ where metadata: BoundedVec, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] pub enum PoolRegistrationStatus { Registered, Unregistered, diff --git a/pallets/pool-system/src/mock.rs b/pallets/pool-system/src/mock.rs index 4f4d190a91..7507eac108 100644 --- a/pallets/pool-system/src/mock.rs +++ b/pallets/pool-system/src/mock.rs @@ -81,9 +81,11 @@ impl pallet_permissions::Config for Runtime { type Editors = frame_support::traits::Everything; type Event = Event; type MaxRolesPerScope = MaxRoles; + type MaxTranches = MaxTranches; type Role = Role; type Scope = PermissionScope; - type Storage = PermissionRoles, MinDelay, TrancheId, Moment>; + type Storage = + PermissionRoles, MinDelay, TrancheId, MaxTranches, Moment>; type WeightInfo = (); } diff --git a/runtime/altair/src/lib.rs b/runtime/altair/src/lib.rs index 3997bb48e7..c0fee685c7 100644 --- a/runtime/altair/src/lib.rs +++ b/runtime/altair/src/lib.rs @@ -855,7 +855,8 @@ impl pallet_collator_selection::Config for Runtime { } parameter_types! { - #[derive(Debug, Eq, PartialEq, scale_info::TypeInfo, Clone)] + #[derive(Encode, Decode, Debug, Eq, PartialEq, PartialOrd, scale_info::TypeInfo, Clone)] + #[cfg_attr(feature = "std", derive(frame_support::Serialize, frame_support::Deserialize))] pub const MaxTranches: u32 = 5; // How much time should lapse before a tranche investor can be removed @@ -871,9 +872,11 @@ impl pallet_permissions::Config for Runtime { type Editors = Editors; type Event = Event; type MaxRolesPerScope = MaxRolesPerPool; + type MaxTranches = MaxTranches; type Role = Role; type Scope = PermissionScope; - type Storage = PermissionRoles, MinDelay, TrancheId, Moment>; + type Storage = + PermissionRoles, MinDelay, TrancheId, MaxTranches, Moment>; type WeightInfo = weights::pallet_permissions::WeightInfo; } @@ -1113,6 +1116,8 @@ impl pallet_pool_system::Config for Runtime { type EpochId = PoolEpochId; type Event = Event; type Investments = Investments; + // FIXME: Correct value + type MaxEpocExecutionTranches = MaxTranches; type MaxNAVAgeUpperBound = MaxNAVAgeUpperBound; type MaxSizeMetadata = MaxSizeMetadata; type MaxTokenNameLength = MaxTrancheNameLengthBytes; @@ -1166,6 +1171,7 @@ impl PoolUpdateGuard for UpdateGuard { TrancheWeight, TrancheId, PoolId, + MaxTranches, >; type ScheduledUpdateDetails = ScheduledUpdateDetails< Rate, @@ -1513,12 +1519,12 @@ impl_runtime_apis! { } } - impl runtime_common::apis::PoolsApi for Runtime { + impl runtime_common::apis::PoolsApi for Runtime { fn currency(pool_id: PoolId) -> Option{ pallet_pool_system::Pool::::get(pool_id).map(|details| details.currency) } - fn inspect_epoch_solution(pool_id: PoolId, solution: Vec) -> Option>{ + fn inspect_epoch_solution(pool_id: PoolId, solution: Vec) -> Option>{ let pool = pallet_pool_system::Pool::::get(pool_id)?; let epoch_execution_info = pallet_pool_system::EpochExecution::::get(pool_id)?; pallet_pool_system::Pallet::::score_solution( diff --git a/runtime/common/src/apis/pools.rs b/runtime/common/src/apis/pools.rs index c370c03a32..5ba5a6e474 100644 --- a/runtime/common/src/apis/pools.rs +++ b/runtime/common/src/apis/pools.rs @@ -31,7 +31,7 @@ decl_runtime_apis! { Balance: Codec, Currency: Codec, BalanceRatio: Codec, - MaxTranches: Get, + MaxTranches: Codec + Get, { fn currency(pool_id: PoolId) -> Option; diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index 7239ea9b34..44d047a08e 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -911,6 +911,8 @@ impl pallet_pool_system::Config for Runtime { type EpochId = PoolEpochId; type Event = Event; type Investments = Investments; + // FIXME: Assign correct value + type MaxEpocExecutionTranches = MaxTranches; type MaxNAVAgeUpperBound = MaxNAVAgeUpperBound; type MaxSizeMetadata = MaxSizeMetadata; type MaxTokenNameLength = MaxTrancheNameLengthBytes; @@ -982,6 +984,7 @@ impl PoolUpdateGuard for UpdateGuard { TrancheWeight, TrancheId, PoolId, + MaxTranches, >; type ScheduledUpdateDetails = ScheduledUpdateDetails< Rate, @@ -1205,7 +1208,8 @@ impl pallet_loans::Config for Runtime { } parameter_types! { - #[derive(Debug, Eq, PartialEq, scale_info::TypeInfo, Clone)] + #[derive(Encode, Decode, Debug, Eq, PartialEq, PartialOrd, scale_info::TypeInfo, Clone)] + #[cfg_attr(feature = "std", derive(frame_support::Serialize, frame_support::Deserialize))] pub const MaxTranches: u32 = 5; // How much time should lapse before a tranche investor can be removed @@ -1221,9 +1225,11 @@ impl pallet_permissions::Config for Runtime { type Editors = Editors; type Event = Event; type MaxRolesPerScope = MaxRolesPerPool; + type MaxTranches = MaxTranches; type Role = Role; type Scope = PermissionScope; - type Storage = PermissionRoles, MinDelay, TrancheId, Moment>; + type Storage = + PermissionRoles, MinDelay, TrancheId, MaxTranches, Moment>; type WeightInfo = weights::pallet_permissions::WeightInfo; } @@ -1854,12 +1860,12 @@ impl_runtime_apis! { } // PoolsApi - impl runtime_common::apis::PoolsApi for Runtime { + impl runtime_common::apis::PoolsApi for Runtime { fn currency(pool_id: PoolId) -> Option{ pallet_pool_system::Pool::::get(pool_id).map(|details| details.currency) } - fn inspect_epoch_solution(pool_id: PoolId, solution: Vec) -> Option>{ + fn inspect_epoch_solution(pool_id: PoolId, solution: Vec) -> Option>{ let pool = pallet_pool_system::Pool::::get(pool_id)?; let epoch_execution_info = pallet_pool_system::EpochExecution::::get(pool_id)?; pallet_pool_system::Pallet::::score_solution( diff --git a/runtime/integration-tests/src/xcm/development/tests/connectors.rs b/runtime/integration-tests/src/xcm/development/tests/connectors.rs index 4158d23c42..9908bec948 100644 --- a/runtime/integration-tests/src/xcm/development/tests/connectors.rs +++ b/runtime/integration-tests/src/xcm/development/tests/connectors.rs @@ -269,7 +269,7 @@ fn encoded_ethereum_xcm_add_pool() { interior: X1(Parachain(1000)), }; // 38 is the pallet index, 0 is the `transact` extrinsic index. - let ethereum_xcm_transact_call_index = vec![38, 0]; + let ethereum_xcm_transact_call_index = BoundedVec::truncate_from(vec![38, 0]); let contract_address = H160::from( <[u8; 20]>::from_hex("cE0Cb9BB900dfD0D378393A041f3abAb6B182882").expect("Decoding failed"), ); @@ -360,7 +360,7 @@ mod utils { .clone() .try_into() .expect("Bad xcm version"), - ethereum_xcm_transact_call_index: vec![38, 0], + ethereum_xcm_transact_call_index: BoundedVec::truncate_from(vec![38, 0]), contract_address: H160::from( <[u8; 20]>::from_hex("cE0Cb9BB900dfD0D378393A041f3abAb6B182882") .expect("Invalid address"), diff --git a/src/rpc/pools.rs b/src/rpc/pools.rs index 6237cffce7..53df0bf678 100644 --- a/src/rpc/pools.rs +++ b/src/rpc/pools.rs @@ -9,12 +9,18 @@ use pallet_pool_system::{ use runtime_common::apis::PoolsApi as PoolsRuntimeApi; use sp_api::ProvideRuntimeApi; use sp_blockchain::HeaderBackend; -use sp_runtime::{generic::BlockId, traits::Block as BlockT}; +use sp_runtime::{ + generic::BlockId, + traits::{Block as BlockT, Get}, +}; use crate::rpc::{invalid_params_error, runtime_error}; #[rpc(client, server)] -pub trait PoolsApi { +pub trait PoolsApi +where + MaxTranches: Get, +{ #[method(name = "pools_currency")] fn currency(&self, poold_id: PoolId, at: Option) -> RpcResult; @@ -24,7 +30,7 @@ pub trait PoolsApi, at: Option, - ) -> RpcResult>; + ) -> RpcResult>; #[method(name = "pools_trancheTokenPrice")] fn tranche_token_price( @@ -75,17 +81,19 @@ impl Pools { } } -impl - PoolsApiServer for Pools +impl + PoolsApiServer + for Pools where Block: BlockT, C: Send + Sync + 'static + ProvideRuntimeApi + HeaderBackend, - C::Api: PoolsRuntimeApi, + C::Api: PoolsRuntimeApi, Balance: Codec + Copy, PoolId: Codec + Copy + Debug, TrancheId: Codec + Clone + Debug, Currency: Codec, BalanceRatio: Codec, + MaxTranches: Codec + Get, { fn currency(&self, pool_id: PoolId, at: Option) -> RpcResult { let api = self.client.runtime_api(); @@ -105,7 +113,7 @@ where pool_id: PoolId, solution: Vec, at: Option, - ) -> RpcResult> { + ) -> RpcResult> { let api = self.client.runtime_api(); let at = if let Some(hash) = at { BlockId::hash(hash) From cfb546b53756d5fd7ae2618a714723de3f2391b0 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Tue, 10 Jan 2023 10:06:57 +0100 Subject: [PATCH 05/12] tests: fix --- libs/types/src/permissions.rs | 5 +- pallets/investments/src/mock.rs | 3 +- pallets/loans/src/mock.rs | 5 +- pallets/permissions/src/mock.rs | 16 ++- pallets/pool-registry/src/lib.rs | 7 +- pallets/pool-system/src/lib.rs | 9 +- pallets/pool-system/src/mock.rs | 3 +- pallets/pool-system/src/solution.rs | 187 +++++++++++++--------------- pallets/pool-system/src/tranches.rs | 39 +++--- runtime/altair/src/lib.rs | 2 - runtime/development/src/lib.rs | 2 - 11 files changed, 135 insertions(+), 143 deletions(-) diff --git a/libs/types/src/permissions.rs b/libs/types/src/permissions.rs index e28b5c548e..8c63cd3b58 100644 --- a/libs/types/src/permissions.rs +++ b/libs/types/src/permissions.rs @@ -461,6 +461,7 @@ mod tests { parameter_types! { pub const MinDelay: u64 = 4; + pub const MaxTranches: u32 = 5; } struct Now(core::time::Duration); @@ -497,9 +498,9 @@ mod tests { #[test] fn permission_roles_work() { - assert!(PermissionRoles::::default().empty()); + assert!(PermissionRoles::::default().empty()); - let mut roles = PermissionRoles::::default(); + let mut roles = PermissionRoles::::default(); // Updating works only when increasing permissions assert!(roles diff --git a/pallets/investments/src/mock.rs b/pallets/investments/src/mock.rs index 9a6579f0d3..aeb440e8d8 100644 --- a/pallets/investments/src/mock.rs +++ b/pallets/investments/src/mock.rs @@ -22,7 +22,7 @@ use cfg_types::{ orders::{FulfillmentWithPrice, TotalOrder}, tokens::CurrencyId, }; -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ dispatch::DispatchResultWithPostInfo, parameter_types, @@ -183,6 +183,7 @@ impl PreConditions for Always { TypeInfo, Serialize, Deserialize, + MaxEncodedLen, )] pub enum InvestmentId { PoolTranche { diff --git a/pallets/loans/src/mock.rs b/pallets/loans/src/mock.rs index c882e4a28f..6c15f20955 100644 --- a/pallets/loans/src/mock.rs +++ b/pallets/loans/src/mock.rs @@ -254,6 +254,7 @@ impl PoolUpdateGuard for UpdateGuard { TrancheWeight, TrancheId, PoolId, + MaxTranches, >; type ScheduledUpdateDetails = ScheduledUpdateDetails; @@ -326,8 +327,8 @@ impl pallet_interest_accrual::Config for Runtime { } parameter_types! { - #[derive(Debug, Eq, PartialEq, scale_info::TypeInfo, Clone)] - pub const MaxTranches: u8 = 5; + #[derive(Debug, Eq, PartialEq, PartialOrd, scale_info::TypeInfo, Clone)] + pub const MaxTranches: u32 = 5; #[derive(Debug, Eq, PartialEq, scale_info::TypeInfo, Clone)] pub const MinDelay: Moment = 0; diff --git a/pallets/permissions/src/mock.rs b/pallets/permissions/src/mock.rs index cf47a486ac..9b960ead69 100644 --- a/pallets/permissions/src/mock.rs +++ b/pallets/permissions/src/mock.rs @@ -10,7 +10,7 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; pub use dummy::pallet as pallet_dummy; use frame_support::{ parameter_types, @@ -50,7 +50,7 @@ pub enum Role { bitflags::bitflags! { /// The current admin roles we support - #[derive(codec::Encode, codec::Decode, scale_info::TypeInfo)] + #[derive(codec::Encode, codec::Decode, scale_info::TypeInfo, MaxEncodedLen)] pub struct OrgStorage: u32 { const SENIOR_EXEC = 0b00000001; const HEAD_OF_SAUBERMACHING = 0b00000010; @@ -60,14 +60,16 @@ bitflags::bitflags! { bitflags::bitflags! { /// The current admin roles we support - #[derive(codec::Encode, codec::Decode, scale_info::TypeInfo)] + #[derive(codec::Encode, codec::Decode, scale_info::TypeInfo, MaxEncodedLen)] pub struct XcmStorage: u32 { const SENDER = 0b00000001; const RECEIVER = 0b00000010; } } -#[derive(codec::Encode, codec::Decode, scale_info::TypeInfo, Debug, Clone, Eq, PartialEq)] +#[derive( + codec::Encode, codec::Decode, scale_info::TypeInfo, Debug, Clone, Eq, PartialEq, MaxEncodedLen, +)] pub struct Storage { org: OrgStorage, xcm: XcmStorage, @@ -82,7 +84,9 @@ impl Default for Storage { } } -#[derive(codec::Encode, codec::Decode, scale_info::TypeInfo, Debug, Clone, Eq, PartialEq)] +#[derive( + codec::Encode, codec::Decode, scale_info::TypeInfo, Debug, Clone, Eq, PartialEq, MaxEncodedLen, +)] pub enum Scope { PalletA, PalletB, @@ -281,6 +285,7 @@ impl frame_system::Config for Runtime { parameter_types! { pub const One: u64 = 1; pub const MaxRoles: u32 = 10; + pub const MaxTranches: u32 = 5; } type AdminOrigin = EitherOfDiverse, EnsureSignedBy>; @@ -290,6 +295,7 @@ impl pallet_permissions::Config for Runtime { type Editors = Editors; type Event = Event; type MaxRolesPerScope = MaxRoles; + type MaxTranches = MaxTranches; type Role = Role; type Scope = Scope; type Storage = Storage; diff --git a/pallets/pool-registry/src/lib.rs b/pallets/pool-registry/src/lib.rs index f98516d409..cda7a60eba 100644 --- a/pallets/pool-registry/src/lib.rs +++ b/pallets/pool-registry/src/lib.rs @@ -98,7 +98,12 @@ pub mod pallet { + MaxEncodedLen + core::fmt::Debug; - type Rate: Parameter + Member + MaybeSerializeDeserialize + FixedPointNumber + TypeInfo; + type Rate: Parameter + + Member + + MaybeSerializeDeserialize + + FixedPointNumber + + TypeInfo + + MaxEncodedLen; /// A fixed-point number which represents an /// interest rate. diff --git a/pallets/pool-system/src/lib.rs b/pallets/pool-system/src/lib.rs index ff49d7b90d..fe61bdecde 100644 --- a/pallets/pool-system/src/lib.rs +++ b/pallets/pool-system/src/lib.rs @@ -88,7 +88,7 @@ pub type EpochExecutionTranchesOf = EpochExecutionTranches< ::Rate, ::TrancheWeight, ::TrancheCurrency, - ::MaxEpocExecutionTranches, + ::MaxTranches, >; /// Types alias for Tranches @@ -133,7 +133,6 @@ type EpochExecutionInfoOf = EpochExecutionInfo< ::TrancheWeight, ::BlockNumber, ::TrancheCurrency, - ::MaxEpocExecutionTranches, ::MaxTranches, >; @@ -328,10 +327,6 @@ pub mod pallet { #[pallet::constant] type PoolDeposit: Get; - /// The maximum amount of execution tranches of an epoch. - #[pallet::constant] - type MaxEpocExecutionTranches: Get + scale_info::TypeInfo; - /// The origin permitted to create pools type PoolCreateOrigin: EnsureOrigin; @@ -938,7 +933,7 @@ pub mod pallet { T::Rate, _, T::TrancheCurrency, - T::MaxEpocExecutionTranches, + T::MaxTranches, >(&epoch.tranches, solution) .map_err(|e| { // In case we have an underflow in the calculation, there diff --git a/pallets/pool-system/src/mock.rs b/pallets/pool-system/src/mock.rs index 7507eac108..033fca1bd8 100644 --- a/pallets/pool-system/src/mock.rs +++ b/pallets/pool-system/src/mock.rs @@ -281,7 +281,7 @@ parameter_types! { /// The index with which this pallet is instantiated in this runtime. pub PoolPalletIndex: u8 = ::index() as u8; - #[derive(scale_info::TypeInfo, Eq, PartialEq, Debug, Clone, Copy )] + #[derive(scale_info::TypeInfo, Eq, PartialEq, PartialOrd, Debug, Clone, Copy )] pub const MaxTranches: u32 = 5; pub const MinUpdateDelay: u64 = 0; // no delay @@ -370,6 +370,7 @@ impl PoolUpdateGuard for UpdateGuard { TrancheWeight, TrancheId, u64, + MaxTranches, >; type ScheduledUpdateDetails = ScheduledUpdateDetails; diff --git a/pallets/pool-system/src/solution.rs b/pallets/pool-system/src/solution.rs index 95681383b3..0fed49a52c 100644 --- a/pallets/pool-system/src/solution.rs +++ b/pallets/pool-system/src/solution.rs @@ -113,23 +113,16 @@ pub struct EpochExecutionInfo< Weight, BlockNumber, TrancheCurrency, - MaxEpocExecutionTranches, MaxTranches, > where - MaxEpocExecutionTranches: Get, MaxTranches: Get, { pub epoch: EpochId, pub nav: Balance, pub reserve: Balance, pub max_reserve: Balance, - pub tranches: EpochExecutionTranches< - Balance, - BalanceRatio, - Weight, - TrancheCurrency, - MaxEpocExecutionTranches, - >, + pub tranches: + EpochExecutionTranches, pub best_submission: Option>, pub challenge_period_end: Option, } @@ -455,28 +448,15 @@ where } } -pub fn calculate_solution_parameters< - Balance, - BalanceRatio, - Rate, - Weight, - Currency, - MaxEpocExecutionTranches, ->( - epoch_tranches: &EpochExecutionTranches< - Balance, - BalanceRatio, - Weight, - Currency, - MaxEpocExecutionTranches, - >, +pub fn calculate_solution_parameters( + epoch_tranches: &EpochExecutionTranches, solution: &[TrancheSolution], ) -> Result<(Balance, Balance, Vec), DispatchError> where BalanceRatio: Copy + FixedPointNumber, Balance: Copy + BaseArithmetic + FixedPointOperand + Unsigned + From, Weight: Copy + From, - MaxEpocExecutionTranches: Get, + MaxTranches: Get, { let acc_invest: Balance = epoch_tranches .residual_top_slice() @@ -510,6 +490,7 @@ where #[cfg(test)] mod test { use super::*; + use crate::mock::MaxTranches; fn get_tranche_solution(invest_fulfillment: f64, redeem_fulfillment: f64) -> TrancheSolution { TrancheSolution { @@ -518,17 +499,17 @@ mod test { } } - fn get_solution(fulfillments: Vec<(f64, f64)>) -> BoundedVec> { + fn get_solution(fulfillments: Vec<(f64, f64)>) -> BoundedVec { let mut solutions = Vec::new(); fulfillments .into_iter() .for_each(|(invest, redeem)| solutions.push(get_tranche_solution(invest, redeem))); - BoundedVec::<_, ConstU32<10>>::truncate_from(solutions) + BoundedVec::<_, MaxTranches>::truncate_from(solutions) } - fn get_full_solution() -> BoundedVec> { + fn get_full_solution() -> BoundedVec { let mut solutions = Vec::new(); solutions.push(get_tranche_solution(1.0, 1.0)); @@ -536,7 +517,7 @@ mod test { solutions.push(get_tranche_solution(1.0, 1.0)); solutions.push(get_tranche_solution(1.0, 1.0)); - BoundedVec::<_, ConstU32<10>>::truncate_from(solutions) + BoundedVec::<_, MaxTranches>::truncate_from(solutions) } #[test] @@ -625,14 +606,14 @@ mod test { #[test] fn epoch_solution_healthy_works() { - let solution = EpochSolution::::Healthy(HealthySolution { + let solution = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 0, }); assert!(solution.healthy()); - let solution = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), @@ -644,82 +625,82 @@ mod test { #[test] fn epoch_solution_solution_works() { - let solution = EpochSolution::::Healthy(HealthySolution { + let solution = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 0, }); - assert!(solution.solution() == get_full_solution()); + assert!(solution.solution() == get_full_solution().as_slice()); - let solution = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, }); - assert!(solution.solution() == get_full_solution()); + assert!(solution.solution() == get_full_solution().as_slice()); } #[test] fn epoch_solution_partial_eq_works() { - let solution_1 = EpochSolution::::Healthy(HealthySolution { + let solution_1 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 3, }); - let solution_2 = EpochSolution::::Healthy(HealthySolution { + let solution_2 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 3, }); assert!(solution_1 == solution_2); - let solution_1 = EpochSolution::::Healthy(HealthySolution { + let solution_1 = EpochSolution::::Healthy(HealthySolution { solution: get_solution(vec![(0.0, 0.0), (1.0, 0.7), (0.7, 0.7)]), score: 3, }); - let solution_2 = EpochSolution::::Healthy(HealthySolution { + let solution_2 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 3, }); assert!(solution_1 != solution_2); - let solution_1 = EpochSolution::::Healthy(HealthySolution { + let solution_1 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 3, }); - let solution_2 = EpochSolution::::Healthy(HealthySolution { + let solution_2 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 4, }); assert!(solution_1 != solution_2); - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, }); - let solution_2 = EpochSolution::::Healthy(HealthySolution { + let solution_2 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 4, }); assert!(solution_1 != solution_2); - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), reserve_improvement_score: Some(2), risk_buffer_improvement_scores: None, }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), @@ -728,16 +709,16 @@ mod test { }); assert!(solution_1 == solution_2); - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), @@ -746,16 +727,16 @@ mod test { }); assert!(solution_1 != solution_2); - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), reserve_improvement_score: Some(5), risk_buffer_improvement_scores: None, }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_solution(vec![(0.0, 0.0), (1.0, 0.7), (0.7, 0.7)]), @@ -768,7 +749,7 @@ mod test { #[test] fn unhealthy_solution_has_state_works() { let unhealthy = UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: get_full_solution(), @@ -784,12 +765,12 @@ mod test { // via the `ParitalOrd` implementation of `EpochSolution`, `HealthySolution` and `UnhealthySolution`. #[test] fn higher_score_is_better() { - let solution_1 = EpochSolution::::Healthy(HealthySolution { + let solution_1 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 3, }); - let solution_2 = EpochSolution::::Healthy(HealthySolution { + let solution_2 = EpochSolution::::Healthy(HealthySolution { solution: get_full_solution(), score: 4, }); @@ -798,19 +779,19 @@ mod test { #[test] fn healthy_always_above_unhealthy() { - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MinRiskBufferViolated, UnhealthyState::MaxReserveViolated, ]), solution: Default::default(), reserve_improvement_score: Some(1000), - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); - let solution_2 = EpochSolution::::Healthy(HealthySolution { + let solution_2 = EpochSolution::::Healthy(HealthySolution { solution: Default::default(), score: 0, }); @@ -819,8 +800,8 @@ mod test { #[test] fn reserve_improvement_better() { - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: Default::default(), @@ -828,8 +809,8 @@ mod test { risk_buffer_improvement_scores: None, }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: Default::default(), @@ -842,8 +823,8 @@ mod test { #[test] fn no_reserve_violation_better() { - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: Default::default(), @@ -851,7 +832,7 @@ mod test { risk_buffer_improvement_scores: None, }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { state: Default::default(), solution: Default::default(), reserve_improvement_score: None, @@ -863,20 +844,20 @@ mod test { #[test] fn no_risk_buff_violation_better() { - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, UnhealthyState::MinRiskBufferViolated, ]), solution: Default::default(), reserve_improvement_score: Some(5), - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, ]), solution: Default::default(), @@ -889,26 +870,26 @@ mod test { #[test] fn reserve_improvement_decides_over_equal_min_risk_buff() { - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, UnhealthyState::MinRiskBufferViolated, ]), solution: Default::default(), reserve_improvement_score: Some(5), - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: BoundedVec::<_, ConstU32<10>>::truncate_from(vec![ + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::<_, MaxTranches>::truncate_from(vec![ UnhealthyState::MaxReserveViolated, UnhealthyState::MinRiskBufferViolated, ]), solution: Default::default(), reserve_improvement_score: Some(6), - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); @@ -918,56 +899,60 @@ mod test { #[test] fn risk_buff_improvement_better() { - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MinRiskBufferViolated], + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::truncate_from(vec![UnhealthyState::MinRiskBufferViolated]), solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MinRiskBufferViolated], + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::truncate_from(vec![UnhealthyState::MinRiskBufferViolated]), solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(vec![2u128, 0u128, 0u128, 0u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::truncate_from(vec![ + 2u128, 0u128, 0u128, 0u128, + ])), // 4 tranches }); assert!(solution_1 < solution_2); - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MinRiskBufferViolated], + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::truncate_from(vec![UnhealthyState::MinRiskBufferViolated]), solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MinRiskBufferViolated], + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::truncate_from(vec![UnhealthyState::MinRiskBufferViolated]), solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(vec![1u128, 2u128, 3u128, 5u128]), // 4 tranches + risk_buffer_improvement_scores: Some(BoundedVec::truncate_from(vec![ + 1u128, 2u128, 3u128, 5u128, + ])), // 4 tranches }); assert!(solution_1 < solution_2); - let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MinRiskBufferViolated], + let solution_1 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::truncate_from(vec![UnhealthyState::MinRiskBufferViolated]), solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 2u128, 3u128, 4u128], )), // 4 tranches }); - let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { - state: vec![UnhealthyState::MinRiskBufferViolated], + let solution_2 = EpochSolution::::Unhealthy(UnhealthySolution { + state: BoundedVec::truncate_from(vec![UnhealthyState::MinRiskBufferViolated]), solution: Default::default(), reserve_improvement_score: None, - risk_buffer_improvement_scores: Some(BoundedVec::<_, ConstU32<10>>::truncate_from( + risk_buffer_improvement_scores: Some(BoundedVec::<_, MaxTranches>::truncate_from( vec![1u128, 3u128, 3u128, 5u128], )), // 4 tranches }); diff --git a/pallets/pool-system/src/tranches.rs b/pallets/pool-system/src/tranches.rs index 641f66597e..d889e43c58 100644 --- a/pallets/pool-system/src/tranches.rs +++ b/pallets/pool-system/src/tranches.rs @@ -320,7 +320,9 @@ where } #[cfg(test)] -impl Tranches { +impl + Tranches +{ pub fn new( pool: PoolId, tranches: Vec>, @@ -336,6 +338,7 @@ impl Tranches TrancheCurrency, TrancheId, PoolId, + crate::mock::MaxTranches, >::id_from_salt(salt)); salt = ( (index.checked_add(1).ok_or(ArithmeticError::Overflow)?) @@ -346,8 +349,11 @@ impl Tranches } Ok(Self { - tranches: BoundedVec::, MaxTranches>::truncate_from(tranches), - ids: BoundedVec::::truncate_from(ids), + tranches: BoundedVec::< + Tranche, + crate::mock::MaxTranches, + >::truncate_from(tranches), + ids: BoundedVec::::truncate_from(ids), salt, }) } @@ -1037,29 +1043,24 @@ impl Default for EpochExecutionTranche where - MaxEpocExecutionTranches: Get, +pub struct EpochExecutionTranches +where + MaxTranches: Get, { pub tranches: BoundedVec< EpochExecutionTranche, - MaxEpocExecutionTranches, + MaxTranches, >, } /// Utility implementations for `EpochExecutionTranches` -impl - EpochExecutionTranches +impl + EpochExecutionTranches where Balance: Zero + Copy + BaseArithmetic + Unsigned + From, Weight: Copy + From, BalanceRatio: Copy, - MaxEpocExecutionTranches: Get, + MaxTranches: Get, { pub fn new( tranches: Vec>, @@ -1117,7 +1118,7 @@ where self, ) -> BoundedVec< EpochExecutionTranche, - MaxEpocExecutionTranches, + MaxTranches, > { self.tranches } @@ -1296,13 +1297,13 @@ where } /// Business logic implementations for `EpochExecutionTranches` -impl - EpochExecutionTranches +impl + EpochExecutionTranches where Balance: Zero + Copy + BaseArithmetic + Unsigned + From, Weight: Copy + From, BalanceRatio: Copy, - MaxEpocExecutionTranches: Get, + MaxTranches: Get, { pub fn prices(&self) -> Vec { self.tranches.iter().map(|tranche| tranche.price).collect() diff --git a/runtime/altair/src/lib.rs b/runtime/altair/src/lib.rs index c0fee685c7..2bd2ced46c 100644 --- a/runtime/altair/src/lib.rs +++ b/runtime/altair/src/lib.rs @@ -1116,8 +1116,6 @@ impl pallet_pool_system::Config for Runtime { type EpochId = PoolEpochId; type Event = Event; type Investments = Investments; - // FIXME: Correct value - type MaxEpocExecutionTranches = MaxTranches; type MaxNAVAgeUpperBound = MaxNAVAgeUpperBound; type MaxSizeMetadata = MaxSizeMetadata; type MaxTokenNameLength = MaxTrancheNameLengthBytes; diff --git a/runtime/development/src/lib.rs b/runtime/development/src/lib.rs index 44d047a08e..ad7502c029 100644 --- a/runtime/development/src/lib.rs +++ b/runtime/development/src/lib.rs @@ -911,8 +911,6 @@ impl pallet_pool_system::Config for Runtime { type EpochId = PoolEpochId; type Event = Event; type Investments = Investments; - // FIXME: Assign correct value - type MaxEpocExecutionTranches = MaxTranches; type MaxNAVAgeUpperBound = MaxNAVAgeUpperBound; type MaxSizeMetadata = MaxSizeMetadata; type MaxTokenNameLength = MaxTrancheNameLengthBytes; From b0db81e29f7babef367d5fb424c0d6dd040eb3e7 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Tue, 10 Jan 2023 10:26:47 +0100 Subject: [PATCH 06/12] tests: more minor fixes --- pallets/loans/src/test_utils.rs | 3 ++- pallets/pool-system/src/tranches.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pallets/loans/src/test_utils.rs b/pallets/loans/src/test_utils.rs index 95e3b3e738..61686524a4 100644 --- a/pallets/loans/src/test_utils.rs +++ b/pallets/loans/src/test_utils.rs @@ -27,8 +27,9 @@ use frame_support::{ }; use frame_system::RawOrigin; #[cfg(feature = "runtime-benchmarks")] +use pallet_pool_system::tranches::TrancheLoc; use pallet_pool_system::{ - tranches::{TrancheInput, TrancheLoc, TrancheMetadata, TrancheType}, + tranches::{TrancheInput, TrancheMetadata, TrancheType}, Pallet as PoolPallet, Pool as PoolStorage, }; use sp_runtime::{ diff --git a/pallets/pool-system/src/tranches.rs b/pallets/pool-system/src/tranches.rs index d889e43c58..431966d2ed 100644 --- a/pallets/pool-system/src/tranches.rs +++ b/pallets/pool-system/src/tranches.rs @@ -350,7 +350,7 @@ impl Ok(Self { tranches: BoundedVec::< - Tranche, + Tranche, crate::mock::MaxTranches, >::truncate_from(tranches), ids: BoundedVec::::truncate_from(ids), From 6e89ec189226f50cbe7162a854100164fcd26864 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Tue, 10 Jan 2023 13:48:22 +0100 Subject: [PATCH 07/12] docs: improve comments --- pallets/connectors/src/routers.rs | 8 ++++---- pallets/permissions/src/lib.rs | 2 +- pallets/pool-system/src/pool_types.rs | 8 +++----- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pallets/connectors/src/routers.rs b/pallets/connectors/src/routers.rs index b138cd9d9c..d04b1fb543 100644 --- a/pallets/connectors/src/routers.rs +++ b/pallets/connectors/src/routers.rs @@ -30,7 +30,7 @@ pub struct XcmDomain { pub fee_currency: CurrencyId, } -/// FIXME: Remove this custom implementation once the following underlying data implements MaxEncodedLen: +// NOTE: Remove this custom implementation once the following underlying data implements MaxEncodedLen: /// * Polkadot Repo: xcm::VersionedMultiLocation /// * PureStake Repo: pallet_xcm_transactor::Config::CurrencyId impl MaxEncodedLen for XcmDomain @@ -38,15 +38,15 @@ where XcmDomain: Encode, { fn max_encoded_len() -> usize { - // custom mel bound for `VersionedMultiLocation` + // custom MEL bound for `VersionedMultiLocation` xcm::v1::MultiLocation::max_encoded_len() - // VersionedMultiLocation is binary enum + // VersionedMultiLocation is enum with two variants .saturating_add(2) .saturating_add(BoundedVec::< u8, ConstU32<{ xcm_primitives::MAX_ETHEREUM_XCM_INPUT_SIZE }>, >::max_encoded_len()) - // custom mel bound for CurrencyId + // custom MEL bound for CurrencyId .saturating_add(cfg_types::tokens::CurrencyId::max_encoded_len()) .saturating_add(H160::max_encoded_len()) } diff --git a/pallets/permissions/src/lib.rs b/pallets/permissions/src/lib.rs index bbac6a2760..b0858ecf45 100644 --- a/pallets/permissions/src/lib.rs +++ b/pallets/permissions/src/lib.rs @@ -65,7 +65,7 @@ pub mod pallet { #[pallet::constant] type MaxRolesPerScope: Get; - /// The maximum number of tranche investors. + /// The maximum number of tranches. #[pallet::constant] type MaxTranches: Get; diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index 39df83bdb4..8cd819eedf 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -164,9 +164,7 @@ where pub max_nav_age: Change, } -// TODO: Check whether macro can be used instead of custom impl. -// Unfortunately, `Change` is the root as it does not impl MaxEncodedLen. -// Could open PR on ORML. +// NOTE: Can be removed once orml_traits::Change impls MaxEncodedLen impl MaxEncodedLen for PoolChanges where @@ -185,9 +183,9 @@ where TrancheMetadata, MaxTranches, >::max_encoded_len()) - // from 4x `Value` enum - .saturating_add(8 * 4) .saturating_add(Moment::max_encoded_len().saturating_mul(2)) + // MEL for Change is 1 + T::max_encoded_len() + .saturating_add(4) } } From c03454d8096aecd4a699c1016fde9912ca1af666 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Tue, 10 Jan 2023 15:07:35 +0100 Subject: [PATCH 08/12] docs: add upstream PR --- pallets/pool-system/src/pool_types.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index 8cd819eedf..512e6b5b94 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -165,6 +165,7 @@ where } // NOTE: Can be removed once orml_traits::Change impls MaxEncodedLen +// https://github.com/open-web3-stack/open-runtime-module-library/pull/867 impl MaxEncodedLen for PoolChanges where From 839c04c3044b1a8f3ee4382c5cf66218a60d13c5 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Wed, 11 Jan 2023 19:15:59 +0100 Subject: [PATCH 09/12] docs: improve for custom mel bound derivation --- pallets/connectors/src/routers.rs | 10 ++++++---- pallets/pool-system/src/pool_types.rs | 5 ++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pallets/connectors/src/routers.rs b/pallets/connectors/src/routers.rs index d04b1fb543..2a380e7a03 100644 --- a/pallets/connectors/src/routers.rs +++ b/pallets/connectors/src/routers.rs @@ -38,16 +38,18 @@ where XcmDomain: Encode, { fn max_encoded_len() -> usize { - // custom MEL bound for `VersionedMultiLocation` + // The domain's `VersionedMultiLocation` (custom bound) xcm::v1::MultiLocation::max_encoded_len() - // VersionedMultiLocation is enum with two variants + // From the two enum variants of `VersionedMultiLocation .saturating_add(2) + // The ethereum xcm call index (default bound) .saturating_add(BoundedVec::< u8, ConstU32<{ xcm_primitives::MAX_ETHEREUM_XCM_INPUT_SIZE }>, >::max_encoded_len()) - // custom MEL bound for CurrencyId - .saturating_add(cfg_types::tokens::CurrencyId::max_encoded_len()) + // The contract address (default bound) .saturating_add(H160::max_encoded_len()) + // The fee currency (custom bound) + .saturating_add(cfg_types::tokens::CurrencyId::max_encoded_len()) } } diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index 512e6b5b94..b6c10dba31 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -179,13 +179,16 @@ where Moment: MaxEncodedLen, { fn max_encoded_len() -> usize { + // The tranches (default bound) BoundedVec::, MaxTranches>::max_encoded_len() + // The tranche metadata (default bound) .saturating_add(BoundedVec::< TrancheMetadata, MaxTranches, >::max_encoded_len()) + // The min epoc time .saturating_add(Moment::max_encoded_len().saturating_mul(2)) - // MEL for Change is 1 + T::max_encoded_len() + // From the `Change` enum which wraps all four fields of Self .saturating_add(4) } } From c6d955f04eea2c61c8690907c6f832bee89fd510 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Wed, 11 Jan 2023 19:16:46 +0100 Subject: [PATCH 10/12] docs: add missing max nav age comment --- pallets/pool-system/src/pool_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index b6c10dba31..d7801f7def 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -186,7 +186,7 @@ where TrancheMetadata, MaxTranches, >::max_encoded_len()) - // The min epoc time + // The min epoc time and max nav age .saturating_add(Moment::max_encoded_len().saturating_mul(2)) // From the `Change` enum which wraps all four fields of Self .saturating_add(4) From 5dfef10cb4926db1cb9c905f28405ef799c91bb3 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Thu, 12 Jan 2023 08:48:21 +0100 Subject: [PATCH 11/12] fix: registry mock mel --- pallets/pool-registry/src/mock.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pallets/pool-registry/src/mock.rs b/pallets/pool-registry/src/mock.rs index c3fe046bdd..d943d989ff 100644 --- a/pallets/pool-registry/src/mock.rs +++ b/pallets/pool-registry/src/mock.rs @@ -103,7 +103,7 @@ parameter_types! { /// The index with which this pallet is instantiated in this runtime. pub PoolPalletIndex: u8 = ::index() as u8; - #[derive(scale_info::TypeInfo, Eq, PartialEq, Debug, Clone, Copy )] + #[derive(scale_info::TypeInfo, Eq, PartialEq, PartialOrd, Debug, Clone, Copy )] pub const MaxTranches: u32 = 5; pub const MinUpdateDelay: u64 = 0; // for testing purposes @@ -351,6 +351,7 @@ impl PoolUpdateGuard for UpdateGuard { TrancheWeight, TrancheId, u64, + MaxTranches, >; type ScheduledUpdateDetails = ScheduledUpdateDetails; From 921d7d7e0a51395257d779ca1e8142a2398de1b0 Mon Sep 17 00:00:00 2001 From: William Freudenberger Date: Thu, 12 Jan 2023 12:05:12 +0100 Subject: [PATCH 12/12] fix: final max encoded len for XcmDomain --- pallets/connectors/src/routers.rs | 4 ++-- pallets/pool-system/src/pool_types.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/connectors/src/routers.rs b/pallets/connectors/src/routers.rs index 2a380e7a03..13066d4c12 100644 --- a/pallets/connectors/src/routers.rs +++ b/pallets/connectors/src/routers.rs @@ -40,8 +40,8 @@ where fn max_encoded_len() -> usize { // The domain's `VersionedMultiLocation` (custom bound) xcm::v1::MultiLocation::max_encoded_len() - // From the two enum variants of `VersionedMultiLocation - .saturating_add(2) + // From the enum wrapping of `VersionedMultiLocation` + .saturating_add(1) // The ethereum xcm call index (default bound) .saturating_add(BoundedVec::< u8, diff --git a/pallets/pool-system/src/pool_types.rs b/pallets/pool-system/src/pool_types.rs index d7801f7def..82c6c7f160 100644 --- a/pallets/pool-system/src/pool_types.rs +++ b/pallets/pool-system/src/pool_types.rs @@ -186,7 +186,7 @@ where TrancheMetadata, MaxTranches, >::max_encoded_len()) - // The min epoc time and max nav age + // The min epoc time and max nav age (default bounds) .saturating_add(Moment::max_encoded_len().saturating_mul(2)) // From the `Change` enum which wraps all four fields of Self .saturating_add(4)