@@ -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]
@@ -4413,6 +4493,10 @@ where
4413
4493
}
4414
4494
}
4415
4495
}
4496
+ let PredictedNextFee { predicted_feerate, predicted_nondust_htlc_count, predicted_fee_sat } = *funding.next_local_fee.lock().unwrap();
4497
+ if predicted_feerate == commitment_data.tx.feerate_per_kw() && predicted_nondust_htlc_count == commitment_data.tx.nondust_htlcs().len() {
4498
+ assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
4499
+ }
4416
4500
}
4417
4501
4418
4502
if msg.htlc_signatures.len() != commitment_data.tx.nondust_htlcs().len() {
@@ -6026,6 +6110,14 @@ struct CommitmentTxInfoCached {
6026
6110
feerate: u32,
6027
6111
}
6028
6112
6113
+ #[cfg(any(test, fuzzing))]
6114
+ #[derive(Clone, Copy, Default)]
6115
+ struct PredictedNextFee {
6116
+ predicted_feerate: u32,
6117
+ predicted_nondust_htlc_count: usize,
6118
+ predicted_fee_sat: u64,
6119
+ }
6120
+
6029
6121
/// Contents of a wire message that fails an HTLC backwards. Useful for [`FundedChannel::fail_htlc`] to
6030
6122
/// fail with either [`msgs::UpdateFailMalformedHTLC`] or [`msgs::UpdateFailHTLC`] as needed.
6031
6123
trait FailHTLCContents {
@@ -10990,6 +11082,10 @@ where
10990
11082
}
10991
11083
}
10992
11084
}
11085
+ let PredictedNextFee { predicted_feerate, predicted_nondust_htlc_count, predicted_fee_sat } = *funding.next_remote_fee.lock().unwrap();
11086
+ if predicted_feerate == counterparty_commitment_tx.feerate_per_kw() && predicted_nondust_htlc_count == counterparty_commitment_tx.nondust_htlcs().len() {
11087
+ assert_eq!(predicted_fee_sat, commitment_data.stats.commit_tx_fee_sat);
11088
+ }
10993
11089
}
10994
11090
10995
11091
(commitment_data.htlcs_included, counterparty_commitment_tx)
@@ -13615,6 +13711,10 @@ where
13615
13711
next_local_commitment_tx_fee_info_cached: Mutex::new(None),
13616
13712
#[cfg(any(test, fuzzing))]
13617
13713
next_remote_commitment_tx_fee_info_cached: Mutex::new(None),
13714
+ #[cfg(any(test, fuzzing))]
13715
+ next_local_fee: Mutex::new(PredictedNextFee::default()),
13716
+ #[cfg(any(test, fuzzing))]
13717
+ next_remote_fee: Mutex::new(PredictedNextFee::default()),
13618
13718
13619
13719
channel_transaction_parameters: channel_parameters,
13620
13720
funding_transaction,
0 commit comments