Skip to content

Commit

Permalink
Add portfolios to settlement weights (#1734)
Browse files Browse the repository at this point in the history
  • Loading branch information
HenriqueNogara authored Oct 11, 2024
1 parent d454888 commit 8965d41
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 30 deletions.
88 changes: 70 additions & 18 deletions pallets/common/src/traits/settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,20 +118,24 @@ pub trait WeightInfo {
fn withdraw_affirmation_as_mediator() -> Weight;
fn reject_instruction_as_mediator(f: u32, n: u32, o: u32) -> Weight;

fn add_and_affirm_with_mediators_legs(legs: &[Leg], n_mediators: u32) -> Weight {
let (f, n, o) = Self::get_transfer_by_asset(legs);
fn add_and_affirm_with_mediators_legs(
legs: &[Leg],
portfolios: u32,
n_mediators: u32,
) -> Weight {
let (f, n, o) = Self::get_transfer_by_asset(legs, portfolios);
Self::add_and_affirm_with_mediators(f, n, o, n_mediators)
}
fn add_instruction_with_mediators_legs(legs: &[Leg], n_mediators: u32) -> Weight {
let (f, n, o) = Self::get_transfer_by_asset(legs);
let (f, n, o) = Self::get_transfer_by_asset(legs, 0);
Self::add_instruction_with_mediators(f, n, o, n_mediators)
}
fn add_instruction_legs(legs: &[Leg]) -> Weight {
let (f, n, o) = Self::get_transfer_by_asset(legs);
let (f, n, o) = Self::get_transfer_by_asset(legs, 0);
Self::add_instruction(f, n, o)
}
fn add_and_affirm_instruction_legs(legs: &[Leg]) -> Weight {
let (f, n, o) = Self::get_transfer_by_asset(legs);
fn add_and_affirm_instruction_legs(legs: &[Leg], portfolios: u32) -> Weight {
let (f, n, o) = Self::get_transfer_by_asset(legs, portfolios);
Self::add_and_affirm_instruction(f, n, o)
}
fn execute_manual_weight_limit(
Expand All @@ -145,18 +149,29 @@ pub trait WeightInfo {
}
Self::execute_manual_instruction(*f, *n, *o)
}
fn get_transfer_by_asset(legs: &[Leg]) -> (u32, u32, u32) {
fn get_transfer_by_asset(legs: &[Leg], portfolios: u32) -> (u32, u32, u32) {
let asset_count =
AssetCount::try_from_legs(legs).unwrap_or(AssetCount::new(1024, 1024, 1024));
(
asset_count.fungible(),
asset_count.non_fungible(),
asset_count.off_chain(),
)
let f = asset_count.fungible();
let n = asset_count.non_fungible();
let max_portfolios = (f.saturating_add(n)).saturating_mul(2); // 2 portfolios per leg. (f+n = max legs).
if portfolios > max_portfolios {
// Too many portfolios, return worse-case count based on portfolio count.
return (portfolios, portfolios, 1024);
}
(f, n, asset_count.off_chain())
}
fn affirm_with_receipts_input(affirmation_count: Option<AffirmationCount>) -> Weight {
fn affirm_with_receipts_input(
affirmation_count: Option<AffirmationCount>,
portfolios: u32,
) -> Weight {
match affirmation_count {
Some(affirmation_count) => {
let max_portfolios = affirmation_count.max_portfolios();
if portfolios > max_portfolios {
// Too many portfolios, return worse-case weight based on portfolio count.
return Self::affirm_with_receipts(portfolios, portfolios, 10);
}
// The weight for the assets being sent
let sender_asset_count = affirmation_count.sender_asset_count();
let sender_side_weight = Self::affirm_with_receipts(
Expand All @@ -178,12 +193,27 @@ pub trait WeightInfo {
.saturating_add(receiver_side_weight)
.saturating_sub(duplicated_weight)
}
None => Self::affirm_with_receipts(10, 100, 10),
None => {
if portfolios > (10 + 100) * 2 {
// Too many portfolios, return worse-case weight based on portfolio count.
Self::affirm_with_receipts(portfolios, portfolios, 10)
} else {
Self::affirm_with_receipts(10, 100, 10)
}
}
}
}
fn affirm_instruction_input(affirmation_count: Option<AffirmationCount>) -> Weight {
fn affirm_instruction_input(
affirmation_count: Option<AffirmationCount>,
portfolios: u32,
) -> Weight {
match affirmation_count {
Some(affirmation_count) => {
let max_portfolios = affirmation_count.max_portfolios();
if portfolios > max_portfolios {
// Too many portfolios, return worse-case weight based on portfolio count.
return Self::affirm_instruction(portfolios, portfolios);
}
// The weight for the assets being sent
let sender_asset_count = affirmation_count.sender_asset_count();
let sender_side_weight = Self::affirm_instruction(
Expand All @@ -203,12 +233,27 @@ pub trait WeightInfo {
.saturating_add(receiver_side_weight)
.saturating_sub(duplicated_weight)
}
None => Self::affirm_instruction(10, 100),
None => {
if portfolios > (10 + 100) * 2 {
// Too many portfolios, return worse-case weight based on portfolio count.
Self::affirm_instruction(portfolios, portfolios)
} else {
Self::affirm_instruction(10, 100)
}
}
}
}
fn withdraw_affirmation_input(affirmation_count: Option<AffirmationCount>) -> Weight {
fn withdraw_affirmation_input(
affirmation_count: Option<AffirmationCount>,
portfolios: u32,
) -> Weight {
match affirmation_count {
Some(affirmation_count) => {
let max_portfolios = affirmation_count.max_portfolios();
if portfolios > max_portfolios {
// Too many portfolios, return worse-case weight based on portfolio count.
return Self::withdraw_affirmation(portfolios, portfolios, 10);
}
// The weight for the assets being sent
let sender_asset_count = affirmation_count.sender_asset_count();
let sender_side_weight = Self::withdraw_affirmation(
Expand All @@ -230,7 +275,14 @@ pub trait WeightInfo {
.saturating_add(receiver_side_weight)
.saturating_sub(duplicated_weight)
}
None => Self::withdraw_affirmation(10, 100, 10),
None => {
if portfolios > (10 + 100) * 2 {
// Too many portfolios, return worse-case weight based on portfolio count.
Self::withdraw_affirmation(portfolios, portfolios, 10)
} else {
Self::withdraw_affirmation(10, 100, 10)
}
}
}
}
fn reject_instruction_input(asset_count: Option<AssetCount>, as_mediator: bool) -> Weight {
Expand Down
24 changes: 12 additions & 12 deletions pallets/settlement/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::affirm_with_receipts_input(None)]
#[weight = <T as Config>::WeightInfo::affirm_with_receipts_input(None, portfolios.len() as u32)]
pub fn affirm_with_receipts(
origin,
id: InstructionId,
Expand Down Expand Up @@ -565,7 +565,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::add_and_affirm_instruction_legs(legs)]
#[weight = <T as Config>::WeightInfo::add_and_affirm_instruction_legs(legs, portfolios.len() as u32)]
pub fn add_and_affirm_instruction(
origin,
venue_id: Option<VenueId>,
Expand Down Expand Up @@ -605,7 +605,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::affirm_instruction_input(None)]
#[weight = <T as Config>::WeightInfo::affirm_instruction_input(None, portfolios.len() as u32)]
pub fn affirm_instruction(origin, id: InstructionId, portfolios: Vec<PortfolioId>) -> DispatchResultWithPostInfo {
Self::affirm_and_maybe_schedule_instruction(
origin,
Expand All @@ -623,7 +623,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::withdraw_affirmation_input(None)]
#[weight = <T as Config>::WeightInfo::withdraw_affirmation_input(None, portfolios.len() as u32)]
pub fn withdraw_affirmation(origin, id: InstructionId, portfolios: Vec<PortfolioId>) -> DispatchResultWithPostInfo {
Self::base_withdraw_affirmation(origin, id, portfolios, None)
}
Expand Down Expand Up @@ -668,7 +668,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::affirm_with_receipts_input(*number_of_assets)]
#[weight = <T as Config>::WeightInfo::affirm_with_receipts_input(*number_of_assets, portfolios.len() as u32)]
pub fn affirm_with_receipts_with_count(
origin,
id: InstructionId,
Expand Down Expand Up @@ -697,7 +697,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::affirm_instruction_input(*number_of_assets)]
#[weight = <T as Config>::WeightInfo::affirm_instruction_input(*number_of_assets, portfolios.len() as u32)]
pub fn affirm_instruction_with_count(
origin,
id: InstructionId,
Expand Down Expand Up @@ -746,7 +746,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::withdraw_affirmation_input(*number_of_assets)]
#[weight = <T as Config>::WeightInfo::withdraw_affirmation_input(*number_of_assets, portfolios.len() as u32)]
pub fn withdraw_affirmation_with_count(
origin,
id: InstructionId,
Expand Down Expand Up @@ -805,7 +805,7 @@ decl_module! {
///
/// # Permissions
/// * Portfolio
#[weight = <T as Config>::WeightInfo::add_and_affirm_with_mediators_legs(legs, mediators.len() as u32)]
#[weight = <T as Config>::WeightInfo::add_and_affirm_with_mediators_legs(legs, portfolios.len() as u32, mediators.len() as u32)]
pub fn add_and_affirm_with_mediators(
origin,
venue_id: Option<VenueId>,
Expand Down Expand Up @@ -870,7 +870,7 @@ decl_module! {
/// * `number_of_assets` - an optional [`AssetCount`] that will be used for a precise fee estimation before executing the extrinsic.
///
/// Note: calling the rpc method `get_execute_instruction_info` returns an instance of [`ExecuteInstructionInfo`], which contain the asset count.
#[weight = <T as Config>::WeightInfo::reject_instruction_input(None, true)]
#[weight = <T as Config>::WeightInfo::reject_instruction_input(*number_of_assets, true)]
pub fn reject_instruction_as_mediator(
origin,
instruction_id: InstructionId,
Expand Down Expand Up @@ -2511,7 +2511,7 @@ impl<T: Config> Module<T> {
) -> Weight {
let affirmation_count =
AffirmationCount::new(sender_asset_count, receiver_asset_count, n_offchain);
<T as Config>::WeightInfo::affirm_with_receipts_input(Some(affirmation_count))
<T as Config>::WeightInfo::affirm_with_receipts_input(Some(affirmation_count), 0)
}

/// Returns the weight for calling `affirm_instruction` while considering the `sender_asset_count` for the sender and`receiver_asset_count`
Expand All @@ -2521,7 +2521,7 @@ impl<T: Config> Module<T> {
receiver_asset_count: AssetCount,
) -> Weight {
let affirmation_count = AffirmationCount::new(sender_asset_count, receiver_asset_count, 0);
<T as Config>::WeightInfo::affirm_instruction_input(Some(affirmation_count))
<T as Config>::WeightInfo::affirm_instruction_input(Some(affirmation_count), 0)
}

/// Returns the weight for calling `withdraw_affirmation` while considering the `sender_asset_count` for the sender and`receiver_asset_count`
Expand All @@ -2533,7 +2533,7 @@ impl<T: Config> Module<T> {
) -> Weight {
let affirmation_count =
AffirmationCount::new(sender_asset_count, receiver_asset_count, n_offchain);
<T as Config>::WeightInfo::withdraw_affirmation_input(Some(affirmation_count))
<T as Config>::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`.
Expand Down
14 changes: 14 additions & 0 deletions primitives/src/settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,13 @@ impl AssetCount {
}
asset_count
}

/// The maximum number of unique portfolios.
pub fn max_portfolios(&self) -> u32 {
self.fungible
.saturating_add(self.non_fungible)
.saturating_mul(2)
}
}

/// Stores the [`AssetCount`] for the instruction, all portfolio that have pre-affirmed the transfer
Expand Down Expand Up @@ -664,6 +671,13 @@ impl AffirmationCount {
pub fn offchain_count(&self) -> u32 {
self.offchain_count
}

/// The maximum number of unique portfolios.
pub fn max_portfolios(&self) -> u32 {
self.sender_asset_count
.max_portfolios()
.saturating_add(self.receiver_asset_count.max_portfolios())
}
}

/// Stores the number of fungible, non fungible and offchain assets in an instruction, the consumed weight for executing the instruction,
Expand Down

0 comments on commit 8965d41

Please sign in to comment.