@@ -1697,42 +1697,77 @@ impl ChannelMonitor {
1697
1697
/// Attempts to claim any claimable HTLCs in a commitment transaction which was not (yet)
1698
1698
/// revoked using data in local_claimable_outpoints.
1699
1699
/// Should not be used if check_spend_revoked_transaction succeeds.
1700
- fn check_spend_local_transaction ( & self , tx : & Transaction , _height : u32 ) -> ( Vec < Transaction > , Vec < SpendableOutputDescriptor > , ( Sha256dHash , Vec < TxOut > ) ) {
1700
+ fn check_spend_local_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , Vec < SpendableOutputDescriptor > , ( Sha256dHash , Vec < TxOut > ) ) {
1701
1701
let commitment_txid = tx. txid ( ) ;
1702
- // TODO: If we find a match here we need to fail back HTLCs that weren't included in the
1703
- // broadcast commitment transaction, either because they didn't meet dust or because they
1704
- // weren't yet included in our commitment transaction(s).
1702
+ let mut local_txn = Vec :: new ( ) ;
1703
+ let mut spendable_outputs = Vec :: new ( ) ;
1704
+ let mut watch_outputs = Vec :: new ( ) ;
1705
+
1706
+ macro_rules! wait_threshold_conf {
1707
+ ( $height: expr, $source: expr, $update: expr, $commitment_tx: expr, $payment_hash: expr) => {
1708
+ log_trace!( self , "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation until {} height" , log_bytes!( $payment_hash. 0 ) , $commitment_tx, height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
1709
+ match self . htlc_updated_waiting_threshold_conf. entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1710
+ hash_map:: Entry :: Occupied ( mut entry) => {
1711
+ let e = entry. get_mut( ) ;
1712
+ e. retain( |ref update| update. 0 != $source) ;
1713
+ e. push( ( $source, $update, $payment_hash) ) ;
1714
+ }
1715
+ hash_map:: Entry :: Vacant ( entry) => {
1716
+ entry. insert( vec![ ( $source, $update, $payment_hash) ] ) ;
1717
+ }
1718
+ }
1719
+ }
1720
+ }
1721
+
1722
+ macro_rules! append_onchain_update {
1723
+ ( $updates: expr) => {
1724
+ local_txn. append( & mut $updates. 0 ) ;
1725
+ spendable_outputs. append( & mut $updates. 1 ) ;
1726
+ watch_outputs. append( & mut $updates. 2 ) ;
1727
+ }
1728
+ }
1729
+
1705
1730
if let & Some ( ref local_tx) = & self . current_local_signed_commitment_tx {
1731
+ for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1732
+ if htlc. transaction_output_index . is_none ( ) {
1733
+ if let & Some ( ref source) = source {
1734
+ wait_threshold_conf ! ( height, source. clone( ) , None , "lastest" , htlc. payment_hash. clone( ) ) ;
1735
+ }
1736
+ }
1737
+ }
1706
1738
if local_tx. txid == commitment_txid {
1707
1739
log_trace ! ( self , "Got latest local commitment tx broadcast, searching for available HTLCs to claim" ) ;
1708
1740
match self . key_storage {
1709
1741
Storage :: Local { ref delayed_payment_base_key, ref latest_per_commitment_point, .. } => {
1710
- let ( local_txn, spendable_outputs, watch_outputs) = self . broadcast_by_local_state ( local_tx, latest_per_commitment_point, & Some ( * delayed_payment_base_key) ) ;
1711
- return ( local_txn, spendable_outputs, ( commitment_txid, watch_outputs) ) ;
1742
+ append_onchain_update ! ( self . broadcast_by_local_state( local_tx, latest_per_commitment_point, & Some ( * delayed_payment_base_key) ) ) ;
1712
1743
} ,
1713
1744
Storage :: Watchtower { .. } => {
1714
- let ( local_txn, spendable_outputs, watch_outputs) = self . broadcast_by_local_state ( local_tx, & None , & None ) ;
1715
- return ( local_txn, spendable_outputs, ( commitment_txid, watch_outputs) ) ;
1745
+ append_onchain_update ! ( self . broadcast_by_local_state( local_tx, & None , & None ) ) ;
1716
1746
}
1717
1747
}
1718
1748
}
1719
1749
}
1720
1750
if let & Some ( ref local_tx) = & self . prev_local_signed_commitment_tx {
1751
+ for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1752
+ if htlc. transaction_output_index . is_none ( ) {
1753
+ if let & Some ( ref source) = source {
1754
+ wait_threshold_conf ! ( height, source. clone( ) , None , "previous" , htlc. payment_hash. clone( ) ) ;
1755
+ }
1756
+ }
1757
+ }
1721
1758
if local_tx. txid == commitment_txid {
1722
1759
log_trace ! ( self , "Got previous local commitment tx broadcast, searching for available HTLCs to claim" ) ;
1723
1760
match self . key_storage {
1724
1761
Storage :: Local { ref delayed_payment_base_key, ref prev_latest_per_commitment_point, .. } => {
1725
- let ( local_txn, spendable_outputs, watch_outputs) = self . broadcast_by_local_state ( local_tx, prev_latest_per_commitment_point, & Some ( * delayed_payment_base_key) ) ;
1726
- return ( local_txn, spendable_outputs, ( commitment_txid, watch_outputs) ) ;
1762
+ append_onchain_update ! ( self . broadcast_by_local_state( local_tx, prev_latest_per_commitment_point, & Some ( * delayed_payment_base_key) ) ) ;
1727
1763
} ,
1728
1764
Storage :: Watchtower { .. } => {
1729
- let ( local_txn, spendable_outputs, watch_outputs) = self . broadcast_by_local_state ( local_tx, & None , & None ) ;
1730
- return ( local_txn, spendable_outputs, ( commitment_txid, watch_outputs) ) ;
1765
+ append_onchain_update ! ( self . broadcast_by_local_state( local_tx, & None , & None ) ) ;
1731
1766
}
1732
1767
}
1733
1768
}
1734
1769
}
1735
- ( Vec :: new ( ) , Vec :: new ( ) , ( commitment_txid, Vec :: new ( ) ) )
1770
+ ( local_txn , spendable_outputs , ( commitment_txid, watch_outputs ) )
1736
1771
}
1737
1772
1738
1773
/// Generate a spendable output event when closing_transaction get registered onchain.
0 commit comments