diff --git a/pallets/asset/src/lib.rs b/pallets/asset/src/lib.rs index 48ac26d0a7..95657cb2ce 100644 --- a/pallets/asset/src/lib.rs +++ b/pallets/asset/src/lib.rs @@ -3293,8 +3293,8 @@ impl Pallet { )?; // Updates the balance in the asset pallet - let sender_new_balance = sender_current_balance - transfer_value; - let receiver_new_balance = receiver_current_balance + transfer_value; + let sender_new_balance = sender_current_balance.saturating_sub(transfer_value); + let receiver_new_balance = receiver_current_balance.saturating_add(transfer_value); BalanceOf::::insert(asset_id, sender_portfolio.did, sender_new_balance); BalanceOf::::insert(asset_id, receiver_portfolio.did, receiver_new_balance); @@ -3461,6 +3461,39 @@ impl Pallet { } }) } + + /// Transfers `transfer_value` of `asset_id` from `sender_pid` to `receiver_pid`. + /// Note: This functions skips all compliance and statistics checks, only checking for balance. + pub fn simplified_fungible_transfer( + asset_id: AssetId, + sender_pid: PortfolioId, + receiver_pid: PortfolioId, + transfer_value: Balance, + inst_id: InstructionId, + inst_memo: Option, + caller_did: IdentityId, + weight_meter: &mut WeightMeter, + ) -> DispatchResult { + ensure!( + BalanceOf::::get(&asset_id, &sender_pid.did) >= transfer_value, + Error::::InsufficientBalance + ); + Portfolio::::ensure_portfolio_validity(&receiver_pid)?; + Portfolio::::ensure_sufficient_balance(&sender_pid, &asset_id, transfer_value)?; + + Self::unverified_transfer_asset( + sender_pid, + receiver_pid, + asset_id, + transfer_value, + Some(inst_id), + inst_memo, + caller_did, + weight_meter, + )?; + + Ok(()) + } } //========================================================================== diff --git a/pallets/nft/src/lib.rs b/pallets/nft/src/lib.rs index 27c647af7f..ab49d48256 100644 --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -712,10 +712,10 @@ impl Pallet { // Update the balance of the sender and the receiver let transferred_amount = nfts.len() as u64; NumberOfNFTs::::mutate(nfts.asset_id(), sender_portfolio.did, |balance| { - *balance -= transferred_amount + *balance = balance.saturating_sub(transferred_amount) }); NumberOfNFTs::::mutate(nfts.asset_id(), receiver_portfolio.did, |balance| { - *balance += transferred_amount + *balance = balance.saturating_add(transferred_amount) }); // Update the portfolio of the sender and the receiver for nft_id in nfts.ids() { @@ -870,6 +870,43 @@ impl Pallet { } }) } + + /// Transfers all `nfts` from `sender_pid` to `receiver_pid`. + /// Note: This functions skips all compliance checks and only checks for onwership. + pub fn simplified_nft_transfer( + sender_pid: PortfolioId, + receiver_pid: PortfolioId, + nfts: NFTs, + inst_id: InstructionId, + inst_memo: Option, + caller_did: IdentityId, + ) -> DispatchResult { + Portfolio::::ensure_portfolio_validity(&receiver_pid)?; + Self::ensure_sender_owns_nfts(&sender_pid, &nfts)?; + Self::unverified_nfts_transfer(&sender_pid, &receiver_pid, &nfts); + Self::deposit_event(Event::NFTPortfolioUpdated( + caller_did, + nfts, + Some(sender_pid), + Some(receiver_pid), + PortfolioUpdateReason::Transferred { + instruction_id: Some(inst_id), + instruction_memo: inst_memo, + }, + )); + Ok(()) + } + + /// Returns `Ok` if `sender_pid` holds all nfts. + fn ensure_sender_owns_nfts(sender_pid: &PortfolioId, nfts: &NFTs) -> DispatchResult { + for nft_id in nfts.ids() { + ensure!( + PortfolioNFT::::contains_key(sender_pid, (nfts.asset_id(), nft_id)), + Error::::InvalidNFTTransferNFTNotOwned + ); + } + Ok(()) + } } impl NFTTrait for Pallet { diff --git a/pallets/runtime/common/src/runtime.rs b/pallets/runtime/common/src/runtime.rs index d45844d19e..4724c58e00 100644 --- a/pallets/runtime/common/src/runtime.rs +++ b/pallets/runtime/common/src/runtime.rs @@ -557,6 +557,7 @@ macro_rules! misc_pallet_impls { type MaxNumberOfPortfolios = MaxNumberOfPortfolios; type MaxNumberOfVenueSigners = MaxNumberOfVenueSigners; type MaxInstructionMediators = MaxInstructionMediators; + type MaximumLockPeriod = MaximumLockPeriod; } impl pallet_sto::Config for Runtime { @@ -736,17 +737,17 @@ macro_rules! runtime_apis { use frame_support::dispatch::result::Result as FrameResult; use node_rpc_runtime_api::asset as rpc_api_asset; - use pallet_identity::types::{AssetDidResult, CddStatus, RpcDidRecords, DidStatus, KeyIdentityData}; + use pallet_identity::types::{AssetDidResult, CddStatus, RpcDidRecords}; + use pallet_identity::types::{DidStatus, KeyIdentityData}; use pallet_pips::{Vote, VoteCount}; use pallet_protocol_fee_rpc_runtime_api::CappedFee; - use polymesh_primitives::asset::AssetId; - use polymesh_primitives::settlement::{InstructionId, ExecuteInstructionInfo, AffirmationCount}; + use polymesh_primitives::asset::{AssetId, CheckpointId}; + use polymesh_primitives::settlement::{ AssetCount, AffirmationCount}; + use polymesh_primitives::settlement::{InstructionId, ExecuteInstructionInfo}; use polymesh_primitives::transfer_compliance::TransferCondition; use polymesh_primitives::compliance_manager::{AssetComplianceResult, ComplianceReport}; - use polymesh_primitives::{ - asset::CheckpointId, IdentityId, Index, NFTs,PortfolioId, Signatory, Ticker, - WeightMeter, IdentityClaim - }; + use polymesh_primitives::{IdentityId, Index, NFTs, PortfolioId}; + use polymesh_primitives::{Signatory, Ticker, WeightMeter, IdentityClaim}; /// The address format for describing accounts. pub type Address = ::Source; @@ -1162,9 +1163,9 @@ macro_rules! runtime_apis { impl node_rpc_runtime_api::settlement::SettlementApi for Runtime { #[inline] fn get_execute_instruction_info( - instruction_id: &InstructionId + instruction_id: InstructionId ) -> Option { - Settlement::execute_instruction_info(instruction_id) + Settlement::manual_execution_weight(instruction_id) } #[inline] @@ -1183,10 +1184,18 @@ macro_rules! runtime_apis { #[inline] fn get_execute_instruction_report(instruction_id: InstructionId) -> Vec { - let mut weight_meter = WeightMeter::max_limit_no_minimum(); - Settlement::execute_instruction_report(&instruction_id, &mut weight_meter) + Settlement::execute_instruction_report(&instruction_id) } + #[inline] + fn lock_instruction_weight(instruction_id: InstructionId) -> Result { + Settlement::lock_instruction_weight(instruction_id) + } + + #[inline] + fn instruction_asset_count(instruction_id: InstructionId) -> AssetCount { + Settlement::instruction_asset_count(&instruction_id) + } } impl node_rpc_runtime_api::compliance::ComplianceApi for Runtime { diff --git a/pallets/runtime/develop/src/runtime.rs b/pallets/runtime/develop/src/runtime.rs index ca1f3cb256..fb2ed79da6 100644 --- a/pallets/runtime/develop/src/runtime.rs +++ b/pallets/runtime/develop/src/runtime.rs @@ -94,6 +94,7 @@ parameter_types! { pub const MaxNumberOfPortfolios: u32 = (10 + 100) * 2; pub const MaxNumberOfVenueSigners: u32 = 50; pub const MaxInstructionMediators: u32 = 4; + pub const MaximumLockPeriod: Moment = 1_440_000; // 24 hours // Multisig pub const MaxMultiSigSigners: u32 = 50; diff --git a/pallets/runtime/mainnet/src/runtime.rs b/pallets/runtime/mainnet/src/runtime.rs index 5375cdf907..d778f3be92 100644 --- a/pallets/runtime/mainnet/src/runtime.rs +++ b/pallets/runtime/mainnet/src/runtime.rs @@ -92,6 +92,7 @@ parameter_types! { pub const MaxNumberOfPortfolios: u32 = (10 + 100) * 2; pub const MaxNumberOfVenueSigners: u32 = 50; pub const MaxInstructionMediators: u32 = 4; + pub const MaximumLockPeriod: Moment = 1_440_000; // 24 hours // Multisig pub const MaxMultiSigSigners: u32 = 50; diff --git a/pallets/runtime/testnet/src/runtime.rs b/pallets/runtime/testnet/src/runtime.rs index 9fe15a5155..d5f7c9d33b 100644 --- a/pallets/runtime/testnet/src/runtime.rs +++ b/pallets/runtime/testnet/src/runtime.rs @@ -95,6 +95,7 @@ parameter_types! { pub const MaxNumberOfPortfolios: u32 = (10 + 100) * 2; pub const MaxNumberOfVenueSigners: u32 = 50; pub const MaxInstructionMediators: u32 = 4; + pub const MaximumLockPeriod: Moment = 1_440_000; // 24 hours // Multisig pub const MaxMultiSigSigners: u32 = 50; diff --git a/pallets/runtime/tests/src/settlement_pallet/execute_instruction.rs b/pallets/runtime/tests/src/settlement_pallet/execute_instruction.rs index 7813c522d3..05d214af09 100644 --- a/pallets/runtime/tests/src/settlement_pallet/execute_instruction.rs +++ b/pallets/runtime/tests/src/settlement_pallet/execute_instruction.rs @@ -3,113 +3,79 @@ use sp_keyring::AccountKeyring; use pallet_asset::BalanceOf; use pallet_portfolio::PortfolioLockedAssets; -use pallet_settlement::{ - AffirmsReceived, Error, Event, InstructionAffirmsPending, InstructionDetails, - InstructionLegStatus, InstructionLegs, InstructionMediatorsAffirmations, InstructionStatuses, - OffChainAffirmations, UserAffirmations, VenueInstructions, -}; -use polymesh_primitives::settlement::{ - AffirmationStatus, Instruction, InstructionId, InstructionStatus, Leg, LegId, SettlementType, -}; +use pallet_settlement::{AffirmsReceived, Error, Event, InstructionAffirmsPending}; +use pallet_settlement::{InstructionDetails, InstructionLegStatus, InstructionLegs}; +use pallet_settlement::{InstructionMediatorsAffirmations, InstructionStatuses}; +use pallet_settlement::{OffChainAffirmations, UserAffirmations, VenueInstructions}; +use polymesh_primitives::settlement::{AffirmationStatus, Instruction, InstructionId}; +use polymesh_primitives::settlement::{InstructionStatus, Leg, LegId, SettlementType}; use polymesh_primitives::PortfolioId; use polymesh_primitives::SystematicIssuers::Settlement as SettlementDID; -use super::setup::create_and_issue_sample_asset_with_venue; +use super::setup::{add_and_affirm_simple_instruction, create_and_issue_sample_asset_with_venue}; use crate::asset_pallet::setup::create_and_issue_sample_asset; use crate::storage::{default_portfolio_btreeset, User}; use crate::{next_block, ExtBuilder, TestStorage}; type Settlement = pallet_settlement::Pallet; type System = frame_system::Pallet; +type Timestamp = pallet_timestamp::Pallet; + +type PortfolioError = pallet_portfolio::Error; #[test] -fn execute_instruction_storage_pruning() { +fn storage_pruning() { ExtBuilder::default().build().execute_with(|| { - let instruction_id = InstructionId(0); + let inst_id = InstructionId(0); let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); let alice = User::new(AccountKeyring::Alice); - let bob_default_portfolio = PortfolioId::default_portfolio(bob.did); - let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); - let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&alice); - let legs: Vec = vec![Leg::Fungible { - sender: PortfolioId::default_portfolio(alice.did), - receiver: PortfolioId::default_portfolio(bob.did), - asset_id, - amount: 1_000, - }]; - assert_ok!(Settlement::add_instruction( - alice.origin(), - venue_id, + let _ = add_and_affirm_simple_instruction( + alice, + bob, + dave, SettlementType::SettleOnAffirmation, - None, - None, - legs.clone(), - None, - )); - assert_ok!(Settlement::affirm_instruction( - alice.origin(), - instruction_id, - default_portfolio_btreeset(alice.did), - )); - assert_ok!(Settlement::affirm_instruction( - bob.origin(), - instruction_id, - default_portfolio_btreeset(bob.did), - )); + ); next_block(); // Asserts all storage have been pruned + assert_eq!(InstructionAffirmsPending::::get(inst_id), 0); + assert_eq!(VenueInstructions::::iter().next(), None); assert_eq!( - InstructionAffirmsPending::::get(instruction_id), - 0 - ); - assert_eq!( - VenueInstructions::::iter_prefix_values(venue_id.unwrap()).next(), - None - ); - assert_eq!( - InstructionLegs::::iter_prefix_values(instruction_id).next(), + InstructionLegs::::iter_prefix_values(inst_id).next(), None ); assert_eq!( - InstructionDetails::::get(instruction_id), + InstructionDetails::::get(inst_id), Instruction::default() ); assert_eq!( - InstructionLegStatus::::iter_prefix_values(instruction_id).next(), + InstructionLegStatus::::iter_prefix_values(inst_id).next(), None ); assert_eq!( - OffChainAffirmations::::iter_prefix_values(instruction_id).next(), + OffChainAffirmations::::iter_prefix_values(inst_id).next(), None ); assert_eq!( - AffirmsReceived::::iter_prefix_values(instruction_id).next(), + AffirmsReceived::::iter_prefix_values(inst_id).next(), None ); assert_eq!( - InstructionMediatorsAffirmations::::iter_prefix_values(instruction_id) - .next(), + InstructionMediatorsAffirmations::::iter_prefix_values(inst_id).next(), None ); + assert_eq!(UserAffirmations::::iter().next(), None); assert_eq!( - UserAffirmations::::get(alice_default_portfolio, instruction_id), - AffirmationStatus::Unknown - ); - assert_eq!( - UserAffirmations::::get(bob_default_portfolio, instruction_id), - AffirmationStatus::Unknown - ); - assert_eq!( - InstructionStatuses::::get(instruction_id), + InstructionStatuses::::get(inst_id), InstructionStatus::Success(1) ); }); } #[test] -fn execute_instruction_storage_rollback() { +fn storage_rollback() { ExtBuilder::default().build().execute_with(|| { System::set_block_number(1); @@ -188,7 +154,7 @@ fn execute_instruction_storage_rollback() { system_events.pop().unwrap().event, crate::storage::EventTest::Settlement(Event::FailedToExecuteInstruction( instruction_id, - Error::::FailedToReleaseLockOrTransferAssets.into() + Error::::FailedAssetTransferringConditions.into() )) ); assert_eq!( diff --git a/pallets/runtime/tests/src/settlement_pallet/lock_instruction.rs b/pallets/runtime/tests/src/settlement_pallet/lock_instruction.rs new file mode 100644 index 0000000000..0f5a120fca --- /dev/null +++ b/pallets/runtime/tests/src/settlement_pallet/lock_instruction.rs @@ -0,0 +1,519 @@ +use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring; +use sp_std::collections::btree_set::BTreeSet; + +use pallet_asset::BalanceOf; +use pallet_portfolio::PortfolioAssetBalances; +use pallet_settlement::{Error, Event, InstructionStatuses, LockedTimestamp}; +use polymesh_primitives::settlement::{InstructionId, InstructionStatus, Leg, SettlementType}; +use polymesh_primitives::traits::PortfolioSubTrait; +use polymesh_primitives::TrustedFor; +use polymesh_primitives::{Claim, PortfolioId, PortfolioKind, PortfolioName, PortfolioNumber}; +use polymesh_primitives::{ClaimType, Condition, ConditionType, CountryCode, Scope, TrustedIssuer}; +use polymesh_runtime_common::Weight; + +use super::setup::{add_and_affirm_simple_instruction, create_and_issue_sample_asset_with_venue}; +use crate::storage::{root, EventTest, User}; +use crate::{ExtBuilder, TestStorage}; + +type Asset = pallet_asset::Pallet; +type ComplianceManager = pallet_compliance_manager::Pallet; +type Identity = pallet_identity::Pallet; +type Portfolio = pallet_portfolio::Pallet; +type Settlement = pallet_settlement::Pallet; +type System = frame_system::Pallet; +type Timestamp = pallet_timestamp::Pallet; + +type AssetError = pallet_asset::Error; +type PortfolioError = pallet_portfolio::Error; +type NFTError = pallet_nft::Error; + +#[test] +fn invalid_caller() { + ExtBuilder::default().build().execute_with(|| { + let inst_id = InstructionId(0); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + let bob_default_portfolio = PortfolioId::default_portfolio(bob.did); + let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); + + let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&alice); + let legs = vec![Leg::Fungible { + sender: alice_default_portfolio, + receiver: bob_default_portfolio, + asset_id, + amount: 1_000, + }]; + + Settlement::add_instruction_with_mediators( + alice.origin(), + venue_id, + SettlementType::SettleOnAffirmation, + None, + None, + legs.clone(), + None, + BTreeSet::from([dave.did]).try_into().unwrap(), + ) + .unwrap(); + + assert_noop!( + Settlement::lock_instruction(alice.origin(), inst_id, Weight::MAX), + Error::::CallerIsNotAMediator + ); + }); +} + +#[test] +fn mediator_has_not_affirmed() { + ExtBuilder::default().build().execute_with(|| { + let inst_id = InstructionId(0); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + let bob_default_portfolio = PortfolioId::default_portfolio(bob.did); + let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); + + let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&alice); + let legs = vec![Leg::Fungible { + sender: alice_default_portfolio, + receiver: bob_default_portfolio, + asset_id, + amount: 1_000, + }]; + + Settlement::add_instruction_with_mediators( + alice.origin(), + venue_id, + SettlementType::SettleAfterLock, + None, + None, + legs.clone(), + None, + BTreeSet::from([dave.did]).try_into().unwrap(), + ) + .unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), inst_id, Weight::MAX), + Error::::NotAllAffirmationsHaveBeenReceived + ); + }); +} + +#[test] +fn invalid_type() { + ExtBuilder::default().build().execute_with(|| { + let inst_id = InstructionId(0); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + let bob_default_portfolio = PortfolioId::default_portfolio(bob.did); + let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); + + let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&alice); + let legs = vec![Leg::Fungible { + sender: alice_default_portfolio, + receiver: bob_default_portfolio, + asset_id, + amount: 1_000, + }]; + + Settlement::add_instruction_with_mediators( + alice.origin(), + venue_id, + SettlementType::SettleOnAffirmation, + None, + None, + legs.clone(), + None, + BTreeSet::from([dave.did]).try_into().unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction_as_mediator(dave.origin(), inst_id, None).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), inst_id, Weight::MAX), + Error::::UnexpectedSettlementType + ); + }); +} + +#[test] +fn missing_affirmation() { + ExtBuilder::default().build().execute_with(|| { + let inst_id = InstructionId(0); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + let bob_default_portfolio = PortfolioId::default_portfolio(bob.did); + let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); + + let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&alice); + let legs = vec![Leg::Fungible { + sender: alice_default_portfolio, + receiver: bob_default_portfolio, + asset_id, + amount: 1_000, + }]; + + Settlement::add_instruction_with_mediators( + alice.origin(), + venue_id, + SettlementType::SettleAfterLock, + None, + None, + legs.clone(), + None, + BTreeSet::from([dave.did]).try_into().unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction_as_mediator(dave.origin(), inst_id, None).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), inst_id, Weight::MAX), + Error::::NotAllAffirmationsHaveBeenReceived + ); + }); +} + +#[test] +fn invalid_inst_status() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + // Force an error + InstructionStatuses::::insert(InstructionId(0), InstructionStatus::Unknown); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::InvalidInstructionStatusForExecution + ); + }); +} + +#[test] +fn expired_mediator_affirmation() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Timestamp::set_timestamp(Timestamp::get() + 2); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::MediatorAffirmationExpired + ); + }); +} + +#[test] +fn unauthorized_venue() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Settlement::set_venue_filtering(dave.origin(), asset_id, true).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::UnauthorizedVenue + ); + }); +} + +#[test] +fn frozen_asset() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + Asset::freeze(dave.origin(), asset_id).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn missing_cdd_claim() { + ExtBuilder::default() + .cdd_providers(vec![AccountKeyring::Eve.to_account_id()]) + .build() + .execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + let cdd_1_id = Identity::get_identity(&AccountKeyring::Eve.to_account_id()).unwrap(); + Identity::invalidate_cdd_claims(root(), cdd_1_id, Timestamp::get(), None).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn receivers_missing_portfolio() { + ExtBuilder::default().build().execute_with(|| { + let inst_id = InstructionId(0); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + let bob_portfolio = PortfolioId::new(bob.did, PortfolioKind::User(PortfolioNumber(1))); + let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); + + let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&alice); + Portfolio::create_portfolio(bob.origin(), PortfolioName(b"MyPid".into())).unwrap(); + + let legs = vec![Leg::Fungible { + sender: alice_default_portfolio, + receiver: bob_portfolio, + asset_id, + amount: 1_000, + }]; + + Settlement::add_instruction_with_mediators( + alice.origin(), + venue_id, + SettlementType::SettleAfterLock, + None, + None, + legs.clone(), + None, + BTreeSet::from([dave.did]).try_into().unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction( + bob.origin(), + inst_id, + BTreeSet::from([bob_portfolio]).try_into().unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction( + alice.origin(), + inst_id, + BTreeSet::from([alice_default_portfolio]) + .try_into() + .unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction_as_mediator(dave.origin(), inst_id, None).unwrap(); + + Portfolio::delete_portfolio(bob.origin(), PortfolioNumber(1)).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), inst_id, Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn receivers_not_compliant() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + ComplianceManager::add_compliance_requirement( + dave.origin(), + asset_id, + Default::default(), + vec![Condition { + condition_type: ConditionType::IsPresent(Claim::Jurisdiction( + CountryCode::BR, + Scope::Asset(asset_id), + )), + issuers: vec![TrustedIssuer { + issuer: dave.did, + trusted_for: TrustedFor::Specific(vec![ClaimType::Jurisdiction]), + }], + }], + ) + .unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn sender_tokens_are_locked() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Portfolio::unlock_tokens(&PortfolioId::default_portfolio(alice.did), &asset_id, 1).unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + PortfolioError::InsufficientTokensLocked + ); + }); +} + +#[test] +fn sender_invalid_portfolio_balance() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + PortfolioAssetBalances::::insert( + &PortfolioId::default_portfolio(alice.did), + &asset_id, + 999, + ); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn sender_invalid_balance() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + BalanceOf::::insert(asset_id, alice.did, 999); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn senders_not_compliant() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + ComplianceManager::add_compliance_requirement( + dave.origin(), + asset_id, + vec![Condition { + condition_type: ConditionType::IsPresent(Claim::Jurisdiction( + CountryCode::BR, + Scope::Asset(asset_id), + )), + issuers: vec![TrustedIssuer { + issuer: dave.did, + trusted_for: TrustedFor::Specific(vec![ClaimType::Jurisdiction]), + }], + }], + Default::default(), + ) + .unwrap(); + + assert_noop!( + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX), + Error::::FailedAssetTransferringConditions + ); + }); +} + +#[test] +fn invalid_weight() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_noop!( + Settlement::lock_instruction( + dave.origin(), + InstructionId(0), + Settlement::lock_instruction_minimum_weight() + ), + Error::::WeightLimitExceeded + ); + }); +} + +#[test] +fn success() { + ExtBuilder::default().build().execute_with(|| { + System::set_block_number(1); + + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_ok!(Settlement::lock_instruction( + dave.origin(), + InstructionId(0), + Weight::MAX + )); + + assert_eq!( + InstructionStatuses::::get(InstructionId(0)), + InstructionStatus::LockedForExecution + ); + + assert!(LockedTimestamp::::get(InstructionId(0)).is_some()); + + let mut system_events = System::events(); + assert_eq!( + system_events.pop().unwrap().event, + EventTest::Settlement(Event::InstructionLocked(dave.did, InstructionId(0))) + ); + }); +} diff --git a/pallets/runtime/tests/src/settlement_pallet/manual_execution.rs b/pallets/runtime/tests/src/settlement_pallet/manual_execution.rs new file mode 100644 index 0000000000..3d64784a34 --- /dev/null +++ b/pallets/runtime/tests/src/settlement_pallet/manual_execution.rs @@ -0,0 +1,352 @@ +use frame_support::{assert_err_ignore_postinfo, assert_noop, assert_ok, assert_storage_noop}; +use sp_keyring::AccountKeyring; + +use pallet_asset::BalanceOf; +use pallet_nft::{NFTOwner, NumberOfNFTs}; +use pallet_portfolio::{PortfolioAssetBalances, PortfolioLockedNFT}; +use pallet_portfolio::{PortfolioLockedAssets, PortfolioNFT}; +use pallet_settlement::Error; +use polymesh_primitives::settlement::{InstructionId, SettlementType}; +use polymesh_primitives::{NFTId, NFTs, PortfolioId, PortfolioKind, PortfolioNumber}; +use polymesh_runtime_common::Weight; + +use super::setup::add_and_affirm_simple_instruction; +use crate::storage::User; +use crate::{ExtBuilder, TestStorage}; + +type Asset = pallet_asset::Pallet; +type Nft = pallet_nft::Pallet; +type Settlement = pallet_settlement::Pallet; +type System = frame_system::Pallet; +type Timestamp = pallet_timestamp::Pallet; + +type AssetError = pallet_asset::Error; +type NFTError = pallet_nft::Error; +type PortfolioError = pallet_portfolio::Error; + +#[test] +fn invalid_caller() { + ExtBuilder::default().build().execute_with(|| { + let eve = User::new(AccountKeyring::Eve); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX).unwrap(); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + eve.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + ), + Error::::CallerIsNotAMediator + )); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + eve.origin(), + InstructionId(0), + Some(PortfolioId::user_portfolio(eve.did, PortfolioNumber(1))), + 1, + 1, + 0, + None + ), + Error::::CallerIsNotAMediator + )); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + bob.origin(), + InstructionId(0), + Some(PortfolioId::user_portfolio(bob.did, PortfolioNumber(1))), + 1, + 1, + 0, + None + ), + Error::::CallerIsNotAMediator + )); + }); +} + +#[test] +fn execute_settle_after_lock_before_lock() { + ExtBuilder::default().build().execute_with(|| { + let eve = User::new(AccountKeyring::Eve); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + eve.origin(), + InstructionId(0), + Some(PortfolioId::user_portfolio(eve.did, PortfolioNumber(1))), + 1, + 1, + 0, + None + ), + Error::::UnexpectedSettlementType + )); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + bob.origin(), + InstructionId(0), + Some(PortfolioId::user_portfolio(bob.did, PortfolioNumber(1))), + 1, + 1, + 0, + None + ), + Error::::UnexpectedSettlementType + )); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + dave.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + ), + Error::::UnexpectedSettlementType + )); + }); +} + +#[test] +fn exceeded_maximum_locking_period() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX).unwrap(); + + Timestamp::set_timestamp(Timestamp::get() + 3); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + dave.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + ), + Error::::ExceededMaximumLockingPeriod + )); + }); +} + +#[test] +fn controller_transfer_nft_is_locked() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (_, asset_id) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX).unwrap(); + + assert_noop!( + Nft::controller_transfer( + dave.origin(), + NFTs::new_unverified(asset_id, vec![NFTId(1)]), + PortfolioId::default_portfolio(alice.did), + PortfolioKind::Default, + ), + NFTError::InvalidNFTTransferNFTIsLocked + ); + }); +} + +#[test] +fn controller_transfer_insufficient_balance() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX).unwrap(); + + assert_noop!( + Asset::controller_transfer( + dave.origin(), + asset_id, + 1_000, + PortfolioId::default_portfolio(alice.did), + ), + PortfolioError::InsufficientPortfolioBalance + ); + }); +} + +#[test] +fn unexpected_settle_on_affirmation() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleOnAffirmation); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + dave.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + ), + Error::::UnexpectedSettlementType + )); + }); +} + +#[test] +fn unexpected_settle_on_block() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction( + alice, + bob, + dave, + SettlementType::SettleOnBlock(System::block_number() + 1), + ); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + dave.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + ), + Error::::UnexpectedSettlementType + )); + }); +} + +#[test] +fn execute_before_lock() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_storage_noop!(assert_err_ignore_postinfo!( + Settlement::execute_manual_instruction( + dave.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + ), + Error::::UnexpectedSettlementType + )); + }); +} + +#[test] +fn successfully_execute_after_locking() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, nft_asset_id) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + Settlement::lock_instruction(dave.origin(), InstructionId(0), Weight::MAX).unwrap(); + + assert_ok!(Settlement::execute_manual_instruction( + dave.origin(), + InstructionId(0), + None, + 1, + 1, + 0, + None + )); + + let bob_default_portfolio = PortfolioId::default_portfolio(bob.did); + let alice_default_portfolio = PortfolioId::default_portfolio(alice.did); + + // The balances should have been updated + assert_eq!(BalanceOf::::get(&asset_id, &alice.did), 0); + assert_eq!(BalanceOf::::get(&asset_id, &bob.did), 1_000); + assert_eq!( + PortfolioAssetBalances::::get(&alice_default_portfolio, &asset_id), + 0 + ); + assert_eq!( + PortfolioAssetBalances::::get(&bob_default_portfolio, &asset_id), + 1_000 + ); + + assert_eq!(NumberOfNFTs::::get(&nft_asset_id, bob.did), 1); + assert_eq!( + NumberOfNFTs::::get(&nft_asset_id, alice.did), + 0 + ); + assert_eq!( + PortfolioNFT::::get(bob_default_portfolio, (&nft_asset_id, NFTId(1))), + true + ); + assert_eq!( + PortfolioNFT::::get(alice_default_portfolio, (&nft_asset_id, NFTId(1))), + false + ); + assert_eq!( + NFTOwner::::get(nft_asset_id, NFTId(1)), + Some(bob_default_portfolio) + ); + + // Alls locks must have been removed + assert_eq!( + PortfolioLockedAssets::::get(alice_default_portfolio, asset_id), + 0 + ); + assert_eq!( + PortfolioLockedNFT::::get( + alice_default_portfolio, + (nft_asset_id, NFTId(1)) + ), + false + ); + }); +} diff --git a/pallets/runtime/tests/src/settlement_pallet/mod.rs b/pallets/runtime/tests/src/settlement_pallet/mod.rs index 30c1539763..294ee1689c 100644 --- a/pallets/runtime/tests/src/settlement_pallet/mod.rs +++ b/pallets/runtime/tests/src/settlement_pallet/mod.rs @@ -1,3 +1,5 @@ -mod execute_instruction; - +pub(crate) mod execute_instruction; +pub(crate) mod lock_instruction; +pub(crate) mod manual_execution; +pub(crate) mod reject_instruction; pub(crate) mod setup; diff --git a/pallets/runtime/tests/src/settlement_pallet/reject_instruction.rs b/pallets/runtime/tests/src/settlement_pallet/reject_instruction.rs new file mode 100644 index 0000000000..8bd9c3aeb1 --- /dev/null +++ b/pallets/runtime/tests/src/settlement_pallet/reject_instruction.rs @@ -0,0 +1,191 @@ +use frame_support::{assert_noop, assert_ok}; +use sp_keyring::AccountKeyring; + +use pallet_portfolio::PortfolioLockedAssets; +use pallet_settlement::{AffirmsReceived, InstructionAffirmsPending, InstructionLegs}; +use pallet_settlement::{Error, InstructionLegStatus, InstructionStatuses}; +use pallet_settlement::{InstructionMediatorsAffirmations, UserAffirmations}; +use polymesh_primitives::settlement::{AssetCount, InstructionId}; +use polymesh_primitives::settlement::{InstructionStatus, SettlementType}; +use polymesh_primitives::{PortfolioId, PortfolioNumber}; +use polymesh_runtime_common::Weight; + +use super::setup::add_and_affirm_simple_instruction; +use crate::storage::User; +use crate::{ExtBuilder, TestStorage}; + +type Settlement = pallet_settlement::Pallet; +type System = frame_system::Pallet; +type Timestamp = pallet_timestamp::Pallet; + +#[test] +fn invalid_caller() { + ExtBuilder::default().build().execute_with(|| { + let eve = User::new(AccountKeyring::Eve); + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let _ = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_noop!( + Settlement::reject_instruction_as_mediator(eve.origin(), InstructionId(0), None), + Error::::CallerIsNotAParty + ); + + assert_noop!( + Settlement::reject_instruction( + bob.origin(), + InstructionId(0), + PortfolioId::user_portfolio(bob.did, PortfolioNumber(1)) + ), + Error::::CallerIsNotAParty + ); + }); +} + +#[test] +fn invalid_caller_locked_for_execution() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let _ = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_ok!(Settlement::lock_instruction( + dave.origin(), + InstructionId(0), + Weight::MAX + )); + + assert_noop!( + Settlement::reject_instruction_as_mediator(bob.origin(), InstructionId(0), None), + Error::::CallerIsNotAMediator + ); + + assert_noop!( + Settlement::reject_instruction_with_count( + bob.origin(), + InstructionId(0), + PortfolioId::default_portfolio(bob.did), + Some(AssetCount::new(1, 1, 0)) + ), + Error::::CallerIsNotAMediator + ); + }); +} + +#[test] +fn invalid_weight() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let _ = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_noop!( + Settlement::reject_instruction_as_mediator( + dave.origin(), + InstructionId(0), + Some(AssetCount::new(0, 0, 1)) + ), + Error::::NumberOfTransferredNFTsUnderestimated + ); + }); +} + +#[test] +fn success() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let (asset_id, _) = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_ok!(Settlement::lock_instruction( + dave.origin(), + InstructionId(0), + Weight::MAX + )); + + assert_ok!(Settlement::reject_instruction_as_mediator( + dave.origin(), + InstructionId(0), + Some(AssetCount::new(1, 1, 0)) + )); + + assert_eq!( + InstructionStatuses::::get(InstructionId(0)), + InstructionStatus::Rejected(System::block_number()) + ); + + assert_eq!( + InstructionLegStatus::::iter_prefix(InstructionId(0)).next(), + None + ); + + assert_eq!( + InstructionAffirmsPending::::get(InstructionId(0)), + 0 + ); + + assert_eq!( + AffirmsReceived::::iter_prefix(InstructionId(0)).next(), + None + ); + + assert_eq!(UserAffirmations::::iter().next(), None); + + assert_eq!( + InstructionLegs::::iter_prefix(InstructionId(0)).next(), + None + ); + + assert_eq!( + InstructionMediatorsAffirmations::::iter_prefix(InstructionId(0)).next(), + None + ); + + assert_eq!( + PortfolioLockedAssets::::get( + PortfolioId::default_portfolio(alice.did), + asset_id + ), + 0 + ); + }); +} + +#[test] +fn success_expired_lock() { + ExtBuilder::default().build().execute_with(|| { + let bob = User::new(AccountKeyring::Bob); + let dave = User::new(AccountKeyring::Dave); + let alice = User::new(AccountKeyring::Alice); + + let _ = + add_and_affirm_simple_instruction(alice, bob, dave, SettlementType::SettleAfterLock); + + assert_ok!(Settlement::lock_instruction( + dave.origin(), + InstructionId(0), + Weight::MAX + )); + + Timestamp::set_timestamp(Timestamp::get() + 3); + + assert_ok!(Settlement::reject_instruction_with_count( + bob.origin(), + InstructionId(0), + PortfolioId::default_portfolio(bob.did), + Some(AssetCount::new(1, 1, 0)) + )); + }); +} diff --git a/pallets/runtime/tests/src/settlement_pallet/setup.rs b/pallets/runtime/tests/src/settlement_pallet/setup.rs index ac91e0b328..8469517a57 100644 --- a/pallets/runtime/tests/src/settlement_pallet/setup.rs +++ b/pallets/runtime/tests/src/settlement_pallet/setup.rs @@ -1,16 +1,21 @@ use frame_support::assert_ok; +use sp_std::collections::btree_set::BTreeSet; use pallet_settlement::VenueCounter; use polymesh_primitives::asset::AssetId; -use polymesh_primitives::settlement::{VenueDetails, VenueId, VenueType}; +use polymesh_primitives::settlement::{InstructionId, Leg}; +use polymesh_primitives::settlement::{SettlementType, VenueDetails, VenueId, VenueType}; +use polymesh_primitives::{BlockNumber, NFTId, NFTs, PortfolioId, WeightMeter}; use crate::asset_pallet::setup::create_and_issue_sample_asset; +use crate::asset_pallet::setup::create_and_issue_sample_nft; use crate::storage::User; use crate::TestStorage; type Asset = pallet_asset::Pallet; type Nft = pallet_nft::Pallet; type Settlement = pallet_settlement::Pallet; +type Timestamp = pallet_timestamp::Pallet; /// Calls [`create_and_issue_sample_asset`] and creates a venue for `asset_owner`. pub fn create_and_issue_sample_asset_with_venue(asset_owner: &User) -> (AssetId, Option) { @@ -21,8 +26,99 @@ pub fn create_and_issue_sample_asset_with_venue(asset_owner: &User) -> (AssetId, asset_owner.origin(), VenueDetails::default(), vec![asset_owner.acc()], - VenueType::Other + VenueType::Other, )); (asset_id, Some(venue_id)) } + +/// 1. The mediator creates and issues one fungible and one non-fungible asset; +/// 2. The mediator transfers the assets to the sender; +/// 2. The mediator creates a settlement instruction with the assets; +/// 3. All parties affirm the instruction; +/// +/// `Note:` The instruction transfers 1_000 tokens and 1 NFT from the sender's default portfolio to the receiver's default portfolio. +pub fn add_and_affirm_simple_instruction( + sender: User, + receiver: User, + mediator: User, + settlement_type: SettlementType, +) -> (AssetId, AssetId) { + let med_default_portfolio = PortfolioId::default_portfolio(mediator.did); + let rcv_default_portfolio = PortfolioId::default_portfolio(receiver.did); + let sender_default_portfolio = PortfolioId::default_portfolio(sender.did); + + // The mediator creates both assets to allow controller transfer tests + let (asset_id, venue_id) = create_and_issue_sample_asset_with_venue(&mediator); + let nft_asset_id = create_and_issue_sample_nft(&mediator); + Asset::simplified_fungible_transfer( + asset_id, + med_default_portfolio, + sender_default_portfolio, + 1_000, + InstructionId(0), + None, + mediator.did, + &mut WeightMeter::max_limit_no_minimum(), + ) + .unwrap(); + Nft::simplified_nft_transfer( + med_default_portfolio, + sender_default_portfolio, + NFTs::new_unverified(nft_asset_id, vec![NFTId(1)]), + InstructionId(0), + None, + mediator.did, + ) + .unwrap(); + + let legs = vec![ + Leg::Fungible { + sender: sender_default_portfolio, + receiver: rcv_default_portfolio, + asset_id, + amount: 1_000, + }, + Leg::NonFungible { + sender: sender_default_portfolio, + receiver: rcv_default_portfolio, + nfts: NFTs::new_unverified(nft_asset_id, vec![NFTId(1)]), + }, + ]; + Settlement::add_instruction_with_mediators( + mediator.origin(), + venue_id, + settlement_type, + None, + None, + legs.clone(), + None, + BTreeSet::from([mediator.did]).try_into().unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction( + receiver.origin(), + InstructionId(0), + BTreeSet::from([rcv_default_portfolio]).try_into().unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction( + sender.origin(), + InstructionId(0), + BTreeSet::from([sender_default_portfolio]) + .try_into() + .unwrap(), + ) + .unwrap(); + + Settlement::affirm_instruction_as_mediator( + mediator.origin(), + InstructionId(0), + Some(Timestamp::get() + 1), + ) + .unwrap(); + + (asset_id, nft_asset_id) +} diff --git a/pallets/runtime/tests/src/settlement_test.rs b/pallets/runtime/tests/src/settlement_test.rs index 54211ae1e6..0eee1a6aef 100644 --- a/pallets/runtime/tests/src/settlement_test.rs +++ b/pallets/runtime/tests/src/settlement_test.rs @@ -839,7 +839,7 @@ fn failed_execution() { 0, None, ), - Error::FailedToReleaseLockOrTransferAssets + Error::FailedAssetTransferringConditions )); }); } @@ -2418,7 +2418,7 @@ fn settle_manual_instruction() { assert_affirm_instruction!(bob.origin(), instruction_id, bob.did); // Ensure it gave the correct error message after it failed because the execution block number hasn't reached yet - assert_noop!( + assert_storage_noop!(assert_err_ignore_postinfo!( Settlement::execute_manual_instruction( alice.origin(), instruction_id, @@ -2428,11 +2428,8 @@ fn settle_manual_instruction() { 0, None ), - DispatchErrorWithPostInfo { - post_info: Some(Settlement::execute_manual_instruction_minimum_weight()).into(), - error: Error::InstructionSettleBlockNotReached.into() - } - ); + Error::InstructionSettleBlockNotReached + )); next_block(); // Ensure bob can't execute instruction with portfolio set to none since he is not the venue creator assert_noop!( @@ -2447,7 +2444,7 @@ fn settle_manual_instruction() { ), DispatchErrorWithPostInfo { post_info: Some(Settlement::execute_manual_instruction_minimum_weight()).into(), - error: Error::Unauthorized.into() + error: Error::CallerIsNotAParty.into() } ); // Ensure correct error message when wrong number of legs is given @@ -2530,7 +2527,7 @@ fn settle_manual_instruction_with_portfolio() { assert_affirm_instruction!(bob.origin(), instruction_id, bob.did); // Ensure it gave the correct error message after it failed because the execution block number hasn't reached yet - assert_noop!( + assert_storage_noop!(assert_err_ignore_postinfo!( Settlement::execute_manual_instruction( alice.origin(), instruction_id, @@ -2540,11 +2537,8 @@ fn settle_manual_instruction_with_portfolio() { 0, None ), - DispatchErrorWithPostInfo { - post_info: Some(Settlement::execute_manual_instruction_minimum_weight()).into(), - error: Error::InstructionSettleBlockNotReached.into() - } - ); + Error::InstructionSettleBlockNotReached + )); next_block(); // Ensure correct error is shown when non party member tries to execute function assert_noop!( @@ -3130,7 +3124,7 @@ fn add_and_execute_offchain_instruction() { ), DispatchErrorWithPostInfo { post_info: Some(Settlement::execute_manual_instruction_minimum_weight()).into(), - error: Error::Unauthorized.into() + error: Error::CallerIsNotAParty.into() } ); assert_ok!(Settlement::execute_manual_instruction( @@ -4171,7 +4165,7 @@ fn reject_instruction_as_mediator() { assert_noop!( Settlement::reject_instruction_as_mediator(dave.origin(), InstructionId(0), None), - Error::CallerIsNotAMediator + Error::CallerIsNotAParty ); assert_ok!(Settlement::reject_instruction_as_mediator( charlie.origin(), diff --git a/pallets/runtime/tests/src/storage.rs b/pallets/runtime/tests/src/storage.rs index b14389c5fb..37f0446a23 100644 --- a/pallets/runtime/tests/src/storage.rs +++ b/pallets/runtime/tests/src/storage.rs @@ -214,6 +214,7 @@ parameter_types! { pub const MaxNumberOfFungibleAssets: u32 = 100; pub const MaxNumberOfNFTsPerLeg: u32 = 10; pub const MaxNumberOfNFTs: u32 = 100; + pub const MaximumLockPeriod: Moment = 2; // Multisig pub const MaxMultiSigSigners: u32 = 50; diff --git a/pallets/settlement/src/benchmarking.rs b/pallets/settlement/src/benchmarking.rs index 8e29b35c08..af1606d98c 100644 --- a/pallets/settlement/src/benchmarking.rs +++ b/pallets/settlement/src/benchmarking.rs @@ -29,7 +29,7 @@ use polymesh_primitives::checked_inc::CheckedInc; use polymesh_primitives::constants::currency::ONE_UNIT; use polymesh_primitives::constants::ENSURED_MAX_LEN; use polymesh_primitives::settlement::ReceiptMetadata; -use polymesh_primitives::{IdentityId, Memo, NFTId, NFTs, PortfolioId, Ticker}; +use polymesh_primitives::{IdentityId, Memo, NFTId, NFTs, PortfolioId, Ticker, WeightMeter}; use crate::*; @@ -468,8 +468,7 @@ benchmarks! { }: _(alice.origin, InstructionId(1), receipt_details, portfolios) execute_manual_instruction { - // Number of fungible, non-fungible and offchain assets in the instruction - let f in 1..T::MaxNumberOfFungibleAssets::get(); + let f in 0..T::MaxNumberOfFungibleAssets::get(); let n in 0..T::MaxNumberOfNFTs::get(); let o in 0..T::MaxNumberOfOffChainAssets::get(); @@ -480,8 +479,16 @@ benchmarks! { let settlement_type = SettlementType::SettleManual(0u32.into()); let venue_id = create_venue_::(alice.did(), vec![alice.account(), bob.account()]); - setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, false, false); - }: _(alice.origin, InstructionId(1), None, f, n, o, Some(Weight::MAX)) + let p = setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, false, false); + let weight = { + frame_support_with_transaction(|| { + let inst_info = + Pallet::::manual_execution_weight(InstructionId(1)).unwrap(); + TransactionOutcome::Rollback(Ok::(inst_info.consumed_weight())) + }) + .unwrap() + }; + }: _(p.asset_mediators[0].clone().origin, InstructionId(1), None, f, n, o, Some(weight)) add_instruction{ // Number of fungible, non-fungible and offchain LEGS in the instruction @@ -554,22 +561,6 @@ benchmarks! { let portfolios = parameters.sdr_portfolios(); }: _(alice.origin, InstructionId(1), portfolios) - reject_instruction { - // Number of fungible, non-fungible and offchain LEGS in the instruction - let f in 1..T::MaxNumberOfFungibleAssets::get(); - let n in 0..T::MaxNumberOfNFTs::get(); - let o in 0..T::MaxNumberOfOffChainAssets::get(); - - let m = T::MaxInstructionMediators::get(); - - let alice = UserBuilder::::default().generate_did().build("Alice"); - let bob = UserBuilder::::default().generate_did().build("Bob"); - let settlement_type = SettlementType::SettleOnBlock(100u32.into()); - let venue_id = create_venue_::(alice.did(), vec![alice.account(), bob.account()]); - - let parameters = setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, false, false); - }: _(alice.origin, InstructionId(1), parameters.portfolios.sdr_portfolios[0]) - execute_instruction_paused { // Number of fungible, non-fungible and offchain assets in the instruction let f in 1..T::MaxNumberOfFungibleAssets::get() as u32; @@ -781,9 +772,8 @@ benchmarks! { ).unwrap(); }: _(david.origin, InstructionId(1)) - reject_instruction_as_mediator { - // Number of fungible, non-fungible and offchain LEGS in the instruction - let f in 1..T::MaxNumberOfFungibleAssets::get(); + base_reject_instruction { + let f in 0..T::MaxNumberOfFungibleAssets::get(); let n in 0..T::MaxNumberOfNFTs::get(); let o in 0..T::MaxNumberOfOffChainAssets::get(); @@ -791,9 +781,128 @@ benchmarks! { let alice = UserBuilder::::default().generate_did().build("Alice"); let bob = UserBuilder::::default().generate_did().build("Bob"); - let settlement_type = SettlementType::SettleOnBlock(100u32.into()); + let settlement_type = SettlementType::SettleManual(0u32.into()); let venue_id = create_venue_::(alice.did(), vec![alice.account(), bob.account()]); + let inst_id = InstructionId(1); let parameters = setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, false, false); - }: _(parameters.asset_mediators[0].origin.clone(), InstructionId(1), None) + let inst_legs: Vec<_> = InstructionLegs::::iter_prefix(&inst_id).collect(); + }: { + Pallet::::base_reject_instruction( + parameters.asset_mediators[0].clone().origin.into(), + inst_id, + None, + Some(AssetCount::new(f, n, o)), + &mut WeightMeter::max_limit_no_minimum() + ) + .unwrap() + } + + lock_instruction_extrinsic { + let f in 0..T::MaxNumberOfFungibleAssets::get(); + let n in 0..T::MaxNumberOfNFTs::get(); + let o in 0..T::MaxNumberOfOffChainAssets::get(); + + let m = T::MaxInstructionMediators::get(); + + let alice = UserBuilder::::default().generate_did().build("Alice"); + let bob = UserBuilder::::default().generate_did().build("Bob"); + let settlement_type = SettlementType::SettleAfterLock; + let venue_id = create_venue_::(alice.did(), vec![alice.account(), bob.account()]); + + let inst_id = InstructionId(1); + let parameters = setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, true, true); + let weight = { + frame_support_with_transaction(|| { + let weight = Pallet::::lock_instruction_weight(InstructionId(1)).unwrap(); + TransactionOutcome::Rollback(Ok::(weight)) + }) + .unwrap() + }; + }: { + Pallet::::lock_instruction( + parameters.asset_mediators[0].clone().origin.into(), + inst_id, + weight + ) + .unwrap(); + } + + execute_locked_instruction { + let f in 0..T::MaxNumberOfFungibleAssets::get(); + let n in 0..T::MaxNumberOfNFTs::get(); + let o in 0..T::MaxNumberOfOffChainAssets::get(); + + let m = T::MaxInstructionMediators::get(); + + let alice = UserBuilder::::default().generate_did().build("Alice"); + let bob = UserBuilder::::default().generate_did().build("Bob"); + let settlement_type = SettlementType::SettleAfterLock; + let venue_id = create_venue_::(alice.did(), vec![alice.account(), bob.account()]); + + let p = setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, false, false); + + Pallet::::base_lock_instruction( + p.asset_mediators[0].clone().origin.into(), + InstructionId(1), + false, + &mut WeightMeter::max_limit_no_minimum(), + ) + .unwrap(); + + let weight = { + frame_support_with_transaction(|| { + let inst_info = + Pallet::::manual_execution_weight(InstructionId(1)).unwrap(); + TransactionOutcome::Rollback(Ok::(inst_info.consumed_weight())) + }) + .unwrap() + }; + }: { + Pallet::::execute_manual_instruction( + p.asset_mediators[0].clone().origin.into(), + InstructionId(1), + None, + f, + n, + o, + Some(weight), + ) + .unwrap(); + } + + execute_manual_instruction_paused { + let f in 0..T::MaxNumberOfFungibleAssets::get(); + let n in 0..T::MaxNumberOfNFTs::get(); + let o in 0..T::MaxNumberOfOffChainAssets::get(); + + let m = T::MaxInstructionMediators::get(); + + let alice = UserBuilder::::default().generate_did().build("Alice"); + let bob = UserBuilder::::default().generate_did().build("Bob"); + let settlement_type = SettlementType::SettleManual(0u32.into()); + let venue_id = create_venue_::(alice.did(), vec![alice.account(), bob.account()]); + + let p = setup_execute_instruction::(&alice, &bob, settlement_type, venue_id, f, n, o, m, true, true); + + let weight = { + frame_support_with_transaction(|| { + let inst_info = + Pallet::::manual_execution_weight(InstructionId(1)).unwrap(); + TransactionOutcome::Rollback(Ok::(inst_info.consumed_weight())) + }) + .unwrap() + }; + }: { + Pallet::::execute_manual_instruction( + p.asset_mediators[0].clone().origin.into(), + InstructionId(1), + None, + f, + n, + o, + Some(weight), + ) + .unwrap(); + } } diff --git a/pallets/settlement/src/lib.rs b/pallets/settlement/src/lib.rs index ee590f6a41..e66f10e250 100644 --- a/pallets/settlement/src/lib.rs +++ b/pallets/settlement/src/lib.rs @@ -55,6 +55,8 @@ use frame_support::dispatch::{ PostDispatchInfo, }; use frame_support::pallet_prelude::*; +use frame_support::storage::with_transaction as frame_support_with_transaction; +use frame_support::storage::TransactionOutcome; use frame_support::traits::schedule::{DispatchTime, Named}; use frame_support::traits::Get; use frame_support::weights::Weight; @@ -69,6 +71,7 @@ use sp_std::vec; use pallet_asset::MandatoryMediators; use pallet_base::{ensure_string_limited, try_next_post}; +use pallet_identity::DidRecords; use polymesh_primitives::asset::AssetId; use polymesh_primitives::constants::queue_priority::SETTLEMENT_INSTRUCTION_EXECUTION_PRIORITY; use polymesh_primitives::crypto::verify_signature; @@ -176,6 +179,12 @@ pub mod pallet { /// An instruction with mediators has been created. /// Parameters: [`InstructionId`] of the instruction and the [`IdentityId`] of all mediators. InstructionMediators(InstructionId, BTreeSet), + /// An instruction has been sucessfully locked for execution + /// + /// Parameters: + /// - `IdentityId`: The [`IdentityId`] of the caller. + /// - `InstructionId`: The [`InstructionId`] of the instruction. + InstructionLocked(IdentityId, InstructionId), } pub trait WeightInfo { @@ -192,7 +201,6 @@ pub mod pallet { fn add_and_affirm_instruction(f: u32, n: u32, o: u32) -> Weight; fn affirm_instruction(f: u32, n: u32) -> Weight; fn withdraw_affirmation(f: u32, n: u32, o: u32) -> Weight; - fn reject_instruction(f: u32, n: u32, o: u32) -> Weight; fn execute_instruction_paused(f: u32, n: u32, o: u32) -> Weight; fn execute_scheduled_instruction(f: u32, n: u32, o: u32) -> Weight; fn ensure_root_origin() -> Weight; @@ -203,7 +211,10 @@ pub mod pallet { fn add_and_affirm_with_mediators(f: u32, n: u32, o: u32, m: u32) -> Weight; fn affirm_instruction_as_mediator() -> Weight; fn withdraw_affirmation_as_mediator() -> Weight; - fn reject_instruction_as_mediator(f: u32, n: u32, o: u32) -> Weight; + fn base_reject_instruction(f: u32, n: u32, o: u32) -> Weight; + fn lock_instruction_extrinsic(f: u32, n: u32, o: u32) -> Weight; + fn execute_locked_instruction(f: u32, n: u32, o: u32) -> Weight; + fn execute_manual_instruction_paused(f: u32, n: u32, o: u32) -> Weight; fn add_and_affirm_with_mediators_legs( legs: &[Leg], @@ -226,15 +237,18 @@ pub mod pallet { Self::add_and_affirm_instruction(f, n, o) } fn execute_manual_weight_limit( - weight_limit: &Option, + weight: &Option, f: &u32, n: &u32, o: &u32, ) -> Weight { - if let Some(weight_limit) = weight_limit { - return *weight_limit; + let min_weight = Self::execute_locked_instruction(0, 0, 1); + + if let Some(weight) = weight { + return weight.max(min_weight); } - Self::execute_manual_instruction(*f, *n, *o) + + Self::execute_manual_instruction(*f, *n, *o).max(min_weight) } fn get_transfer_by_asset(legs: &[Leg], portfolios: u32) -> (u32, u32, u32) { let asset_count = @@ -372,30 +386,24 @@ pub mod pallet { } } } - fn reject_instruction_input(asset_count: Option, as_mediator: bool) -> Weight { - match asset_count { - Some(asset_count) => { - if as_mediator { - return Self::reject_instruction_as_mediator( - asset_count.fungible(), - asset_count.non_fungible(), - asset_count.off_chain(), - ); - } - Self::reject_instruction( - asset_count.fungible(), - asset_count.non_fungible(), - asset_count.off_chain(), - ) - } - None => { - let (f, n, o) = (10, 100, 10); - if as_mediator { - return Self::reject_instruction_as_mediator(f, n, o); - } - Self::reject_instruction(f, n, o) - } - } + + fn reject_instruction(inst_asset_count: Option) -> Weight { + let inst_asset_count = inst_asset_count.unwrap_or(AssetCount::new(10, 100, 10)); + + let input_weight = Self::base_reject_instruction( + inst_asset_count.fungible(), + inst_asset_count.non_fungible(), + inst_asset_count.off_chain(), + ); + + let min_weight = Self::base_reject_instruction(0, 0, 1); + + input_weight.max(min_weight) + } + + fn lock_instruction(weight_limit: Weight) -> Weight { + let min_weight = Self::lock_instruction_extrinsic(0, 0, 1); + weight_limit.max(min_weight) } } @@ -452,6 +460,10 @@ pub mod pallet { /// Maximum number mediators in the instruction level (this does not include asset mediators). #[pallet::constant] type MaxInstructionMediators: Get; + + /// The maximum time period that an instruction can be held in the `LockedForExecution` status. + #[pallet::constant] + type MaximumLockPeriod: Get; } #[pallet::error] @@ -544,6 +556,16 @@ pub mod pallet { MediatorAffirmationExpired, /// Offchain assets must have a venue. OffChainAssetsMustHaveAVenue, + /// Unexpected settlement type. + UnexpectedSettlementType, + /// [`InstructionStatus::Unknow`] can't be rejected. + InvalidInstructionStatusForRejection, + /// All locked instructions must register a lock timestamp. + LockTimestampNotFound, + /// The instruction has been locked for too much time. + ExceededMaximumLockingPeriod, + /// Not all conditions for transferring the asset have been met. + FailedAssetTransferringConditions, } storage_migration_ver!(3); @@ -703,6 +725,11 @@ pub mod pallet { ValueQuery, >; + /// The moment the instruction was moved to the `LockedForExecution` status. + #[pallet::storage] + pub type LockedTimestamp = + StorageMap<_, Twox64Concat, InstructionId, T::Moment, OptionQuery>; + /// Storage version. #[pallet::storage] pub(super) type StorageVersion = StorageValue<_, Version, ValueQuery>; @@ -776,12 +803,12 @@ pub mod pallet { details: VenueDetails, ) -> DispatchResult { ensure_string_limited::(&details)?; - let did = pallet_identity::Pallet::::ensure_perms(origin)?; - Self::venue_for_management(id, did)?; + let caller_did = pallet_identity::Pallet::::ensure_perms(origin)?; + Self::ensure_venue_creator(&id, &caller_did)?; // Commit to storage. Details::::insert(id, details.clone()); - Self::deposit_event(Event::VenueDetailsUpdated(did, id, details)); + Self::deposit_event(Event::VenueDetailsUpdated(caller_did, id, details)); Ok(()) } @@ -796,13 +823,13 @@ pub mod pallet { id: VenueId, typ: VenueType, ) -> DispatchResult { - let did = pallet_identity::Pallet::::ensure_perms(origin)?; + let caller_did = pallet_identity::Pallet::::ensure_perms(origin)?; - let mut venue = Self::venue_for_management(id, did)?; + let mut venue = Self::ensure_venue_creator(&id, &caller_did)?; venue.venue_type = typ; VenueInfo::::insert(id, venue); - Self::deposit_event(Event::VenueTypeUpdated(did, id, typ)); + Self::deposit_event(Event::VenueTypeUpdated(caller_did, id, typ)); Ok(()) } @@ -945,19 +972,24 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { let mut weight_meter = Self::ensure_valid_weight_meter( Self::execute_manual_instruction_minimum_weight(), - weight_limit.unwrap_or(Self::execute_manual_instruction_weight_limit( - fungible_transfers, - nfts_transfers, - offchain_transfers, - )), + weight_limit.unwrap_or_else(|| { + ::WeightInfo::execute_manual_instruction( + fungible_transfers, + nfts_transfers, + offchain_transfers, + ) + }), )?; + let input_cost = AssetCount::new(fungible_transfers, nfts_transfers, offchain_transfers); - Self::base_execute_manual_instruction( + + Self::base_manual_execution( origin, id, portfolio, &input_cost, + false, &mut weight_meter, ) .map_err(|e| DispatchErrorWithPostInfo { @@ -1090,14 +1122,18 @@ pub mod pallet { /// /// # Permissions /// * Portfolio - #[pallet::weight(::WeightInfo::reject_instruction_input(None, false))] + #[pallet::weight(::WeightInfo::reject_instruction(None))] #[pallet::call_index(13)] pub fn reject_instruction( origin: OriginFor, id: InstructionId, portfolio: PortfolioId, ) -> DispatchResultWithPostInfo { - Self::base_reject_instruction(origin, id, Some(portfolio), None) + let mut weight_meter = Self::ensure_valid_weight_meter( + Self::reject_instruction_minimum_weight(), + ::WeightInfo::reject_instruction(Some(AssetCount::new(10, 100, 10))), + )?; + Self::base_reject_instruction(origin, id, Some(portfolio), None, &mut weight_meter) } /// Root callable extrinsic, used as an internal call to execute a scheduled settlement instruction. @@ -1191,7 +1227,7 @@ pub mod pallet { /// /// # Permissions /// * Portfolio - #[pallet::weight(::WeightInfo::reject_instruction_input(*number_of_assets, false))] + #[pallet::weight(::WeightInfo::reject_instruction(*number_of_assets))] #[pallet::call_index(17)] pub fn reject_instruction_with_count( origin: OriginFor, @@ -1199,8 +1235,21 @@ pub mod pallet { portfolio: PortfolioId, number_of_assets: Option, ) -> DispatchResult { - Self::base_reject_instruction(origin, id, Some(portfolio), number_of_assets) - .map_err(|e| e.error)?; + let mut weight_meter = Self::ensure_valid_weight_meter( + Self::reject_instruction_minimum_weight(), + ::WeightInfo::reject_instruction(number_of_assets), + ) + .map_err(|e| e.error)?; + + Self::base_reject_instruction( + origin, + id, + Some(portfolio), + number_of_assets, + &mut weight_meter, + ) + .map_err(|e| e.error)?; + Ok(()) } @@ -1351,14 +1400,57 @@ pub mod pallet { /// * `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. - #[pallet::weight(::WeightInfo::reject_instruction_input(*number_of_assets, true))] + #[pallet::weight(::WeightInfo::reject_instruction(*number_of_assets))] #[pallet::call_index(23)] pub fn reject_instruction_as_mediator( origin: OriginFor, instruction_id: InstructionId, number_of_assets: Option, ) -> DispatchResultWithPostInfo { - Self::base_reject_instruction(origin, instruction_id, None, number_of_assets) + let mut weight_meter = Self::ensure_valid_weight_meter( + Self::reject_instruction_minimum_weight(), + ::WeightInfo::reject_instruction(number_of_assets), + )?; + + Self::base_reject_instruction( + origin, + instruction_id, + None, + number_of_assets, + &mut weight_meter, + ) + } + + /// Moves the instruction status to `LockedForExecution`. This function must be called by a + /// mediator of the instruction and will only suceed if the following conditions are met: + /// - All affirmations have been received. + /// - Instruction is pending or has failed at least one time. + /// - All mediator's affirmations are still valid. + /// - All assets are in the allowed venue list. + /// - All senders have the right amount of assets being transferred. + /// - All senders and receivers are compliant and have valid CDD claims. + /// - All assets' statistics are still valid. + /// - There are no frozen assets. + /// + /// # Arguments + /// * `origin` - The origin of the call, specifying the caller. + /// * `inst_id` - The [`InstructionId`] of the instruction to be locked. + /// * `weight_limit` - A maximum [`Weight`] value to be charged for locking the instruction. + #[pallet::weight(::WeightInfo::lock_instruction(*weight_limit))] + #[pallet::call_index(24)] + pub fn lock_instruction( + origin: OriginFor, + inst_id: InstructionId, + weight_limit: Weight, + ) -> DispatchResultWithPostInfo { + let mut weight_meter = Self::ensure_valid_weight_meter( + Self::lock_instruction_minimum_weight(), + weight_limit, + )?; + + Self::base_lock_instruction(origin, inst_id, false, &mut weight_meter)?; + + Ok(PostDispatchInfo::from(Some(weight_meter.consumed()))) } } } @@ -1414,11 +1506,10 @@ impl Pallet { )) } - // Extract `Venue` with `id`, assuming it was created by `did`, or error. - fn venue_for_management(id: VenueId, did: IdentityId) -> Result { - // Ensure venue exists & that DID created it. - let venue = VenueInfo::::get(id).ok_or(Error::::InvalidVenue)?; - ensure!(venue.creator == did, Error::::Unauthorized); + /// Returns `Ok(Venue)` if `venue_id` was created by `did`. + fn ensure_venue_creator(venue_id: &VenueId, did: &IdentityId) -> Result { + let venue = VenueInfo::::get(venue_id).ok_or(Error::::InvalidVenue)?; + ensure!(&venue.creator == did, Error::::Unauthorized); Ok(venue) } @@ -1450,7 +1541,7 @@ impl Pallet { // Ensure venue exists & sender is its creator. if let Some(venue_id) = venue_id { - Self::venue_for_management(venue_id, did)?; + Self::ensure_venue_creator(&venue_id, &did)?; } // Verifies if all legs are valid. @@ -1715,8 +1806,9 @@ impl Pallet { id: InstructionId, caller_did: IdentityId, weight_meter: &mut WeightMeter, + skip_base_charge: bool, ) -> DispatchResult { - if let Err(e) = Self::execute_instruction(id, caller_did, weight_meter) { + if let Err(e) = Self::execute_instruction(id, caller_did, weight_meter, skip_base_charge) { InstructionStatuses::::insert(id, InstructionStatus::Failed); return Err(e); } @@ -1724,91 +1816,53 @@ impl Pallet { } fn execute_instruction( - instruction_id: InstructionId, + inst_id: InstructionId, caller_did: IdentityId, weight_meter: &mut WeightMeter, + skip_base_charge: bool, ) -> DispatchResult { - let mut failed_leg_id = None; - let tx_result = with_transaction(|| { - // Ensures the number of pending affirmations is zero - let n_pending_affirmations = InstructionAffirmsPending::::take(instruction_id); - ensure!( - n_pending_affirmations == 0, - Error::::NotAllAffirmationsHaveBeenReceived - ); - // Ensures the instruction is pending or has failed at least one time - let instruction_status = InstructionStatuses::::get(instruction_id); - ensure!( - instruction_status == InstructionStatus::Pending - || instruction_status == InstructionStatus::Failed, - Error::::InvalidInstructionStatusForExecution - ); - // Ensures all mediator's affirmations are still valid - Self::ensure_non_expired_affirmations(&instruction_id)?; - - // The order of execution of the legs matter in some edge cases around compliance. - let mut instruction_legs: Vec<(LegId, Leg)> = - InstructionLegs::::drain_prefix(&instruction_id).collect(); - instruction_legs.sort_by_key(|leg_id_leg| leg_id_leg.0); - - // Ensures all affirmations have been received - Self::ensure_no_missing_affirmation(&instruction_id, &instruction_legs)?; + // The order of execution of the legs matter in some edge cases around compliance + let mut inst_legs: Vec<_> = InstructionLegs::::iter_prefix(&inst_id).collect(); + inst_legs.sort_by_key(|leg| leg.0); + let inst_asset_count = AssetCount::from_legs(&inst_legs); - let instruction_asset_count = AssetCount::from_legs(&instruction_legs); + // Manual executions charge the weight in advance + if !skip_base_charge { weight_meter .check_accrue(::WeightInfo::execute_instruction_paused( - instruction_asset_count.fungible(), - instruction_asset_count.non_fungible(), - instruction_asset_count.off_chain(), + inst_asset_count.fungible(), + inst_asset_count.non_fungible(), + inst_asset_count.off_chain(), )) .map_err(|_| Error::::WeightLimitExceeded)?; + } - // Ensures the venue is allowed for all tickers in the instruction - let instruction_details = InstructionDetails::::take(instruction_id); - Self::ensure_allowed_venue(&instruction_legs, instruction_details.venue_id)?; - - // Attempts to release the locks - Self::release_locks(instruction_id, &instruction_legs)?; + Self::validate_execute_instruction_pre_conditions(&inst_id, &inst_legs)?; + let inst_memo = InstructionMemos::::get(&inst_id); - // Transfer all fungible an non fungible assets - let instruction_memo = InstructionMemos::::get(&instruction_id); - match Self::transfer_pending_legs( - instruction_id, - &instruction_legs, - instruction_memo, - caller_did, - weight_meter, - ) { - Ok(_) => { - // Remove remaning storage - if let Some(venue_id) = instruction_details.venue_id { - VenueInstructions::::remove(venue_id, instruction_id); - } - let _ = InstructionLegStatus::::clear_prefix( - instruction_id, - instruction_legs.len() as u32, - None, - ); - // Change instruction status - InstructionStatuses::::insert( - instruction_id, - InstructionStatus::Success(System::::block_number()), - ); - Self::deposit_event(Event::InstructionExecuted(caller_did, instruction_id)); - Ok(()) - } - Err(leg_id) => { - failed_leg_id = Some(leg_id); - Err(Error::::FailedToReleaseLockOrTransferAssets.into()) - } + let mut failed_leg_id = None; + let tx_result = with_transaction(|| { + Self::release_locks(&inst_id, &inst_legs)?; + if let Err(leg_id) = + Self::transfer_assets(inst_id, &inst_legs, inst_memo, caller_did, weight_meter) + { + failed_leg_id = Some(leg_id); + return Err(Error::::FailedAssetTransferringConditions.into()); } + Self::prune_instruction(&inst_id, &inst_legs)?; + Self::deposit_event(Event::InstructionExecuted(caller_did, inst_id)); + InstructionStatuses::::insert( + inst_id, + InstructionStatus::Success(System::::block_number()), + ); + Ok(()) }); - // Since with_transaction reverts events as well, the events have to be emitted here + // Since with_transaction reverts events as well, the event has to be emitted here if let Some(failed_leg_id) = failed_leg_id { Self::deposit_event(Event::LegFailedExecution( caller_did, - instruction_id, + inst_id, failed_leg_id, )); } @@ -1816,12 +1870,50 @@ impl Pallet { tx_result } - /// Returns `Ok` if all mediator's affirmation are still valid. Otherwise, returns an error. - /// This call also removes all elements from the `InstructionMediatorsAffirmations` storage. - fn ensure_non_expired_affirmations(instruction_id: &InstructionId) -> DispatchResult { + /// Returns `Ok` if the following conditions for executing the instruction are met: + /// - Instruction is pending or has failed at least one time + /// - All affirmations have been received + /// - All mediator's affirmations are still valid + /// - All assets are in the allowed venue list + fn validate_execute_instruction_pre_conditions( + inst_id: &InstructionId, + inst_legs: &[(LegId, Leg)], + ) -> DispatchResult { + Self::ensure_instruction_is_pending_or_failed(inst_id)?; + + ensure!( + InstructionAffirmsPending::::get(inst_id) == 0, + Error::::NotAllAffirmationsHaveBeenReceived + ); + + Self::validate_mediators_affirmations(inst_id)?; + + Self::validate_parties_affirmations(inst_id, inst_legs)?; + + let inst_details = InstructionDetails::::get(inst_id); + Self::ensure_allowed_venue(inst_legs, inst_details.venue_id)?; + + Ok(()) + } + + /// Returns `Ok` if the instruction status is `Pending` or `Failed`. + fn ensure_instruction_is_pending_or_failed(inst_id: &InstructionId) -> DispatchResult { + let inst_status = InstructionStatuses::::get(inst_id); + + ensure!( + inst_status == InstructionStatus::Pending || inst_status == InstructionStatus::Failed, + Error::::InvalidInstructionStatusForExecution + ); + + Ok(()) + } + + /// Returns `Ok` if all mediator's affirmation are still valid. + fn validate_mediators_affirmations(inst_id: &InstructionId) -> DispatchResult { let current_timestamp = >::get(); - for (_, mediator_affirmation) in - InstructionMediatorsAffirmations::::drain_prefix(instruction_id) + + for mediator_affirmation in + InstructionMediatorsAffirmations::::iter_prefix_values(inst_id) { match mediator_affirmation { MediatorAffirmationStatus::Affirmed { expiry, .. } => { @@ -1837,48 +1929,48 @@ impl Pallet { } } } + Ok(()) } - /// Returns `Ok` if all affirmations have been received. Otherwise, returns an error. - /// This call also removes all elements from `UserAffirmations`, `AffirmsReceived` and `OffChainAffirmations` storage. - fn ensure_no_missing_affirmation( - instruction_id: &InstructionId, - instruction_legs: &[(LegId, Leg)], + /// Returns `Ok` if all affirmations have been received. + #[rustfmt::skip] + fn validate_parties_affirmations( + inst_id: &InstructionId, + inst_legs: &[(LegId, Leg)], ) -> DispatchResult { let mut unique_portfolios = BTreeSet::new(); - for (leg_id, leg) in instruction_legs { + for (leg_id, leg) in inst_legs { match leg { - Leg::Fungible { - sender, receiver, .. - } - | Leg::NonFungible { - sender, receiver, .. - } => { + Leg::Fungible { sender, receiver, .. } + | Leg::NonFungible { sender, receiver, .. } => { + ensure!( + InstructionLegStatus::::get(inst_id, leg_id) + == LegStatus::ExecutionPending, + Error::::UnexpectedLegStatus + ); + if unique_portfolios.insert(sender) { - let sdr_affirmation_status = - UserAffirmations::::take(sender, instruction_id); + let sdr_affirmation_status = UserAffirmations::::get(sender, inst_id); ensure!( sdr_affirmation_status == AffirmationStatus::Affirmed, Error::::NotAllAffirmationsHaveBeenReceived ); - let sdr_affirmation_status = - AffirmsReceived::::take(instruction_id, sender); + let sdr_affirmation_status = AffirmsReceived::::get(inst_id, sender); ensure!( sdr_affirmation_status == AffirmationStatus::Affirmed, Error::::NotAllAffirmationsHaveBeenReceived ); } + if unique_portfolios.insert(receiver) { - let rcv_affirmation_status = - UserAffirmations::::take(receiver, instruction_id); + let rcv_affirmation_status = UserAffirmations::::get(receiver, inst_id); ensure!( rcv_affirmation_status == AffirmationStatus::Affirmed, Error::::NotAllAffirmationsHaveBeenReceived ); - let rcv_affirmation_status = - AffirmsReceived::::take(instruction_id, receiver); + let rcv_affirmation_status = AffirmsReceived::::get(inst_id, receiver); ensure!( rcv_affirmation_status == AffirmationStatus::Affirmed, Error::::NotAllAffirmationsHaveBeenReceived @@ -1886,11 +1978,18 @@ impl Pallet { } } Leg::OffChain { .. } => { - ensure!( - OffChainAffirmations::::take(instruction_id, leg_id) - == AffirmationStatus::Affirmed, - Error::::NotAllAffirmationsHaveBeenReceived, - ); + match InstructionLegStatus::::get(inst_id, leg_id) { + LegStatus::ExecutionToBeSkipped(_, _) => { + ensure!( + OffChainAffirmations::::get(inst_id, leg_id) + == AffirmationStatus::Affirmed, + Error::::NotAllAffirmationsHaveBeenReceived, + ); + } + LegStatus::PendingTokenLock | LegStatus::ExecutionPending => { + return Err(Error::::UnexpectedLegStatus.into()); + } + } } } } @@ -1898,108 +1997,98 @@ impl Pallet { Ok(()) } - fn transfer_pending_legs( - instruction_id: InstructionId, - instruction_legs: &[(LegId, Leg)], - instruction_memo: Option, + #[rustfmt::skip] + fn transfer_assets( + inst_id: InstructionId, + inst_legs: &[(LegId, Leg)], + inst_memo: Option, caller_did: IdentityId, weight_meter: &mut WeightMeter, ) -> Result<(), LegId> { - for (leg_id, leg) in instruction_legs { - if InstructionLegStatus::::get(instruction_id, leg_id) == LegStatus::ExecutionPending - { - match leg { - Leg::Fungible { - sender, - receiver, - asset_id, - amount, - } => { - if >::base_transfer( - *sender, - *receiver, - *asset_id, - *amount, - Some(instruction_id), - instruction_memo.clone(), - caller_did, - weight_meter, - ) - .is_err() - { - return Err(*leg_id); - } + for (leg_id, leg) in inst_legs { + match leg { + Leg::Fungible { sender, receiver, asset_id, amount } => { + if Asset::::base_transfer( + *sender, + *receiver, + *asset_id, + *amount, + Some(inst_id), + inst_memo.clone(), + caller_did, + weight_meter, + ) + .is_err() + { + return Err(*leg_id); } - Leg::NonFungible { - sender, - receiver, - nfts, - } => { - if >::base_nft_transfer( - *sender, - *receiver, - nfts.clone(), - instruction_id, - instruction_memo.clone(), - caller_did, - weight_meter, - ) - .is_err() - { - return Err(*leg_id); - } + } + Leg::NonFungible { sender, receiver, nfts } => { + if Nft::::base_nft_transfer( + *sender, + *receiver, + nfts.clone(), + inst_id, + inst_memo.clone(), + caller_did, + weight_meter, + ) + .is_err() + { + return Err(*leg_id); } - Leg::OffChain { .. } => {} } + Leg::OffChain { .. } => {} } } + Ok(()) } - /// Clears the storage for a rejected instruction and updates the instruction status to - /// [`InstructionStatus::Rejected`]. - fn prune_rejected_instruction(instruction_id: InstructionId) { - let instruction_details = InstructionDetails::::take(&instruction_id); + /// Removes the following storage related to the instruction: + /// - `InstructionDetails` + /// - `VenueInstructions` + /// - `InstructionAffirmsPending` + /// - `InstructionMediatorsAffirmations` + /// - `InstructionLegStatus` + /// - `UserAffirmations` + /// - `AffirmsReceived` + /// - `OffChainAffirmations` + #[rustfmt::skip] + fn prune_instruction( + inst_id: &InstructionId, + inst_legs: &[(LegId, Leg)], + ) -> DispatchResult { + let instruction_details = InstructionDetails::::take(&inst_id); + if let Some(venue_id) = instruction_details.venue_id { - VenueInstructions::::remove(venue_id, instruction_id); + VenueInstructions::::remove(venue_id, inst_id); } - InstructionAffirmsPending::::remove(instruction_id); - let _ = InstructionMediatorsAffirmations::::clear_prefix( - instruction_id, - T::MaxInstructionMediators::get(), - None, - ); - // We need all portfolios to clear the UserAffirmations storage - let instruction_legs = - InstructionLegs::::drain_prefix(&instruction_id).collect::>(); - let _ = InstructionLegStatus::::clear_prefix( - &instruction_id, - instruction_legs.len() as u32, - None, - ); - for (leg_id, leg) in instruction_legs { + + InstructionAffirmsPending::::remove(inst_id); + + let _ = InstructionMediatorsAffirmations::::clear_prefix(inst_id, u32::MAX, None); + + for (leg_id, leg) in inst_legs { match leg { - Leg::Fungible { - sender, receiver, .. - } - | Leg::NonFungible { - sender, receiver, .. - } => { - UserAffirmations::::remove(sender, instruction_id); - UserAffirmations::::remove(receiver, instruction_id); - AffirmsReceived::::remove(instruction_id, sender); - AffirmsReceived::::remove(instruction_id, receiver); + Leg::Fungible { sender, receiver, .. } + | Leg::NonFungible { sender, receiver, .. } => { + UserAffirmations::::remove(sender, inst_id); + UserAffirmations::::remove(receiver, inst_id); + AffirmsReceived::::remove(inst_id, sender); + AffirmsReceived::::remove(inst_id, receiver); + InstructionLegStatus::::remove(inst_id, leg_id); + InstructionLegs::::remove(inst_id, leg_id); } Leg::OffChain { .. } => { - OffChainAffirmations::::remove(instruction_id, leg_id); + OffChainAffirmations::::remove(inst_id, leg_id); + InstructionLegStatus::::remove(inst_id, leg_id); + InstructionLegs::::remove(inst_id, leg_id); } } } - // Update the intruction Status to InstructionStatus::Rejected - InstructionStatuses::::insert( - instruction_id, - InstructionStatus::Rejected(System::::block_number()), - ); + + Ok(()) } pub fn unsafe_affirm_instruction( @@ -2043,7 +2132,7 @@ impl Pallet { Ok(filtered_legs) } - fn release_locks(id: InstructionId, instruction_legs: &[(LegId, Leg)]) -> DispatchResult { + fn release_locks(id: &InstructionId, instruction_legs: &[(LegId, Leg)]) -> DispatchResult { for (leg_id, leg) in instruction_legs { if let LegStatus::ExecutionPending = InstructionLegStatus::::get(id, leg_id) { Self::unlock_via_leg(&leg)?; @@ -2258,7 +2347,6 @@ impl Pallet { receipt: Option>, portfolios: BTreeSet, caller_did: IdentityId, - weight_meter: &mut WeightMeter, ) -> DispatchResult { match receipt { Some(receipt) => { @@ -2271,7 +2359,6 @@ impl Pallet { InstructionAffirmsPending::::get(id), InstructionDetails::::get(id).settlement_type, caller_did, - weight_meter, )?; Ok(()) } @@ -2281,7 +2368,6 @@ impl Pallet { affirms_pending: u64, settlement_type: SettlementType, caller_did: IdentityId, - weight_meter: &mut WeightMeter, ) -> DispatchResult { // We assume `settlement_type == SettleOnAffirmation`, // to be defensive, however, this is checked before instruction execution. @@ -2289,7 +2375,12 @@ impl Pallet { // We use execute_instruction here directly // and not the execute_instruction_retryable variant // because direct settlement is not retryable. - Self::execute_instruction(id, caller_did, weight_meter)?; + Self::execute_instruction( + id, + caller_did, + &mut WeightMeter::max_limit_no_minimum(), + true, + )?; } Ok(()) } @@ -2323,23 +2414,23 @@ impl Pallet { FilteredLegs::filter_sender(instruction_legs, portfolio) } - fn get_instruction_asset_count(id: &InstructionId) -> AssetCount { - // Get the weight limit for the instruction - let legs: Vec<(LegId, Leg)> = InstructionLegs::::iter_prefix(id).collect(); - AssetCount::from_legs(&legs) + /// Returns the [`AssetCount`] for the given `inst_id`. + pub fn instruction_asset_count(inst_id: &InstructionId) -> AssetCount { + let inst_legs: Vec<_> = InstructionLegs::::iter_prefix(inst_id).collect(); + AssetCount::from_legs(&inst_legs) } fn base_update_venue_signers( did: IdentityId, - id: VenueId, + venue_id: VenueId, signers: Vec, add_signers: bool, ) -> DispatchResult { // Ensure venue exists & sender is its creator. - Self::venue_for_management(id, did)?; + Self::ensure_venue_creator(&venue_id, &did)?; if add_signers { - let current_number_of_signers = NumberOfVenueSigners::::get(id); + let current_number_of_signers = NumberOfVenueSigners::::get(venue_id); ensure!( (current_number_of_signers as usize).saturating_add(signers.len()) <= T::MaxNumberOfVenueSigners::get() as usize, @@ -2347,95 +2438,120 @@ impl Pallet { ); for signer in &signers { ensure!( - !VenueSigners::::get(&id, &signer), + !VenueSigners::::get(&venue_id, &signer), Error::::SignerAlreadyExists ); } - NumberOfVenueSigners::::insert(id, current_number_of_signers + signers.len() as u32); + NumberOfVenueSigners::::insert( + venue_id, + current_number_of_signers + signers.len() as u32, + ); for signer in &signers { - >::insert(&id, &signer, true); + >::insert(&venue_id, &signer, true); } } else { for signer in &signers { ensure!( - VenueSigners::::get(&id, &signer), + VenueSigners::::get(&venue_id, &signer), Error::::SignerDoesNotExist ); } - let current_number_of_signers = NumberOfVenueSigners::::get(id); + let current_number_of_signers = NumberOfVenueSigners::::get(venue_id); NumberOfVenueSigners::::insert( - id, + venue_id, current_number_of_signers.saturating_sub(signers.len() as u32), ); for signer in &signers { - >::remove(&id, &signer); + >::remove(&venue_id, &signer); } } - Self::deposit_event(Event::VenueSignersUpdated(did, id, signers, add_signers)); + Self::deposit_event(Event::VenueSignersUpdated( + did, + venue_id, + signers, + add_signers, + )); Ok(()) } fn base_reject_instruction( origin: OriginFor, - instruction_id: InstructionId, - portfolio: Option, - instruction_count: Option, + inst_id: InstructionId, + caller_pid: Option, + input_asset_count: Option, + weight_meter: &mut WeightMeter, ) -> DispatchResultWithPostInfo { - // Makes sure the instruction exists - ensure!( - InstructionStatuses::::get(instruction_id) != InstructionStatus::Unknown, - Error::::UnknownInstruction - ); - // Get all legs for the instruction - let legs: Vec<(LegId, Leg)> = InstructionLegs::::iter_prefix(&instruction_id).collect(); - let instruction_asset_count = AssetCount::from_legs(&legs); - // If the fee was estimated in advance, the input values must be at least equal to the actual values - if let Some(instruction_count) = instruction_count { - Self::ensure_valid_cost(&instruction_asset_count, &instruction_count)?; - } - // Check if the caller is a mediator or a portfolio owner let origin_data = pallet_identity::Pallet::::ensure_origin_call_permissions(origin)?; - let actual_weight = { - match portfolio { - Some(portfolio) => { - // The portfolio must be present in at least one leg - ensure!( - Self::is_portfolio_present(&legs, &portfolio), - Error::::CallerIsNotAParty - ); - // The caller must have the right permissions to the portfolio - T::Portfolio::ensure_portfolio_custody_and_permission( - portfolio, - origin_data.primary_did, + let caller_did = origin_data.primary_did; + + let inst_legs: Vec<_> = InstructionLegs::::iter_prefix(&inst_id).collect(); + let inst_asset_count = AssetCount::from_legs(&inst_legs); + + if let Some(input_asset_count) = input_asset_count { + Self::ensure_valid_cost(&inst_asset_count, &input_asset_count)?; + } + + Self::check_accrue( + weight_meter, + ::WeightInfo::base_reject_instruction( + inst_asset_count.fungible() as u32, + inst_asset_count.non_fungible() as u32, + inst_asset_count.off_chain() as u32, + ), + )?; + + let inst_details = InstructionDetails::::get(&inst_id); + match InstructionStatuses::::get(inst_id) { + InstructionStatus::Pending | InstructionStatus::Failed => { + Self::ensure_valid_caller( + caller_did, + origin_data.secondary_key.as_ref(), + caller_pid, + inst_details.venue_id, + &inst_id, + &inst_legs, + )?; + } + InstructionStatus::LockedForExecution => { + // If the locking perid is exceeded, any party can reject the instruction + if Self::ensure_maximum_locking_period_not_exceeded(&inst_id).is_err() { + Self::ensure_valid_caller( + caller_did, origin_data.secondary_key.as_ref(), + caller_pid, + inst_details.venue_id, + &inst_id, + &inst_legs, )?; - Self::reject_instruction_weight(instruction_asset_count, false) - } - None => { - // The caller must be a mediator + } else { ensure!( - InstructionMediatorsAffirmations::::get( - instruction_id, - origin_data.primary_did - ) != MediatorAffirmationStatus::Unknown, + Self::ensure_mediator(&inst_id, &caller_did).is_ok(), Error::::CallerIsNotAMediator ); - Self::reject_instruction_weight(instruction_asset_count, true) } } - }; - // All checks have been made - write to storage - Self::release_locks(instruction_id, &legs)?; - let _ = T::Scheduler::cancel_named(instruction_id.execution_name()); - // Remove all data from storage - Self::prune_rejected_instruction(instruction_id); - Self::deposit_event(Event::InstructionRejected( - origin_data.primary_did, - instruction_id, - )); - // Return the actual weight for the call - Ok(PostDispatchInfo::from(Some(actual_weight))) + InstructionStatus::Unknown + | InstructionStatus::Rejected(_) + | InstructionStatus::Success(_) => { + return Err(Error::::InvalidInstructionStatusForRejection.into()); + } + } + + Self::release_locks(&inst_id, &inst_legs)?; + + // Note: ignoring the error here is fine, since the instruction might not be scheduled yet + let _ = T::Scheduler::cancel_named(inst_id.execution_name()); + + Self::prune_instruction(&inst_id, &inst_legs)?; + InstructionStatuses::::insert( + inst_id, + InstructionStatus::Rejected(System::::block_number()), + ); + + Self::deposit_event(Event::InstructionRejected(caller_did, inst_id)); + + Ok(PostDispatchInfo::from(Some(weight_meter.consumed()))) } /// Returns `Ok` if the number of fungible, nonfungible and offchain assets is under the input given by the user. @@ -2499,7 +2615,7 @@ impl Pallet { weight_meter: &mut WeightMeter, ) -> PostDispatchInfo { let caller_did = SettlementDID.as_id(); - if let Err(e) = Self::execute_instruction_retryable(id, caller_did, weight_meter) { + if let Err(e) = Self::execute_instruction_retryable(id, caller_did, weight_meter, false) { Self::deposit_event(Event::FailedToExecuteInstruction(id, e)); } PostDispatchInfo::from(Some(weight_meter.consumed())) @@ -2628,59 +2744,108 @@ impl Pallet { pallet_asset::Assets::::contains_key(asset_id) } - fn base_execute_manual_instruction( + fn base_manual_execution( origin: OriginFor, - id: InstructionId, - portfolio: Option, - input_cost: &AssetCount, + inst_id: InstructionId, + caller_pid: Option, + input_asset_count: &AssetCount, + skip_caller_check: bool, weight_meter: &mut WeightMeter, ) -> DispatchResultWithPostInfo { - // check origin has the permissions required and valid instruction - let (caller_did, sk, instruction_details) = - Self::ensure_origin_perm_and_instruction_validity(origin, id, true)?; + let origin_data = pallet_identity::Pallet::::ensure_origin_call_permissions(origin)?; + let caller_did = origin_data.primary_did; + let caller_sk = origin_data.secondary_key.as_ref(); - let instruction_legs: Vec<(LegId, Leg)> = InstructionLegs::::iter_prefix(&id).collect(); - match portfolio { - Some(portfolio) => { - // Ensure that the caller is a party of this instruction - T::Portfolio::ensure_portfolio_custody_and_permission( - portfolio, - caller_did, - sk.as_ref(), + let inst_legs: Vec<_> = InstructionLegs::::iter_prefix(inst_id).collect(); + let inst_asset_count = AssetCount::from_legs(&inst_legs); + Self::ensure_valid_cost(&inst_asset_count, input_asset_count)?; + + let inst_details = InstructionDetails::::get(&inst_id); + + // RPC don't need to check the caller + if !skip_caller_check && inst_details.settlement_type != SettlementType::SettleAfterLock { + Self::ensure_valid_caller( + caller_did, + caller_sk, + caller_pid, + inst_details.venue_id, + &inst_id, + &inst_legs, + )?; + } + + match InstructionStatuses::::get(&inst_id) { + InstructionStatus::Pending => { + Self::check_accrue( + weight_meter, + ::WeightInfo::execute_manual_instruction_paused( + inst_asset_count.fungible() as u32, + inst_asset_count.non_fungible() as u32, + inst_asset_count.off_chain() as u32, + ), )?; - ensure!( - Self::is_portfolio_present(&instruction_legs, &portfolio), - Error::::CallerIsNotAParty - ); + Self::ensure_manual_settlement_type(inst_details.settlement_type)?; + Self::execute_instruction_retryable(inst_id, caller_did, weight_meter, true)?; } - None => { - // If the caller is not the venue creator, they should be a counter party in an offchain leg - match instruction_details.venue_id { - Some(venue_id) => { - if Self::venue_for_management(venue_id, caller_did).is_err() { - ensure!( - Self::is_offchain_party(&instruction_legs, &caller_did), - Error::::Unauthorized - ); - }; - } - None => { - ensure!( - Self::is_offchain_party(&instruction_legs, &caller_did), - Error::::Unauthorized - ); - } + InstructionStatus::Failed => { + Self::check_accrue( + weight_meter, + ::WeightInfo::execute_manual_instruction_paused( + inst_asset_count.fungible() as u32, + inst_asset_count.non_fungible() as u32, + inst_asset_count.off_chain() as u32, + ), + )?; + Self::execute_instruction_retryable(inst_id, caller_did, weight_meter, true)?; + } + InstructionStatus::LockedForExecution => { + Self::check_accrue( + weight_meter, + ::WeightInfo::execute_locked_instruction( + inst_asset_count.fungible() as u32, + inst_asset_count.non_fungible() as u32, + inst_asset_count.off_chain() as u32, + ), + )?; + if !skip_caller_check { + ensure!( + Self::ensure_mediator(&inst_id, &caller_did).is_ok(), + Error::::CallerIsNotAMediator + ); } + Self::simplified_asset_transfer( + inst_id, + inst_legs.clone(), + caller_did, + weight_meter, + )?; + Self::prune_instruction(&inst_id, &inst_legs)?; + } + InstructionStatus::Success(_) + | InstructionStatus::Unknown + | InstructionStatus::Rejected(_) => { + return Err(Error::::InvalidInstructionStatusForExecution.into()) } } - let instruction_asset_count = AssetCount::from_legs(&instruction_legs); - Self::ensure_valid_cost(&instruction_asset_count, input_cost)?; + Self::deposit_event(Event::SettlementManuallyExecuted(caller_did, inst_id)); + Ok(PostDispatchInfo::from(Some(weight_meter.consumed()))) + } - Self::execute_instruction_retryable(id, caller_did, weight_meter)?; - Self::deposit_event(Event::SettlementManuallyExecuted(caller_did, id)); + /// Returns `Ok` if [`SettlementType::SettleManual`] and the `block_number` is reached. + fn ensure_manual_settlement_type( + settlement_type: SettlementType, + ) -> DispatchResult { + if let SettlementType::SettleManual(block_number) = settlement_type { + ensure!( + System::::block_number() >= block_number, + Error::::InstructionSettleBlockNotReached + ); - Ok(PostDispatchInfo::from(Some(weight_meter.consumed()))) + return Ok(()); + } + + Err(Error::::UnexpectedSettlementType.into()) } /// Returns `Ok` if `origin` represents the root, otherwise returns an `Err` with the consumed weight for this function. @@ -2691,43 +2856,6 @@ impl Pallet { }) } - /// Returns `true` if the given `portfolio_id` is a party in the given `instruction_set`, otherwise returns `false`. - fn is_portfolio_present(instruction_set: &[(LegId, Leg)], portfolio_id: &PortfolioId) -> bool { - for (_, leg) in instruction_set { - match leg { - Leg::Fungible { - sender, receiver, .. - } - | Leg::NonFungible { - sender, receiver, .. - } => { - if sender == portfolio_id || receiver == portfolio_id { - return true; - } - } - Leg::OffChain { .. } => continue, - } - } - false - } - - /// Returns `true` if the given `caller_did` is a party in any [`Leg::OffChain`] in the `instruction_set`. - fn is_offchain_party(instruction_set: &[(LegId, Leg)], caller_did: &IdentityId) -> bool { - for (_, leg) in instruction_set { - if let Leg::OffChain { - sender_identity, - receiver_identity, - .. - } = leg - { - if sender_identity == caller_did || receiver_identity == caller_did { - return true; - } - } - } - false - } - /// Ensures the all receipts are valid. A receipt is considered valid if the signer is allowed by the venue, /// if the receipt has not been used before, if the receipt's `leg_id` and `instruction_id` are referencing the /// correct instruction/leg and if its signature is valid. @@ -2910,7 +3038,7 @@ impl Pallet { if n_pending_affirmations == 0 && instruction.settlement_type == SettlementType::SettleOnAffirmation { - let instruction_asset_count = Self::get_instruction_asset_count(&instruction_id); + let instruction_asset_count = Self::instruction_asset_count(&instruction_id); let weight_limit = Self::execute_scheduled_instruction_weight_limit( instruction_asset_count.fungible(), instruction_asset_count.non_fungible(), @@ -2973,6 +3101,214 @@ impl Pallet { Ok(()) } + /// Returns `Ok` if any of the following conditions is true: + /// - The caller has the permission of the given portfolio and that portfolio is a party in the instruction. + /// - The caller is the venue creator of the instruction. + /// - The caller is an instruction mediator. + /// - The caller is a counter party in an offchain leg. + fn ensure_valid_caller( + caller_did: IdentityId, + caller_sk: Option<&SecondaryKey>, + caller_pid: Option, + venue_id: Option, + inst_id: &InstructionId, + inst_legs: &[(LegId, Leg)], + ) -> DispatchResult { + if let Some(caller_pid) = caller_pid { + T::Portfolio::ensure_portfolio_custody_and_permission( + caller_pid, caller_did, caller_sk, + )?; + Self::ensure_portfolio_belongs_to_instruction(&inst_id, &caller_pid)?; + return Ok(()); + } + + if let Some(venue_id) = venue_id { + if Self::ensure_venue_creator(&venue_id, &caller_did).is_ok() { + return Ok(()); + } + } + + if Self::ensure_mediator(&inst_id, &caller_did).is_ok() { + return Ok(()); + } + + if Self::is_offchain_party(&caller_did, inst_legs) { + return Ok(()); + } + + Err(Error::::CallerIsNotAParty.into()) + } + + /// Returns `Ok` if the `pid` is a party in the instruction of the given `inst_id`. + fn ensure_portfolio_belongs_to_instruction( + inst_id: &InstructionId, + pid: &PortfolioId, + ) -> DispatchResult { + match UserAffirmations::::get(pid, inst_id) { + AffirmationStatus::Unknown => Err(Error::::CallerIsNotAParty.into()), + AffirmationStatus::Pending | AffirmationStatus::Affirmed => Ok(()), + } + } + + /// Returns `true` if `caller_did` is a party in any offchain leg in the instruction. + #[rustfmt::skip] + fn is_offchain_party(caller_did: &IdentityId, inst_legs: &[(LegId, Leg)]) -> bool { + for (_, leg) in inst_legs { + if let Leg::OffChain { sender_identity, receiver_identity, .. } = leg { + if sender_identity == caller_did || receiver_identity == caller_did { + return true; + } + } + } + false + } + + /// Returns `Ok` if the given `did` is a mediator in the instruction. + fn ensure_mediator(inst_id: &InstructionId, did: &IdentityId) -> DispatchResult { + if InstructionMediatorsAffirmations::::get(inst_id, did) + == MediatorAffirmationStatus::Unknown + { + return Err(Error::::CallerIsNotAMediator.into()); + } + + Ok(()) + } + + /// If the caller is a mediator and all conditions for executing the instruction are met, updates the instruction status to `LockedForExecution`. + fn base_lock_instruction( + origin: OriginFor, + inst_id: InstructionId, + skip_caller_check: bool, + weight_meter: &mut WeightMeter, + ) -> DispatchResult { + let caller_did = pallet_identity::Pallet::::ensure_perms(origin.clone())?; + + if !skip_caller_check { + Self::ensure_mediator(&inst_id, &caller_did)?; + } + + let inst_details = InstructionDetails::::get(&inst_id); + ensure!( + inst_details.settlement_type == SettlementType::SettleAfterLock, + Error::::UnexpectedSettlementType + ); + + // The order of execution of the legs matter in some edge cases around compliance + let mut inst_legs: Vec<_> = InstructionLegs::::iter_prefix(&inst_id).collect(); + inst_legs.sort_by_key(|leg| leg.0); + let inst_asset_count = AssetCount::from_legs(&inst_legs); + + Self::check_accrue( + weight_meter, + ::WeightInfo::lock_instruction_extrinsic( + inst_asset_count.fungible(), + inst_asset_count.non_fungible(), + inst_asset_count.off_chain(), + ), + )?; + + Self::validate_execute_instruction_pre_conditions(&inst_id, &inst_legs)?; + + let inst_memo = InstructionMemos::::get(&inst_id); + frame_support_with_transaction(|| { + if let Err(e) = Self::release_locks(&inst_id, &inst_legs) { + return TransactionOutcome::Rollback(Err(e)); + }; + + if Self::transfer_assets(inst_id, &inst_legs, inst_memo, caller_did, weight_meter) + .is_err() + { + return TransactionOutcome::Rollback(Err( + Error::::FailedAssetTransferringConditions.into(), + )); + } + + TransactionOutcome::Rollback(Ok(())) + })?; + + InstructionStatuses::::insert(inst_id, InstructionStatus::LockedForExecution); + LockedTimestamp::::insert(inst_id, pallet_timestamp::Pallet::::get()); + + Self::deposit_event(Event::InstructionLocked(caller_did, inst_id)); + Ok(()) + } + + /// Transfer all assets in the instruction. Only the following checks are assessed: + /// - The locking period must be below the maximum. + /// - All assets are locked. + /// - All senders must have the required balance. + #[rustfmt::skip] + fn simplified_asset_transfer( + inst_id: InstructionId, + inst_legs: Vec<(LegId, Leg)>, + caller_did: IdentityId, + weight_meter: &mut WeightMeter, + ) -> DispatchResult { + Self::ensure_maximum_locking_period_not_exceeded(&inst_id)?; + + Self::release_locks(&inst_id, &inst_legs)?; + + let inst_memo = InstructionMemos::::get(&inst_id); + for (_, leg) in inst_legs { + match leg { + Leg::Fungible { sender, receiver, asset_id, amount } => { + Asset::::simplified_fungible_transfer( + asset_id, + sender, + receiver, + amount, + inst_id, + inst_memo.clone(), + caller_did, + weight_meter, + )?; + } + Leg::NonFungible { sender, receiver, nfts } => { + Nft::::simplified_nft_transfer( + sender, + receiver, + nfts, + inst_id, + inst_memo.clone(), + caller_did, + )?; + } + Leg::OffChain { .. } => continue, + } + } + + Self::deposit_event(Event::InstructionExecuted(caller_did, inst_id)); + InstructionStatuses::::insert( + inst_id, + InstructionStatus::Success(System::::block_number()) + ); + + Ok(()) + } + + /// Returns `Ok` if the maximum locking period was not exceeded. + fn ensure_maximum_locking_period_not_exceeded(inst_id: &InstructionId) -> DispatchResult { + let locked_timestamp = + LockedTimestamp::::get(inst_id).ok_or(Error::::LockTimestampNotFound)?; + + let now = pallet_timestamp::Pallet::::get(); + ensure!( + now - locked_timestamp <= T::MaximumLockPeriod::get(), + Error::::ExceededMaximumLockingPeriod + ); + + Ok(()) + } + + /// Consumes the given weight after checking that it can be consumed. + /// Returns an error if the weight limit is exceeded. + fn check_accrue(weight_meter: &mut WeightMeter, weight: Weight) -> DispatchResult { + weight_meter + .check_accrue(weight) + .map_err(|_| Error::::WeightLimitExceeded)?; + Ok(()) + } + /// Returns the worst case weight for an instruction with `f` fungible legs, `n` nfts being transferred and `o` offchain assets. fn execute_scheduled_instruction_weight_limit(f: u32, n: u32, o: u32) -> Weight { ::WeightInfo::execute_scheduled_instruction(f, n, o) @@ -2980,17 +3316,12 @@ impl Pallet { /// Returns the minimum weight for calling the `execute_scheduled_instruction` function. fn execute_scheduled_instruction_minimum_weight() -> Weight { - ::WeightInfo::execute_scheduled_instruction(0, 0, 0) - } - - /// Returns the worst case weight for an instruction with `f` fungible legs, `n` nfts being transferred and `o` offchain assets. - fn execute_manual_instruction_weight_limit(f: u32, n: u32, o: u32) -> Weight { - ::WeightInfo::execute_manual_instruction(f, n, o) + ::WeightInfo::execute_scheduled_instruction(0, 0, 1) } /// Returns the minimum weight for calling the `execute_manual_instruction` extrinsic. pub fn execute_manual_instruction_minimum_weight() -> Weight { - ::WeightInfo::execute_manual_instruction(0, 0, 0) + ::WeightInfo::execute_locked_instruction(0, 0, 1) } /// Returns the weight for calling `affirm_with_receipts` while considering the `sender_asset_count` for the sender, `receiver_asset_count` @@ -3027,12 +3358,14 @@ impl Pallet { ::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`. - fn reject_instruction_weight(instruction_asset_count: AssetCount, as_mediator: bool) -> Weight { - ::WeightInfo::reject_instruction_input( - Some(instruction_asset_count), - as_mediator, - ) + /// Returns the miminum weight for calling the `reject_instruction` extrinsic. + fn reject_instruction_minimum_weight() -> Weight { + ::WeightInfo::base_reject_instruction(0, 0, 1) + } + + /// Returns the minimum weight required for calling the `lock_instruction` extrinsic. + pub fn lock_instruction_minimum_weight() -> Weight { + ::WeightInfo::lock_instruction_extrinsic(0, 0, 1) } pub fn get_actual_weight(call: &Call) -> Option { @@ -3061,43 +3394,15 @@ impl Pallet { )) } Call::reject_instruction { id, .. } => { - let asset_count = Self::get_instruction_asset_count(id); - Some(Self::reject_instruction_weight(asset_count, false)) + let inst_asset_count = Self::instruction_asset_count(id); + Some(::WeightInfo::reject_instruction(Some( + inst_asset_count, + ))) } _ => None, } } - /// Returns an instance of [`ExecuteInstructionInfo`]. - pub fn execute_instruction_info( - instruction_id: &InstructionId, - ) -> Option { - if !InstructionDetails::::contains_key(instruction_id) { - return None; - } - - let caller_did = SettlementDID.as_id(); - let instruction_asset_count = Self::get_instruction_asset_count(instruction_id); - let mut weight_meter = - WeightMeter::max_limit(Self::execute_manual_instruction_minimum_weight()); - match Self::execute_instruction_retryable(*instruction_id, caller_did, &mut weight_meter) { - Ok(_) => Some(ExecuteInstructionInfo::new( - instruction_asset_count.fungible(), - instruction_asset_count.non_fungible(), - instruction_asset_count.off_chain(), - weight_meter.consumed(), - None, - )), - Err(e) => Some(ExecuteInstructionInfo::new( - instruction_asset_count.fungible(), - instruction_asset_count.non_fungible(), - instruction_asset_count.off_chain(), - weight_meter.consumed(), - Some(e.into()), - )), - } - } - /// Returns an instance of [`AffirmationCount`]. pub fn affirmation_count( instruction_id: InstructionId, @@ -3113,6 +3418,8 @@ impl Pallet { } /// Returns a vector containing all errors for the transfer. An empty vec means there's no error. + /// + /// `Note:` should only be called as a RPC. #[rustfmt::skip] pub fn transfer_report( leg: Leg, @@ -3130,7 +3437,7 @@ impl Pallet { weight_meter, ) } - Leg::NonFungible { sender, receiver, nfts} => { + Leg::NonFungible { sender, receiver, nfts } => { >::nft_transfer_report( &sender, &receiver, @@ -3146,44 +3453,99 @@ impl Pallet { } /// Returns a vector containing all errors for the execution. An empty vec means there's no error. - pub fn execute_instruction_report( - instruction_id: &InstructionId, - weight_meter: &mut WeightMeter, - ) -> Vec { + /// + /// `Note:` should only be called as a RPC. + pub fn execute_instruction_report(inst_id: &InstructionId) -> Vec { let mut execution_errors = Vec::new(); - if InstructionAffirmsPending::::get(instruction_id) != 0 { + let mut weight_meter = WeightMeter::max_limit_no_minimum(); + let inst_legs: Vec<_> = InstructionLegs::::iter_prefix(inst_id).collect(); + + if InstructionAffirmsPending::::get(inst_id) != 0 { execution_errors.push(Error::::NotAllAffirmationsHaveBeenReceived.into()); } - if let Err(e) = Self::ensure_non_expired_affirmations(&instruction_id) { + if let Err(e) = Self::ensure_instruction_is_pending_or_failed(inst_id) { execution_errors.push(e); } - match InstructionStatuses::::get(instruction_id) { - InstructionStatus::Unknown - | InstructionStatus::Success(_) - | InstructionStatus::Rejected(_) => { - execution_errors.push(Error::::InvalidInstructionStatusForExecution.into()); - } - InstructionStatus::Pending | InstructionStatus::Failed => {} + if let Err(e) = Self::validate_mediators_affirmations(inst_id) { + execution_errors.push(e); } - let instruction_legs: Vec<(LegId, Leg)> = - InstructionLegs::::iter_prefix(&instruction_id).collect(); - let venue_id = InstructionDetails::::get(instruction_id).venue_id; - if let Err(e) = Self::ensure_allowed_venue(&instruction_legs, venue_id) { + if let Err(e) = Self::validate_parties_affirmations(inst_id, &inst_legs) { execution_errors.push(e); } - for (leg_id, leg) in instruction_legs { - let leg_status = InstructionLegStatus::::get(instruction_id, leg_id); - if leg_status == LegStatus::ExecutionPending { - let transfer_errors = Self::transfer_report(leg, true, weight_meter); - execution_errors.extend_from_slice(&transfer_errors); - } + let inst_details = InstructionDetails::::get(inst_id); + if let Err(e) = Self::ensure_allowed_venue(&inst_legs, inst_details.venue_id) { + execution_errors.push(e); + } + + for (_, leg) in inst_legs { + let transfer_errors = Self::transfer_report(leg, true, &mut weight_meter); + execution_errors.extend_from_slice(&transfer_errors); } execution_errors } + + /// Returns the weight for executing `execute_manual_instruction`. + /// + /// `Note:` should only be called as a RPC. + pub fn manual_execution_weight(inst_id: InstructionId) -> Option { + let mut weight_meter = + WeightMeter::max_limit(Self::execute_manual_instruction_minimum_weight()); + + let caller_did = SettlementDID.as_id(); + let caller_account_id = DidRecords::::get(&caller_did)?.primary_key?; + let inst_legs: Vec<_> = InstructionLegs::::iter_prefix(inst_id).collect(); + let inst_asset_count = AssetCount::from_legs(&inst_legs); + + match Self::base_manual_execution( + RawOrigin::Signed(caller_account_id).into(), + inst_id, + None, + &inst_asset_count, + true, + &mut weight_meter, + ) { + Ok(_) => Some(ExecuteInstructionInfo::new( + inst_asset_count.fungible(), + inst_asset_count.non_fungible(), + inst_asset_count.off_chain(), + weight_meter.consumed(), + None, + )), + Err(e) => Some(ExecuteInstructionInfo::new( + inst_asset_count.fungible(), + inst_asset_count.non_fungible(), + inst_asset_count.off_chain(), + weight_meter.consumed(), + Some(e.into()), + )), + } + } + + /// Returns the weight for executing `lock_instruction`. + /// + /// `Note:` should only be called as a RPC. + pub fn lock_instruction_weight(inst_id: InstructionId) -> Result { + let mut weight_meter = WeightMeter::max_limit(Self::lock_instruction_minimum_weight()); + + let caller_did = SettlementDID.as_id(); + let caller_account_id = DidRecords::::get(&caller_did) + .ok_or(Error::::Unauthorized)? + .primary_key + .ok_or(Error::::Unauthorized)?; + + Self::base_lock_instruction( + RawOrigin::Signed(caller_account_id).into(), + inst_id, + true, + &mut weight_meter, + )?; + + Ok(weight_meter.consumed()) + } } diff --git a/pallets/sto/src/lib.rs b/pallets/sto/src/lib.rs index 954c2571b4..c70654f015 100644 --- a/pallets/sto/src/lib.rs +++ b/pallets/sto/src/lib.rs @@ -43,7 +43,6 @@ use polymesh_primitives::impl_checked_inc; use polymesh_primitives::settlement::{Leg, ReceiptDetails, SettlementType, VenueId, VenueType}; use polymesh_primitives::{ storage_migration_ver, traits::PortfolioSubTrait, Balance, EventDid, IdentityId, PortfolioId, - WeightMeter, }; use polymesh_primitives_derive::VecU8StrongTyped; @@ -598,7 +597,6 @@ pub mod pallet { receipt, portfolios, did, - &mut WeightMeter::max_limit_no_minimum(), )?; for (id, amount) in purchases { diff --git a/pallets/weights/src/pallet_settlement.rs b/pallets/weights/src/pallet_settlement.rs index f50f05e422..3c4e096059 100644 --- a/pallets/weights/src/pallet_settlement.rs +++ b/pallets/weights/src/pallet_settlement.rs @@ -54,176 +54,174 @@ use polymesh_primitives::{RocksDbWeight as DbWeight, Weight}; pub struct SubstrateWeight; impl pallet_settlement::WeightInfo for SubstrateWeight { // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueCounter (r:1 w:1) - // Proof Skipped: Settlement VenueCounter (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Settlement VenueCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:0 w:1) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Settlement Details (r:0 w:1) // Proof Skipped: Settlement Details (max_values: None, max_size: None, mode: Measured) // Storage: Settlement NumberOfVenueSigners (r:0 w:1) - // Proof Skipped: Settlement NumberOfVenueSigners (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement NumberOfVenueSigners (max_values: None, max_size: Some(20), added: 2495, mode: MaxEncodedLen) // Storage: Settlement VenueSigners (r:0 w:49) - // Proof Skipped: Settlement VenueSigners (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueSigners (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) // Storage: Settlement UserVenues (r:0 w:1) - // Proof Skipped: Settlement UserVenues (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserVenues (max_values: None, max_size: Some(56), added: 2531, mode: MaxEncodedLen) /// The range of component `d` is `[1, 2048]`. /// The range of component `s` is `[0, 50]`. fn create_venue(d: u32, s: u32) -> Weight { - // Minimum execution time: 38_007 nanoseconds. - Weight::from_ref_time(43_823_114) - // Standard Error: 328 - .saturating_add(Weight::from_ref_time(338).saturating_mul(d.into())) - // Standard Error: 13_352 - .saturating_add(Weight::from_ref_time(2_337_555).saturating_mul(s.into())) + // Minimum execution time: 41_385 nanoseconds. + Weight::from_ref_time(40_955_341) + // Standard Error: 226 + .saturating_add(Weight::from_ref_time(1_587).saturating_mul(d.into())) + // Standard Error: 9_189 + .saturating_add(Weight::from_ref_time(2_230_351).saturating_mul(s.into())) .saturating_add(DbWeight::get().reads(2)) .saturating_add(DbWeight::get().writes(5)) .saturating_add(DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Settlement Details (r:0 w:1) // Proof Skipped: Settlement Details (max_values: None, max_size: None, mode: Measured) /// The range of component `d` is `[1, 2048]`. fn update_venue_details(d: u32) -> Weight { - // Minimum execution time: 27_702 nanoseconds. - Weight::from_ref_time(34_850_082) - // Standard Error: 450 - .saturating_add(Weight::from_ref_time(2_322).saturating_mul(d.into())) + // Minimum execution time: 33_023 nanoseconds. + Weight::from_ref_time(33_959_581) + // Standard Error: 82 + .saturating_add(Weight::from_ref_time(1_742).saturating_mul(d.into())) .saturating_add(DbWeight::get().reads(2)) .saturating_add(DbWeight::get().writes(1)) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:1) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) fn update_venue_type() -> Weight { - // Minimum execution time: 27_330 nanoseconds. - Weight::from_ref_time(28_732_000) + // Minimum execution time: 32_322 nanoseconds. + Weight::from_ref_time(32_606_000) .saturating_add(DbWeight::get().reads(2)) .saturating_add(DbWeight::get().writes(1)) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Settlement NumberOfVenueSigners (r:1 w:1) - // Proof Skipped: Settlement NumberOfVenueSigners (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement NumberOfVenueSigners (max_values: None, max_size: Some(20), added: 2495, mode: MaxEncodedLen) // Storage: Settlement VenueSigners (r:49 w:49) - // Proof Skipped: Settlement VenueSigners (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueSigners (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) /// The range of component `s` is `[0, 50]`. fn update_venue_signers(s: u32) -> Weight { - // Minimum execution time: 29_644 nanoseconds. - Weight::from_ref_time(41_178_975) - // Standard Error: 25_032 - .saturating_add(Weight::from_ref_time(4_526_473).saturating_mul(s.into())) + // Minimum execution time: 33_917 nanoseconds. + Weight::from_ref_time(40_492_609) + // Standard Error: 8_991 + .saturating_add(Weight::from_ref_time(4_508_521).saturating_mul(s.into())) .saturating_add(DbWeight::get().reads(3)) .saturating_add(DbWeight::get().reads((1_u64).saturating_mul(s.into()))) .saturating_add(DbWeight::get().writes(1)) .saturating_add(DbWeight::get().writes((1_u64).saturating_mul(s.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: ExternalAgents GroupOfAgent (r:1 w:0) - // Proof Skipped: ExternalAgents GroupOfAgent (max_values: None, max_size: None, mode: Measured) + // Proof: ExternalAgents GroupOfAgent (max_values: None, max_size: Some(77), added: 2552, mode: MaxEncodedLen) // Storage: Permissions CurrentPalletName (r:1 w:0) // Proof Skipped: Permissions CurrentPalletName (max_values: Some(1), max_size: None, mode: Measured) // Storage: Permissions CurrentDispatchableName (r:1 w:0) // Proof Skipped: Permissions CurrentDispatchableName (max_values: Some(1), max_size: None, mode: Measured) // Storage: Settlement VenueFiltering (r:0 w:1) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) fn set_venue_filtering() -> Weight { - // Minimum execution time: 33_059 nanoseconds. - Weight::from_ref_time(34_743_000) + // Minimum execution time: 37_752 nanoseconds. + Weight::from_ref_time(37_838_000) .saturating_add(DbWeight::get().reads(4)) .saturating_add(DbWeight::get().writes(1)) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: ExternalAgents GroupOfAgent (r:1 w:0) - // Proof Skipped: ExternalAgents GroupOfAgent (max_values: None, max_size: None, mode: Measured) + // Proof: ExternalAgents GroupOfAgent (max_values: None, max_size: Some(77), added: 2552, mode: MaxEncodedLen) // Storage: Permissions CurrentPalletName (r:1 w:0) // Proof Skipped: Permissions CurrentPalletName (max_values: Some(1), max_size: None, mode: Measured) // Storage: Permissions CurrentDispatchableName (r:1 w:0) // Proof Skipped: Permissions CurrentDispatchableName (max_values: Some(1), max_size: None, mode: Measured) // Storage: Settlement VenueAllowList (r:0 w:99) - // Proof Skipped: Settlement VenueAllowList (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueAllowList (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[0, 100]`. fn allow_venues(v: u32) -> Weight { - // Minimum execution time: 29_734 nanoseconds. - Weight::from_ref_time(34_041_969) - // Standard Error: 18_920 - .saturating_add(Weight::from_ref_time(2_558_029).saturating_mul(v.into())) + // Minimum execution time: 35_859 nanoseconds. + Weight::from_ref_time(34_464_663) + // Standard Error: 4_034 + .saturating_add(Weight::from_ref_time(2_541_369).saturating_mul(v.into())) .saturating_add(DbWeight::get().reads(4)) .saturating_add(DbWeight::get().writes((1_u64).saturating_mul(v.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: ExternalAgents GroupOfAgent (r:1 w:0) - // Proof Skipped: ExternalAgents GroupOfAgent (max_values: None, max_size: None, mode: Measured) + // Proof: ExternalAgents GroupOfAgent (max_values: None, max_size: Some(77), added: 2552, mode: MaxEncodedLen) // Storage: Permissions CurrentPalletName (r:1 w:0) // Proof Skipped: Permissions CurrentPalletName (max_values: Some(1), max_size: None, mode: Measured) // Storage: Permissions CurrentDispatchableName (r:1 w:0) // Proof Skipped: Permissions CurrentDispatchableName (max_values: Some(1), max_size: None, mode: Measured) // Storage: Settlement VenueAllowList (r:0 w:99) - // Proof Skipped: Settlement VenueAllowList (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueAllowList (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) /// The range of component `v` is `[0, 100]`. fn disallow_venues(v: u32) -> Weight { - // Minimum execution time: 32_018 nanoseconds. - Weight::from_ref_time(35_158_836) - // Standard Error: 18_808 - .saturating_add(Weight::from_ref_time(2_479_690).saturating_mul(v.into())) + // Minimum execution time: 35_647 nanoseconds. + Weight::from_ref_time(36_426_253) + // Standard Error: 3_426 + .saturating_add(Weight::from_ref_time(2_428_140).saturating_mul(v.into())) .saturating_add(DbWeight::get().reads(4)) .saturating_add(DbWeight::get().writes((1_u64).saturating_mul(v.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:110 w:110) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement VenueSigners (r:1 w:0) - // Proof Skipped: Settlement VenueSigners (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueSigners (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) // Storage: Settlement ReceiptsUsed (r:10 w:10) - // Proof Skipped: Settlement ReceiptsUsed (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement ReceiptsUsed (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:0) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement OffChainAffirmations (r:10 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Portfolio PortfolioNFT (r:100 w:0) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Asset Assets (r:10 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioAssetBalances (r:10 w:0) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegStatus (r:0 w:120) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn affirm_with_receipts(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 1_362_039 nanoseconds. - Weight::from_ref_time(30_752_065) - // Standard Error: 920_495 - .saturating_add(Weight::from_ref_time(50_145_102).saturating_mul(f.into())) - // Standard Error: 85_148 - .saturating_add(Weight::from_ref_time(37_317_225).saturating_mul(n.into())) - // Standard Error: 833_827 - .saturating_add(Weight::from_ref_time(84_072_250).saturating_mul(o.into())) + // Minimum execution time: 1_276_985 nanoseconds. + Weight::from_ref_time(1_278_730_000) + // Standard Error: 123_056 + .saturating_add(Weight::from_ref_time(30_410_197).saturating_mul(n.into())) + // Standard Error: 1_225_926 + .saturating_add(Weight::from_ref_time(33_590_810).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(6)) .saturating_add(DbWeight::get().reads((6_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((5_u64).saturating_mul(n.into()))) @@ -234,85 +232,85 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionDetails (r:1 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionStatuses (r:1 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) + // Storage: Settlement InstructionDetails (r:1 w:1) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + // Storage: Settlement InstructionMediatorsAffirmations (r:445 w:444) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) + // Storage: Settlement InstructionStatuses (r:1 w:1) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) - // Storage: Settlement InstructionMediatorsAffirmations (r:445 w:444) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Storage: Settlement InstructionLegStatus (r:120 w:120) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:10 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:220 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:220 w:220) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionLegStatus (r:120 w:120) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement InstructionMemos (r:1 w:0) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionMemos (r:1 w:0) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Asset Assets (r:10 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Asset BalanceOf (r:20 w:20) - // Proof Skipped: Asset BalanceOf (max_values: None, max_size: None, mode: Measured) + // Proof: Asset BalanceOf (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:20 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioAssetBalances (r:20 w:20) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Asset Frozen (r:110 w:0) - // Proof Skipped: Asset Frozen (max_values: None, max_size: None, mode: Measured) - // Storage: Instance2Group ActiveMembers (r:1 w:0) - // Proof Skipped: Instance2Group ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Asset Frozen (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: CddServiceProviders ActiveMembers (r:1 w:0) + // Proof Skipped: CddServiceProviders ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) // Storage: Identity Claims (r:205 w:0) // Proof Skipped: Identity Claims (max_values: None, max_size: None, mode: Measured) // Storage: Statistics AssetTransferCompliances (r:10 w:0) - // Proof Skipped: Statistics AssetTransferCompliances (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics AssetTransferCompliances (max_values: None, max_size: Some(246), added: 2721, mode: MaxEncodedLen) // Storage: Statistics AssetStats (r:140 w:100) - // Proof Skipped: Statistics AssetStats (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics AssetStats (max_values: None, max_size: Some(107), added: 2582, mode: MaxEncodedLen) // Storage: ComplianceManager AssetCompliances (r:110 w:0) // Proof Skipped: ComplianceManager AssetCompliances (max_values: None, max_size: None, mode: Measured) // Storage: Checkpoint CachedNextCheckpoints (r:10 w:0) // Proof Skipped: Checkpoint CachedNextCheckpoints (max_values: None, max_size: None, mode: Measured) // Storage: Checkpoint CheckpointIdSequence (r:10 w:0) - // Proof Skipped: Checkpoint CheckpointIdSequence (max_values: None, max_size: None, mode: Measured) + // Proof: Checkpoint CheckpointIdSequence (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) // Storage: Portfolio PortfolioAssetCount (r:10 w:10) - // Proof Skipped: Portfolio PortfolioAssetCount (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetCount (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) // Storage: Statistics ActiveAssetStats (r:10 w:0) - // Proof Skipped: Statistics ActiveAssetStats (max_values: None, max_size: None, mode: Measured) - // Storage: NFT CollectionAsset (r:100 w:0) - // Proof Skipped: NFT CollectionAsset (max_values: None, max_size: None, mode: Measured) - // Storage: NFT NumberOfNFTs (r:200 w:200) - // Proof Skipped: NFT NumberOfNFTs (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics ActiveAssetStats (max_values: None, max_size: Some(423), added: 2898, mode: MaxEncodedLen) + // Storage: Nft CollectionAsset (r:100 w:0) + // Proof: Nft CollectionAsset (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Nft NumberOfNFTs (r:200 w:200) + // Proof: Nft NumberOfNFTs (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) // Storage: Portfolio PortfolioNFT (r:100 w:200) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) - // Storage: NFT NFTOwner (r:0 w:100) - // Proof Skipped: NFT NFTOwner (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) - /// The range of component `f` is `[1, 10]`. + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) + // Storage: Nft NFTOwner (r:0 w:100) + // Proof: Nft NFTOwner (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + /// The range of component `f` is `[0, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn execute_manual_instruction(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 4_326_122 nanoseconds. - Weight::from_ref_time(4_334_153_000) - // Standard Error: 5_116_456 - .saturating_add(Weight::from_ref_time(248_402_942).saturating_mul(f.into())) - // Standard Error: 494_029 - .saturating_add(Weight::from_ref_time(179_827_924).saturating_mul(n.into())) + // Minimum execution time: 4_514_820 nanoseconds. + Weight::from_ref_time(4_527_914_000) + // Standard Error: 4_810_168 + .saturating_add(Weight::from_ref_time(262_353_483).saturating_mul(f.into())) + // Standard Error: 482_935 + .saturating_add(Weight::from_ref_time(178_946_838).saturating_mul(n.into())) .saturating_add(DbWeight::get().reads(19)) .saturating_add(DbWeight::get().reads((60_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((18_u64).saturating_mul(n.into()))) @@ -323,29 +321,29 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Asset Assets (r:110 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Identity DidRecords (r:2 w:0) - // Proof Skipped: Identity DidRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity DidRecords (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:220 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Asset AssetsExemptFromAffirmation (r:110 w:0) - // Proof Skipped: Asset AssetsExemptFromAffirmation (max_values: None, max_size: None, mode: Measured) + // Proof: Asset AssetsExemptFromAffirmation (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Asset PreApprovedAsset (r:110 w:0) - // Proof Skipped: Asset PreApprovedAsset (max_values: None, max_size: None, mode: Measured) + // Proof: Asset PreApprovedAsset (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio PreApprovedPortfolios (r:110 w:0) - // Proof Skipped: Portfolio PreApprovedPortfolios (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PreApprovedPortfolios (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) // Storage: Asset MandatoryMediators (r:110 w:0) - // Proof Skipped: Asset MandatoryMediators (max_values: None, max_size: None, mode: Measured) + // Proof: Asset MandatoryMediators (max_values: None, max_size: Some(161), added: 2636, mode: MaxEncodedLen) // Storage: Settlement InstructionCounter (r:1 w:1) - // Proof Skipped: Settlement InstructionCounter (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Settlement InstructionCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Scheduler Lookup (r:1 w:1) @@ -355,33 +353,33 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { // Storage: Settlement InstructionLegs (r:0 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement UserAffirmations (r:0 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:0 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:0 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement InstructionMemos (r:0 w:1) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:0 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:0 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:0 w:440) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn add_instruction(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 649_862 nanoseconds. - Weight::from_ref_time(181_103_629) - // Standard Error: 859_961 - .saturating_add(Weight::from_ref_time(49_562_998).saturating_mul(f.into())) - // Standard Error: 79_548 - .saturating_add(Weight::from_ref_time(50_371_349).saturating_mul(n.into())) - // Standard Error: 778_992 - .saturating_add(Weight::from_ref_time(377_069).saturating_mul(o.into())) + // Minimum execution time: 610_762 nanoseconds. + Weight::from_ref_time(87_500_816) + // Standard Error: 357_048 + .saturating_add(Weight::from_ref_time(46_327_984).saturating_mul(f.into())) + // Standard Error: 33_027 + .saturating_add(Weight::from_ref_time(49_697_462).saturating_mul(n.into())) + // Standard Error: 323_430 + .saturating_add(Weight::from_ref_time(2_138_918).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(8)) .saturating_add(DbWeight::get().reads((9_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((9_u64).saturating_mul(n.into()))) @@ -391,29 +389,29 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((2_u64).saturating_mul(o.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Asset Assets (r:110 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Identity DidRecords (r:2 w:0) - // Proof Skipped: Identity DidRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity DidRecords (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:220 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioCustodian (r:220 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Asset AssetsExemptFromAffirmation (r:110 w:0) - // Proof Skipped: Asset AssetsExemptFromAffirmation (max_values: None, max_size: None, mode: Measured) + // Proof: Asset AssetsExemptFromAffirmation (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Asset PreApprovedAsset (r:110 w:0) - // Proof Skipped: Asset PreApprovedAsset (max_values: None, max_size: None, mode: Measured) + // Proof: Asset PreApprovedAsset (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio PreApprovedPortfolios (r:110 w:0) - // Proof Skipped: Portfolio PreApprovedPortfolios (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PreApprovedPortfolios (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) // Storage: Asset MandatoryMediators (r:110 w:0) - // Proof Skipped: Asset MandatoryMediators (max_values: None, max_size: None, mode: Measured) + // Proof: Asset MandatoryMediators (max_values: None, max_size: Some(161), added: 2636, mode: MaxEncodedLen) // Storage: Settlement InstructionCounter (r:1 w:1) - // Proof Skipped: Settlement InstructionCounter (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Settlement InstructionCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Scheduler Lookup (r:1 w:1) @@ -423,45 +421,45 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { // Storage: Settlement InstructionLegs (r:121 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioNFT (r:100 w:0) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioAssetBalances (r:10 w:0) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:0 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:0 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:0 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement InstructionMemos (r:0 w:1) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:0 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:0 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:0 w:440) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegStatus (r:0 w:110) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn add_and_affirm_instruction(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 1_044_625 nanoseconds. - Weight::from_ref_time(35_687_014) - // Standard Error: 1_353_987 - .saturating_add(Weight::from_ref_time(88_363_287).saturating_mul(f.into())) - // Standard Error: 125_247 - .saturating_add(Weight::from_ref_time(84_907_864).saturating_mul(n.into())) - // Standard Error: 1_226_503 - .saturating_add(Weight::from_ref_time(10_688_477).saturating_mul(o.into())) + // Minimum execution time: 1_029_987 nanoseconds. + Weight::from_ref_time(77_252_339) + // Standard Error: 542_986 + .saturating_add(Weight::from_ref_time(82_177_471).saturating_mul(f.into())) + // Standard Error: 50_227 + .saturating_add(Weight::from_ref_time(81_572_761).saturating_mul(n.into())) + // Standard Error: 491_862 + .saturating_add(Weight::from_ref_time(7_687_029).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(9)) .saturating_add(DbWeight::get().reads((13_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((13_u64).saturating_mul(n.into()))) @@ -472,42 +470,42 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((2_u64).saturating_mul(o.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:110 w:110) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:0) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioNFT (r:100 w:0) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Asset Assets (r:10 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioAssetBalances (r:10 w:0) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegStatus (r:0 w:110) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[1, 100]`. fn affirm_instruction(f: u32, n: u32) -> Weight { - // Minimum execution time: 573_378 nanoseconds. - Weight::from_ref_time(227_742_958) - // Standard Error: 621_956 - .saturating_add(Weight::from_ref_time(33_924_547).saturating_mul(f.into())) - // Standard Error: 58_443 - .saturating_add(Weight::from_ref_time(36_201_669).saturating_mul(n.into())) + // Minimum execution time: 547_185 nanoseconds. + Weight::from_ref_time(86_626_498) + // Standard Error: 312_581 + .saturating_add(Weight::from_ref_time(41_128_481).saturating_mul(f.into())) + // Standard Error: 29_372 + .saturating_add(Weight::from_ref_time(35_113_985).saturating_mul(n.into())) .saturating_add(DbWeight::get().reads(15)) .saturating_add(DbWeight::get().reads((6_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((5_u64).saturating_mul(n.into()))) @@ -516,37 +514,39 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((4_u64).saturating_mul(n.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:110 w:110) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:0) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionLegStatus (r:110 w:110) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn withdraw_affirmation(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 472_688 nanoseconds. - Weight::from_ref_time(149_586_656) - // Standard Error: 627_411 - .saturating_add(Weight::from_ref_time(35_874_804).saturating_mul(f.into())) - // Standard Error: 58_037 - .saturating_add(Weight::from_ref_time(37_322_729).saturating_mul(n.into())) + // Minimum execution time: 459_491 nanoseconds. + Weight::from_ref_time(62_774_505) + // Standard Error: 242_434 + .saturating_add(Weight::from_ref_time(34_528_713).saturating_mul(f.into())) + // Standard Error: 22_425 + .saturating_add(Weight::from_ref_time(35_990_085).saturating_mul(n.into())) + // Standard Error: 219_608 + .saturating_add(Weight::from_ref_time(4_360_142).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(5)) .saturating_add(DbWeight::get().reads((5_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((5_u64).saturating_mul(n.into()))) @@ -555,133 +555,80 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((4_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().writes((4_u64).saturating_mul(n.into()))) } - // Storage: Settlement InstructionStatuses (r:1 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionLegs (r:121 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) - // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) - // Storage: Portfolio PortfolioCustodian (r:1 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionLegStatus (r:120 w:120) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) - // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) - // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) - // Storage: Scheduler Lookup (r:1 w:1) - // Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - // Storage: Scheduler Agenda (r:1 w:1) - // Proof: Scheduler Agenda (max_values: None, max_size: Some(10463), added: 12938, mode: MaxEncodedLen) - // Storage: Settlement InstructionDetails (r:1 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionMediatorsAffirmations (r:5 w:4) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement UserAffirmations (r:0 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement OffChainAffirmations (r:0 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionAffirmsPending (r:0 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement AffirmsReceived (r:0 w:220) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) - /// The range of component `f` is `[1, 10]`. - /// The range of component `n` is `[0, 100]`. - /// The range of component `o` is `[0, 10]`. - fn reject_instruction(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 580_358 nanoseconds. - Weight::from_ref_time(118_055_273) - // Standard Error: 1_085_190 - .saturating_add(Weight::from_ref_time(28_028_976).saturating_mul(f.into())) - // Standard Error: 100_383 - .saturating_add(Weight::from_ref_time(36_339_812).saturating_mul(n.into())) - // Standard Error: 983_014 - .saturating_add(Weight::from_ref_time(11_885_329).saturating_mul(o.into())) - .saturating_add(DbWeight::get().reads(12)) - .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(f.into()))) - .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(n.into()))) - .saturating_add(DbWeight::get().reads((2_u64).saturating_mul(o.into()))) - .saturating_add(DbWeight::get().writes(10)) - .saturating_add(DbWeight::get().writes((7_u64).saturating_mul(f.into()))) - .saturating_add(DbWeight::get().writes((7_u64).saturating_mul(n.into()))) - .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) - } - // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionStatuses (r:1 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) + // Storage: Settlement InstructionAffirmsPending (r:1 w:1) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:445 w:444) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionLegs (r:121 w:120) - // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegStatus (r:120 w:120) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:10 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:220 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:220 w:220) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionLegStatus (r:120 w:120) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement InstructionMemos (r:1 w:0) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionMemos (r:1 w:0) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Asset Assets (r:10 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Asset BalanceOf (r:20 w:20) - // Proof Skipped: Asset BalanceOf (max_values: None, max_size: None, mode: Measured) + // Proof: Asset BalanceOf (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:20 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioAssetBalances (r:20 w:20) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Asset Frozen (r:110 w:0) - // Proof Skipped: Asset Frozen (max_values: None, max_size: None, mode: Measured) - // Storage: Instance2Group ActiveMembers (r:1 w:0) - // Proof Skipped: Instance2Group ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Asset Frozen (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: CddServiceProviders ActiveMembers (r:1 w:0) + // Proof Skipped: CddServiceProviders ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) // Storage: Identity Claims (r:4 w:0) // Proof Skipped: Identity Claims (max_values: None, max_size: None, mode: Measured) // Storage: Statistics AssetTransferCompliances (r:10 w:0) - // Proof Skipped: Statistics AssetTransferCompliances (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics AssetTransferCompliances (max_values: None, max_size: Some(246), added: 2721, mode: MaxEncodedLen) // Storage: ComplianceManager AssetCompliances (r:110 w:0) // Proof Skipped: ComplianceManager AssetCompliances (max_values: None, max_size: None, mode: Measured) // Storage: Checkpoint CachedNextCheckpoints (r:10 w:0) // Proof Skipped: Checkpoint CachedNextCheckpoints (max_values: None, max_size: None, mode: Measured) // Storage: Checkpoint CheckpointIdSequence (r:10 w:0) - // Proof Skipped: Checkpoint CheckpointIdSequence (max_values: None, max_size: None, mode: Measured) + // Proof: Checkpoint CheckpointIdSequence (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) // Storage: Portfolio PortfolioAssetCount (r:10 w:10) - // Proof Skipped: Portfolio PortfolioAssetCount (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetCount (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) // Storage: Statistics ActiveAssetStats (r:10 w:0) - // Proof Skipped: Statistics ActiveAssetStats (max_values: None, max_size: None, mode: Measured) - // Storage: NFT CollectionAsset (r:100 w:0) - // Proof Skipped: NFT CollectionAsset (max_values: None, max_size: None, mode: Measured) - // Storage: NFT NumberOfNFTs (r:200 w:200) - // Proof Skipped: NFT NumberOfNFTs (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics ActiveAssetStats (max_values: None, max_size: Some(423), added: 2898, mode: MaxEncodedLen) + // Storage: Nft CollectionAsset (r:100 w:0) + // Proof: Nft CollectionAsset (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Nft NumberOfNFTs (r:200 w:200) + // Proof: Nft NumberOfNFTs (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) // Storage: Portfolio PortfolioNFT (r:100 w:200) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) - // Storage: NFT NFTOwner (r:0 w:100) - // Proof Skipped: NFT NFTOwner (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) + // Storage: Nft NFTOwner (r:0 w:100) + // Proof: Nft NFTOwner (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn execute_instruction_paused(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 2_385_781 nanoseconds. - Weight::from_ref_time(2_426_592_000) - // Standard Error: 3_430_970 - .saturating_add(Weight::from_ref_time(118_611_412).saturating_mul(f.into())) - // Standard Error: 331_283 - .saturating_add(Weight::from_ref_time(176_390_618).saturating_mul(n.into())) + // Minimum execution time: 2_585_824 nanoseconds. + Weight::from_ref_time(2_591_906_000) + // Standard Error: 3_083_758 + .saturating_add(Weight::from_ref_time(128_978_773).saturating_mul(f.into())) + // Standard Error: 297_758 + .saturating_add(Weight::from_ref_time(183_587_286).saturating_mul(n.into())) .saturating_add(DbWeight::get().reads(16)) .saturating_add(DbWeight::get().reads((26_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((18_u64).saturating_mul(n.into()))) @@ -691,82 +638,82 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((16_u64).saturating_mul(n.into()))) .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) } - // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Storage: Settlement InstructionLegs (r:121 w:120) + // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionStatuses (r:1 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) + // Storage: Settlement InstructionAffirmsPending (r:1 w:1) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:445 w:444) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionLegs (r:121 w:120) - // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegStatus (r:120 w:120) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:10 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:220 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:220 w:220) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionLegStatus (r:120 w:120) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement InstructionMemos (r:1 w:0) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionMemos (r:1 w:0) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Asset Assets (r:10 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Asset BalanceOf (r:20 w:20) - // Proof Skipped: Asset BalanceOf (max_values: None, max_size: None, mode: Measured) + // Proof: Asset BalanceOf (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:20 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioAssetBalances (r:20 w:20) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Asset Frozen (r:110 w:0) - // Proof Skipped: Asset Frozen (max_values: None, max_size: None, mode: Measured) - // Storage: Instance2Group ActiveMembers (r:1 w:0) - // Proof Skipped: Instance2Group ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Asset Frozen (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: CddServiceProviders ActiveMembers (r:1 w:0) + // Proof Skipped: CddServiceProviders ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) // Storage: Identity Claims (r:205 w:0) // Proof Skipped: Identity Claims (max_values: None, max_size: None, mode: Measured) // Storage: Statistics AssetTransferCompliances (r:10 w:0) - // Proof Skipped: Statistics AssetTransferCompliances (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics AssetTransferCompliances (max_values: None, max_size: Some(246), added: 2721, mode: MaxEncodedLen) // Storage: Statistics AssetStats (r:140 w:100) - // Proof Skipped: Statistics AssetStats (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics AssetStats (max_values: None, max_size: Some(107), added: 2582, mode: MaxEncodedLen) // Storage: ComplianceManager AssetCompliances (r:110 w:0) // Proof Skipped: ComplianceManager AssetCompliances (max_values: None, max_size: None, mode: Measured) // Storage: Checkpoint CachedNextCheckpoints (r:10 w:0) // Proof Skipped: Checkpoint CachedNextCheckpoints (max_values: None, max_size: None, mode: Measured) // Storage: Checkpoint CheckpointIdSequence (r:10 w:0) - // Proof Skipped: Checkpoint CheckpointIdSequence (max_values: None, max_size: None, mode: Measured) + // Proof: Checkpoint CheckpointIdSequence (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) // Storage: Portfolio PortfolioAssetCount (r:10 w:10) - // Proof Skipped: Portfolio PortfolioAssetCount (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetCount (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) // Storage: Statistics ActiveAssetStats (r:10 w:0) - // Proof Skipped: Statistics ActiveAssetStats (max_values: None, max_size: None, mode: Measured) - // Storage: NFT CollectionAsset (r:100 w:0) - // Proof Skipped: NFT CollectionAsset (max_values: None, max_size: None, mode: Measured) - // Storage: NFT NumberOfNFTs (r:200 w:200) - // Proof Skipped: NFT NumberOfNFTs (max_values: None, max_size: None, mode: Measured) + // Proof: Statistics ActiveAssetStats (max_values: None, max_size: Some(423), added: 2898, mode: MaxEncodedLen) + // Storage: Nft CollectionAsset (r:100 w:0) + // Proof: Nft CollectionAsset (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Nft NumberOfNFTs (r:200 w:200) + // Proof: Nft NumberOfNFTs (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) // Storage: Portfolio PortfolioNFT (r:100 w:200) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) - // Storage: NFT NFTOwner (r:0 w:100) - // Proof Skipped: NFT NFTOwner (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) + // Storage: Nft NFTOwner (r:0 w:100) + // Proof: Nft NFTOwner (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn execute_scheduled_instruction(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 4_243_219 nanoseconds. - Weight::from_ref_time(4_250_300_000) - // Standard Error: 4_870_147 - .saturating_add(Weight::from_ref_time(258_973_141).saturating_mul(f.into())) - // Standard Error: 470_246 - .saturating_add(Weight::from_ref_time(175_126_988).saturating_mul(n.into())) + // Minimum execution time: 4_535_778 nanoseconds. + Weight::from_ref_time(4_545_473_000) + // Standard Error: 5_054_732 + .saturating_add(Weight::from_ref_time(255_662_317).saturating_mul(f.into())) + // Standard Error: 488_069 + .saturating_add(Weight::from_ref_time(182_489_794).saturating_mul(n.into())) .saturating_add(DbWeight::get().reads(17)) .saturating_add(DbWeight::get().reads((60_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((18_u64).saturating_mul(n.into()))) @@ -777,45 +724,45 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) } fn ensure_root_origin() -> Weight { - // Minimum execution time: 591 nanoseconds. - Weight::from_ref_time(651_000) + // Minimum execution time: 725 nanoseconds. + Weight::from_ref_time(745_000) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:110 w:110) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement VenueSigners (r:1 w:0) - // Proof Skipped: Settlement VenueSigners (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueSigners (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) // Storage: Settlement ReceiptsUsed (r:10 w:10) - // Proof Skipped: Settlement ReceiptsUsed (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement ReceiptsUsed (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:0) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement OffChainAffirmations (r:10 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegStatus (r:0 w:10) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn affirm_with_receipts_rcv(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 1_165_554 nanoseconds. - Weight::from_ref_time(152_923_311) - // Standard Error: 520_828 - .saturating_add(Weight::from_ref_time(21_184_928).saturating_mul(f.into())) - // Standard Error: 48_178 - .saturating_add(Weight::from_ref_time(21_625_684).saturating_mul(n.into())) - // Standard Error: 471_790 - .saturating_add(Weight::from_ref_time(85_672_760).saturating_mul(o.into())) + // Minimum execution time: 1_081_866 nanoseconds. + Weight::from_ref_time(67_059_248) + // Standard Error: 180_174 + .saturating_add(Weight::from_ref_time(21_277_938).saturating_mul(f.into())) + // Standard Error: 16_666 + .saturating_add(Weight::from_ref_time(21_673_587).saturating_mul(n.into())) + // Standard Error: 163_210 + .saturating_add(Weight::from_ref_time(80_525_907).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(6)) .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(n.into()))) @@ -826,30 +773,30 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:110 w:110) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:0) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[1, 100]`. fn affirm_instruction_rcv(f: u32, n: u32) -> Weight { - // Minimum execution time: 366_979 nanoseconds. - Weight::from_ref_time(152_848_331) - // Standard Error: 572_932 - .saturating_add(Weight::from_ref_time(23_592_317).saturating_mul(f.into())) - // Standard Error: 53_837 - .saturating_add(Weight::from_ref_time(21_858_616).saturating_mul(n.into())) + // Minimum execution time: 340_257 nanoseconds. + Weight::from_ref_time(97_574_625) + // Standard Error: 158_488 + .saturating_add(Weight::from_ref_time(22_224_675).saturating_mul(f.into())) + // Standard Error: 14_892 + .saturating_add(Weight::from_ref_time(21_509_612).saturating_mul(n.into())) .saturating_add(DbWeight::get().reads(15)) .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(n.into()))) @@ -858,33 +805,33 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((2_u64).saturating_mul(n.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:110 w:110) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:0) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. fn withdraw_affirmation_rcv(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 334_761 nanoseconds. - Weight::from_ref_time(135_422_202) - // Standard Error: 432_167 - .saturating_add(Weight::from_ref_time(21_839_953).saturating_mul(f.into())) - // Standard Error: 39_976 - .saturating_add(Weight::from_ref_time(21_464_027).saturating_mul(n.into())) - // Standard Error: 391_476 - .saturating_add(Weight::from_ref_time(1_853_671).saturating_mul(o.into())) + // Minimum execution time: 318_139 nanoseconds. + Weight::from_ref_time(67_427_076) + // Standard Error: 131_902 + .saturating_add(Weight::from_ref_time(21_560_028).saturating_mul(f.into())) + // Standard Error: 12_201 + .saturating_add(Weight::from_ref_time(21_454_679).saturating_mul(n.into())) + // Standard Error: 119_483 + .saturating_add(Weight::from_ref_time(3_457_461).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(5)) .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(n.into()))) @@ -894,29 +841,29 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((2_u64).saturating_mul(n.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Asset Assets (r:110 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Identity DidRecords (r:2 w:0) - // Proof Skipped: Identity DidRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity DidRecords (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:220 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioCustodian (r:110 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Asset AssetsExemptFromAffirmation (r:110 w:0) - // Proof Skipped: Asset AssetsExemptFromAffirmation (max_values: None, max_size: None, mode: Measured) + // Proof: Asset AssetsExemptFromAffirmation (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Asset PreApprovedAsset (r:110 w:0) - // Proof Skipped: Asset PreApprovedAsset (max_values: None, max_size: None, mode: Measured) + // Proof: Asset PreApprovedAsset (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio PreApprovedPortfolios (r:110 w:0) - // Proof Skipped: Portfolio PreApprovedPortfolios (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PreApprovedPortfolios (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) // Storage: Asset MandatoryMediators (r:110 w:0) - // Proof Skipped: Asset MandatoryMediators (max_values: None, max_size: None, mode: Measured) + // Proof: Asset MandatoryMediators (max_values: None, max_size: Some(161), added: 2636, mode: MaxEncodedLen) // Storage: Settlement InstructionCounter (r:1 w:1) - // Proof Skipped: Settlement InstructionCounter (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Settlement InstructionCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Scheduler Lookup (r:1 w:1) @@ -926,34 +873,34 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { // Storage: Settlement InstructionLegs (r:0 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement UserAffirmations (r:0 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:0 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:0 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement InstructionMemos (r:0 w:1) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:0 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:0 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:0 w:444) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. /// The range of component `m` is `[0, 4]`. fn add_instruction_with_mediators(f: u32, n: u32, o: u32, m: u32) -> Weight { - // Minimum execution time: 633_118 nanoseconds. - Weight::from_ref_time(167_302_584) - // Standard Error: 809_143 - .saturating_add(Weight::from_ref_time(50_685_362).saturating_mul(f.into())) - // Standard Error: 74_667 - .saturating_add(Weight::from_ref_time(50_629_572).saturating_mul(n.into())) - // Standard Error: 733_198 - .saturating_add(Weight::from_ref_time(3_558_326).saturating_mul(o.into())) + // Minimum execution time: 620_019 nanoseconds. + Weight::from_ref_time(69_250_596) + // Standard Error: 326_940 + .saturating_add(Weight::from_ref_time(48_979_300).saturating_mul(f.into())) + // Standard Error: 30_169 + .saturating_add(Weight::from_ref_time(49_750_596).saturating_mul(n.into())) + // Standard Error: 296_253 + .saturating_add(Weight::from_ref_time(3_149_566).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(8)) .saturating_add(DbWeight::get().reads((9_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((9_u64).saturating_mul(n.into()))) @@ -964,29 +911,29 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((1_u64).saturating_mul(m.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement VenueInfo (r:1 w:0) - // Proof Skipped: Settlement VenueInfo (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) // Storage: Asset Assets (r:110 w:0) // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) // Storage: Settlement VenueFiltering (r:110 w:0) - // Proof Skipped: Settlement VenueFiltering (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Identity DidRecords (r:2 w:0) - // Proof Skipped: Identity DidRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity DidRecords (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio Portfolios (r:220 w:0) // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioCustodian (r:220 w:0) - // Proof Skipped: Portfolio PortfolioCustodian (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioCustodian (max_values: None, max_size: Some(81), added: 2556, mode: MaxEncodedLen) // Storage: Asset AssetsExemptFromAffirmation (r:110 w:0) - // Proof Skipped: Asset AssetsExemptFromAffirmation (max_values: None, max_size: None, mode: Measured) + // Proof: Asset AssetsExemptFromAffirmation (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Asset PreApprovedAsset (r:110 w:0) - // Proof Skipped: Asset PreApprovedAsset (max_values: None, max_size: None, mode: Measured) + // Proof: Asset PreApprovedAsset (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Portfolio PreApprovedPortfolios (r:110 w:0) - // Proof Skipped: Portfolio PreApprovedPortfolios (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PreApprovedPortfolios (max_values: None, max_size: Some(82), added: 2557, mode: MaxEncodedLen) // Storage: Asset MandatoryMediators (r:110 w:0) - // Proof Skipped: Asset MandatoryMediators (max_values: None, max_size: None, mode: Measured) + // Proof: Asset MandatoryMediators (max_values: None, max_size: Some(161), added: 2636, mode: MaxEncodedLen) // Storage: Settlement InstructionCounter (r:1 w:1) - // Proof Skipped: Settlement InstructionCounter (max_values: Some(1), max_size: None, mode: Measured) + // Proof: Settlement InstructionCounter (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Timestamp Now (r:1 w:0) // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) // Storage: Scheduler Lookup (r:1 w:1) @@ -996,46 +943,46 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { // Storage: Settlement InstructionLegs (r:121 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Portfolio PortfolioNFT (r:100 w:0) - // Proof Skipped: Portfolio PortfolioNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioAssetBalances (r:10 w:0) - // Proof Skipped: Portfolio PortfolioAssetBalances (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:0 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:0 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:0 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement InstructionMemos (r:0 w:1) - // Proof Skipped: Settlement InstructionMemos (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:0 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:0 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:0 w:444) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:110) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement InstructionLegStatus (r:0 w:110) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) /// The range of component `f` is `[1, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. /// The range of component `m` is `[0, 4]`. fn add_and_affirm_with_mediators(f: u32, n: u32, o: u32, m: u32) -> Weight { - // Minimum execution time: 1_081_398 nanoseconds. - Weight::from_ref_time(102_620_422) - // Standard Error: 1_211_850 - .saturating_add(Weight::from_ref_time(79_234_687).saturating_mul(f.into())) - // Standard Error: 111_828 - .saturating_add(Weight::from_ref_time(85_074_081).saturating_mul(n.into())) - // Standard Error: 1_098_106 - .saturating_add(Weight::from_ref_time(13_898_085).saturating_mul(o.into())) + // Minimum execution time: 1_041_334 nanoseconds. + Weight::from_ref_time(114_114_731) + // Standard Error: 440_207 + .saturating_add(Weight::from_ref_time(83_718_795).saturating_mul(f.into())) + // Standard Error: 40_621 + .saturating_add(Weight::from_ref_time(81_776_034).saturating_mul(n.into())) + // Standard Error: 398_889 + .saturating_add(Weight::from_ref_time(4_906_594).saturating_mul(o.into())) .saturating_add(DbWeight::get().reads(9)) .saturating_add(DbWeight::get().reads((13_u64).saturating_mul(f.into()))) .saturating_add(DbWeight::get().reads((13_u64).saturating_mul(n.into()))) @@ -1047,86 +994,332 @@ impl pallet_settlement::WeightInfo for SubstrateWeight { .saturating_add(DbWeight::get().writes((1_u64).saturating_mul(m.into()))) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:1 w:1) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) fn affirm_instruction_as_mediator() -> Weight { - // Minimum execution time: 97_645 nanoseconds. - Weight::from_ref_time(104_767_000) + // Minimum execution time: 76_558 nanoseconds. + Weight::from_ref_time(78_467_000) .saturating_add(DbWeight::get().reads(5)) .saturating_add(DbWeight::get().writes(2)) } // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionDetails (r:1 w:0) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) // Storage: Settlement InstructionStatuses (r:1 w:0) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) // Storage: Settlement InstructionMediatorsAffirmations (r:1 w:1) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:1 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) fn withdraw_affirmation_as_mediator() -> Weight { - // Minimum execution time: 100_541 nanoseconds. - Weight::from_ref_time(107_081_000) + // Minimum execution time: 75_250 nanoseconds. + Weight::from_ref_time(76_169_000) .saturating_add(DbWeight::get().reads(5)) .saturating_add(DbWeight::get().writes(2)) } - // Storage: Settlement InstructionStatuses (r:1 w:1) - // Proof Skipped: Settlement InstructionStatuses (max_values: None, max_size: None, mode: Measured) + // Storage: Identity KeyRecords (r:1 w:0) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Settlement InstructionLegs (r:121 w:120) // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) - // Storage: Identity KeyRecords (r:1 w:0) - // Proof Skipped: Identity KeyRecords (max_values: None, max_size: None, mode: Measured) - // Storage: Settlement InstructionMediatorsAffirmations (r:6 w:4) - // Proof Skipped: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: None, mode: Measured) + // Storage: Settlement InstructionStatuses (r:1 w:1) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) + // Storage: Settlement InstructionDetails (r:1 w:1) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + // Storage: Settlement VenueInfo (r:1 w:0) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + // Storage: Settlement InstructionMediatorsAffirmations (r:444 w:444) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) // Storage: Settlement InstructionLegStatus (r:120 w:120) - // Proof Skipped: Settlement InstructionLegStatus (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) - // Proof Skipped: Portfolio PortfolioLockedNFT (max_values: None, max_size: None, mode: Measured) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) - // Proof Skipped: Portfolio PortfolioLockedAssets (max_values: None, max_size: None, mode: Measured) - // Storage: Scheduler Lookup (r:1 w:1) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Scheduler Lookup (r:1 w:0) // Proof: Scheduler Lookup (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) - // Storage: Scheduler Agenda (r:1 w:1) - // Proof: Scheduler Agenda (max_values: None, max_size: Some(10463), added: 12938, mode: MaxEncodedLen) + // Storage: Settlement UserAffirmations (r:0 w:220) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + // Storage: Settlement OffChainAffirmations (r:0 w:10) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement InstructionAffirmsPending (r:0 w:1) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + // Storage: Settlement VenueInstructions (r:0 w:1) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) + // Storage: Settlement AffirmsReceived (r:0 w:220) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + /// The range of component `f` is `[0, 10]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `o` is `[0, 10]`. + fn base_reject_instruction(f: u32, n: u32, o: u32) -> Weight { + // Minimum execution time: 545_769 nanoseconds. + Weight::from_ref_time(57_609_468) + // Standard Error: 175_623 + .saturating_add(Weight::from_ref_time(33_741_621).saturating_mul(f.into())) + // Standard Error: 17_936 + .saturating_add(Weight::from_ref_time(32_236_704).saturating_mul(n.into())) + // Standard Error: 175_623 + .saturating_add(Weight::from_ref_time(13_428_424).saturating_mul(o.into())) + .saturating_add(DbWeight::get().reads(10)) + .saturating_add(DbWeight::get().reads((7_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().reads((7_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().reads((2_u64).saturating_mul(o.into()))) + .saturating_add(DbWeight::get().writes(8)) + .saturating_add(DbWeight::get().writes((11_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().writes((11_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) + } + // Storage: Identity KeyRecords (r:1 w:0) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + // Storage: Settlement InstructionMediatorsAffirmations (r:445 w:0) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) + // Storage: Settlement InstructionDetails (r:1 w:0) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegs (r:121 w:0) + // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) + // Storage: Settlement InstructionStatuses (r:1 w:1) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) + // Storage: Settlement InstructionAffirmsPending (r:1 w:0) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + // Storage: Timestamp Now (r:1 w:0) + // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegStatus (r:120 w:0) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + // Storage: Settlement OffChainAffirmations (r:10 w:0) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement UserAffirmations (r:220 w:0) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + // Storage: Settlement AffirmsReceived (r:220 w:0) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + // Storage: Settlement VenueFiltering (r:110 w:0) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement InstructionMemos (r:1 w:0) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioLockedAssets (r:10 w:0) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioLockedNFT (r:100 w:0) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) + // Storage: Asset Assets (r:10 w:0) + // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) + // Storage: Asset BalanceOf (r:20 w:0) + // Proof: Asset BalanceOf (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + // Storage: Portfolio Portfolios (r:20 w:0) + // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) + // Storage: Portfolio PortfolioAssetBalances (r:20 w:0) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Asset Frozen (r:110 w:0) + // Proof: Asset Frozen (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: CddServiceProviders ActiveMembers (r:1 w:0) + // Proof Skipped: CddServiceProviders ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Identity Claims (r:4 w:0) + // Proof Skipped: Identity Claims (max_values: None, max_size: None, mode: Measured) + // Storage: Statistics AssetTransferCompliances (r:10 w:0) + // Proof: Statistics AssetTransferCompliances (max_values: None, max_size: Some(246), added: 2721, mode: MaxEncodedLen) + // Storage: ComplianceManager AssetCompliances (r:110 w:0) + // Proof Skipped: ComplianceManager AssetCompliances (max_values: None, max_size: None, mode: Measured) + // Storage: Checkpoint CachedNextCheckpoints (r:10 w:0) + // Proof Skipped: Checkpoint CachedNextCheckpoints (max_values: None, max_size: None, mode: Measured) + // Storage: Checkpoint CheckpointIdSequence (r:10 w:0) + // Proof: Checkpoint CheckpointIdSequence (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioAssetCount (r:10 w:0) + // Proof: Portfolio PortfolioAssetCount (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + // Storage: Statistics ActiveAssetStats (r:10 w:0) + // Proof: Statistics ActiveAssetStats (max_values: None, max_size: Some(423), added: 2898, mode: MaxEncodedLen) + // Storage: Nft CollectionAsset (r:100 w:0) + // Proof: Nft CollectionAsset (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Nft NumberOfNFTs (r:200 w:0) + // Proof: Nft NumberOfNFTs (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioNFT (r:100 w:0) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) + // Storage: Settlement LockedTimestamp (r:0 w:1) + // Proof: Settlement LockedTimestamp (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + /// The range of component `f` is `[0, 10]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `o` is `[0, 10]`. + fn lock_instruction_extrinsic(f: u32, n: u32, o: u32) -> Weight { + // Minimum execution time: 2_304_759 nanoseconds. + Weight::from_ref_time(2_306_732_000) + // Standard Error: 2_531_717 + .saturating_add(Weight::from_ref_time(127_090_962).saturating_mul(f.into())) + // Standard Error: 254_181 + .saturating_add(Weight::from_ref_time(160_208_420).saturating_mul(n.into())) + .saturating_add(DbWeight::get().reads(17)) + .saturating_add(DbWeight::get().reads((26_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().reads((18_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(o.into()))) + .saturating_add(DbWeight::get().writes(2)) + } + // Storage: Identity KeyRecords (r:1 w:0) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegs (r:121 w:120) + // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) // Storage: Settlement InstructionDetails (r:1 w:1) - // Proof Skipped: Settlement InstructionDetails (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + // Storage: Settlement VenueInfo (r:1 w:0) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + // Storage: Settlement InstructionMediatorsAffirmations (r:444 w:444) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) + // Storage: Settlement InstructionStatuses (r:1 w:1) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) + // Storage: Settlement LockedTimestamp (r:1 w:0) + // Proof: Settlement LockedTimestamp (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + // Storage: Timestamp Now (r:1 w:0) + // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegStatus (r:120 w:120) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Settlement InstructionMemos (r:1 w:0) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + // Storage: Portfolio Portfolios (r:110 w:0) + // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) + // Storage: Portfolio PortfolioNFT (r:100 w:200) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) + // Storage: Nft NumberOfNFTs (r:200 w:200) + // Proof: Nft NumberOfNFTs (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + // Storage: Asset BalanceOf (r:20 w:20) + // Proof: Asset BalanceOf (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + // Storage: Asset Assets (r:10 w:0) + // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) + // Storage: Portfolio PortfolioAssetBalances (r:20 w:20) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Checkpoint CachedNextCheckpoints (r:10 w:0) + // Proof Skipped: Checkpoint CachedNextCheckpoints (max_values: None, max_size: None, mode: Measured) + // Storage: Checkpoint CheckpointIdSequence (r:10 w:0) + // Proof: Checkpoint CheckpointIdSequence (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioAssetCount (r:10 w:10) + // Proof: Portfolio PortfolioAssetCount (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + // Storage: Statistics ActiveAssetStats (r:10 w:0) + // Proof: Statistics ActiveAssetStats (max_values: None, max_size: Some(423), added: 2898, mode: MaxEncodedLen) + // Storage: Identity Claims (r:200 w:0) + // Proof Skipped: Identity Claims (max_values: None, max_size: None, mode: Measured) + // Storage: Statistics AssetStats (r:100 w:100) + // Proof: Statistics AssetStats (max_values: None, max_size: Some(107), added: 2582, mode: MaxEncodedLen) // Storage: Settlement UserAffirmations (r:0 w:220) - // Proof Skipped: Settlement UserAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) // Storage: Settlement OffChainAffirmations (r:0 w:10) - // Proof Skipped: Settlement OffChainAffirmations (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) // Storage: Settlement InstructionAffirmsPending (r:0 w:1) - // Proof Skipped: Settlement InstructionAffirmsPending (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) // Storage: Settlement VenueInstructions (r:0 w:1) - // Proof Skipped: Settlement VenueInstructions (max_values: None, max_size: None, mode: Measured) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) // Storage: Settlement AffirmsReceived (r:0 w:220) - // Proof Skipped: Settlement AffirmsReceived (max_values: None, max_size: None, mode: Measured) - /// The range of component `f` is `[1, 10]`. + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + // Storage: Nft NFTOwner (r:0 w:100) + // Proof: Nft NFTOwner (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + /// The range of component `f` is `[0, 10]`. /// The range of component `n` is `[0, 100]`. /// The range of component `o` is `[0, 10]`. - fn reject_instruction_as_mediator(f: u32, n: u32, o: u32) -> Weight { - // Minimum execution time: 603_653 nanoseconds. - Weight::from_ref_time(139_191_704) - // Standard Error: 1_088_239 - .saturating_add(Weight::from_ref_time(25_785_995).saturating_mul(f.into())) - // Standard Error: 100_665 - .saturating_add(Weight::from_ref_time(36_080_056).saturating_mul(n.into())) - // Standard Error: 985_776 - .saturating_add(Weight::from_ref_time(12_324_568).saturating_mul(o.into())) + fn execute_locked_instruction(f: u32, n: u32, o: u32) -> Weight { + // Minimum execution time: 2_551_296 nanoseconds. + Weight::from_ref_time(2_553_993_000) + // Standard Error: 2_755_470 + .saturating_add(Weight::from_ref_time(148_087_830).saturating_mul(f.into())) + // Standard Error: 276_646 + .saturating_add(Weight::from_ref_time(55_665_624).saturating_mul(n.into())) .saturating_add(DbWeight::get().reads(12)) - .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(f.into()))) - .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().reads((47_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().reads((11_u64).saturating_mul(n.into()))) .saturating_add(DbWeight::get().reads((2_u64).saturating_mul(o.into()))) - .saturating_add(DbWeight::get().writes(10)) - .saturating_add(DbWeight::get().writes((7_u64).saturating_mul(f.into()))) - .saturating_add(DbWeight::get().writes((7_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().writes(8)) + .saturating_add(DbWeight::get().writes((26_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().writes((16_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) + } + // Storage: Identity KeyRecords (r:1 w:0) + // Proof: Identity KeyRecords (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegs (r:121 w:120) + // Proof Skipped: Settlement InstructionLegs (max_values: None, max_size: None, mode: Measured) + // Storage: Settlement InstructionDetails (r:1 w:1) + // Proof: Settlement InstructionDetails (max_values: None, max_size: Some(65), added: 2540, mode: MaxEncodedLen) + // Storage: Settlement VenueInfo (r:1 w:0) + // Proof: Settlement VenueInfo (max_values: None, max_size: Some(49), added: 2524, mode: MaxEncodedLen) + // Storage: Settlement InstructionMediatorsAffirmations (r:445 w:444) + // Proof: Settlement InstructionMediatorsAffirmations (max_values: None, max_size: Some(58), added: 2533, mode: MaxEncodedLen) + // Storage: Settlement InstructionStatuses (r:1 w:1) + // Proof: Settlement InstructionStatuses (max_values: None, max_size: Some(21), added: 2496, mode: MaxEncodedLen) + // Storage: Settlement InstructionAffirmsPending (r:1 w:1) + // Proof: Settlement InstructionAffirmsPending (max_values: None, max_size: Some(24), added: 2499, mode: MaxEncodedLen) + // Storage: Timestamp Now (r:1 w:0) + // Proof: Timestamp Now (max_values: Some(1), max_size: Some(8), added: 503, mode: MaxEncodedLen) + // Storage: Settlement InstructionLegStatus (r:120 w:120) + // Proof: Settlement InstructionLegStatus (max_values: None, max_size: Some(73), added: 2548, mode: MaxEncodedLen) + // Storage: Settlement OffChainAffirmations (r:10 w:10) + // Proof: Settlement OffChainAffirmations (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement UserAffirmations (r:220 w:220) + // Proof: Settlement UserAffirmations (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + // Storage: Settlement AffirmsReceived (r:220 w:220) + // Proof: Settlement AffirmsReceived (max_values: None, max_size: Some(66), added: 2541, mode: MaxEncodedLen) + // Storage: Settlement VenueFiltering (r:110 w:0) + // Proof: Settlement VenueFiltering (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: Settlement InstructionMemos (r:1 w:0) + // Proof: Settlement InstructionMemos (max_values: None, max_size: Some(48), added: 2523, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioLockedAssets (r:10 w:10) + // Proof: Portfolio PortfolioLockedAssets (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioLockedNFT (r:100 w:100) + // Proof: Portfolio PortfolioLockedNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) + // Storage: Asset Assets (r:10 w:0) + // Proof Skipped: Asset Assets (max_values: None, max_size: None, mode: Measured) + // Storage: Asset BalanceOf (r:20 w:20) + // Proof: Asset BalanceOf (max_values: None, max_size: Some(80), added: 2555, mode: MaxEncodedLen) + // Storage: Portfolio Portfolios (r:20 w:0) + // Proof Skipped: Portfolio Portfolios (max_values: None, max_size: None, mode: Measured) + // Storage: Portfolio PortfolioAssetBalances (r:20 w:20) + // Proof: Portfolio PortfolioAssetBalances (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + // Storage: Asset Frozen (r:110 w:0) + // Proof: Asset Frozen (max_values: None, max_size: Some(33), added: 2508, mode: MaxEncodedLen) + // Storage: CddServiceProviders ActiveMembers (r:1 w:0) + // Proof Skipped: CddServiceProviders ActiveMembers (max_values: Some(1), max_size: None, mode: Measured) + // Storage: Identity Claims (r:4 w:0) + // Proof Skipped: Identity Claims (max_values: None, max_size: None, mode: Measured) + // Storage: Statistics AssetTransferCompliances (r:10 w:0) + // Proof: Statistics AssetTransferCompliances (max_values: None, max_size: Some(246), added: 2721, mode: MaxEncodedLen) + // Storage: ComplianceManager AssetCompliances (r:110 w:0) + // Proof Skipped: ComplianceManager AssetCompliances (max_values: None, max_size: None, mode: Measured) + // Storage: Checkpoint CachedNextCheckpoints (r:10 w:0) + // Proof Skipped: Checkpoint CachedNextCheckpoints (max_values: None, max_size: None, mode: Measured) + // Storage: Checkpoint CheckpointIdSequence (r:10 w:0) + // Proof: Checkpoint CheckpointIdSequence (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioAssetCount (r:10 w:10) + // Proof: Portfolio PortfolioAssetCount (max_values: None, max_size: Some(57), added: 2532, mode: MaxEncodedLen) + // Storage: Statistics ActiveAssetStats (r:10 w:0) + // Proof: Statistics ActiveAssetStats (max_values: None, max_size: Some(423), added: 2898, mode: MaxEncodedLen) + // Storage: Nft CollectionAsset (r:100 w:0) + // Proof: Nft CollectionAsset (max_values: None, max_size: Some(40), added: 2515, mode: MaxEncodedLen) + // Storage: Nft NumberOfNFTs (r:200 w:200) + // Proof: Nft NumberOfNFTs (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) + // Storage: Portfolio PortfolioNFT (r:100 w:200) + // Proof: Portfolio PortfolioNFT (max_values: None, max_size: Some(90), added: 2565, mode: MaxEncodedLen) + // Storage: Settlement VenueInstructions (r:0 w:1) + // Proof: Settlement VenueInstructions (max_values: None, max_size: Some(32), added: 2507, mode: MaxEncodedLen) + // Storage: Nft NFTOwner (r:0 w:100) + // Proof: Nft NFTOwner (max_values: None, max_size: Some(97), added: 2572, mode: MaxEncodedLen) + /// The range of component `f` is `[0, 10]`. + /// The range of component `n` is `[0, 100]`. + /// The range of component `o` is `[0, 10]`. + fn execute_manual_instruction_paused(f: u32, n: u32, o: u32) -> Weight { + // Minimum execution time: 2_610_539 nanoseconds. + Weight::from_ref_time(2_619_700_000) + // Standard Error: 2_902_849 + .saturating_add(Weight::from_ref_time(137_575_439).saturating_mul(f.into())) + // Standard Error: 291_442 + .saturating_add(Weight::from_ref_time(180_560_856).saturating_mul(n.into())) + .saturating_add(DbWeight::get().reads(18)) + .saturating_add(DbWeight::get().reads((26_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().reads((18_u64).saturating_mul(n.into()))) + .saturating_add(DbWeight::get().reads((3_u64).saturating_mul(o.into()))) + .saturating_add(DbWeight::get().writes(8)) + .saturating_add(DbWeight::get().writes((16_u64).saturating_mul(f.into()))) + .saturating_add(DbWeight::get().writes((16_u64).saturating_mul(n.into()))) .saturating_add(DbWeight::get().writes((3_u64).saturating_mul(o.into()))) } } diff --git a/primitives/src/settlement.rs b/primitives/src/settlement.rs index d12ddf1dd2..912666dcde 100644 --- a/primitives/src/settlement.rs +++ b/primitives/src/settlement.rs @@ -44,19 +44,8 @@ impl_checked_inc!(VenueId); pub struct VenueDetails(Vec); /// Status of an instruction -#[derive( - Clone, - Debug, - Decode, - Default, - Encode, - MaxEncodedLen, - Eq, - Ord, - PartialEq, - PartialOrd, - TypeInfo -)] +#[derive(Encode, Decode, MaxEncodedLen, TypeInfo)] +#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] pub enum InstructionStatus { /// Invalid instruction or details pruned #[default] @@ -69,6 +58,8 @@ pub enum InstructionStatus { Success(BlockNumber), /// Instruction has been rejected. Rejected(BlockNumber), + /// Instruction is locked for execution. + LockedForExecution, } /// Type of the venue. Used for offchain filtering. @@ -148,20 +139,8 @@ pub enum AffirmationStatus { } /// Type of settlement -#[derive( - Copy, - Clone, - Debug, - Decode, - Default, - Encode, - MaxEncodedLen, - Eq, - Ord, - PartialEq, - PartialOrd, - TypeInfo -)] +#[derive(Encode, Decode, MaxEncodedLen, TypeInfo)] +#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] pub enum SettlementType { /// Instruction should be settled in the next block as soon as all affirmations are received. #[default] @@ -170,6 +149,8 @@ pub enum SettlementType { SettleOnBlock(BlockNumber), /// Instruction must be settled manually on or after BlockNumber. SettleManual(BlockNumber), + /// Instruction will be settled after lock. + SettleAfterLock, } /// A per-Instruction leg ID. @@ -810,6 +791,11 @@ impl ExecuteInstructionInfo { error: error.map(|e| e.to_string()), } } + + /// Returns the weight needed for executing the instruction. + pub fn consumed_weight(&self) -> Weight { + self.consumed_weight + } } /// The status of the mediator's affirmation. diff --git a/rpc/runtime-api/src/settlement.rs b/rpc/runtime-api/src/settlement.rs index 41f3dfa268..ab4b400c7e 100644 --- a/rpc/runtime-api/src/settlement.rs +++ b/rpc/runtime-api/src/settlement.rs @@ -16,11 +16,11 @@ //! Runtime API definition for Settlement module. use frame_support::dispatch::DispatchError; +use frame_support::weights::Weight; use sp_std::vec::Vec; -use polymesh_primitives::settlement::{ - AffirmationCount, ExecuteInstructionInfo, InstructionId, Leg, -}; +use polymesh_primitives::settlement::{AffirmationCount, ExecuteInstructionInfo}; +use polymesh_primitives::settlement::{AssetCount, InstructionId, Leg}; use polymesh_primitives::PortfolioId; sp_api::decl_runtime_apis! { @@ -38,7 +38,7 @@ sp_api::decl_runtime_apis! { /// "params": [1] /// }' /// ``` - fn get_execute_instruction_info(instruction_id: &InstructionId) -> Option; + fn get_execute_instruction_info(instruction_id: InstructionId) -> Option; /// Returns an [`AffirmationCount`] instance containing the number of assets being sent/received from `portfolios`, /// and the number of off-chain assets in the instruction. @@ -86,5 +86,11 @@ sp_api::decl_runtime_apis! { /// }' /// ``` fn get_execute_instruction_report(instruction_id: InstructionId) -> Vec; + + /// Returns the weight for calling `lock_instruction` for the given `instruction_id`. + fn lock_instruction_weight(instruction_id: InstructionId) -> Result; + + /// Returns the [`AssetCount`] for the given `instruction_id`. + fn instruction_asset_count(instruction_id: InstructionId) -> AssetCount; } } diff --git a/rpc/src/settlement.rs b/rpc/src/settlement.rs index 6858d25932..a0432b2039 100644 --- a/rpc/src/settlement.rs +++ b/rpc/src/settlement.rs @@ -25,9 +25,8 @@ use sp_blockchain::HeaderBackend; use sp_runtime::traits::Block as BlockT; pub use node_rpc_runtime_api::settlement::SettlementApi as SettlementRuntimeApi; -use polymesh_primitives::settlement::{ - AffirmationCount, ExecuteInstructionInfo, InstructionId, Leg, -}; +use polymesh_primitives::settlement::{AffirmationCount, ExecuteInstructionInfo}; +use polymesh_primitives::settlement::{InstructionId, Leg}; use polymesh_primitives::PortfolioId; use crate::Error; @@ -96,7 +95,7 @@ where // If the block hash is not supplied assume the best block. let at_hash = at.unwrap_or_else(|| self.client.info().best_hash); - api.get_execute_instruction_info(at_hash, &instruction_id) + api.get_execute_instruction_info(at_hash, instruction_id) .map_err(|e| { CallError::Custom(ErrorObject::owned( Error::RuntimeError.into(),