@@ -64,11 +64,18 @@ pub struct ChannelMonitorUpdate {
6464 pub ( crate ) updates : Vec < ChannelMonitorUpdateStep > ,
6565 /// The sequence number of this update. Updates *must* be replayed in-order according to this
6666 /// sequence number (and updates may panic if they are not). The update_id values are strictly
67- /// increasing and increase by one for each new update.
67+ /// increasing and increase by one for each new update, with one exception specified below .
6868 ///
6969 /// This sequence number is also used to track up to which points updates which returned
7070 /// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
7171 /// ChannelMonitor when ChannelManager::channel_monitor_updated is called.
72+ ///
73+ /// The only instance where update_id values are not strictly increasing is the case where: (1)
74+ /// the channel has been force closed and (2) we receive a preimage from a forward link that
75+ /// allows us to spend an HTLC output on this channel's (the backward link's) broadcasted
76+ /// commitment transaction. In this case, we allow the `ChannelManager` to send a
77+ /// `ChannelMonitorUpdate` with an update_id of `std::u64::MAX`, with the update providing said
78+ /// payment preimage. No other update types are allowed after force-close.
7279 pub update_id : u64 ,
7380}
7481
@@ -1150,6 +1157,46 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
11501157 L :: Target : Logger ,
11511158 {
11521159 self . payment_preimages . insert ( payment_hash. clone ( ) , payment_preimage. clone ( ) ) ;
1160+
1161+ // If the channel is force closed, try to claim the output from this preimage.
1162+ // First check if a counterparty commitment transaction has been broadcasted:
1163+ macro_rules! claim_htlcs {
1164+ ( $commitment_number: expr, $txid: expr) => {
1165+ let ( htlc_claim_reqs, set_script) = self . get_counterparty_htlc_output_claim_reqs( $commitment_number, $txid, None ) ;
1166+ if set_script {
1167+ self . counterparty_payment_script = {
1168+ // Note that the Network here is ignored as we immediately drop the address for the
1169+ // script_pubkey version
1170+ let payment_hash160 = WPubkeyHash :: hash( & self . keys. pubkeys( ) . payment_point. serialize( ) ) ;
1171+ Builder :: new( ) . push_opcode( opcodes:: all:: OP_PUSHBYTES_0 ) . push_slice( & payment_hash160[ ..] ) . into_script( )
1172+ } ;
1173+ }
1174+ self . onchain_tx_handler. update_claims_view( & Vec :: new( ) , htlc_claim_reqs, None , broadcaster, fee_estimator, logger) ;
1175+ }
1176+ }
1177+ if let Some ( txid) = self . current_counterparty_commitment_txid {
1178+ if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
1179+ claim_htlcs ! ( * commitment_number, txid) ;
1180+ return ;
1181+ }
1182+ }
1183+ if let Some ( txid) = self . prev_counterparty_commitment_txid {
1184+ if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
1185+ claim_htlcs ! ( * commitment_number, txid) ;
1186+ return ;
1187+ }
1188+ }
1189+
1190+ // Then if a holder commitment transaction has been signed, broadcast transactions claiming
1191+ // the HTLC output from each of the holder commitment transactions.
1192+ if self . holder_tx_signed {
1193+ let ( claim_reqs, _, _) = self . broadcast_by_holder_state ( None , & self . current_holder_commitment_tx ) ;
1194+ self . onchain_tx_handler . update_claims_view ( & Vec :: new ( ) , claim_reqs, None , broadcaster, fee_estimator, logger) ;
1195+ if let Some ( ref tx) = self . prev_holder_signed_commitment_tx {
1196+ let ( claim_reqs, _, _) = self . broadcast_by_holder_state ( None , & tx) ;
1197+ self . onchain_tx_handler . update_claims_view ( & Vec :: new ( ) , claim_reqs, None , broadcaster, fee_estimator, logger) ;
1198+ }
1199+ }
11531200 }
11541201
11551202 pub ( crate ) fn broadcast_latest_holder_commitment_txn < B : Deref , L : Deref > ( & mut self , broadcaster : & B , logger : & L )
@@ -1171,7 +1218,18 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
11711218 F :: Target : FeeEstimator ,
11721219 L :: Target : Logger ,
11731220 {
1174- if self . latest_update_id + 1 != updates. update_id {
1221+ // ChannelMonitor updates may be applied after force close if we receive a
1222+ // preimage for a broadcasted commitment transaction HTLC output that we'd
1223+ // like to claim on-chain. If this is the case, we no longer have guaranteed
1224+ // access to the monitor's update ID, so we use a sentinel value instead.
1225+ if updates. update_id == std:: u64:: MAX {
1226+ match updates. updates [ 0 ] {
1227+ ChannelMonitorUpdateStep :: PaymentPreimage { .. } => { } ,
1228+ _ => panic ! ( "Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage" ) ,
1229+ }
1230+ assert_eq ! ( updates. updates. len( ) , 1 ) ;
1231+ }
1232+ if updates. update_id != std:: u64:: MAX && self . latest_update_id + 1 != updates. update_id {
11751233 panic ! ( "Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!" ) ;
11761234 }
11771235 for update in updates. updates . iter ( ) {
@@ -1439,39 +1497,61 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
14391497 check_htlc_fails ! ( txid, "previous" , ' prev_loop) ;
14401498 }
14411499
1500+ let ( htlc_claim_reqs, set_script) = self . get_counterparty_htlc_output_claim_reqs ( commitment_number, commitment_txid, Some ( tx) ) ;
1501+ if set_script {
1502+ self . counterparty_payment_script = {
1503+ // Note that the Network here is ignored as we immediately drop the address for the
1504+ // script_pubkey version
1505+ let payment_hash160 = WPubkeyHash :: hash ( & self . keys . pubkeys ( ) . payment_point . serialize ( ) ) ;
1506+ Builder :: new ( ) . push_opcode ( opcodes:: all:: OP_PUSHBYTES_0 ) . push_slice ( & payment_hash160[ ..] ) . into_script ( )
1507+ } ;
1508+ }
1509+ for req in htlc_claim_reqs {
1510+ claimable_outpoints. push ( req) ;
1511+ }
1512+
1513+ }
1514+ ( claimable_outpoints, ( commitment_txid, watch_outputs) )
1515+ }
1516+
1517+ fn get_counterparty_htlc_output_claim_reqs ( & self , commitment_number : u64 , commitment_txid : Txid , tx : Option < & Transaction > ) -> ( Vec < ClaimRequest > , bool ) {
1518+ let mut claims = Vec :: new ( ) ;
1519+ let mut set_counterparty_payment_script = false ;
1520+ if let Some ( htlc_outputs) = self . counterparty_claimable_outpoints . get ( & commitment_txid) {
14421521 if let Some ( revocation_points) = self . their_cur_revocation_points {
14431522 let revocation_point_option =
14441523 if revocation_points. 0 == commitment_number { Some ( & revocation_points. 1 ) }
1445- else if let Some ( point) = revocation_points. 2 . as_ref ( ) {
1446- if revocation_points. 0 == commitment_number + 1 { Some ( point) } else { None }
1447- } else { None } ;
1524+ else if let Some ( point) = revocation_points. 2 . as_ref ( ) {
1525+ if revocation_points. 0 == commitment_number + 1 { Some ( point) } else { None }
1526+ } else { None } ;
14481527 if let Some ( revocation_point) = revocation_point_option {
1449- self . counterparty_payment_script = {
1450- // Note that the Network here is ignored as we immediately drop the address for the
1451- // script_pubkey version
1452- let payment_hash160 = WPubkeyHash :: hash ( & self . keys . pubkeys ( ) . payment_point . serialize ( ) ) ;
1453- Builder :: new ( ) . push_opcode ( opcodes:: all:: OP_PUSHBYTES_0 ) . push_slice ( & payment_hash160[ ..] ) . into_script ( )
1454- } ;
1528+ set_counterparty_payment_script = true ;
14551529
14561530 // Then, try to find htlc outputs
1457- for ( _, & ( ref htlc, _) ) in per_commitment_data . iter ( ) . enumerate ( ) {
1531+ for ( _, & ( ref htlc, _) ) in htlc_outputs . iter ( ) . enumerate ( ) {
14581532 if let Some ( transaction_output_index) = htlc. transaction_output_index {
1459- if transaction_output_index as usize >= tx. output . len ( ) ||
1460- tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
1461- return ( claimable_outpoints, ( commitment_txid, watch_outputs) ) ; // Corrupted per_commitment_data, fuck this user
1533+ if let Some ( transaction) = tx {
1534+ if transaction_output_index as usize >= transaction. output . len ( ) ||
1535+ transaction. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
1536+ return ( claims, set_counterparty_payment_script) // Corrupted per_commitment_data, fuck this user
1537+ }
14621538 }
1463- let preimage = if htlc. offered { if let Some ( p) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
1539+ let preimage = if htlc. offered {
1540+ if let Some ( p) = self . payment_preimages . get ( & htlc. payment_hash ) {
1541+ Some ( * p)
1542+ } else { None }
1543+ } else { None } ;
14641544 let aggregable = if !htlc. offered { false } else { true } ;
14651545 if preimage. is_some ( ) || !htlc. offered {
14661546 let witness_data = InputMaterial :: CounterpartyHTLC { per_commitment_point : * revocation_point, counterparty_delayed_payment_base_key : self . counterparty_tx_cache . counterparty_delayed_payment_base_key , counterparty_htlc_base_key : self . counterparty_tx_cache . counterparty_htlc_base_key , preimage, htlc : htlc. clone ( ) } ;
1467- claimable_outpoints . push ( ClaimRequest { absolute_timelock : htlc. cltv_expiry , aggregable, outpoint : BitcoinOutPoint { txid : commitment_txid, vout : transaction_output_index } , witness_data } ) ;
1547+ claims . push ( ClaimRequest { absolute_timelock : htlc. cltv_expiry , aggregable, outpoint : BitcoinOutPoint { txid : commitment_txid, vout : transaction_output_index } , witness_data } ) ;
14681548 }
14691549 }
14701550 }
14711551 }
14721552 }
14731553 }
1474- ( claimable_outpoints , ( commitment_txid , watch_outputs ) )
1554+ ( claims , set_counterparty_payment_script )
14751555 }
14761556
14771557 /// Attempts to claim a counterparty HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1501,7 +1581,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
15011581 ( claimable_outpoints, Some ( ( htlc_txid, outputs) ) )
15021582 }
15031583
1504- fn broadcast_by_holder_state ( & self , commitment_tx : & Transaction , holder_tx : & HolderSignedTx ) -> ( Vec < ClaimRequest > , Vec < ( u32 , TxOut ) > , Option < ( Script , PublicKey , PublicKey ) > ) {
1584+ fn broadcast_by_holder_state ( & self , commitment_tx : Option < & Transaction > , holder_tx : & HolderSignedTx ) -> ( Vec < ClaimRequest > , Vec < ( u32 , TxOut ) > , Option < ( Script , PublicKey , PublicKey ) > ) {
15051585 let mut claim_requests = Vec :: with_capacity ( holder_tx. htlc_outputs . len ( ) ) ;
15061586 let mut watch_outputs = Vec :: with_capacity ( holder_tx. htlc_outputs . len ( ) ) ;
15071587
@@ -1522,7 +1602,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
15221602 } else { None } ,
15231603 amount : htlc. amount_msat ,
15241604 } } ) ;
1525- watch_outputs. push ( ( transaction_output_index, commitment_tx. output [ transaction_output_index as usize ] . clone ( ) ) ) ;
1605+ if let Some ( commitment_tx) = commitment_tx {
1606+ watch_outputs. push ( ( transaction_output_index, commitment_tx. output [ transaction_output_index as usize ] . clone ( ) ) ) ;
1607+ }
15261608 }
15271609 }
15281610
@@ -1574,13 +1656,13 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
15741656 if self . current_holder_commitment_tx . txid == commitment_txid {
15751657 is_holder_tx = true ;
15761658 log_trace ! ( logger, "Got latest holder commitment tx broadcast, searching for available HTLCs to claim" ) ;
1577- let mut res = self . broadcast_by_holder_state ( tx , & self . current_holder_commitment_tx ) ;
1659+ let mut res = self . broadcast_by_holder_state ( Some ( tx ) , & self . current_holder_commitment_tx ) ;
15781660 append_onchain_update ! ( res) ;
15791661 } else if let & Some ( ref holder_tx) = & self . prev_holder_signed_commitment_tx {
15801662 if holder_tx. txid == commitment_txid {
15811663 is_holder_tx = true ;
15821664 log_trace ! ( logger, "Got previous holder commitment tx broadcast, searching for available HTLCs to claim" ) ;
1583- let mut res = self . broadcast_by_holder_state ( tx , holder_tx) ;
1665+ let mut res = self . broadcast_by_holder_state ( Some ( tx ) , holder_tx) ;
15841666 append_onchain_update ! ( res) ;
15851667 }
15861668 }
@@ -1749,7 +1831,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
17491831 self . pending_monitor_events . push ( MonitorEvent :: CommitmentTxBroadcasted ( self . funding_info . 0 ) ) ;
17501832 if let Some ( commitment_tx) = self . onchain_tx_handler . get_fully_signed_holder_tx ( & self . funding_redeemscript ) {
17511833 self . holder_tx_signed = true ;
1752- let ( mut new_outpoints, new_outputs, _) = self . broadcast_by_holder_state ( & commitment_tx, & self . current_holder_commitment_tx ) ;
1834+ let ( mut new_outpoints, new_outputs, _) = self . broadcast_by_holder_state ( Some ( & commitment_tx) , & self . current_holder_commitment_tx ) ;
17531835 if !new_outputs. is_empty ( ) {
17541836 watch_outputs. push ( ( self . current_holder_commitment_tx . txid . clone ( ) , new_outputs) ) ;
17551837 }
@@ -1777,7 +1859,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
17771859 }
17781860 }
17791861
1780- self . onchain_tx_handler . block_connected ( & txn_matched, claimable_outpoints, height, & * broadcaster, & * fee_estimator, & * logger) ;
1862+ self . onchain_tx_handler . update_claims_view ( & txn_matched, claimable_outpoints, Some ( height) , & & * broadcaster, & & * fee_estimator, & & * logger) ;
17811863 self . last_block_hash = block_hash;
17821864
17831865 // Determine new outputs to watch by comparing against previously known outputs to watch,
0 commit comments