From f97feea394aa354f31f1bd52fc15fb97d4ca6975 Mon Sep 17 00:00:00 2001 From: Kobby Pentangeli Date: Thu, 4 Apr 2024 08:55:26 +0000 Subject: [PATCH] Fix: include number of inputs in the `total_estimated_tx_size` --- src/utils/fees.rs | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/utils/fees.rs b/src/utils/fees.rs index 9d2870f..ce86895 100644 --- a/src/utils/fees.rs +++ b/src/utils/fees.rs @@ -32,6 +32,7 @@ pub fn estimate_commit_fee( estimate_transaction_fees( script_type, unsigned_commit_tx.vsize(), + unsigned_commit_tx.input.len(), current_fee_rate, multisig_config, ) @@ -72,6 +73,7 @@ pub fn estimate_reveal_fee( estimate_transaction_fees( script_type, unsigned_reveal_tx.vsize(), + unsigned_reveal_tx.input.len(), current_fee_rate, multisig_config, ) @@ -80,11 +82,12 @@ pub fn estimate_reveal_fee( fn estimate_transaction_fees( script_type: ScriptType, unsigned_tx_size: usize, + number_of_inputs: usize, current_fee_rate: FeeRate, multisig_config: &Option, ) -> Amount { let estimated_sig_size = estimate_signature_size(script_type, multisig_config); - let total_estimated_tx_size = unsigned_tx_size + estimated_sig_size; + let total_estimated_tx_size = unsigned_tx_size + (number_of_inputs * estimated_sig_size); current_fee_rate .fee_vb(total_estimated_tx_size as u64) @@ -115,24 +118,27 @@ mod tests { fn estimate_transaction_fees_p2wsh_single_signature() { let script_type = ScriptType::P2WSH; let unsigned_tx_size = 100; // in vbytes + let number_of_inputs = 5_usize; let current_fee_rate = FeeRate::from_sat_per_vb(5_u64).unwrap(); let multisig_config: Option = None; // No multisig config for single signature let fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); - // Expected fee calculation: (100 + 73) * 5 = 865 satoshis - assert_eq!(fee, Amount::from_sat(865)); + // Expected fee calculation: (100 + (5 * 73)) * 5 = 2325 satoshis + assert_eq!(fee, Amount::from_sat(2325)); } #[test] fn estimate_transaction_fees_p2wsh_multisig() { let script_type = ScriptType::P2WSH; let unsigned_tx_size = 200; // in vbytes + let number_of_inputs = 10_usize; let current_fee_rate = FeeRate::from_sat_per_vb(10_u64).unwrap(); let multisig_config = Some(MultisigConfig { required: 2, @@ -142,30 +148,33 @@ mod tests { let fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); - // Expected fee calculation: (200 + (73 * 2)) * 10 = 3460 satoshis - assert_eq!(fee, Amount::from_sat(3460)); + // Expected fee calculation: (200 + (10 * 73 * 2)) * 10 = 16600 satoshis + assert_eq!(fee, Amount::from_sat(16600)); } #[test] fn estimate_transaction_fees_p2tr() { let script_type = ScriptType::P2TR; let unsigned_tx_size = 150; // in vbytes + let number_of_inputs = 5_usize; let current_fee_rate = FeeRate::from_sat_per_vb(1_u64).unwrap(); let multisig_config = None; let fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); - // Expected fee calculation: (150 + 65) * 1 = 215 satoshis - assert_eq!(fee, Amount::from_sat(215)); + // Expected fee calculation: (150 + (5 * 65)) * 1 = 475 satoshis + assert_eq!(fee, Amount::from_sat(475)); } #[test] @@ -173,12 +182,14 @@ mod tests { fn estimate_transaction_fees_overflow() { let script_type = ScriptType::P2TR; let unsigned_tx_size = usize::MAX; + let number_of_inputs = 5_usize; let current_fee_rate = FeeRate::from_sat_per_vb(1_u64).unwrap(); let multisig_config = None; let _fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); @@ -188,6 +199,7 @@ mod tests { fn estimate_transaction_fees_low_fee_rate() { let script_type = ScriptType::P2WSH; let unsigned_tx_size = 250; // in vbytes + let number_of_inputs = 15_usize; let current_fee_rate = FeeRate::from_sat_per_vb(1_u64).unwrap(); // Low fee rate let multisig_config = Some(MultisigConfig { required: 3, @@ -197,37 +209,41 @@ mod tests { let fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); - // Expected fee calculation: (250 + (73 * 3)) * 1 = 469 satoshis - assert_eq!(fee, Amount::from_sat(469)); + // Expected fee calculation: (250 + (15 * 73 * 3)) * 1 = 3535 satoshis + assert_eq!(fee, Amount::from_sat(3535)); } #[test] fn estimate_transaction_fees_high_fee_rate() { let script_type = ScriptType::P2TR; let unsigned_tx_size = 180; // in vbytes + let number_of_inputs = 9_usize; let current_fee_rate = FeeRate::from_sat_per_vb(50_u64).unwrap(); // High fee rate let multisig_config = None; let fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); - // Expected fee calculation: (180 + 65) * 50 = 12250 satoshis - assert_eq!(fee, Amount::from_sat(12250)); + // Expected fee calculation: (180 + (9 * 65)) * 50 = 38250 satoshis + assert_eq!(fee, Amount::from_sat(38250)); } #[test] fn estimate_transaction_fees_varying_fee_rate() { let script_type = ScriptType::P2WSH; let unsigned_tx_size = 300; // in vbytes - // Simulating a fee rate that might be seen during network congestion + let number_of_inputs = 10_usize; + // Simulating a fee rate that might be seen during network congestion let fee_rates: Vec = vec![5, 10, 20, 30, 40]; for fee_rate in fee_rates { @@ -240,12 +256,13 @@ mod tests { let fee = estimate_transaction_fees( script_type, unsigned_tx_size, + number_of_inputs, current_fee_rate, &multisig_config, ); // Expected fee calculation changes with the fee_rate - let expected_fee = (300 + (73 * 2)) as u64 * fee_rate; + let expected_fee = (300 + (10 * 73 * 2)) as u64 * fee_rate; assert_eq!( fee, Amount::from_sat(expected_fee),