Skip to content

Commit 20eee80

Browse files
committed
validate predicted fees
1 parent bbf593a commit 20eee80

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

lightning/src/ln/channel.rs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,10 @@ pub(super) struct FundingScope {
19841984
next_local_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
19851985
#[cfg(any(test, fuzzing))]
19861986
next_remote_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
1987+
#[cfg(any(test, fuzzing))]
1988+
next_local_fee: Mutex<PredictedNextFee>,
1989+
#[cfg(any(test, fuzzing))]
1990+
next_remote_fee: Mutex<PredictedNextFee>,
19871991

19881992
pub(super) channel_transaction_parameters: ChannelTransactionParameters,
19891993

@@ -2060,6 +2064,10 @@ impl Readable for FundingScope {
20602064
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
20612065
#[cfg(any(test, fuzzing))]
20622066
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
2067+
#[cfg(any(test, fuzzing))]
2068+
next_local_fee: Mutex::new(PredictedNextFee::default()),
2069+
#[cfg(any(test, fuzzing))]
2070+
next_remote_fee: Mutex::new(PredictedNextFee::default()),
20632071
})
20642072
}
20652073
}
@@ -3206,6 +3214,10 @@ where
32063214
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
32073215
#[cfg(any(test, fuzzing))]
32083216
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
3217+
#[cfg(any(test, fuzzing))]
3218+
next_local_fee: Mutex::new(PredictedNextFee::default()),
3219+
#[cfg(any(test, fuzzing))]
3220+
next_remote_fee: Mutex::new(PredictedNextFee::default()),
32093221

32103222
channel_transaction_parameters: ChannelTransactionParameters {
32113223
holder_pubkeys: pubkeys,
@@ -3449,6 +3461,10 @@ where
34493461
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
34503462
#[cfg(any(test, fuzzing))]
34513463
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
3464+
#[cfg(any(test, fuzzing))]
3465+
next_local_fee: Mutex::new(PredictedNextFee::default()),
3466+
#[cfg(any(test, fuzzing))]
3467+
next_remote_fee: Mutex::new(PredictedNextFee::default()),
34523468

34533469
channel_transaction_parameters: ChannelTransactionParameters {
34543470
holder_pubkeys: pubkeys,
@@ -4322,6 +4338,25 @@ where
43224338
}
43234339
}
43244340

4341+
#[cfg(any(test, fuzzing))]
4342+
{
4343+
let mut local_predicted_htlcs = next_local_commitment_stats.next_commitment_htlcs;
4344+
local_predicted_htlcs.sort_unstable();
4345+
*funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4346+
predicted_feerate: self.feerate_per_kw,
4347+
predicted_htlcs: local_predicted_htlcs,
4348+
predicted_fee_sat: next_local_commitment_stats.commit_tx_fee_sat,
4349+
};
4350+
4351+
let mut remote_predicted_htlcs = next_remote_commitment_stats.next_commitment_htlcs;
4352+
remote_predicted_htlcs.sort_unstable();
4353+
*funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4354+
predicted_feerate: self.feerate_per_kw,
4355+
predicted_htlcs: remote_predicted_htlcs,
4356+
predicted_fee_sat: next_remote_commitment_stats.commit_tx_fee_sat,
4357+
};
4358+
}
4359+
43254360
Ok(())
43264361
}
43274362

@@ -4352,6 +4387,25 @@ where
43524387
msg.feerate_per_kw, next_remote_commitment_stats.dust_exposure_msat)));
43534388
}
43544389

4390+
#[cfg(any(test, fuzzing))]
4391+
{
4392+
let mut local_predicted_htlcs = next_local_commitment_stats.next_commitment_htlcs;
4393+
local_predicted_htlcs.sort_unstable();
4394+
*funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4395+
predicted_feerate: msg.feerate_per_kw,
4396+
predicted_htlcs: local_predicted_htlcs,
4397+
predicted_fee_sat: next_local_commitment_stats.commit_tx_fee_sat,
4398+
};
4399+
4400+
let mut remote_predicted_htlcs = next_remote_commitment_stats.next_commitment_htlcs;
4401+
remote_predicted_htlcs.sort_unstable();
4402+
*funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4403+
predicted_feerate: msg.feerate_per_kw,
4404+
predicted_htlcs: remote_predicted_htlcs,
4405+
predicted_fee_sat: next_remote_commitment_stats.commit_tx_fee_sat,
4406+
};
4407+
}
4408+
43554409
Ok(())
43564410
}
43574411

@@ -4411,6 +4465,12 @@ where
44114465
}
44124466
}
44134467
}
4468+
let PredictedNextFee { predicted_feerate, predicted_htlcs, predicted_fee_sat } = funding.next_local_fee.lock().unwrap().clone();
4469+
let mut actual_nondust_htlcs: Vec<_> = commitment_data.tx.nondust_htlcs().iter().map(|&HTLCOutputInCommitment { offered, amount_msat, .. } | HTLCAmountDirection { outbound: offered, amount_msat }).collect();
4470+
actual_nondust_htlcs.sort_unstable();
4471+
if predicted_feerate == commitment_data.tx.feerate_per_kw() && predicted_htlcs == actual_nondust_htlcs {
4472+
assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
4473+
}
44144474
}
44154475

