Skip to content

Commit 308ea2f

Browse files
committed
Sanity check fees on transactions produced by the bump event handler
We add a few debug assertions to ensure we don't overpay fees by 5% more than expected.
1 parent 9d687a0 commit 308ea2f

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

lightning/src/events/bump_transaction.rs

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,8 @@ where
734734
previous_utxo: anchor_utxo,
735735
satisfaction_weight: commitment_tx.weight() as u64 + ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT,
736736
}];
737+
#[cfg(debug_assertions)]
738+
let must_spend_amount = must_spend.iter().map(|input| input.previous_utxo.value).sum::<u64>();
737739

738740
log_debug!(self.logger, "Peforming coin selection for commitment package (commitment and anchor transaction) targeting {} sat/kW",
739741
package_target_feerate_sat_per_1000_weight);
@@ -747,10 +749,13 @@ where
747749
input: vec![anchor_descriptor.unsigned_tx_input()],
748750
output: vec![],
749751
};
752+
753+
#[cfg(debug_assertions)]
754+
let total_satisfaction_weight = ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT +
755+
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.satisfaction_weight).sum::<u64>();
750756
#[cfg(debug_assertions)]
751-
let total_satisfaction_weight =
752-
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.satisfaction_weight).sum::<u64>() +
753-
ANCHOR_INPUT_WITNESS_WEIGHT + EMPTY_SCRIPT_SIG_WEIGHT;
757+
let total_input_amount = must_spend_amount +
758+
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.output.value).sum::<u64>();
754759

755760
self.process_coin_selection(&mut anchor_tx, coin_selection);
756761
let anchor_txid = anchor_tx.txid();
@@ -773,6 +778,16 @@ where
773778
// never underestimate.
774779
assert!(expected_signed_tx_weight >= signed_tx_weight &&
775780
expected_signed_tx_weight - (expected_signed_tx_weight / 100) <= signed_tx_weight);
781+
782+
let expected_package_fee = fee_for_weight(package_target_feerate_sat_per_1000_weight,
783+
signed_tx_weight + commitment_tx.weight() as u64);
784+
let package_fee = total_input_amount -
785+
anchor_tx.output.iter().map(|output| output.value).sum::<u64>();
786+
// Our fee should be within a 5% error margin of the expected fee based on the
787+
// feerate and transaction weight and we should never pay less than required.
788+
let fee_error_margin = expected_package_fee * 5 / 100;
789+
assert!(package_fee >= expected_package_fee &&
790+
package_fee - fee_error_margin <= expected_package_fee);
776791
}
777792

778793
log_info!(self.logger, "Broadcasting anchor transaction {} to bump channel close with txid {}",
@@ -812,16 +827,24 @@ where
812827

813828
log_debug!(self.logger, "Peforming coin selection for HTLC transaction targeting {} sat/kW",
814829
target_feerate_sat_per_1000_weight);
830+
815831
#[cfg(debug_assertions)]
816832
let must_spend_satisfaction_weight =
817833
must_spend.iter().map(|input| input.satisfaction_weight).sum::<u64>();
834+
#[cfg(debug_assertions)]
835+
let must_spend_amount = must_spend.iter().map(|input| input.previous_utxo.value).sum::<u64>();
836+
818837
let coin_selection = self.utxo_source.select_confirmed_utxos(
819838
claim_id, must_spend, &htlc_tx.output, target_feerate_sat_per_1000_weight,
820839
)?;
840+
841+
#[cfg(debug_assertions)]
842+
let total_satisfaction_weight = must_spend_satisfaction_weight +
843+
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.satisfaction_weight).sum::<u64>();
821844
#[cfg(debug_assertions)]
822-
let total_satisfaction_weight =
823-
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.satisfaction_weight).sum::<u64>() +
824-
must_spend_satisfaction_weight;
845+
let total_input_amount = must_spend_amount +
846+
coin_selection.confirmed_utxos.iter().map(|utxo| utxo.output.value).sum::<u64>();
847+
825848
self.process_coin_selection(&mut htlc_tx, coin_selection);
826849

827850
#[cfg(debug_assertions)]
@@ -846,6 +869,15 @@ where
846869
// never underestimate.
847870
assert!(expected_signed_tx_weight >= signed_tx_weight &&
848871
expected_signed_tx_weight - (expected_signed_tx_weight / 100) <= signed_tx_weight);
872+
873+
let expected_signed_tx_fee = fee_for_weight(target_feerate_sat_per_1000_weight, signed_tx_weight);
874+
let signed_tx_fee = total_input_amount -
875+
htlc_tx.output.iter().map(|output| output.value).sum::<u64>();
876+
// Our fee should be within a 5% error margin of the expected fee based on the
877+
// feerate and transaction weight and we should never pay less than required.
878+
let fee_error_margin = expected_signed_tx_fee * 5 / 100;
879+
assert!(signed_tx_fee >= expected_signed_tx_fee &&
880+
signed_tx_fee - fee_error_margin <= expected_signed_tx_fee);
849881
}
850882

851883
log_info!(self.logger, "Broadcasting {}", log_tx!(htlc_tx));

0 commit comments

Comments
 (0)