Skip to content

Commit 2580d94

Browse files
committed
validate predicted fees
1 parent 34553af commit 2580d94

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,
@@ -4329,6 +4345,25 @@ where
43294345
}
43304346
}
43314347

4348+
#[cfg(any(test, fuzzing))]
4349+
{
4350+
let mut local_predicted_htlcs = next_local_commitment_stats.next_commitment_htlcs;
4351+
local_predicted_htlcs.sort_unstable();
4352+
*funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4353+
predicted_feerate: self.feerate_per_kw,
4354+
predicted_htlcs: local_predicted_htlcs,
4355+
predicted_fee_sat: next_local_commitment_stats.commit_tx_fee_sat,
4356+
};
4357+
4358+
let mut remote_predicted_htlcs = next_remote_commitment_stats.next_commitment_htlcs;
4359+
remote_predicted_htlcs.sort_unstable();
4360+
*funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4361+
predicted_feerate: self.feerate_per_kw,
4362+
predicted_htlcs: remote_predicted_htlcs,
4363+
predicted_fee_sat: next_remote_commitment_stats.commit_tx_fee_sat,
4364+
};
4365+
}
4366+
43324367
Ok(())
43334368
}
43344369

@@ -4357,6 +4392,25 @@ where
43574392
msg.feerate_per_kw, next_remote_commitment_stats.dust_exposure_msat)));
43584393
}
43594394

4395+
#[cfg(any(test, fuzzing))]
4396+
{
4397+
let mut local_predicted_htlcs = next_local_commitment_stats.next_commitment_htlcs;
4398+
local_predicted_htlcs.sort_unstable();
4399+
*funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4400+
predicted_feerate: msg.feerate_per_kw,
4401+
predicted_htlcs: local_predicted_htlcs,
4402+
predicted_fee_sat: next_local_commitment_stats.commit_tx_fee_sat,
4403+
};
4404+
4405+
let mut remote_predicted_htlcs = next_remote_commitment_stats.next_commitment_htlcs;
4406+
remote_predicted_htlcs.sort_unstable();
4407+
*funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4408+
predicted_feerate: msg.feerate_per_kw,
4409+
predicted_htlcs: remote_predicted_htlcs,
4410+
predicted_fee_sat: next_remote_commitment_stats.commit_tx_fee_sat,
4411+
};
4412+
}
4413+
43604414
Ok(())
43614415
}
43624416

@@ -4416,6 +4470,12 @@ where
44164470
}
44174471
}
44184472
}
4473+
let PredictedNextFee { predicted_feerate, predicted_htlcs, predicted_fee_sat } = funding.next_local_fee.lock().unwrap().clone();
4474+
let mut actual_nondust_htlcs: Vec<_> = commitment_data.tx.nondust_htlcs().iter().map(|&HTLCOutputInCommitment { offered, amount_msat, .. } | HTLCAmountDirection { outbound: offered, amount_msat }).collect();
4475+
actual_nondust_htlcs.sort_unstable();
4476+
if predicted_feerate == commitment_data.tx.feerate_per_kw() && predicted_htlcs == actual_nondust_htlcs {
4477+
assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
4478+
}
44194479
}
44204480

44214481
if msg.htlc_signatures.len() != commitment_data.tx.nondust_htlcs().len() {
@@ -4487,6 +4547,27 @@ where
44874547
return false;
44884548
}
44894549

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

@@ -4539,6 +4620,35 @@ where
45394620
}
45404621
}
45414622

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

@@ -6028,6 +6138,14 @@ struct CommitmentTxInfoCached {
60286138
feerate: u32,
60296139
}
60306140

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

1099711121
(commitment_data.htlcs_included, counterparty_commitment_tx)
@@ -13617,6 +13741,10 @@ where
1361713741
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
1361813742
#[cfg(any(test, fuzzing))]
1361913743
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
13744+
#[cfg(any(test, fuzzing))]
13745+
next_local_fee: Mutex::new(PredictedNextFee::default()),
13746+
#[cfg(any(test, fuzzing))]
13747+
next_remote_fee: Mutex::new(PredictedNextFee::default()),
1362013748

1362113749
channel_transaction_parameters: channel_parameters,
1362213750
funding_transaction,

0 commit comments

Comments
 (0)