@@ -39,7 +39,7 @@ use ln::chan_utils;
39
39
use ln:: chan_utils:: { CounterpartyCommitmentSecrets , HTLCOutputInCommitment , HolderCommitmentTransaction , HTLCType } ;
40
40
use ln:: channelmanager:: { HTLCSource , PaymentPreimage , PaymentHash } ;
41
41
use ln:: onchaintx:: OnchainTxHandler ;
42
- use ln:: onchain_utils:: { InputDescriptors , PackageTemplate } ;
42
+ use ln:: onchain_utils:: { InputDescriptors , PackageTemplate , OnchainRequest , BumpStrategy } ;
43
43
use chain:: chaininterface:: { ChainListener , ChainWatchInterface , BroadcasterInterface , FeeEstimator } ;
44
44
use chain:: transaction:: OutPoint ;
45
45
use chain:: keysinterface:: { SpendableOutputDescriptor , ChannelKeys } ;
@@ -458,26 +458,6 @@ impl Readable for CounterpartyCommitmentTransaction {
458
458
}
459
459
}
460
460
461
- /// ClaimRequest is a descriptor structure to communicate between detection
462
- /// and reaction module. They are generated by ChannelMonitor while parsing
463
- /// onchain txn leaked from a channel and handed over to OnchainTxHandler which
464
- /// is responsible for opportunistic aggregation, selecting and enforcing
465
- /// bumping logic, building and signing transactions.
466
- pub ( crate ) struct ClaimRequest {
467
- // Block height before which claiming is exclusive to one party,
468
- // after reaching it, claiming may be contentious.
469
- pub ( crate ) absolute_timelock : u32 ,
470
- // Timeout tx must have nLocktime set which means aggregating multiple
471
- // ones must take the higher nLocktime among them to satisfy all of them.
472
- // Sadly it has few pitfalls, a) it takes longuer to get fund back b) CLTV_DELTA
473
- // of a sooner-HTLC could be swallowed by the highest nLocktime of the HTLC set.
474
- // Do simplify we mark them as non-aggregable.
475
- pub ( crate ) aggregable : bool ,
476
- // Template (list of outpoint and set of data needed to generate transaction digest
477
- // and satisfy witness program).
478
- pub ( crate ) package_template : PackageTemplate ,
479
- }
480
-
481
461
/// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
482
462
/// once they mature to enough confirmations (ANTI_REORG_DELAY)
483
463
#[ derive( Clone , PartialEq ) ]
@@ -1368,7 +1348,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1368
1348
/// HTLC-Success/HTLC-Timeout transactions.
1369
1349
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
1370
1350
/// revoked counterparty commitment tx
1371
- fn check_spend_counterparty_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , logger : & L ) -> ( Vec < ClaimRequest > , ( Txid , Vec < TxOut > ) ) where L :: Target : Logger {
1351
+ fn check_spend_counterparty_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , logger : & L ) -> ( Vec < OnchainRequest > , ( Txid , Vec < TxOut > ) ) where L :: Target : Logger {
1372
1352
// Most secp and related errors trying to create keys means we have no hope of constructing
1373
1353
// a spend transaction...so we return no transactions to broadcast
1374
1354
let mut claimable_outpoints = Vec :: new ( ) ;
@@ -1401,7 +1381,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1401
1381
for ( idx, outp) in tx. output . iter ( ) . enumerate ( ) {
1402
1382
if outp. script_pubkey == revokeable_p2wsh {
1403
1383
let malleable_justice_tx = PackageTemplate :: build_malleable_justice_tx ( per_commitment_point, per_commitment_key, self . counterparty_tx_cache . counterparty_delayed_payment_base_key , self . counterparty_tx_cache . counterparty_htlc_base_key , InputDescriptors :: RevokedOutput , commitment_txid, idx as u32 , outp. value , None , self . counterparty_tx_cache . on_counterparty_tx_csv ) ;
1404
- claimable_outpoints. push ( ClaimRequest { absolute_timelock : height + self . counterparty_tx_cache . on_counterparty_tx_csv as u32 , aggregable : true , package_template : malleable_justice_tx} ) ;
1384
+ claimable_outpoints. push ( OnchainRequest { aggregation : true , bump_strategy : BumpStrategy :: RBF , feerate_previous : 0 , height_timer : None , absolute_timelock : height + self . counterparty_tx_cache . on_counterparty_tx_csv as u32 , height_original : height , content : malleable_justice_tx} ) ;
1405
1385
}
1406
1386
}
1407
1387
@@ -1414,7 +1394,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1414
1394
return ( claimable_outpoints, ( commitment_txid, watch_outputs) ) ; // Corrupted per_commitment_data, fuck this user
1415
1395
}
1416
1396
let malleable_justice_tx = PackageTemplate :: build_malleable_justice_tx ( per_commitment_point, per_commitment_key, self . counterparty_tx_cache . counterparty_delayed_payment_base_key , self . counterparty_tx_cache . counterparty_htlc_base_key , if htlc. offered { InputDescriptors :: RevokedOfferedHTLC } else { InputDescriptors :: RevokedReceivedHTLC } , commitment_txid, transaction_output_index, htlc. amount_msat / 1000 , Some ( htlc. clone ( ) ) , self . counterparty_tx_cache . on_counterparty_tx_csv ) ;
1417
- claimable_outpoints. push ( ClaimRequest { absolute_timelock : htlc. cltv_expiry , aggregable : true , package_template : malleable_justice_tx} ) ;
1397
+ claimable_outpoints. push ( OnchainRequest { aggregation : true , bump_strategy : BumpStrategy :: RBF , feerate_previous : 0 , height_timer : None , absolute_timelock : htlc. cltv_expiry , height_original : height , content : malleable_justice_tx} ) ;
1418
1398
}
1419
1399
}
1420
1400
}
@@ -1546,10 +1526,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1546
1526
return ( claimable_outpoints, ( commitment_txid, watch_outputs) ) ; // Corrupted per_commitment_data, fuck this user
1547
1527
}
1548
1528
let preimage = if htlc. offered { if let Some ( p) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
1549
- let aggregable = if !htlc. offered { false } else { true } ;
1550
1529
if preimage. is_some ( ) || !htlc. offered {
1551
1530
let counterparty_htlc_tx = PackageTemplate :: build_counterparty_htlc_tx ( * revocation_point, self . counterparty_tx_cache . counterparty_delayed_payment_base_key , self . counterparty_tx_cache . counterparty_htlc_base_key , preimage, htlc. clone ( ) , commitment_txid, transaction_output_index) ;
1552
- claimable_outpoints. push ( ClaimRequest { absolute_timelock : htlc. cltv_expiry , aggregable , package_template : counterparty_htlc_tx } ) ;
1531
+ claimable_outpoints. push ( OnchainRequest { aggregation : if !htlc . offered { false } else { true } , bump_strategy : BumpStrategy :: RBF , feerate_previous : 0 , height_timer : None , absolute_timelock : htlc. cltv_expiry , height_original : height , content : counterparty_htlc_tx } ) ;
1553
1532
}
1554
1533
}
1555
1534
}
@@ -1560,7 +1539,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1560
1539
}
1561
1540
1562
1541
/// Attempts to claim a counterparty HTLC-Success/HTLC-Timeout's outputs using the revocation key
1563
- fn check_spend_counterparty_htlc < L : Deref > ( & mut self , tx : & Transaction , commitment_number : u64 , height : u32 , logger : & L ) -> ( Vec < ClaimRequest > , Option < ( Txid , Vec < TxOut > ) > ) where L :: Target : Logger {
1542
+ fn check_spend_counterparty_htlc < L : Deref > ( & mut self , tx : & Transaction , commitment_number : u64 , height : u32 , logger : & L ) -> ( Vec < OnchainRequest > , Option < ( Txid , Vec < TxOut > ) > ) where L :: Target : Logger {
1564
1543
let htlc_txid = tx. txid ( ) ;
1565
1544
if tx. input . len ( ) != 1 || tx. output . len ( ) != 1 || tx. input [ 0 ] . witness . len ( ) != 5 {
1566
1545
return ( Vec :: new ( ) , None )
@@ -1581,11 +1560,11 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1581
1560
1582
1561
log_trace ! ( logger, "Remote HTLC broadcast {}:{}" , htlc_txid, 0 ) ;
1583
1562
let malleable_justice_tx = PackageTemplate :: build_malleable_justice_tx ( per_commitment_point, per_commitment_key, self . counterparty_tx_cache . counterparty_delayed_payment_base_key , self . counterparty_tx_cache . counterparty_htlc_base_key , InputDescriptors :: RevokedOutput , htlc_txid, 0 , tx. output [ 0 ] . value , None , self . counterparty_tx_cache . on_counterparty_tx_csv ) ;
1584
- let claimable_outpoints = vec ! ( ClaimRequest { absolute_timelock: height + self . counterparty_tx_cache. on_counterparty_tx_csv as u32 , aggregable : true , package_template : malleable_justice_tx } ) ;
1563
+ let claimable_outpoints = vec ! ( OnchainRequest { aggregation : true , bump_strategy : BumpStrategy :: RBF , feerate_previous : 0 , height_timer : None , absolute_timelock: height + self . counterparty_tx_cache. on_counterparty_tx_csv as u32 , height_original : height , content : malleable_justice_tx } ) ;
1585
1564
( claimable_outpoints, Some ( ( htlc_txid, tx. output . clone ( ) ) ) )
1586
1565
}
1587
1566
1588
- fn broadcast_by_holder_state ( & self , commitment_tx : & Transaction , holder_tx : & HolderSignedTx ) -> ( Vec < ClaimRequest > , Vec < TxOut > , Option < ( Script , PublicKey , PublicKey ) > ) {
1567
+ fn broadcast_by_holder_state ( & self , commitment_tx : & Transaction , holder_tx : & HolderSignedTx , height : u32 ) -> ( Vec < OnchainRequest > , Vec < TxOut > , Option < ( Script , PublicKey , PublicKey ) > ) {
1589
1568
let mut claim_requests = Vec :: with_capacity ( holder_tx. htlc_outputs . len ( ) ) ;
1590
1569
let mut watch_outputs = Vec :: with_capacity ( holder_tx. htlc_outputs . len ( ) ) ;
1591
1570
@@ -1602,7 +1581,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1602
1581
continue ;
1603
1582
}
1604
1583
} else { None } , htlc. amount_msat , holder_tx. txid , transaction_output_index) ;
1605
- claim_requests. push ( ClaimRequest { absolute_timelock : :: std :: u32 :: MAX , aggregable : false , package_template : holder_htlc_tx } ) ;
1584
+ claim_requests. push ( OnchainRequest { aggregation : false , bump_strategy : BumpStrategy :: CPFP , feerate_previous : 0 , height_timer : None , absolute_timelock : height , height_original : height , content : holder_htlc_tx } ) ;
1606
1585
watch_outputs. push ( commitment_tx. output [ transaction_output_index as usize ] . clone ( ) ) ;
1607
1586
}
1608
1587
}
@@ -1613,7 +1592,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1613
1592
/// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
1614
1593
/// revoked using data in holder_claimable_outpoints.
1615
1594
/// Should not be used if check_spend_revoked_transaction succeeds.
1616
- fn check_spend_holder_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , logger : & L ) -> ( Vec < ClaimRequest > , ( Txid , Vec < TxOut > ) ) where L :: Target : Logger {
1595
+ fn check_spend_holder_transaction < L : Deref > ( & mut self , tx : & Transaction , height : u32 , logger : & L ) -> ( Vec < OnchainRequest > , ( Txid , Vec < TxOut > ) ) where L :: Target : Logger {
1617
1596
let commitment_txid = tx. txid ( ) ;
1618
1597
let mut claim_requests = Vec :: new ( ) ;
1619
1598
let mut watch_outputs = Vec :: new ( ) ;
@@ -1655,13 +1634,13 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1655
1634
if self . current_holder_commitment_tx . txid == commitment_txid {
1656
1635
is_holder_tx = true ;
1657
1636
log_trace ! ( logger, "Got latest holder commitment tx broadcast, searching for available HTLCs to claim" ) ;
1658
- let mut res = self . broadcast_by_holder_state ( tx, & self . current_holder_commitment_tx ) ;
1637
+ let mut res = self . broadcast_by_holder_state ( tx, & self . current_holder_commitment_tx , height ) ;
1659
1638
append_onchain_update ! ( res) ;
1660
1639
} else if let & Some ( ref holder_tx) = & self . prev_holder_signed_commitment_tx {
1661
1640
if holder_tx. txid == commitment_txid {
1662
1641
is_holder_tx = true ;
1663
1642
log_trace ! ( logger, "Got previous holder commitment tx broadcast, searching for available HTLCs to claim" ) ;
1664
- let mut res = self . broadcast_by_holder_state ( tx, holder_tx) ;
1643
+ let mut res = self . broadcast_by_holder_state ( tx, holder_tx, height ) ;
1665
1644
append_onchain_update ! ( res) ;
1666
1645
}
1667
1646
}
@@ -1816,13 +1795,13 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1816
1795
let should_broadcast = self . would_broadcast_at_height ( height, & logger) ;
1817
1796
if should_broadcast {
1818
1797
let holder_commitment_tx = PackageTemplate :: build_holder_commitment_tx ( self . funding_redeemscript . clone ( ) , self . funding_info . 0 . txid . clone ( ) , self . funding_info . 0 . index as u32 ) ;
1819
- claimable_outpoints. push ( ClaimRequest { absolute_timelock : height, aggregable : false , package_template : holder_commitment_tx } ) ;
1798
+ claimable_outpoints. push ( OnchainRequest { aggregation : false , bump_strategy : BumpStrategy :: CPFP , feerate_previous : 0 , height_timer : None , absolute_timelock : height, height_original : height , content : holder_commitment_tx } ) ;
1820
1799
}
1821
1800
if should_broadcast {
1822
1801
self . pending_monitor_events . push ( MonitorEvent :: CommitmentTxBroadcasted ( self . funding_info . 0 ) ) ;
1823
1802
if let Some ( commitment_tx) = self . onchain_tx_handler . get_fully_signed_holder_tx ( & self . funding_redeemscript ) {
1824
1803
self . holder_tx_signed = true ;
1825
- let ( mut new_outpoints, new_outputs, _) = self . broadcast_by_holder_state ( & commitment_tx, & self . current_holder_commitment_tx ) ;
1804
+ let ( mut new_outpoints, new_outputs, _) = self . broadcast_by_holder_state ( & commitment_tx, & self . current_holder_commitment_tx , height ) ;
1826
1805
if !new_outputs. is_empty ( ) {
1827
1806
watch_outputs. push ( ( self . current_holder_commitment_tx . txid . clone ( ) , new_outputs) ) ;
1828
1807
}
0 commit comments