44164476
if msg.htlc_signatures.len() != commitment_data.tx.nondust_htlcs().len() {
@@ -4484,6 +4544,27 @@ where
44844544
return false;
44854545
}
44864546

4547+
#[cfg(any(test, fuzzing))]
4548+
{
4549+
let next_local_commitment_stats = self.get_next_local_commitment_stats(funding, None, true, 0, feerate_per_kw, dust_exposure_limiting_feerate);
4550+
let mut local_predicted_htlcs = next_local_commitment_stats.next_commitment_htlcs;
4551+
local_predicted_htlcs.sort_unstable();
4552+
*funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4553+
predicted_feerate: feerate_per_kw,
4554+
predicted_htlcs: local_predicted_htlcs,
4555+
predicted_fee_sat: next_local_commitment_stats.commit_tx_fee_sat,
4556+
};
4557+
4558+
let next_remote_commitment_stats = self.get_next_remote_commitment_stats(funding, None, true, 0, feerate_per_kw, dust_exposure_limiting_feerate);
4559+
let mut remote_predicted_htlcs = next_remote_commitment_stats.next_commitment_htlcs;
4560+
remote_predicted_htlcs.sort_unstable();
4561+
*funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4562+
predicted_feerate: feerate_per_kw,
4563+
predicted_htlcs: remote_predicted_htlcs,
4564+
predicted_fee_sat: next_remote_commitment_stats.commit_tx_fee_sat,
4565+
};
4566+
}
4567+
44874568
return true;
44884569
}
44894570

@@ -4538,6 +4619,35 @@ where
45384619
}
45394620
}
45404621

4622+
#[cfg(any(test, fuzzing))]
4623+
{
4624+
let next_local_commitment_stats = if fee_spike_buffer_htlc == 1 {
4625+
self.get_next_local_commitment_stats(funding, None, false, 0, self.feerate_per_kw, dust_exposure_limiting_feerate)
4626+
} else {
4627+
next_local_commitment_stats
4628+
};
4629+
let mut local_predicted_htlcs = next_local_commitment_stats.next_commitment_htlcs;
4630+
local_predicted_htlcs.sort_unstable();
4631+
*funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4632+
predicted_feerate: self.feerate_per_kw,
4633+
predicted_htlcs: local_predicted_htlcs,
4634+
predicted_fee_sat: next_local_commitment_stats.commit_tx_fee_sat,
4635+
};
4636+
4637+
let next_remote_commitment_stats = if fee_spike_buffer_htlc == 1 {
4638+
self.get_next_remote_commitment_stats(funding, None, false, 0, self.feerate_per_kw, dust_exposure_limiting_feerate)
4639+
} else {
4640+
next_remote_commitment_stats
4641+
};
4642+
let mut remote_predicted_htlcs = next_remote_commitment_stats.next_commitment_htlcs;
4643+
remote_predicted_htlcs.sort_unstable();
4644+
*funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4645+
predicted_feerate: self.feerate_per_kw,
4646+
predicted_htlcs: remote_predicted_htlcs,
4647+
predicted_fee_sat: next_remote_commitment_stats.commit_tx_fee_sat,
4648+
};
4649+
}
4650+
45414651
Ok(())
45424652
}
45434653

@@ -6027,6 +6137,14 @@ struct CommitmentTxInfoCached {
60276137
feerate: u32,
60286138
}
60296139

6140+
#[cfg(any(test, fuzzing))]
6141+
#[derive(Clone, Default)]
6142+
struct PredictedNextFee {
6143+
predicted_feerate: u32,
6144+
predicted_htlcs: Vec<HTLCAmountDirection>,
6145+
predicted_fee_sat: u64,
6146+
}
6147+
60306148
/// Contents of a wire message that fails an HTLC backwards. Useful for [`FundedChannel::fail_htlc`] to
60316149
/// fail with either [`msgs::UpdateFailMalformedHTLC`] or [`msgs::UpdateFailHTLC`] as needed.
60326150
trait FailHTLCContents {
@@ -10991,6 +11109,12 @@ where
1099111109
}
1099211110
}
1099311111
}
11112+
let PredictedNextFee { predicted_feerate, predicted_htlcs, predicted_fee_sat } = funding.next_remote_fee.lock().unwrap().clone();
11113+
let mut actual_nondust_htlcs: Vec<_> = counterparty_commitment_tx.nondust_htlcs().iter().map(|&HTLCOutputInCommitment { offered, amount_msat, .. }| HTLCAmountDirection { outbound: !offered, amount_msat }).collect();
11114+
actual_nondust_htlcs.sort_unstable();
11115+
if predicted_feerate == counterparty_commitment_tx.feerate_per_kw() && predicted_htlcs == actual_nondust_htlcs {
11116+
assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
11117+
}
1099411118
}
1099511119

1099611120
(commitment_data.htlcs_included, counterparty_commitment_tx)
@@ -13616,6 +13740,10 @@ where
1361613740
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
1361713741
#[cfg(any(test, fuzzing))]
1361813742
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
13743+
#[cfg(any(test, fuzzing))]
13744+
next_local_fee: Mutex::new(PredictedNextFee::default()),
13745+
#[cfg(any(test, fuzzing))]
13746+
next_remote_fee: Mutex::new(PredictedNextFee::default()),
1361913747

1362013748
channel_transaction_parameters: channel_parameters,
1362113749
funding_transaction,

0 commit comments

Comments
 (0)