@@ -64,14 +64,32 @@ pub struct ChannelMonitorUpdate {
64
64
pub ( crate ) updates : Vec < ChannelMonitorUpdateStep > ,
65
65
/// The sequence number of this update. Updates *must* be replayed in-order according to this
66
66
/// 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 .
68
68
///
69
69
/// This sequence number is also used to track up to which points updates which returned
70
70
/// ChannelMonitorUpdateErr::TemporaryFailure have been applied to all copies of a given
71
71
/// 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 [`CLOSED_CHANNEL_UPDATE_ID`], with the update
78
+ /// providing said payment preimage. No other update types are allowed after force-close.
79
+ ///
80
+ /// [`CLOSED_CHANNEL_UPDATE_ID`]: constant.CLOSED_CHANNEL_UPDATE_ID.html
72
81
pub update_id : u64 ,
73
82
}
74
83
84
+ /// If:
85
+ /// (1) a channel has been force closed and
86
+ /// (2) we receive a preimage from a forward link that allows us to spend an HTLC output on
87
+ /// this channel's (the backward link's) broadcasted commitment transaction
88
+ /// then we allow the `ChannelManager` to send a `ChannelMonitorUpdate` with this update ID,
89
+ /// with the update providing said payment preimage. No other update types are allowed after
90
+ /// force-close.
91
+ pub const CLOSED_CHANNEL_UPDATE_ID : u64 = std:: u64:: MAX ;
92
+
75
93
impl Writeable for ChannelMonitorUpdate {
76
94
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , :: std:: io:: Error > {
77
95
self . update_id . write ( w) ?;
@@ -1150,6 +1168,46 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1150
1168
L :: Target : Logger ,
1151
1169
{
1152
1170
self . payment_preimages . insert ( payment_hash. clone ( ) , payment_preimage. clone ( ) ) ;
1171
+
1172
+ // If the channel is force closed, try to claim the output from this preimage.
1173
+ // First check if a counterparty commitment transaction has been broadcasted:
1174
+ macro_rules! claim_htlcs {
1175
+ ( $commitment_number: expr, $txid: expr) => {
1176
+ let ( htlc_claim_reqs, set_script) = self . get_counterparty_htlc_output_claim_reqs( $commitment_number, $txid, None ) ;
1177
+ if set_script {
1178
+ self . counterparty_payment_script = {
1179
+ // Note that the Network here is ignored as we immediately drop the address for the
1180
+ // script_pubkey version
1181
+ let payment_hash160 = WPubkeyHash :: hash( & self . keys. pubkeys( ) . payment_point. serialize( ) ) ;
1182
+ Builder :: new( ) . push_opcode( opcodes:: all:: OP_PUSHBYTES_0 ) . push_slice( & payment_hash160[ ..] ) . into_script( )
1183
+ } ;
1184
+ }
1185
+ self . onchain_tx_handler. update_claims_view( & Vec :: new( ) , htlc_claim_reqs, None , broadcaster, fee_estimator, logger) ;
1186
+ }
1187
+ }
1188
+ if let Some ( txid) = self . current_counterparty_commitment_txid {
1189
+ if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
1190
+ claim_htlcs ! ( * commitment_number, txid) ;
1191
+ return ;
1192
+ }
1193
+ }
1194
+ if let Some ( txid) = self . prev_counterparty_commitment_txid {
1195
+ if let Some ( commitment_number) = self . counterparty_commitment_txn_on_chain . get ( & txid) {
1196
+ claim_htlcs ! ( * commitment_number, txid) ;
1197
+ return ;
1198
+ }
1199
+ }
1200
+
1201
+ // Then if a holder commitment transaction has been signed, broadcast transactions claiming
1202
+ // the HTLC output from each of the holder commitment transactions.
1203
+ if self . broadcasted_holder_revokable_script . is_some ( ) {
1204
+ let ( claim_reqs, _, _) = self . broadcast_by_holder_state ( None , & self . current_holder_commitment_tx ) ;
1205
+ self . onchain_tx_handler . update_claims_view ( & Vec :: new ( ) , claim_reqs, None , broadcaster, fee_estimator, logger) ;
1206
+ if let Some ( ref tx) = self . prev_holder_signed_commitment_tx {
1207
+ let ( claim_reqs, _, _) = self . broadcast_by_holder_state ( None , & tx) ;
1208
+ self . onchain_tx_handler . update_claims_view ( & Vec :: new ( ) , claim_reqs, None , broadcaster, fee_estimator, logger) ;
1209
+ }
1210
+ }
1153
1211
}
1154
1212
1155
1213
pub ( crate ) fn broadcast_latest_holder_commitment_txn < B : Deref , L : Deref > ( & mut self , broadcaster : & B , logger : & L )
@@ -1171,7 +1229,18 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1171
1229
F :: Target : FeeEstimator ,
1172
1230
L :: Target : Logger ,
1173
1231
{
1174
- if self . latest_update_id + 1 != updates. update_id {
1232
+ // ChannelMonitor updates may be applied after force close if we receive a
1233
+ // preimage for a broadcasted commitment transaction HTLC output that we'd
1234
+ // like to claim on-chain. If this is the case, we no longer have guaranteed
1235
+ // access to the monitor's update ID, so we use a sentinel value instead.
1236
+ if updates. update_id == CLOSED_CHANNEL_UPDATE_ID {
1237
+ match updates. updates [ 0 ] {
1238
+ ChannelMonitorUpdateStep :: PaymentPreimage { .. } => { } ,
1239
+ _ => panic ! ( "Attempted to apply post-force-close ChannelMonitorUpdate that wasn't providing a payment preimage" ) ,
1240
+ }
1241
+ assert_eq ! ( updates. updates. len( ) , 1 ) ;
1242
+ }
1243
+ if updates. update_id != CLOSED_CHANNEL_UPDATE_ID && self . latest_update_id + 1 != updates. update_id {
1175
1244
panic ! ( "Attempted to apply ChannelMonitorUpdates out of order, check the update_id before passing an update to update_monitor!" ) ;
1176
1245
}
1177
1246
for update in updates. updates . iter ( ) {
@@ -1438,39 +1507,61 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1438
1507
check_htlc_fails ! ( txid, "previous" , ' prev_loop) ;
1439
1508
}
1440
1509
1510
+ let ( htlc_claim_reqs, set_script) = self . get_counterparty_htlc_output_claim_reqs ( commitment_number, commitment_txid, Some ( tx) ) ;
1511
+ if set_script {
1512
+ self . counterparty_payment_script = {
1513
+ // Note that the Network here is ignored as we immediately drop the address for the
1514
+ // script_pubkey version
1515
+ let payment_hash160 = WPubkeyHash :: hash ( & self . keys . pubkeys ( ) . payment_point . serialize ( ) ) ;
1516
+ Builder :: new ( ) . push_opcode ( opcodes:: all:: OP_PUSHBYTES_0 ) . push_slice ( & payment_hash160[ ..] ) . into_script ( )
1517
+ } ;
1518
+ }
1519
+ for req in htlc_claim_reqs {
1520
+ claimable_outpoints. push ( req) ;
1521
+ }
1522
+
1523
+ }
1524
+ ( claimable_outpoints, ( commitment_txid, watch_outputs) )
1525
+ }
1526
+
1527
+ fn get_counterparty_htlc_output_claim_reqs ( & self , commitment_number : u64 , commitment_txid : Txid , tx : Option < & Transaction > ) -> ( Vec < ClaimRequest > , bool ) {
1528
+ let mut claims = Vec :: new ( ) ;
1529
+ let mut set_counterparty_payment_script = false ;
1530
+ if let Some ( htlc_outputs) = self . counterparty_claimable_outpoints . get ( & commitment_txid) {
1441
1531
if let Some ( revocation_points) = self . their_cur_revocation_points {
1442
1532
let revocation_point_option =
1443
1533
if revocation_points. 0 == commitment_number { Some ( & revocation_points. 1 ) }
1444
- else if let Some ( point) = revocation_points. 2 . as_ref ( ) {
1445
- if revocation_points. 0 == commitment_number + 1 { Some ( point) } else { None }
1446
- } else { None } ;
1534
+ else if let Some ( point) = revocation_points. 2 . as_ref ( ) {
1535
+ if revocation_points. 0 == commitment_number + 1 { Some ( point) } else { None }
1536
+ } else { None } ;
1447
1537
if let Some ( revocation_point) = revocation_point_option {
1448
- self . counterparty_payment_script = {
1449
- // Note that the Network here is ignored as we immediately drop the address for the
1450
- // script_pubkey version
1451
- let payment_hash160 = WPubkeyHash :: hash ( & self . keys . pubkeys ( ) . payment_point . serialize ( ) ) ;
1452
- Builder :: new ( ) . push_opcode ( opcodes:: all:: OP_PUSHBYTES_0 ) . push_slice ( & payment_hash160[ ..] ) . into_script ( )
1453
- } ;
1538
+ set_counterparty_payment_script = true ;
1454
1539
1455
1540
// Then, try to find htlc outputs
1456
- for ( _, & ( ref htlc, _) ) in per_commitment_data . iter ( ) . enumerate ( ) {
1541
+ for ( _, & ( ref htlc, _) ) in htlc_outputs . iter ( ) . enumerate ( ) {
1457
1542
if let Some ( transaction_output_index) = htlc. transaction_output_index {
1458
- if transaction_output_index as usize >= tx. output . len ( ) ||
1459
- tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
1460
- return ( claimable_outpoints, ( commitment_txid, watch_outputs) ) ; // Corrupted per_commitment_data, fuck this user
1543
+ if let Some ( transaction) = tx {
1544
+ if transaction_output_index as usize >= transaction. output . len ( ) ||
1545
+ transaction. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 {
1546
+ return ( claims, set_counterparty_payment_script) // Corrupted per_commitment_data, fuck this user
1547
+ }
1461
1548
}
1462
- let preimage = if htlc. offered { if let Some ( p) = self . payment_preimages . get ( & htlc. payment_hash ) { Some ( * p) } else { None } } else { None } ;
1549
+ let preimage = if htlc. offered {
1550
+ if let Some ( p) = self . payment_preimages . get ( & htlc. payment_hash ) {
1551
+ Some ( * p)
1552
+ } else { None }
1553
+ } else { None } ;
1463
1554
let aggregable = if !htlc. offered { false } else { true } ;
1464
1555
if preimage. is_some ( ) || !htlc. offered {
1465
1556
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 ( ) } ;
1466
- claimable_outpoints . push ( ClaimRequest { absolute_timelock : htlc. cltv_expiry , aggregable, outpoint : BitcoinOutPoint { txid : commitment_txid, vout : transaction_output_index } , witness_data } ) ;
1557
+ claims . push ( ClaimRequest { absolute_timelock : htlc. cltv_expiry , aggregable, outpoint : BitcoinOutPoint { txid : commitment_txid, vout : transaction_output_index } , witness_data } ) ;
1467
1558
}
1468
1559
}
1469
1560
}
1470
1561
}
1471
1562
}
1472
1563
}
1473
- ( claimable_outpoints , ( commitment_txid , watch_outputs ) )
1564
+ ( claims , set_counterparty_payment_script )
1474
1565
}
1475
1566
1476
1567
/// Attempts to claim a counterparty HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1500,7 +1591,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1500
1591
( claimable_outpoints, Some ( ( htlc_txid, outputs) ) )
1501
1592
}
1502
1593
1503
- fn broadcast_by_holder_state ( & self , commitment_tx : & Transaction , holder_tx : & HolderSignedTx ) -> ( Vec < ClaimRequest > , Vec < ( u32 , TxOut ) > , Option < ( Script , PublicKey , PublicKey ) > ) {
1594
+ fn broadcast_by_holder_state ( & self , commitment_tx : Option < & Transaction > , holder_tx : & HolderSignedTx ) -> ( Vec < ClaimRequest > , Vec < ( u32 , TxOut ) > , Option < ( Script , PublicKey , PublicKey ) > ) {
1504
1595
let mut claim_requests = Vec :: with_capacity ( holder_tx. htlc_outputs . len ( ) ) ;
1505
1596
let mut watch_outputs = Vec :: with_capacity ( holder_tx. htlc_outputs . len ( ) ) ;
1506
1597
@@ -1521,7 +1612,9 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1521
1612
} else { None } ,
1522
1613
amount : htlc. amount_msat ,
1523
1614
} } ) ;
1524
- watch_outputs. push ( ( transaction_output_index, commitment_tx. output [ transaction_output_index as usize ] . clone ( ) ) ) ;
1615
+ if let Some ( commitment_tx) = commitment_tx {
1616
+ watch_outputs. push ( ( transaction_output_index, commitment_tx. output [ transaction_output_index as usize ] . clone ( ) ) ) ;
1617
+ }
1525
1618
}
1526
1619
}
1527
1620
@@ -1573,13 +1666,13 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1573
1666
if self . current_holder_commitment_tx . txid == commitment_txid {
1574
1667
is_holder_tx = true ;
1575
1668
log_trace ! ( logger, "Got latest holder commitment tx broadcast, searching for available HTLCs to claim" ) ;
1576
- let mut res = self . broadcast_by_holder_state ( tx , & self . current_holder_commitment_tx ) ;
1669
+ let mut res = self . broadcast_by_holder_state ( Some ( tx ) , & self . current_holder_commitment_tx ) ;
1577
1670
append_onchain_update ! ( res) ;
1578
1671
} else if let & Some ( ref holder_tx) = & self . prev_holder_signed_commitment_tx {
1579
1672
if holder_tx. txid == commitment_txid {
1580
1673
is_holder_tx = true ;
1581
1674
log_trace ! ( logger, "Got previous holder commitment tx broadcast, searching for available HTLCs to claim" ) ;
1582
- let mut res = self . broadcast_by_holder_state ( tx , holder_tx) ;
1675
+ let mut res = self . broadcast_by_holder_state ( Some ( tx ) , holder_tx) ;
1583
1676
append_onchain_update ! ( res) ;
1584
1677
}
1585
1678
}
@@ -1748,7 +1841,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1748
1841
self . pending_monitor_events . push ( MonitorEvent :: CommitmentTxBroadcasted ( self . funding_info . 0 ) ) ;
1749
1842
if let Some ( commitment_tx) = self . onchain_tx_handler . get_fully_signed_holder_tx ( & self . funding_redeemscript ) {
1750
1843
self . holder_tx_signed = true ;
1751
- let ( mut new_outpoints, new_outputs, _) = self . broadcast_by_holder_state ( & commitment_tx, & self . current_holder_commitment_tx ) ;
1844
+ let ( mut new_outpoints, new_outputs, _) = self . broadcast_by_holder_state ( Some ( & commitment_tx) , & self . current_holder_commitment_tx ) ;
1752
1845
if !new_outputs. is_empty ( ) {
1753
1846
watch_outputs. push ( ( self . current_holder_commitment_tx . txid . clone ( ) , new_outputs) ) ;
1754
1847
}
@@ -1776,7 +1869,7 @@ impl<ChanSigner: ChannelKeys> ChannelMonitor<ChanSigner> {
1776
1869
}
1777
1870
}
1778
1871
1779
- self . onchain_tx_handler . block_connected ( & txn_matched, claimable_outpoints, height, & * broadcaster, & * fee_estimator, & * logger) ;
1872
+ self . onchain_tx_handler . update_claims_view ( & txn_matched, claimable_outpoints, Some ( height) , & & * broadcaster, & & * fee_estimator, & & * logger) ;
1780
1873
self . last_block_hash = block_hash;
1781
1874
1782
1875
// Determine new outputs to watch by comparing against previously known outputs to watch,
0 commit comments