@@ -3464,7 +3464,16 @@ fn test_lost_preimage_monitor_events() {
34643464 do_test_lost_preimage_monitor_events ( false ) ;
34653465}
34663466
3467- fn do_test_lost_timeout_monitor_events ( on_counterparty_tx : bool , dust_htlcs : bool ) {
3467+ #[ derive( PartialEq ) ]
3468+ enum CommitmentType {
3469+ RevokedCounterparty ,
3470+ LatestCounterparty ,
3471+ PreviousCounterparty ,
3472+ LocalWithoutLastHTLC ,
3473+ LocalWithLastHTLC ,
3474+ }
3475+
3476+ fn do_test_lost_timeout_monitor_events ( confirm_tx : CommitmentType , dust_htlcs : bool ) {
34683477 // `MonitorEvent`s aren't delivered to the `ChannelManager` in a durable fasion - if the
34693478 // `ChannelManager` fetches the pending `MonitorEvent`s, then the `ChannelMonitor` gets
34703479 // persisted (i.e. due to a block update) then the node crashes, prior to persisting the
@@ -3511,9 +3520,37 @@ fn do_test_lost_timeout_monitor_events(on_counterparty_tx: bool, dust_htlcs: boo
35113520
35123521 send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , 25_000_000 ) ;
35133522
3523+ let cs_revoked_commit = get_local_commitment_txn ! ( nodes[ 2 ] , chan_b) ;
3524+ assert_eq ! ( cs_revoked_commit. len( ) , 1 ) ;
3525+
35143526 let amt = if dust_htlcs { 1_000 } else { 10_000_000 } ;
35153527 let ( _, hash_a, ..) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , amt) ;
3516- let ( _, hash_b, ..) = route_payment ( & nodes[ 1 ] , & [ & nodes[ 2 ] ] , amt) ;
3528+
3529+ let cs_previous_commit = get_local_commitment_txn ! ( nodes[ 2 ] , chan_b) ;
3530+ assert_eq ! ( cs_previous_commit. len( ) , 1 ) ;
3531+
3532+ let ( route, hash_b, _, payment_secret_b) =
3533+ get_route_and_payment_hash ! ( nodes[ 1 ] , nodes[ 2 ] , amt) ;
3534+ let onion = RecipientOnionFields :: secret_only ( payment_secret_b) ;
3535+ nodes[ 1 ] . node . send_payment_with_route ( route, hash_b, onion, PaymentId ( hash_b. 0 ) ) . unwrap ( ) ;
3536+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
3537+
3538+ let updates = get_htlc_update_msgs ( & nodes[ 1 ] , & node_c_id) ;
3539+ nodes[ 2 ] . node . handle_update_add_htlc ( node_b_id, & updates. update_add_htlcs [ 0 ] ) ;
3540+ nodes[ 2 ] . node . handle_commitment_signed_batch_test ( node_b_id, & updates. commitment_signed ) ;
3541+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
3542+
3543+ let ( cs_raa, cs_cs) = get_revoke_commit_msgs ! ( nodes[ 2 ] , node_b_id) ;
3544+ if confirm_tx == CommitmentType :: LocalWithLastHTLC {
3545+ // Only deliver the last RAA + CS if we need to update the local commitment with the third
3546+ // HTLC.
3547+ nodes[ 1 ] . node . handle_revoke_and_ack ( node_c_id, & cs_raa) ;
3548+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
3549+ nodes[ 1 ] . node . handle_commitment_signed_batch_test ( node_c_id, & cs_cs) ;
3550+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
3551+
3552+ let _bs_raa = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendRevokeAndACK , node_c_id) ;
3553+ }
35173554
35183555 nodes[ 1 ] . node . peer_disconnected ( nodes[ 2 ] . node . get_our_node_id ( ) ) ;
35193556 nodes[ 2 ] . node . peer_disconnected ( nodes[ 1 ] . node . get_our_node_id ( ) ) ;
@@ -3547,44 +3584,68 @@ fn do_test_lost_timeout_monitor_events(on_counterparty_tx: bool, dust_htlcs: boo
35473584 let bs_commit_tx = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
35483585 assert_eq ! ( bs_commit_tx. len( ) , 1 ) ;
35493586
3550- let selected_commit_tx = if on_counterparty_tx {
3551- & cs_commit_tx[ 0 ]
3552- } else {
3553- & bs_commit_tx[ 0 ]
3587+ let selected_commit_tx = match confirm_tx {
3588+ CommitmentType :: RevokedCounterparty => & cs_revoked_commit[ 0 ] ,
3589+ CommitmentType :: PreviousCounterparty => & cs_previous_commit[ 0 ] ,
3590+ CommitmentType :: LatestCounterparty => & cs_commit_tx[ 0 ] ,
3591+ CommitmentType :: LocalWithoutLastHTLC |CommitmentType :: LocalWithLastHTLC => & bs_commit_tx[ 0 ] ,
35543592 } ;
35553593
35563594 mine_transaction ( & nodes[ 1 ] , selected_commit_tx) ;
35573595 // If the block gets connected first we may re-broadcast B's commitment transaction before
3558- // seeing the C's confirm.
3559- nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clear ( ) ;
3596+ // seeing the C's confirm. In any case, if we confirmed the revoked counterparty commitment
3597+ // transaction, we want to go ahead and confirm the spend of it.
3598+ let bs_transactions = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
3599+ if confirm_tx == CommitmentType :: RevokedCounterparty {
3600+ assert ! ( bs_transactions. len( ) == 1 || bs_transactions. len( ) == 2 ) ;
3601+ mine_transaction ( & nodes[ 1 ] , bs_transactions. last ( ) . unwrap ( ) ) ;
3602+ } else {
3603+ assert ! ( bs_transactions. len( ) == 1 || bs_transactions. len( ) == 0 ) ;
3604+ }
3605+
35603606 connect_blocks ( & nodes[ 1 ] , ANTI_REORG_DELAY - 1 ) ;
35613607 let mut events = nodes[ 1 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
3562- if on_counterparty_tx {
3563- assert_eq ! ( events. len( ) , 1 , "{events:?}" ) ;
3564- match events[ 0 ] {
3565- Event :: SpendableOutputs { .. } => { } ,
3566- _ => panic ! ( "Unexpected event {events:?}" ) ,
3567- }
3568- } else {
3569- assert_eq ! ( events. len( ) , 0 ) ;
3608+ match confirm_tx {
3609+ CommitmentType :: LocalWithoutLastHTLC |CommitmentType :: LocalWithLastHTLC => {
3610+ assert_eq ! ( events. len( ) , 0 , "{events:?}" ) ;
3611+ } ,
3612+ CommitmentType :: PreviousCounterparty |CommitmentType :: LatestCounterparty => {
3613+ assert_eq ! ( events. len( ) , 1 , "{events:?}" ) ;
3614+ match events[ 0 ] {
3615+ Event :: SpendableOutputs { .. } => { } ,
3616+ _ => panic ! ( "Unexpected event {events:?}" ) ,
3617+ }
3618+ } ,
3619+ CommitmentType :: RevokedCounterparty => {
3620+ assert_eq ! ( events. len( ) , 2 , "{events:?}" ) ;
3621+ for event in events {
3622+ match event {
3623+ Event :: SpendableOutputs { .. } => { } ,
3624+ _ => panic ! ( "Unexpected event {event:?}" ) ,
3625+ }
3626+ }
3627+ } ,
35703628 }
35713629
3572- connect_blocks ( & nodes[ 1 ] , TEST_FINAL_CLTV - ANTI_REORG_DELAY + 1 ) ;
3573- if !on_counterparty_tx {
3574- if !dust_htlcs {
3575- handle_bump_events ( & nodes[ 1 ] , false , 1 ) ;
3630+ if confirm_tx != CommitmentType :: RevokedCounterparty {
3631+ connect_blocks ( & nodes[ 1 ] , TEST_FINAL_CLTV - ANTI_REORG_DELAY + 1 ) ;
3632+ if confirm_tx == CommitmentType :: LocalWithoutLastHTLC || confirm_tx == CommitmentType :: LocalWithLastHTLC {
3633+ if !dust_htlcs {
3634+ handle_bump_events ( & nodes[ 1 ] , false , 1 ) ;
3635+ }
35763636 }
35773637 }
3638+
35783639 let bs_htlc_timeouts =
35793640 nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
3580- if dust_htlcs {
3641+ if dust_htlcs || confirm_tx == CommitmentType :: RevokedCounterparty {
35813642 assert_eq ! ( bs_htlc_timeouts. len( ) , 0 ) ;
35823643 } else {
35833644 assert_eq ! ( bs_htlc_timeouts. len( ) , 1 ) ;
35843645
35853646 // Now replay the timeouts on node B, which after 6 confirmations should fail the HTLCs via
35863647 // `MonitorUpdate`s
3587- mine_transactions ( & nodes[ 1 ] , & bs_htlc_timeouts. iter ( ) . collect :: < Vec < _ > > ( ) ) ;
3648+ mine_transaction ( & nodes[ 1 ] , & bs_htlc_timeouts[ 0 ] ) ;
35883649 connect_blocks ( & nodes[ 1 ] , ANTI_REORG_DELAY - 1 ) ;
35893650 }
35903651
@@ -3637,8 +3698,14 @@ fn do_test_lost_timeout_monitor_events(on_counterparty_tx: bool, dust_htlcs: boo
36373698
36383699#[ test]
36393700fn test_lost_timeout_monitor_events ( ) {
3640- do_test_lost_timeout_monitor_events ( true , false ) ;
3641- do_test_lost_timeout_monitor_events ( false , false ) ;
3642- do_test_lost_timeout_monitor_events ( true , true ) ;
3643- do_test_lost_timeout_monitor_events ( false , true ) ;
3701+ do_test_lost_timeout_monitor_events ( CommitmentType :: RevokedCounterparty , false ) ;
3702+ do_test_lost_timeout_monitor_events ( CommitmentType :: RevokedCounterparty , true ) ;
3703+ do_test_lost_timeout_monitor_events ( CommitmentType :: PreviousCounterparty , false ) ;
3704+ do_test_lost_timeout_monitor_events ( CommitmentType :: PreviousCounterparty , true ) ;
3705+ do_test_lost_timeout_monitor_events ( CommitmentType :: LatestCounterparty , false ) ;
3706+ do_test_lost_timeout_monitor_events ( CommitmentType :: LatestCounterparty , true ) ;
3707+ do_test_lost_timeout_monitor_events ( CommitmentType :: LocalWithoutLastHTLC , false ) ;
3708+ do_test_lost_timeout_monitor_events ( CommitmentType :: LocalWithoutLastHTLC , true ) ;
3709+ do_test_lost_timeout_monitor_events ( CommitmentType :: LocalWithLastHTLC , false ) ;
3710+ do_test_lost_timeout_monitor_events ( CommitmentType :: LocalWithLastHTLC , true ) ;
36443711}
0 commit comments