@@ -1984,6 +1984,10 @@ pub(super) struct FundingScope {
1984
1984
next_local_commitment_tx_fee_info_cached: Mutex<Option<CommitmentTxInfoCached>>,
1985
1985
#[cfg(any(test, fuzzing))]
1986
1986
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>,
1987
1991
1988
1992
pub(super) channel_transaction_parameters: ChannelTransactionParameters,
1989
1993
@@ -2060,6 +2064,10 @@ impl Readable for FundingScope {
2060
2064
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
2061
2065
#[cfg(any(test, fuzzing))]
2062
2066
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()),
2063
2071
})
2064
2072
}
2065
2073
}
@@ -3206,6 +3214,10 @@ where
3206
3214
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
3207
3215
#[cfg(any(test, fuzzing))]
3208
3216
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()),
3209
3221
3210
3222
channel_transaction_parameters: ChannelTransactionParameters {
3211
3223
holder_pubkeys: pubkeys,
@@ -3449,6 +3461,10 @@ where
3449
3461
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
3450
3462
#[cfg(any(test, fuzzing))]
3451
3463
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()),
3452
3468
3453
3469
channel_transaction_parameters: ChannelTransactionParameters {
3454
3470
holder_pubkeys: pubkeys,
@@ -4220,7 +4236,8 @@ where
4220
4236
include_counterparty_unknown_htlcs,
4221
4237
);
4222
4238
let next_value_to_self_msat = self.get_next_commitment_value_to_self_msat(true, funding);
4223
- SpecTxBuilder {}.get_next_commitment_stats(
4239
+
4240
+ let ret = SpecTxBuilder {}.get_next_commitment_stats(
4224
4241
true,
4225
4242
funding.is_outbound(),
4226
4243
funding.get_value_satoshis(),
@@ -4231,7 +4248,38 @@ where
4231
4248
dust_exposure_limiting_feerate,
4232
4249
self.holder_dust_limit_satoshis,
4233
4250
funding.get_channel_type(),
4234
- )
4251
+ );
4252
+
4253
+ #[cfg(any(test, fuzzing))]
4254
+ {
4255
+ if addl_nondust_htlc_count == 0 {
4256
+ *funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4257
+ predicted_feerate: feerate_per_kw,
4258
+ predicted_nondust_htlc_count: ret.nondust_htlc_count,
4259
+ predicted_fee_sat: ret.commit_tx_fee_sat,
4260
+ };
4261
+ } else {
4262
+ let predicted_stats = SpecTxBuilder {}.get_next_commitment_stats(
4263
+ true,
4264
+ funding.is_outbound(),
4265
+ funding.get_value_satoshis(),
4266
+ next_value_to_self_msat,
4267
+ &next_commitment_htlcs,
4268
+ 0,
4269
+ feerate_per_kw,
4270
+ dust_exposure_limiting_feerate,
4271
+ self.holder_dust_limit_satoshis,
4272
+ funding.get_channel_type(),
4273
+ );
4274
+ *funding.next_local_fee.lock().unwrap() = PredictedNextFee {
4275
+ predicted_feerate: feerate_per_kw,
4276
+ predicted_nondust_htlc_count: predicted_stats.nondust_htlc_count,
4277
+ predicted_fee_sat: predicted_stats.commit_tx_fee_sat,
4278
+ };
4279
+ }
4280
+ }
4281
+
4282
+ ret
4235
4283
}
4236
4284
4237
4285
fn get_next_remote_commitment_stats(
@@ -4245,7 +4293,8 @@ where
4245
4293
include_counterparty_unknown_htlcs,
4246
4294
);
4247
4295
let next_value_to_self_msat = self.get_next_commitment_value_to_self_msat(false, funding);
4248
- SpecTxBuilder {}.get_next_commitment_stats(
4296
+
4297
+ let ret = SpecTxBuilder {}.get_next_commitment_stats(
4249
4298
false,
4250
4299
funding.is_outbound(),
4251
4300
funding.get_value_satoshis(),
@@ -4256,7 +4305,38 @@ where
4256
4305
dust_exposure_limiting_feerate,
4257
4306
self.counterparty_dust_limit_satoshis,
4258
4307
funding.get_channel_type(),
4259
- )
4308
+ );
4309
+
4310
+ #[cfg(any(test, fuzzing))]
4311
+ {
4312
+ if addl_nondust_htlc_count == 0 {
4313
+ *funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4314
+ predicted_feerate: feerate_per_kw,
4315
+ predicted_nondust_htlc_count: ret.nondust_htlc_count,
4316
+ predicted_fee_sat: ret.commit_tx_fee_sat,
4317
+ };
4318
+ } else {
4319
+ let predicted_stats = SpecTxBuilder {}.get_next_commitment_stats(
4320
+ false,
4321
+ funding.is_outbound(),
4322
+ funding.get_value_satoshis(),
4323
+ next_value_to_self_msat,
4324
+ &next_commitment_htlcs,
4325
+ 0,
4326
+ feerate_per_kw,
4327
+ dust_exposure_limiting_feerate,
4328
+ self.counterparty_dust_limit_satoshis,
4329
+ funding.get_channel_type(),
4330
+ );
4331
+ *funding.next_remote_fee.lock().unwrap() = PredictedNextFee {
4332
+ predicted_feerate: feerate_per_kw,
4333
+ predicted_nondust_htlc_count: predicted_stats.nondust_htlc_count,
4334
+ predicted_fee_sat: predicted_stats.commit_tx_fee_sat,
4335
+ };
4336
+ }
4337
+ }
4338
+
4339
+ ret
4260
4340
}
4261
4341
4262
4342
#[rustfmt::skip]
@@ -4414,6 +4494,10 @@ where
4414
4494
}
4415
4495
}
4416
4496
}
4497
+ let PredictedNextFee { predicted_feerate, predicted_nondust_htlc_count, predicted_fee_sat } = *funding.next_local_fee.lock().unwrap();
4498
+ if predicted_feerate == commitment_data.tx.feerate_per_kw() && predicted_nondust_htlc_count == commitment_data.tx.nondust_htlcs().len() {
4499
+ assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
4500
+ }
4417
4501
}
4418
4502
4419
4503
if msg.htlc_signatures.len() != commitment_data.tx.nondust_htlcs().len() {
@@ -6031,6 +6115,14 @@ struct CommitmentTxInfoCached {
6031
6115
feerate: u32,
6032
6116
}
6033
6117
6118
+ #[cfg(any(test, fuzzing))]
6119
+ #[derive(Clone, Copy, Default)]
6120
+ struct PredictedNextFee {
6121
+ predicted_feerate: u32,
6122
+ predicted_nondust_htlc_count: usize,
6123
+ predicted_fee_sat: u64,
6124
+ }
6125
+
6034
6126
/// Contents of a wire message that fails an HTLC backwards. Useful for [`FundedChannel::fail_htlc`] to
6035
6127
/// fail with either [`msgs::UpdateFailMalformedHTLC`] or [`msgs::UpdateFailHTLC`] as needed.
6036
6128
trait FailHTLCContents {
@@ -10995,6 +11087,10 @@ where
10995
11087
}
10996
11088
}
10997
11089
}
11090
+ let PredictedNextFee { predicted_feerate, predicted_nondust_htlc_count, predicted_fee_sat } = *funding.next_remote_fee.lock().unwrap();
11091
+ if predicted_feerate == counterparty_commitment_tx.feerate_per_kw() && predicted_nondust_htlc_count == counterparty_commitment_tx.nondust_htlcs().len() {
11092
+ assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
11093
+ }
10998
11094
}
10999
11095
11000
11096
(commitment_data.htlcs_included, counterparty_commitment_tx)
@@ -13620,6 +13716,10 @@ where
13620
13716
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
13621
13717
#[cfg(any(test, fuzzing))]
13622
13718
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
13719
+ #[cfg(any(test, fuzzing))]
13720
+ next_local_fee: Mutex::new(PredictedNextFee::default()),
13721
+ #[cfg(any(test, fuzzing))]
13722
+ next_remote_fee: Mutex::new(PredictedNextFee::default()),
13623
13723
13624
13724
channel_transaction_parameters: channel_parameters,
13625
13725
funding_transaction,
0 commit comments