@@ -1568,6 +1568,7 @@ impl ChannelMonitor {
1568
1568
if let Some ( transaction_output_index) = htlc. transaction_output_index {
1569
1569
if let & Some ( ( ref their_sig, ref our_sig) ) = sigs {
1570
1570
if htlc. offered {
1571
+ log_trace ! ( self , "Broadcasting HTLC-Timeout transaction against local commitment transactions" ) ;
1571
1572
let mut htlc_timeout_tx = chan_utils:: build_htlc_transaction ( & local_tx. txid , local_tx. feerate_per_kw , self . their_to_self_delay . unwrap ( ) , htlc, & local_tx. delayed_payment_key , & local_tx. revocation_key ) ;
1572
1573
1573
1574
htlc_timeout_tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ; // First is the multisig dummy
@@ -1584,6 +1585,7 @@ impl ChannelMonitor {
1584
1585
res. push ( htlc_timeout_tx) ;
1585
1586
} else {
1586
1587
if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
1588
+ log_trace ! ( self , "Broadcasting HTLC-Success transaction against local commitment transactions" ) ;
1587
1589
let mut htlc_success_tx = chan_utils:: build_htlc_transaction ( & local_tx. txid , local_tx. feerate_per_kw , self . their_to_self_delay . unwrap ( ) , htlc, & local_tx. delayed_payment_key , & local_tx. revocation_key ) ;
1588
1590
1589
1591
htlc_success_tx. input [ 0 ] . witness . push ( Vec :: new ( ) ) ; // First is the multisig dummy
@@ -1618,6 +1620,7 @@ impl ChannelMonitor {
1618
1620
// weren't yet included in our commitment transaction(s).
1619
1621
if let & Some ( ref local_tx) = & self . current_local_signed_commitment_tx {
1620
1622
if local_tx. txid == commitment_txid {
1623
+ log_trace ! ( self , "Got latest local commitment tx broadcast, searching for available HTLCs to claim" ) ;
1621
1624
match self . key_storage {
1622
1625
Storage :: Local { ref delayed_payment_base_key, ref latest_per_commitment_point, .. } => {
1623
1626
let ( local_txn, spendable_outputs, watch_outputs) = self . broadcast_by_local_state ( local_tx, latest_per_commitment_point, & Some ( * delayed_payment_base_key) ) ;
@@ -1632,6 +1635,7 @@ impl ChannelMonitor {
1632
1635
}
1633
1636
if let & Some ( ref local_tx) = & self . prev_local_signed_commitment_tx {
1634
1637
if local_tx. txid == commitment_txid {
1638
+ log_trace ! ( self , "Got previous local commitment tx broadcast, searching for available HTLCs to claim" ) ;
1635
1639
match self . key_storage {
1636
1640
Storage :: Local { ref delayed_payment_base_key, ref prev_latest_per_commitment_point, .. } => {
1637
1641
let ( local_txn, spendable_outputs, watch_outputs) = self . broadcast_by_local_state ( local_tx, prev_latest_per_commitment_point, & Some ( * delayed_payment_base_key) ) ;
@@ -1784,44 +1788,66 @@ impl ChannelMonitor {
1784
1788
}
1785
1789
1786
1790
pub ( super ) fn would_broadcast_at_height ( & self , height : u32 ) -> bool {
1787
- // TODO: We need to consider HTLCs which weren't included in latest local commitment
1788
- // transaction (or in any of the latest two local commitment transactions). This probably
1789
- // needs to use the same logic as the revoked-tx-announe logic - checking the last two
1790
- // remote commitment transactions. This probably has implications for what data we need to
1791
- // store in local commitment transactions .
1791
+ // We need to consider all HTLCs which are:
1792
+ // * in any unrevoked remote commitment transaction, as they could broadcast said
1793
+ // transactions and we'd end up in a race, or
1794
+ // * are in our latest local commitment transaction, as this is the thing we will
1795
+ // broadcast if we go on-chain .
1792
1796
// Note that we consider HTLCs which were below dust threshold here - while they don't
1793
1797
// strictly imply that we need to fail the channel, we need to go ahead and fail them back
1794
1798
// to the source, and if we don't fail the channel we will have to ensure that the next
1795
1799
// updates that peer sends us are update_fails, failing the channel if not. It's probably
1796
1800
// easier to just fail the channel as this case should be rare enough anyway.
1801
+ macro_rules! scan_commitment {
1802
+ ( $htlcs: expr, $local_tx: expr) => {
1803
+ for ref htlc in $htlcs {
1804
+ // For inbound HTLCs which we know the preimage for, we have to ensure we hit the
1805
+ // chain with enough room to claim the HTLC without our counterparty being able to
1806
+ // time out the HTLC first.
1807
+ // For outbound HTLCs which our counterparty hasn't failed/claimed, our primary
1808
+ // concern is being able to claim the corresponding inbound HTLC (on another
1809
+ // channel) before it expires. In fact, we don't even really care if our
1810
+ // counterparty here claims such an outbound HTLC after it expired as long as we
1811
+ // can still claim the corresponding HTLC. Thus, to avoid needlessly hitting the
1812
+ // chain when our counterparty is waiting for expiration to off-chain fail an HTLC
1813
+ // we give ourselves a few blocks of headroom after expiration before going
1814
+ // on-chain for an expired HTLC.
1815
+ // Note that, to avoid a potential attack whereby a node delays claiming an HTLC
1816
+ // from us until we've reached the point where we go on-chain with the
1817
+ // corresponding inbound HTLC, we must ensure that outbound HTLCs go on chain at
1818
+ // least CLTV_CLAIM_BUFFER blocks prior to the inbound HTLC.
1819
+ // aka outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS == height - CLTV_CLAIM_BUFFER
1820
+ // inbound_cltv == height + CLTV_CLAIM_BUFFER
1821
+ // outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS + CLTV_CLAIM_BUFER <= inbound_cltv - CLTV_CLAIM_BUFFER
1822
+ // HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= inbound_cltv - outbound_cltv
1823
+ // HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= CLTV_EXPIRY_DELTA
1824
+ let htlc_outbound = $local_tx == htlc. offered;
1825
+ if ( htlc_outbound && htlc. cltv_expiry + HTLC_FAIL_TIMEOUT_BLOCKS <= height) ||
1826
+ ( !htlc_outbound && htlc. cltv_expiry <= height + CLTV_CLAIM_BUFFER && self . payment_preimages. contains_key( & htlc. payment_hash) ) {
1827
+ log_info!( self , "Force-closing channel due to {} HTLC timeout, HTLC expiry is {}" , if htlc_outbound { "outbound" } else { "inbound " } , htlc. cltv_expiry) ;
1828
+ return true ;
1829
+ }
1830
+ }
1831
+ }
1832
+ }
1833
+
1797
1834
if let Some ( ref cur_local_tx) = self . current_local_signed_commitment_tx {
1798
- for & ( ref htlc, _, _) in cur_local_tx. htlc_outputs . iter ( ) {
1799
- // For inbound HTLCs which we know the preimage for, we have to ensure we hit the
1800
- // chain with enough room to claim the HTLC without our counterparty being able to
1801
- // time out the HTLC first.
1802
- // For outbound HTLCs which our counterparty hasn't failed/claimed, our primary
1803
- // concern is being able to claim the corresponding inbound HTLC (on another
1804
- // channel) before it expires. In fact, we don't even really care if our
1805
- // counterparty here claims such an outbound HTLC after it expired as long as we
1806
- // can still claim the corresponding HTLC. Thus, to avoid needlessly hitting the
1807
- // chain when our counterparty is waiting for expiration to off-chain fail an HTLC
1808
- // we give ourselves a few blocks of headroom after expiration before going
1809
- // on-chain for an expired HTLC.
1810
- // Note that, to avoid a potential attack whereby a node delays claiming an HTLC
1811
- // from us until we've reached the point where we go on-chain with the
1812
- // corresponding inbound HTLC, we must ensure that outbound HTLCs go on chain at
1813
- // least CLTV_CLAIM_BUFFER blocks prior to the inbound HTLC.
1814
- // aka outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS == height - CLTV_CLAIM_BUFFER
1815
- // inbound_cltv == height + CLTV_CLAIM_BUFFER
1816
- // outbound_cltv + HTLC_FAIL_TIMEOUT_BLOCKS + CLTV_CLAIM_BUFER <= inbound_cltv - CLTV_CLAIM_BUFFER
1817
- // HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= inbound_cltv - outbound_cltv
1818
- // HTLC_FAIL_TIMEOUT_BLOCKS + 2*CLTV_CLAIM_BUFER <= CLTV_EXPIRY_DELTA
1819
- if ( htlc. offered && htlc. cltv_expiry + HTLC_FAIL_TIMEOUT_BLOCKS <= height) ||
1820
- ( !htlc. offered && htlc. cltv_expiry <= height + CLTV_CLAIM_BUFFER && self . payment_preimages . contains_key ( & htlc. payment_hash ) ) {
1821
- return true ;
1835
+ scan_commitment ! ( cur_local_tx. htlc_outputs. iter( ) . map( |& ( ref a, _, _) | a) , true ) ;
1836
+ }
1837
+
1838
+ if let Storage :: Local { ref current_remote_commitment_txid, ref prev_remote_commitment_txid, .. } = self . key_storage {
1839
+ if let & Some ( ref txid) = current_remote_commitment_txid {
1840
+ if let Some ( ref htlc_outputs) = self . remote_claimable_outpoints . get ( txid) {
1841
+ scan_commitment ! ( htlc_outputs. iter( ) . map( |& ( ref a, _) | a) , false ) ;
1842
+ }
1843
+ }
1844
+ if let & Some ( ref txid) = prev_remote_commitment_txid {
1845
+ if let Some ( ref htlc_outputs) = self . remote_claimable_outpoints . get ( txid) {
1846
+ scan_commitment ! ( htlc_outputs. iter( ) . map( |& ( ref a, _) | a) , false ) ;
1822
1847
}
1823
1848
}
1824
1849
}
1850
+
1825
1851
false
1826
1852
}
1827
1853
0 commit comments