@@ -364,7 +364,8 @@ impl OnchainEventEntry {
364364 // it's broadcastable when we see the previous block.
365365 conf_threshold = cmp:: max ( conf_threshold, self . height + descriptor. to_self_delay as u32 - 1 ) ;
366366 } ,
367- OnchainEvent :: FundingSpendConfirmation { on_local_output_csv : Some ( csv) , .. } => {
367+ OnchainEvent :: FundingSpendConfirmation { on_local_output_csv : Some ( csv) , .. } |
368+ OnchainEvent :: HTLCSpendConfirmation { on_to_local_output_csv : Some ( csv) , .. } => {
368369 // A CSV'd transaction is confirmable in block (input height) + CSV delay, which means
369370 // it's broadcastable when we see the previous block.
370371 conf_threshold = cmp:: max ( conf_threshold, self . height + csv as u32 - 1 ) ;
@@ -383,25 +384,47 @@ impl OnchainEventEntry {
383384/// once they mature to enough confirmations (ANTI_REORG_DELAY)
384385#[ derive( PartialEq ) ]
385386enum OnchainEvent {
386- /// HTLC output getting solved by a timeout, at maturation we pass upstream payment source information to solve
387- /// inbound HTLC in backward channel. Note, in case of preimage, we pass info to upstream without delay as we can
388- /// only win from it, so it's never an OnchainEvent
387+ /// An outbound HTLC failing after a transaction is confirmed. Used
388+ /// * when an outbound HTLC output is spent by us after the HTLC timed out
389+ /// * an outbound HTLC which was not present in the commitment transaction which appeared
390+ /// on-chain (either because it was not fully committed to or it was dust).
391+ /// Note that this is *not* used for preimage claims, as those are passed upstream immediately,
392+ /// appearing only as an `HTLCSpendConfirmation`, below.
389393 HTLCUpdate {
390394 source : HTLCSource ,
391395 payment_hash : PaymentHash ,
392396 onchain_value_satoshis : Option < u64 > ,
397+ /// None in the second case, above, ie when there is no relevant output in the commitment
398+ /// transaction which appeared on chain.
399+ input_idx : Option < u32 > ,
393400 } ,
394401 MaturingOutput {
395402 descriptor : SpendableOutputDescriptor ,
396403 } ,
397404 /// A spend of the funding output, either a commitment transaction or a cooperative closing
398405 /// transaction.
399406 FundingSpendConfirmation {
400- txid : Txid ,
401407 /// The CSV delay for the output of the funding spend transaction (implying it is a local
402408 /// commitment transaction, and this is the delay on the to_self output).
403409 on_local_output_csv : Option < u16 > ,
404410 } ,
411+ /// A spend of a commitment transaction HTLC output, set in the cases where *no* `HTLCUpdate`
412+ /// is constructed. This is used when
413+ /// * an outbound HTLC is claimed by our counterparty with a preimage, causing us to
414+ /// immediately claim the HTLC on the inbound edge and track the resolution here,
415+ /// * an inbound HTLC is claimed by our counterparty (with a timeout),
416+ /// * an inbound HTLC is claimed by us (with a preimage).
417+ /// * a revoked-state HTLC transaction was broadcasted, which was claimed by the revocation
418+ /// signature.
419+ HTLCSpendConfirmation {
420+ input_idx : u32 ,
421+ /// If the claim was made by either party with a preimage, this is filled in
422+ preimage : Option < PaymentPreimage > ,
423+ /// If the claim was made by us on an inbound HTLC against a local commitment transaction,
424+ /// we set this to the output CSV value which we will have to wait until to spend the
425+ /// output (and generate a SpendableOutput event).
426+ on_to_local_output_csv : Option < u16 > ,
427+ } ,
405428}
406429
407430impl Writeable for OnchainEventEntry {
@@ -438,14 +461,20 @@ impl_writeable_tlv_based_enum_upgradable!(OnchainEvent,
438461 ( 0 , source, required) ,
439462 ( 1 , onchain_value_satoshis, option) ,
440463 ( 2 , payment_hash, required) ,
464+ ( 3 , input_idx, option) ,
441465 } ,
442466 ( 1 , MaturingOutput ) => {
443467 ( 0 , descriptor, required) ,
444468 } ,
445469 ( 3 , FundingSpendConfirmation ) => {
446- ( 0 , txid, required) ,
447- ( 2 , on_local_output_csv, option) ,
470+ ( 0 , on_local_output_csv, option) ,
448471 } ,
472+ ( 5 , HTLCSpendConfirmation ) => {
473+ ( 0 , input_idx, required) ,
474+ ( 2 , preimage, option) ,
475+ ( 4 , on_to_local_output_csv, option) ,
476+ } ,
477+
449478) ;
450479
451480#[ cfg_attr( any( test, feature = "fuzztarget" , feature = "_test_utils" ) , derive( PartialEq ) ) ]
@@ -506,6 +535,19 @@ impl_writeable_tlv_based_enum_upgradable!(ChannelMonitorUpdateStep,
506535 } ,
507536) ;
508537
538+ /// An HTLC which has been irrevocably resolved on-chain, and has reached ANTI_REORG_DELAY.
539+ #[ derive( PartialEq ) ]
540+ struct IrrevocablyResolvedHTLC {
541+ input_idx : u32 ,
542+ /// Only set if the HTLC claim was ours using a payment preimage
543+ payment_preimage : Option < PaymentPreimage > ,
544+ }
545+
546+ impl_writeable_tlv_based ! ( IrrevocablyResolvedHTLC , {
547+ ( 0 , input_idx, required) ,
548+ ( 2 , payment_preimage, option) ,
549+ } ) ;
550+
509551/// A ChannelMonitor handles chain events (blocks connected and disconnected) and generates
510552/// on-chain transactions to ensure no loss of funds occurs.
511553///
@@ -619,6 +661,10 @@ pub(crate) struct ChannelMonitorImpl<Signer: Sign> {
619661 holder_tx_signed : bool ,
620662
621663 funding_spend_confirmed : Option < Txid > ,
664+ /// The set of HTLCs which have been either claimed or failed on chain and have reached
665+ /// the requisite confirmations on the claim/fail transaction (either ANTI_REORG_DELAY or the
666+ /// spending CSV for revocable outputs).
667+ htlcs_resolved_on_chain : Vec < IrrevocablyResolvedHTLC > ,
622668
623669 // We simply modify best_block in Channel's block_connected so that serialization is
624670 // consistent but hopefully the users' copy handles block_connected in a consistent way.
@@ -679,7 +725,8 @@ impl<Signer: Sign> PartialEq for ChannelMonitorImpl<Signer> {
679725 self . outputs_to_watch != other. outputs_to_watch ||
680726 self . lockdown_from_offchain != other. lockdown_from_offchain ||
681727 self . holder_tx_signed != other. holder_tx_signed ||
682- self . funding_spend_confirmed != other. funding_spend_confirmed
728+ self . funding_spend_confirmed != other. funding_spend_confirmed ||
729+ self . htlcs_resolved_on_chain != other. htlcs_resolved_on_chain
683730 {
684731 false
685732 } else {
@@ -846,6 +893,7 @@ impl<Signer: Sign> Writeable for ChannelMonitorImpl<Signer> {
846893
847894 write_tlv_fields ! ( writer, {
848895 ( 1 , self . funding_spend_confirmed, option) ,
896+ ( 3 , self . htlcs_resolved_on_chain, vec_type) ,
849897 } ) ;
850898
851899 Ok ( ( ) )
@@ -945,6 +993,7 @@ impl<Signer: Sign> ChannelMonitor<Signer> {
945993 lockdown_from_offchain : false ,
946994 holder_tx_signed : false ,
947995 funding_spend_confirmed : None ,
996+ htlcs_resolved_on_chain : Vec :: new ( ) ,
948997
949998 best_block,
950999
@@ -1311,6 +1360,7 @@ macro_rules! fail_unbroadcast_htlcs {
13111360 source: ( * * source) . clone( ) ,
13121361 payment_hash: htlc. payment_hash. clone( ) ,
13131362 onchain_value_satoshis: Some ( htlc. amount_msat / 1000 ) ,
1363+ input_idx: None ,
13141364 } ,
13151365 } ;
13161366 log_trace!( $logger, "Failing HTLC with payment_hash {} from {} counterparty commitment tx due to broadcast of {} commitment transaction, waiting for confirmation (at height {})" ,
@@ -2024,7 +2074,6 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
20242074 txid,
20252075 height : height,
20262076 event : OnchainEvent :: FundingSpendConfirmation {
2027- txid,
20282077 on_local_output_csv : balance_spendable_csv,
20292078 } ,
20302079 } ) ;
@@ -2115,8 +2164,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21152164 . iter ( )
21162165 . filter_map ( |entry| match & entry. event {
21172166 OnchainEvent :: HTLCUpdate { source, .. } => Some ( source) ,
2118- OnchainEvent :: MaturingOutput { .. } => None ,
2119- OnchainEvent :: FundingSpendConfirmation { .. } => None ,
2167+ _ => None ,
21202168 } )
21212169 . collect ( ) ;
21222170 #[ cfg( debug_assertions) ]
@@ -2125,7 +2173,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21252173 // Produce actionable events from on-chain events having reached their threshold.
21262174 for entry in onchain_events_reaching_threshold_conf. drain ( ..) {
21272175 match entry. event {
2128- OnchainEvent :: HTLCUpdate { ref source, payment_hash, onchain_value_satoshis } => {
2176+ OnchainEvent :: HTLCUpdate { ref source, payment_hash, onchain_value_satoshis, input_idx } => {
21292177 // Check for duplicate HTLC resolutions.
21302178 #[ cfg( debug_assertions) ]
21312179 {
@@ -2149,15 +2197,21 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
21492197 source : source. clone ( ) ,
21502198 onchain_value_satoshis,
21512199 } ) ) ;
2200+ if let Some ( idx) = input_idx {
2201+ self . htlcs_resolved_on_chain . push ( IrrevocablyResolvedHTLC { input_idx : idx, payment_preimage : None } ) ;
2202+ }
21522203 } ,
21532204 OnchainEvent :: MaturingOutput { descriptor } => {
21542205 log_debug ! ( logger, "Descriptor {} has got enough confirmations to be passed upstream" , log_spendable!( descriptor) ) ;
21552206 self . pending_events . push ( Event :: SpendableOutputs {
21562207 outputs : vec ! [ descriptor]
21572208 } ) ;
21582209 } ,
2159- OnchainEvent :: FundingSpendConfirmation { txid, .. } => {
2160- self . funding_spend_confirmed = Some ( txid) ;
2210+ OnchainEvent :: HTLCSpendConfirmation { input_idx, preimage, .. } => {
2211+ self . htlcs_resolved_on_chain . push ( IrrevocablyResolvedHTLC { input_idx, payment_preimage : preimage } ) ;
2212+ } ,
2213+ OnchainEvent :: FundingSpendConfirmation { .. } => {
2214+ self . funding_spend_confirmed = Some ( entry. txid ) ;
21612215 } ,
21622216 }
21632217 }
@@ -2336,15 +2390,32 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23362390 let revocation_sig_claim = ( input. witness . len ( ) == 3 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 2 ] . len ( ) ) == Some ( HTLCType :: OfferedHTLC ) && input. witness [ 1 ] . len ( ) == 33 )
23372391 || ( input. witness . len ( ) == 3 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 2 ] . len ( ) ) == Some ( HTLCType :: AcceptedHTLC ) && input. witness [ 1 ] . len ( ) == 33 ) ;
23382392 let accepted_preimage_claim = input. witness . len ( ) == 5 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 4 ] . len ( ) ) == Some ( HTLCType :: AcceptedHTLC ) ;
2339- let offered_preimage_claim = input. witness . len ( ) == 3 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 2 ] . len ( ) ) == Some ( HTLCType :: OfferedHTLC ) ;
2393+ let accepted_timeout_claim = input. witness . len ( ) == 3 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 2 ] . len ( ) ) == Some ( HTLCType :: AcceptedHTLC ) && !revocation_sig_claim;
2394+ let offered_preimage_claim = input. witness . len ( ) == 3 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 2 ] . len ( ) ) == Some ( HTLCType :: OfferedHTLC ) && !revocation_sig_claim;
2395+ let offered_timeout_claim = input. witness . len ( ) == 5 && HTLCType :: scriptlen_to_htlctype ( input. witness [ 4 ] . len ( ) ) == Some ( HTLCType :: OfferedHTLC ) ;
2396+
2397+ let mut payment_preimage = PaymentPreimage ( [ 0 ; 32 ] ) ;
2398+ if accepted_preimage_claim {
2399+ payment_preimage. 0 . copy_from_slice ( & input. witness [ 3 ] ) ;
2400+ } else if offered_preimage_claim {
2401+ payment_preimage. 0 . copy_from_slice ( & input. witness [ 1 ] ) ;
2402+ }
23402403
23412404 macro_rules! log_claim {
23422405 ( $tx_info: expr, $holder_tx: expr, $htlc: expr, $source_avail: expr) => {
2343- // We found the output in question, but aren't failing it backwards
2344- // as we have no corresponding source and no valid counterparty commitment txid
2345- // to try a weak source binding with same-hash, same-value still-valid offered HTLC.
2346- // This implies either it is an inbound HTLC or an outbound HTLC on a revoked transaction.
23472406 let outbound_htlc = $holder_tx == $htlc. offered;
2407+ // HTLCs must either be claimed by a matching script type or through the
2408+ // revocation path:
2409+ #[ cfg( not( fuzzing) ) ] // Note that the fuzzer is not bound by pesky things like "signatures"
2410+ debug_assert!( !$htlc. offered || offered_preimage_claim || offered_timeout_claim || revocation_sig_claim) ;
2411+ #[ cfg( not( fuzzing) ) ] // Note that the fuzzer is not bound by pesky things like "signatures"
2412+ debug_assert!( $htlc. offered || accepted_preimage_claim || accepted_timeout_claim || revocation_sig_claim) ;
2413+ // Further, only exactly one of the possible spend paths should have been
2414+ // matched by any HTLC spend:
2415+ #[ cfg( not( fuzzing) ) ] // Note that the fuzzer is not bound by pesky things like "signatures"
2416+ debug_assert_eq!( accepted_preimage_claim as u8 + accepted_timeout_claim as u8 +
2417+ offered_preimage_claim as u8 + offered_timeout_claim as u8 +
2418+ revocation_sig_claim as u8 , 1 ) ;
23482419 if ( $holder_tx && revocation_sig_claim) ||
23492420 ( outbound_htlc && !$source_avail && ( accepted_preimage_claim || offered_preimage_claim) ) {
23502421 log_error!( logger, "Input spending {} ({}:{}) in {} resolves {} HTLC with payment hash {} with {}!" ,
@@ -2396,6 +2467,30 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
23962467 }
23972468 if payment_data. is_none( ) {
23982469 log_claim!( $tx_info, $holder_tx, htlc_output, false ) ;
2470+ let outbound_htlc = $holder_tx == htlc_output. offered;
2471+ if !outbound_htlc || revocation_sig_claim {
2472+ self . onchain_events_awaiting_threshold_conf. push( OnchainEventEntry {
2473+ txid: tx. txid( ) , height,
2474+ event: OnchainEvent :: HTLCSpendConfirmation {
2475+ input_idx: input. previous_output. vout,
2476+ preimage: if accepted_preimage_claim || offered_preimage_claim {
2477+ Some ( payment_preimage) } else { None } ,
2478+ // If this is a payment to us (!outbound_htlc, above),
2479+ // wait for the CSV delay before dropping the HTLC from
2480+ // claimable balance if the claim was an HTLC-Success
2481+ // transaction.
2482+ on_to_local_output_csv: if accepted_preimage_claim {
2483+ Some ( self . on_holder_tx_csv) } else { None } ,
2484+ } ,
2485+ } ) ;
2486+ } else {
2487+ // Outbound claims should always have payment_data, unless
2488+ // we've already failed the HTLC as the commitment transaction
2489+ // which was broadcasted was revoked. In that case, we should
2490+ // spend the HTLC output here immediately, and expose that fact
2491+ // as a ClaimableBalance, something which we do not yet do.
2492+ // TODO: Track the above as claimable!
2493+ }
23992494 continue ' outer_loop;
24002495 }
24012496 }
@@ -2421,11 +2516,18 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
24212516 // Check that scan_commitment, above, decided there is some source worth relaying an
24222517 // HTLC resolution backwards to and figure out whether we learned a preimage from it.
24232518 if let Some ( ( source, payment_hash, amount_msat) ) = payment_data {
2424- let mut payment_preimage = PaymentPreimage ( [ 0 ; 32 ] ) ;
24252519 if accepted_preimage_claim {
24262520 if !self . pending_monitor_events . iter ( ) . any (
24272521 |update| if let & MonitorEvent :: HTLCEvent ( ref upd) = update { upd. source == source } else { false } ) {
2428- payment_preimage. 0 . copy_from_slice ( & input. witness [ 3 ] ) ;
2522+ self . onchain_events_awaiting_threshold_conf . push ( OnchainEventEntry {
2523+ txid : tx. txid ( ) ,
2524+ height,
2525+ event : OnchainEvent :: HTLCSpendConfirmation {
2526+ input_idx : input. previous_output . vout ,
2527+ preimage : Some ( payment_preimage) ,
2528+ on_to_local_output_csv : None ,
2529+ } ,
2530+ } ) ;
24292531 self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
24302532 source,
24312533 payment_preimage : Some ( payment_preimage) ,
@@ -2438,7 +2540,15 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
24382540 |update| if let & MonitorEvent :: HTLCEvent ( ref upd) = update {
24392541 upd. source == source
24402542 } else { false } ) {
2441- payment_preimage. 0 . copy_from_slice ( & input. witness [ 1 ] ) ;
2543+ self . onchain_events_awaiting_threshold_conf . push ( OnchainEventEntry {
2544+ txid : tx. txid ( ) ,
2545+ height,
2546+ event : OnchainEvent :: HTLCSpendConfirmation {
2547+ input_idx : input. previous_output . vout ,
2548+ preimage : Some ( payment_preimage) ,
2549+ on_to_local_output_csv : None ,
2550+ } ,
2551+ } ) ;
24422552 self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
24432553 source,
24442554 payment_preimage : Some ( payment_preimage) ,
@@ -2462,6 +2572,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
24622572 event : OnchainEvent :: HTLCUpdate {
24632573 source, payment_hash,
24642574 onchain_value_satoshis : Some ( amount_msat / 1000 ) ,
2575+ input_idx : Some ( input. previous_output . vout ) ,
24652576 } ,
24662577 } ;
24672578 log_info ! ( logger, "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height {})" , log_bytes!( payment_hash. 0 ) , entry. confirmation_threshold( ) ) ;
@@ -2834,8 +2945,10 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
28342945 }
28352946
28362947 let mut funding_spend_confirmed = None ;
2948+ let mut htlcs_resolved_on_chain = Some ( Vec :: new ( ) ) ;
28372949 read_tlv_fields ! ( reader, {
28382950 ( 1 , funding_spend_confirmed, option) ,
2951+ ( 3 , htlcs_resolved_on_chain, vec_type) ,
28392952 } ) ;
28402953
28412954 let mut secp_ctx = Secp256k1 :: new ( ) ;
@@ -2886,6 +2999,7 @@ impl<'a, Signer: Sign, K: KeysInterface<Signer = Signer>> ReadableArgs<&'a K>
28862999 lockdown_from_offchain,
28873000 holder_tx_signed,
28883001 funding_spend_confirmed,
3002+ htlcs_resolved_on_chain : htlcs_resolved_on_chain. unwrap ( ) ,
28893003
28903004 best_block,
28913005
0 commit comments