diff --git a/pallets/common/src/traits/settlement.rs b/pallets/common/src/traits/settlement.rs index ef68492b23..fd2834f2f9 100644 --- a/pallets/common/src/traits/settlement.rs +++ b/pallets/common/src/traits/settlement.rs @@ -117,20 +117,24 @@ pub trait WeightInfo { fn withdraw_affirmation_as_mediator() -> Weight; fn reject_instruction_as_mediator(f: u32, n: u32, o: u32) -> Weight; - fn add_and_affirm_with_mediators_legs(legs: &[Leg], n_mediators: u32) -> Weight { - let (f, n, o) = Self::get_transfer_by_asset(legs); + fn add_and_affirm_with_mediators_legs( + legs: &[Leg], + portfolios: u32, + n_mediators: u32, + ) -> Weight { + let (f, n, o) = Self::get_transfer_by_asset(legs, portfolios); Self::add_and_affirm_with_mediators(f, n, o, n_mediators) } fn add_instruction_with_mediators_legs(legs: &[Leg], n_mediators: u32) -> Weight { - let (f, n, o) = Self::get_transfer_by_asset(legs); + let (f, n, o) = Self::get_transfer_by_asset(legs, 0); Self::add_instruction_with_mediators(f, n, o, n_mediators) } fn add_instruction_legs(legs: &[Leg]) -> Weight { - let (f, n, o) = Self::get_transfer_by_asset(legs); + let (f, n, o) = Self::get_transfer_by_asset(legs, 0); Self::add_instruction(f, n, o) } - fn add_and_affirm_instruction_legs(legs: &[Leg]) -> Weight { - let (f, n, o) = Self::get_transfer_by_asset(legs); + fn add_and_affirm_instruction_legs(legs: &[Leg], portfolios: u32) -> Weight { + let (f, n, o) = Self::get_transfer_by_asset(legs, portfolios); Self::add_and_affirm_instruction(f, n, o) } fn execute_manual_weight_limit( @@ -144,18 +148,29 @@ pub trait WeightInfo { } Self::execute_manual_instruction(*f, *n, *o) } - fn get_transfer_by_asset(legs: &[Leg]) -> (u32, u32, u32) { + fn get_transfer_by_asset(legs: &[Leg], portfolios: u32) -> (u32, u32, u32) { let asset_count = AssetCount::try_from_legs(legs).unwrap_or(AssetCount::new(1024, 1024, 1024)); - ( - asset_count.fungible(), - asset_count.non_fungible(), - asset_count.off_chain(), - ) + let f = asset_count.fungible(); + let n = asset_count.non_fungible(); + let max_portfolios = (f.saturating_add(n)).saturating_mul(2); // 2 portfolios per leg. (f+n = max legs). + if portfolios > max_portfolios { + // Too many portfolios, return worse-case count based on portfolio count. + return (portfolios, portfolios, 1024); + } + (f, n, asset_count.off_chain()) } - fn affirm_with_receipts_input(affirmation_count: Option) -> Weight { + fn affirm_with_receipts_input( + affirmation_count: Option, + portfolios: u32, + ) -> Weight { match affirmation_count { Some(affirmation_count) => { + let max_portfolios = affirmation_count.max_portfolios(); + if portfolios > max_portfolios { + // Too many portfolios, return worse-case weight based on portfolio count. + return Self::affirm_with_receipts(portfolios, portfolios, 10); + } // The weight for the assets being sent let sender_asset_count = affirmation_count.sender_asset_count(); let sender_side_weight = Self::affirm_with_receipts( @@ -177,12 +192,27 @@ pub trait WeightInfo { .saturating_add(receiver_side_weight) .saturating_sub(duplicated_weight) } - None => Self::affirm_with_receipts(10, 100, 10), + None => { + if portfolios > (10 + 100) * 2 { + // Too many portfolios, return worse-case weight based on portfolio count. + Self::affirm_with_receipts(portfolios, portfolios, 10) + } else { + Self::affirm_with_receipts(10, 100, 10) + } + } } } - fn affirm_instruction_input(affirmation_count: Option) -> Weight { + fn affirm_instruction_input( + affirmation_count: Option, + portfolios: u32, + ) -> Weight { match affirmation_count { Some(affirmation_count) => { + let max_portfolios = affirmation_count.max_portfolios(); + if portfolios > max_portfolios { + // Too many portfolios, return worse-case weight based on portfolio count. + return Self::affirm_instruction(portfolios, portfolios); + } // The weight for the assets being sent let sender_asset_count = affirmation_count.sender_asset_count(); let sender_side_weight = Self::affirm_instruction( @@ -202,12 +232,27 @@ pub trait WeightInfo { .saturating_add(receiver_side_weight) .saturating_sub(duplicated_weight) } - None => Self::affirm_instruction(10, 100), + None => { + if portfolios > (10 + 100) * 2 { + // Too many portfolios, return worse-case weight based on portfolio count. + Self::affirm_instruction(portfolios, portfolios) + } else { + Self::affirm_instruction(10, 100) + } + } } } - fn withdraw_affirmation_input(affirmation_count: Option) -> Weight { + fn withdraw_affirmation_input( + affirmation_count: Option, + portfolios: u32, + ) -> Weight { match affirmation_count { Some(affirmation_count) => { + let max_portfolios = affirmation_count.max_portfolios(); + if portfolios > max_portfolios { + // Too many portfolios, return worse-case weight based on portfolio count. + return Self::withdraw_affirmation(portfolios, portfolios, 10); + } // The weight for the assets being sent let sender_asset_count = affirmation_count.sender_asset_count(); let sender_side_weight = Self::withdraw_affirmation( @@ -229,7 +274,14 @@ pub trait WeightInfo { .saturating_add(receiver_side_weight) .saturating_sub(duplicated_weight) } - None => Self::withdraw_affirmation(10, 100, 10), + None => { + if portfolios > (10 + 100) * 2 { + // Too many portfolios, return worse-case weight based on portfolio count. + Self::withdraw_affirmation(portfolios, portfolios, 10) + } else { + Self::withdraw_affirmation(10, 100, 10) + } + } } } fn reject_instruction_input(asset_count: Option, as_mediator: bool) -> Weight { diff --git a/pallets/nft/src/lib.rs b/pallets/nft/src/lib.rs index 79a6b60c49..cc3431e620 100644 --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -4,7 +4,6 @@ use codec::{Decode, Encode}; use frame_support::dispatch::{ DispatchError, DispatchResult, DispatchResultWithPostInfo, PostDispatchInfo, }; -use frame_support::storage::child::KillStorageResult; use frame_support::storage::StorageDoubleMap; use frame_support::traits::Get; use frame_support::weights::Weight; @@ -444,13 +443,7 @@ impl Module { NumberOfNFTs::insert(&ticker, &caller_portfolio.did, new_balance); PortfolioNFT::remove(&caller_portfolio, (&ticker, &nft_id)); NFTOwner::remove(ticker, nft_id); - let removed_keys = { - #[allow(deprecated)] - match MetadataValue::remove_prefix((&collection_id, &nft_id), None) { - KillStorageResult::AllRemoved(n) => n, - KillStorageResult::SomeRemaining(n) => n, - } - }; + let removed_keys = MetadataValue::drain_prefix((&collection_id, &nft_id)).count(); Self::deposit_event(Event::NFTPortfolioUpdated( caller_portfolio.did, @@ -460,7 +453,7 @@ impl Module { PortfolioUpdateReason::Redeemed, )); Ok(PostDispatchInfo::from(Some( - ::WeightInfo::redeem_nft(removed_keys), + ::WeightInfo::redeem_nft(removed_keys as u32), ))) } diff --git a/pallets/runtime/develop/src/runtime.rs b/pallets/runtime/develop/src/runtime.rs index 9210708a9a..7c51583381 100644 --- a/pallets/runtime/develop/src/runtime.rs +++ b/pallets/runtime/develop/src/runtime.rs @@ -57,7 +57,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { authoring_version: 1, // `spec_version: aaa_bbb_ccd` should match node version v`aaa.bbb.cc` // N.B. `d` is unpinned from the binary version - spec_version: 6_003_040, + spec_version: 6_003_050, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/pallets/runtime/mainnet/rust-toolchain.toml b/pallets/runtime/mainnet/rust-toolchain.toml new file mode 100644 index 0000000000..f76705ac00 --- /dev/null +++ b/pallets/runtime/mainnet/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "nightly-2023-12-11" +targets = [ "wasm32-unknown-unknown" ] +components = [ "rustfmt" ] +profile = "minimal" diff --git a/pallets/runtime/mainnet/src/runtime.rs b/pallets/runtime/mainnet/src/runtime.rs index 57b52180d9..f86acfc3bb 100644 --- a/pallets/runtime/mainnet/src/runtime.rs +++ b/pallets/runtime/mainnet/src/runtime.rs @@ -53,7 +53,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { authoring_version: 1, // `spec_version: aaa_bbb_ccd` should match node version v`aaa.bbb.cc` // N.B. `d` is unpinned from the binary version - spec_version: 6_003_040, + spec_version: 6_003_050, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/pallets/runtime/testnet/rust-toolchain.toml b/pallets/runtime/testnet/rust-toolchain.toml new file mode 100644 index 0000000000..f76705ac00 --- /dev/null +++ b/pallets/runtime/testnet/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "nightly-2023-12-11" +targets = [ "wasm32-unknown-unknown" ] +components = [ "rustfmt" ] +profile = "minimal" diff --git a/pallets/runtime/testnet/src/runtime.rs b/pallets/runtime/testnet/src/runtime.rs index ee11204137..b76fef7668 100644 --- a/pallets/runtime/testnet/src/runtime.rs +++ b/pallets/runtime/testnet/src/runtime.rs @@ -55,7 +55,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { authoring_version: 1, // `spec_version: aaa_bbb_ccd` should match node version v`aaa.bbb.cc` // N.B. `d` is unpinned from the binary version - spec_version: 6_003_040, + spec_version: 6_003_050, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 4, diff --git a/pallets/settlement/src/lib.rs b/pallets/settlement/src/lib.rs index 3c4a39a280..09bc17c200 100644 --- a/pallets/settlement/src/lib.rs +++ b/pallets/settlement/src/lib.rs @@ -393,7 +393,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::affirm_with_receipts_input(None)] + #[weight = ::WeightInfo::affirm_with_receipts_input(None, portfolios.len() as u32)] pub fn affirm_with_receipts( origin, id: InstructionId, @@ -555,7 +555,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::add_and_affirm_instruction_legs(legs)] + #[weight = ::WeightInfo::add_and_affirm_instruction_legs(legs, portfolios.len() as u32)] pub fn add_and_affirm_instruction( origin, venue_id: VenueId, @@ -595,7 +595,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::affirm_instruction_input(None)] + #[weight = ::WeightInfo::affirm_instruction_input(None, portfolios.len() as u32)] pub fn affirm_instruction(origin, id: InstructionId, portfolios: Vec) -> DispatchResultWithPostInfo { Self::affirm_and_maybe_schedule_instruction( origin, @@ -613,7 +613,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::withdraw_affirmation_input(None)] + #[weight = ::WeightInfo::withdraw_affirmation_input(None, portfolios.len() as u32)] pub fn withdraw_affirmation(origin, id: InstructionId, portfolios: Vec) -> DispatchResultWithPostInfo { Self::base_withdraw_affirmation(origin, id, portfolios, None) } @@ -658,7 +658,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::affirm_with_receipts_input(*number_of_assets)] + #[weight = ::WeightInfo::affirm_with_receipts_input(*number_of_assets, portfolios.len() as u32)] pub fn affirm_with_receipts_with_count( origin, id: InstructionId, @@ -687,7 +687,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::affirm_instruction_input(*number_of_assets)] + #[weight = ::WeightInfo::affirm_instruction_input(*number_of_assets, portfolios.len() as u32)] pub fn affirm_instruction_with_count( origin, id: InstructionId, @@ -736,7 +736,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::withdraw_affirmation_input(*number_of_assets)] + #[weight = ::WeightInfo::withdraw_affirmation_input(*number_of_assets, portfolios.len() as u32)] pub fn withdraw_affirmation_with_count( origin, id: InstructionId, @@ -795,7 +795,7 @@ decl_module! { /// /// # Permissions /// * Portfolio - #[weight = ::WeightInfo::add_and_affirm_with_mediators_legs(legs, mediators.len() as u32)] + #[weight = ::WeightInfo::add_and_affirm_with_mediators_legs(legs, portfolios.len() as u32, mediators.len() as u32)] pub fn add_and_affirm_with_mediators( origin, venue_id: VenueId, @@ -860,7 +860,7 @@ decl_module! { /// * `number_of_assets` - an optional [`AssetCount`] that will be used for a precise fee estimation before executing the extrinsic. /// /// Note: calling the rpc method `get_execute_instruction_info` returns an instance of [`ExecuteInstructionInfo`], which contain the asset count. - #[weight = ::WeightInfo::reject_instruction_input(None, true)] + #[weight = ::WeightInfo::reject_instruction_input(*number_of_assets, true)] pub fn reject_instruction_as_mediator( origin, instruction_id: InstructionId, @@ -2460,7 +2460,7 @@ impl Module { ) -> Weight { let affirmation_count = AffirmationCount::new(sender_asset_count, receiver_asset_count, n_offchain); - ::WeightInfo::affirm_with_receipts_input(Some(affirmation_count)) + ::WeightInfo::affirm_with_receipts_input(Some(affirmation_count), 0) } /// Returns the weight for calling `affirm_instruction` while considering the `sender_asset_count` for the sender and`receiver_asset_count` @@ -2470,7 +2470,7 @@ impl Module { receiver_asset_count: AssetCount, ) -> Weight { let affirmation_count = AffirmationCount::new(sender_asset_count, receiver_asset_count, 0); - ::WeightInfo::affirm_instruction_input(Some(affirmation_count)) + ::WeightInfo::affirm_instruction_input(Some(affirmation_count), 0) } /// Returns the weight for calling `withdraw_affirmation` while considering the `sender_asset_count` for the sender and`receiver_asset_count` @@ -2482,7 +2482,7 @@ impl Module { ) -> Weight { let affirmation_count = AffirmationCount::new(sender_asset_count, receiver_asset_count, n_offchain); - ::WeightInfo::withdraw_affirmation_input(Some(affirmation_count)) + ::WeightInfo::withdraw_affirmation_input(Some(affirmation_count), 0) } /// Returns the weight for calling `reject_instruction_weight` with the number of assets in `instruction_asset_count`. diff --git a/primitives/src/settlement.rs b/primitives/src/settlement.rs index 3d7f457f31..f6c05535ad 100644 --- a/primitives/src/settlement.rs +++ b/primitives/src/settlement.rs @@ -356,6 +356,13 @@ impl AssetCount { } } + /// The maximum number of unique portfolios. + pub fn max_portfolios(&self) -> u32 { + self.fungible + .saturating_add(self.non_fungible) + .saturating_mul(2) + } + /// Returns the number of fungible transfers. pub fn fungible(&self) -> u32 { self.fungible @@ -663,6 +670,13 @@ impl AffirmationCount { pub fn offchain_count(&self) -> u32 { self.offchain_count } + + /// The maximum number of unique portfolios. + pub fn max_portfolios(&self) -> u32 { + self.sender_asset_count + .max_portfolios() + .saturating_add(self.receiver_asset_count.max_portfolios()) + } } /// Stores the number of fungible, non fungible and offchain assets in an instruction, the consumed weight for executing the instruction,