From 73f4bc8443fef38576f22c7014b7ec81bcd75fb8 Mon Sep 17 00:00:00 2001 From: Maxim Shishmarev <msgmaxim@gmail.com> Date: Tue, 3 Oct 2023 11:26:34 +1100 Subject: [PATCH] Feat: don't include dust btc amounts on rotation (#4063) * feat: don't include dust btc amounts on rotation * chore: return None early on empty utxo list --------- Co-authored-by: dandanlen <3168260+dandanlen@users.noreply.github.com> --- state-chain/pallets/cf-environment/src/lib.rs | 32 +++++++++++-------- .../pallets/cf-environment/src/tests.rs | 6 ++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/state-chain/pallets/cf-environment/src/lib.rs b/state-chain/pallets/cf-environment/src/lib.rs index 17fb26a09a..e84c483d2b 100644 --- a/state-chain/pallets/cf-environment/src/lib.rs +++ b/state-chain/pallets/cf-environment/src/lib.rs @@ -424,20 +424,24 @@ impl<T: Config> Pallet<T> { T::BitcoinFeeInfo::bitcoin_fee_info(); match utxo_selection_type { UtxoSelectionType::SelectAllForRotation => { - let available_utxos = BitcoinAvailableUtxos::<T>::take(); - (!available_utxos.is_empty()).then_some(available_utxos).and_then( - |available_utxos| { - available_utxos - .iter() - .map(|Utxo { amount, .. }| *amount) - .sum::<u64>() - .checked_sub( - ((available_utxos.len() as u64) * fee_per_input_utxo) + - fee_per_output_utxo + min_fee_required_per_tx, - ) - .map(|change_amount| (available_utxos, change_amount)) - }, - ) + let spendable_utxos: Vec<_> = BitcoinAvailableUtxos::<T>::take() + .into_iter() + .filter(|utxo| utxo.amount > fee_per_input_utxo) + .collect(); + + if spendable_utxos.is_empty() { + return None + } + + let total_fee = spendable_utxos.len() as u64 * fee_per_input_utxo + + fee_per_output_utxo + min_fee_required_per_tx; + + spendable_utxos + .iter() + .map(|utxo| utxo.amount) + .sum::<u64>() + .checked_sub(total_fee) + .map(|change_amount| (spendable_utxos, change_amount)) }, UtxoSelectionType::Some { output_amount, number_of_outputs } => BitcoinAvailableUtxos::<T>::try_mutate(|available_utxos| { diff --git a/state-chain/pallets/cf-environment/src/tests.rs b/state-chain/pallets/cf-environment/src/tests.rs index e3aa2754b5..058343229d 100644 --- a/state-chain/pallets/cf-environment/src/tests.rs +++ b/state-chain/pallets/cf-environment/src/tests.rs @@ -46,6 +46,12 @@ fn test_btc_utxo_selection() { add_utxo_amount(100000); add_utxo_amount(5000000); add_utxo_amount(25000); + // dust amount should be ignored in all cases + let dust_amount = { + use cf_traits::GetBitcoinFeeInfo; + <Test as crate::Config>::BitcoinFeeInfo::bitcoin_fee_info().fee_per_input_utxo + }; + add_utxo_amount(dust_amount); // select some utxos for a tx assert_eq!(