Skip to content

Commit

Permalink
Test the consistency of functions used to calculate the fees of htlcs
Browse files Browse the repository at this point in the history
Specifically, we check that the slope `commit_tx_fee_sat` / `num_htlcs`
is consistent with `per_outbound_htlc_counterparty_commit_tx_fee_msat`.
  • Loading branch information
tankyleo committed Feb 9, 2025
1 parent f6c14a8 commit b677a0c
Showing 1 changed file with 32 additions and 1 deletion.
33 changes: 32 additions & 1 deletion lightning/src/ln/chan_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1893,7 +1893,7 @@ pub fn get_commitment_transaction_number_obscure_factor(
mod tests {
use super::{CounterpartyCommitmentSecrets, ChannelPublicKeys};
use crate::chain;
use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment};
use crate::ln::chan_utils::{get_htlc_redeemscript, get_to_countersignatory_with_anchors_redeemscript, CommitmentTransaction, TxCreationKeys, ChannelTransactionParameters, CounterpartyChannelTransactionParameters, HTLCOutputInCommitment, commit_tx_fee_sat, htlc_success_tx_weight, per_outbound_htlc_counterparty_commit_tx_fee_msat};
use bitcoin::secp256k1::{PublicKey, SecretKey, Secp256k1};
use crate::util::test_utils;
use crate::sign::{ChannelSigner, SignerProvider};
Expand Down Expand Up @@ -2430,4 +2430,35 @@ mod tests {
assert!(monitor.provide_secret(281474976710648, secrets.last().unwrap().clone()).is_err());
}
}

#[test]
fn test_commit_tx_fee_sat_num_htlcs_slope_per_outbound_htlc_counterparty_commit_tx_fee_msat() {
// Test that the slope (commit_tx_fee_sat/num_htlcs) is consistent with per_outbound_htlc_counterparty_commit_tx_fee_msat.
// `got`: floor(feerate * commit_tx_base_weight) + floor(num_htlcs * feerate * htlc_output_weight + num_htlcs * feerate * htlc_tx_weight)
// `want`: floor(feerate * commit_tx_base_weight + num_htlcs * feerate * htlc_output_weight) + floor(num_htlcs * feerate * htlc_tx_weight)
// At most, the difference between the two calculations is 1 satoshi, depending on how the num_htlcs * feerate * htlc_output_weight term
// adds with the two others.
//
// In the case of anchor channels, set `htlc_tx_weight` above to zero; the fees are exogenous.

let num_htlcs = 966; // BOLT #2 maximum number of htlcs on a commit tx

let features = ChannelTypeFeatures::only_static_remote_key();
// Tests the range 1sat/vb - 250sat/vb
for feerate in 253..62500 {
let got = commit_tx_fee_sat(feerate, 0, &features) + num_htlcs * per_outbound_htlc_counterparty_commit_tx_fee_msat(feerate, &features) / 1000;
let want = commit_tx_fee_sat(feerate, num_htlcs as usize, &features) + num_htlcs * feerate as u64 * htlc_success_tx_weight(&features) / 1000;
let diff = u64::abs_diff(got, want);
assert!(diff <= 1, "assert failed for feerate: {}, absolute difference was: {}", feerate, diff);
}

let features = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
// Tests the range 1sat/vb - 250sat/vb
for feerate in 253..62500 {
let got = commit_tx_fee_sat(feerate, 0, &features) + num_htlcs * per_outbound_htlc_counterparty_commit_tx_fee_msat(feerate, &features) / 1000;
let want = commit_tx_fee_sat(feerate, num_htlcs as usize, &features);
let diff = u64::checked_sub(want, got).expect("got should not be greater than want");
assert!(diff <= 1, "assert failed for feerate: {}, checked difference was: {}", feerate, diff);
}
}
}

0 comments on commit b677a0c

Please sign in to comment.