Skip to content

Commit

Permalink
refactor: improve calculate_required_asset_amounts for contract cal…
Browse files Browse the repository at this point in the history
…ls (#1576)

# Summary
Improve the calculation by removing repetitive steps and unnecessary
`collect`s.
  • Loading branch information
hal3e authored Jan 17, 2025
1 parent 1570dc0 commit 1c6c231
Showing 1 changed file with 15 additions and 34 deletions.
49 changes: 15 additions & 34 deletions packages/fuels-programs/src/calls/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,46 +131,27 @@ pub(crate) fn calculate_required_asset_amounts(
calls: &[ContractCall],
base_asset_id: AssetId,
) -> Vec<(AssetId, u64)> {
let call_param_assets = calls
.iter()
.filter_map(|call| {
(call.call_parameters.amount() != 0).then_some((
call.call_parameters.asset_id().unwrap_or(base_asset_id),
call.call_parameters.amount(),
))
})
.collect::<Vec<_>>();
let call_param_assets = calls.iter().map(|call| {
(
call.call_parameters.asset_id().unwrap_or(base_asset_id),
call.call_parameters.amount(),
)
});

let custom_assets = calls
let grouped_assets = calls
.iter()
.flat_map(|call| call.custom_assets.iter().collect::<Vec<_>>())
.group_by(|custom| custom.0 .0)
.into_iter()
.map(|(asset_id, groups_w_same_asset_id)| {
let total_amount_in_group = groups_w_same_asset_id.map(|(_, amount)| amount).sum();
(asset_id, total_amount_in_group)
})
.collect::<Vec<_>>();

let merged_assets = chain!(call_param_assets, custom_assets).collect::<Vec<_>>();

sum_up_amounts_for_each_asset_id(merged_assets)
}

/// Sum up the amounts required in each call for each asset ID, so you can get a total for each
/// asset over all calls.
fn sum_up_amounts_for_each_asset_id(
amounts_per_asset_id: Vec<(AssetId, u64)>,
) -> Vec<(AssetId, u64)> {
amounts_per_asset_id
.into_iter()
.flat_map(|call| call.custom_assets.clone())
.map(|((asset_id, _), amount)| (asset_id, amount))
.chain(call_param_assets)
.sorted_by_key(|(asset_id, _)| *asset_id)
.group_by(|(asset_id, _)| *asset_id)
.group_by(|(asset_id, _)| *asset_id);

grouped_assets
.into_iter()
.map(|(asset_id, groups_w_same_asset_id)| {
.filter_map(|(asset_id, groups_w_same_asset_id)| {
let total_amount_in_group = groups_w_same_asset_id.map(|(_, amount)| amount).sum();

(asset_id, total_amount_in_group)
(total_amount_in_group != 0).then_some((asset_id, total_amount_in_group))
})
.collect()
}
Expand Down

0 comments on commit 1c6c231

Please sign in to comment.