@@ -24,7 +24,7 @@ use bitcoin::secp256k1;
24
24
use ln:: msgs:: DecodeError ;
25
25
use ln:: PaymentPreimage ;
26
26
use ln:: chan_utils:: { ChannelTransactionParameters , HolderCommitmentTransaction } ;
27
- use chain:: chaininterface:: { FeeEstimator , BroadcasterInterface } ;
27
+ use chain:: chaininterface:: { FeeEstimator , BroadcasterInterface , ConfirmationTarget } ;
28
28
use chain:: channelmonitor:: { ANTI_REORG_DELAY , CLTV_SHARED_CLAIM_BUFFER } ;
29
29
use chain:: keysinterface:: { Sign , KeysInterface } ;
30
30
use chain:: utxointerface:: UtxoPool ;
@@ -144,7 +144,7 @@ impl Writeable for Option<Vec<Option<(usize, Signature)>>> {
144
144
/// do RBF bumping if possible.
145
145
pub struct OnchainTxHandler < ChannelSigner : Sign > {
146
146
destination_script : Script ,
147
- holder_commitment : HolderCommitmentTransaction ,
147
+ pub ( super ) holder_commitment : HolderCommitmentTransaction ,
148
148
// holder_htlc_sigs and prev_holder_htlc_sigs are in the order as they appear in the commitment
149
149
// transaction outputs (hence the Option<>s inside the Vec). The first usize is the index in
150
150
// the set of HTLCs in the HolderCommitmentTransaction.
@@ -345,37 +345,39 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
345
345
/// (CSV or CLTV following cases). In case of high-fee spikes, claim tx may stuck in the mempool, so you need to bump its feerate quickly using Replace-By-Fee or Child-Pay-For-Parent.
346
346
/// Panics if there are signing errors, because signing operations in reaction to on-chain events
347
347
/// are not expected to fail, and if they do, we may lose funds.
348
- fn generate_claim_tx < F : Deref , L : Deref , U : Deref > ( & mut self , height : u32 , cached_request : & mut PackageTemplate , fee_estimator : & F , logger : & L , utxo_pool : & U ) -> Option < ( Option < u32 > , u64 , Transaction ) >
348
+ fn generate_claim_tx < F : Deref , L : Deref , U : Deref > ( & mut self , height : u32 , cached_request : & mut PackageTemplate , fee_estimator : & F , logger : & L , utxo_pool : & U ) -> Option < ( Option < u32 > , u64 , Vec < Transaction > ) >
349
349
where F :: Target : FeeEstimator ,
350
350
L :: Target : Logger ,
351
351
U :: Target : UtxoPool ,
352
352
{
353
353
if cached_request. outpoints ( ) . len ( ) == 0 { return None } // But don't prune pending claiming request yet, we may have to resurrect HTLCs
354
354
355
355
if !cached_request. is_malleable ( ) {
356
- cached_request. set_bumping_utxo ( utxo_pool) ;
356
+ if cached_request. feerate_previous ( ) < fee_estimator. get_est_sat_per_1000_weight ( ConfirmationTarget :: HighPriority ) as u64 {
357
+ // Bumping UTXO is allocated the first time we detect the pre-signed feerate
358
+ // is under our fee estimator confirmation target
359
+ cached_request. set_bumping_utxo ( utxo_pool) ;
360
+ }
357
361
}
358
362
359
363
// Compute new height timer to decide when we need to regenerate a new bumped version of the claim tx (if we
360
364
// didn't receive confirmation of it before, or not enough reorg-safe depth on top of it).
361
- let new_timer = Some ( cached_request. get_height_timer ( height) ) ;
362
- if cached_request. is_malleable ( ) {
363
- let predicted_weight = cached_request. package_weight ( & self . destination_script , self . holder_commitment . get_num_outputs ( ) ) ;
364
- if let Some ( ( output_value, new_feerate) ) = cached_request. compute_package_output ( predicted_weight, fee_estimator, logger) {
365
- assert ! ( new_feerate != 0 ) ;
366
-
367
- let transaction = cached_request. finalize_package ( self , output_value, self . destination_script . clone ( ) , logger) . unwrap ( ) ;
368
- log_trace ! ( logger, "...with timer {} and feerate {}" , new_timer. unwrap( ) , new_feerate) ;
369
- assert ! ( predicted_weight >= transaction. get_weight( ) ) ;
370
- return Some ( ( new_timer, new_feerate, transaction) )
371
- }
372
- } else {
373
- // Note: Currently, amounts of holder outputs spending witnesses aren't used
374
- // as we can't malleate spending package to increase their feerate. This
375
- // should change with the remaining anchor output patchset.
376
- if let Some ( transaction) = cached_request. finalize_package ( self , 0 , self . destination_script . clone ( ) , logger) {
377
- return Some ( ( None , 0 , transaction) ) ;
365
+ let mut new_timer = Some ( cached_request. get_height_timer ( height) ) ;
366
+ let predicted_weight = cached_request. package_weight ( & self . destination_script , self . holder_commitment . get_num_outputs ( ) ) ;
367
+ if let Some ( ( output_value, new_feerate) ) = cached_request. compute_package_output ( predicted_weight, fee_estimator, logger) {
368
+ if output_value != 0 { assert ! ( new_feerate != 0 ) ; }
369
+
370
+ let txn = cached_request. finalize_package ( self , output_value, self . destination_script . clone ( ) , & * logger, & * utxo_pool) . unwrap ( ) ;
371
+ log_trace ! ( logger, "...with timer {} weight {} feerate {} CPFP: {}" , new_timer. unwrap( ) , predicted_weight, new_feerate, txn. len( ) > 1 ) ;
372
+ assert ! ( predicted_weight >= txn[ 0 ] . get_weight( ) + if txn. len( ) == 2 { txn[ 1 ] . get_weight( ) } else { 0 } ) ;
373
+
374
+ //TODO: for now disable timer for untractable package
375
+ // Enabling them is pending on fixing tests first
376
+ if !cached_request. is_malleable ( ) {
377
+ new_timer = None ;
378
378
}
379
+
380
+ return Some ( ( new_timer, new_feerate, txn) )
379
381
}
380
382
None
381
383
}
@@ -444,17 +446,19 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
444
446
// Generate claim transactions and track them to bump if necessary at
445
447
// height timer expiration (i.e in how many blocks we're going to take action).
446
448
for mut req in preprocessed_requests {
447
- if let Some ( ( new_timer, new_feerate, tx ) ) = self . generate_claim_tx ( height, & mut req, & * fee_estimator, & * logger, & * utxo_pool) {
449
+ if let Some ( ( new_timer, new_feerate, txn ) ) = self . generate_claim_tx ( height, & mut req, & * fee_estimator, & * logger, & * utxo_pool) {
448
450
req. set_timer ( new_timer) ;
449
451
req. set_feerate ( new_feerate) ;
450
- let txid = tx . txid ( ) ;
452
+ let txid = txn [ 0 ] . txid ( ) ;
451
453
for k in req. outpoints ( ) {
452
454
log_trace ! ( logger, "Registering claiming request for {}:{}" , k. txid, k. vout) ;
453
455
self . claimable_outpoints . insert ( k. clone ( ) , ( txid, height) ) ;
454
456
}
455
457
self . pending_claim_requests . insert ( txid, req) ;
456
- log_trace ! ( logger, "Broadcasting onchain {}" , log_tx!( tx) ) ;
457
- broadcaster. broadcast_transaction ( & tx) ;
458
+ for tx in txn {
459
+ log_trace ! ( logger, "Broadcasting onchain {}" , log_tx!( tx) ) ;
460
+ broadcaster. broadcast_transaction ( & tx) ;
461
+ }
458
462
}
459
463
}
460
464
@@ -569,9 +573,11 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
569
573
// Build, bump and rebroadcast tx accordingly
570
574
log_trace ! ( logger, "Bumping {} candidates" , bump_candidates. len( ) ) ;
571
575
for ( first_claim_txid, ref mut request) in bump_candidates. iter_mut ( ) {
572
- if let Some ( ( new_timer, new_feerate, bump_tx) ) = self . generate_claim_tx ( height, request, & * fee_estimator, & * logger, & * utxo_pool) {
573
- log_trace ! ( logger, "Broadcasting onchain {}" , log_tx!( bump_tx) ) ;
574
- broadcaster. broadcast_transaction ( & bump_tx) ;
576
+ if let Some ( ( new_timer, new_feerate, bump_txn) ) = self . generate_claim_tx ( height, request, & * fee_estimator, & * logger, & * utxo_pool) {
577
+ for bump_tx in bump_txn {
578
+ log_trace ! ( logger, "Broadcasting onchain {}" , log_tx!( bump_tx) ) ;
579
+ broadcaster. broadcast_transaction ( & bump_tx) ;
580
+ }
575
581
if let Some ( request) = self . pending_claim_requests . get_mut ( first_claim_txid) {
576
582
request. set_timer ( new_timer) ;
577
583
request. set_feerate ( new_feerate) ;
@@ -637,11 +643,13 @@ impl<ChannelSigner: Sign> OnchainTxHandler<ChannelSigner> {
637
643
}
638
644
}
639
645
for ( _, ref mut request) in bump_candidates. iter_mut ( ) {
640
- if let Some ( ( new_timer, new_feerate, bump_tx ) ) = self . generate_claim_tx ( height, request, & & * fee_estimator, & & * logger, & & * utxo_pool) {
646
+ if let Some ( ( new_timer, new_feerate, bump_txn ) ) = self . generate_claim_tx ( height, request, & & * fee_estimator, & & * logger, & & * utxo_pool) {
641
647
request. set_timer ( new_timer) ;
642
648
request. set_feerate ( new_feerate) ;
643
- log_info ! ( logger, "Broadcasting onchain {}" , log_tx!( bump_tx) ) ;
644
- broadcaster. broadcast_transaction ( & bump_tx) ;
649
+ for bump_tx in bump_txn {
650
+ log_info ! ( logger, "Broadcasting onchain {}" , log_tx!( bump_tx) ) ;
651
+ broadcaster. broadcast_transaction ( & bump_tx) ;
652
+ }
645
653
}
646
654
}
647
655
for ( ancestor_claim_txid, request) in bump_candidates. drain ( ) {
0 commit comments