@@ -3713,3 +3713,110 @@ fn test_partial_claim_mon_update_compl_actions() {
37133713 send_payment ( & nodes[ 2 ] , & [ & nodes[ 3 ] ] , 100_000 ) ;
37143714 assert ! ( !get_monitor!( nodes[ 3 ] , chan_4_id) . get_stored_preimages( ) . contains_key( & payment_hash) ) ;
37153715}
3716+
3717+
3718+ #[ test]
3719+ fn test_claim_to_closed_channel_blocks_forwarded_preimage_removal ( ) {
3720+ // One of the last features for async persistence we implemented was the correct blocking of
3721+ // RAA(s) which remove a preimage from an outbound channel for a forwarded payment until the
3722+ // preimage write makes it durably to the closed inbound channel.
3723+ // This tests that behavior.
3724+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
3725+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
3726+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
3727+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
3728+
3729+ // First open channels, route a payment, and force-close the first hop.
3730+ let chan_a = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 500_000_000 ) ;
3731+ let chan_b = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 500_000_000 ) ;
3732+
3733+ let ( payment_preimage, payment_hash, ..) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , 1_000_000 ) ;
3734+
3735+ nodes[ 0 ] . node . force_close_broadcasting_latest_txn ( & chan_a. 2 , & nodes[ 1 ] . node . get_our_node_id ( ) , String :: new ( ) ) . unwrap ( ) ;
3736+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
3737+ let a_reason = ClosureReason :: HolderForceClosed { broadcasted_latest_txn : Some ( true ) } ;
3738+ check_closed_event ! ( nodes[ 0 ] , 1 , a_reason, [ nodes[ 1 ] . node. get_our_node_id( ) ] , 1000000 ) ;
3739+ check_closed_broadcast ! ( nodes[ 0 ] , true ) ;
3740+
3741+ let as_commit_tx = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
3742+ assert_eq ! ( as_commit_tx. len( ) , 1 ) ;
3743+
3744+ mine_transaction ( & nodes[ 1 ] , & as_commit_tx[ 0 ] ) ;
3745+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3746+ check_closed_event ! ( nodes[ 1 ] , 1 , ClosureReason :: CommitmentTxConfirmed , [ nodes[ 0 ] . node. get_our_node_id( ) ] , 1000000 ) ;
3747+ check_closed_broadcast ! ( nodes[ 1 ] , true ) ;
3748+
3749+ // Now that B has a pending forwarded payment across it with the inbound edge on-chain, claim
3750+ // the payment on C and give B the preimage for it.
3751+ nodes[ 2 ] . node . claim_funds ( payment_preimage) ;
3752+ check_added_monitors ! ( nodes[ 2 ] , 1 ) ;
3753+ expect_payment_claimed ! ( nodes[ 2 ] , payment_hash, 1_000_000 ) ;
3754+
3755+ let updates = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
3756+ chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: InProgress ) ;
3757+ nodes[ 1 ] . node . handle_update_fulfill_htlc ( nodes[ 2 ] . node . get_our_node_id ( ) , & updates. update_fulfill_htlcs [ 0 ] ) ;
3758+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3759+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 2 ] , updates. commitment_signed, false ) ;
3760+
3761+ // At this point nodes[1] has the preimage and is waiting for the `ChannelMonitorUpdate` for
3762+ // channel A to hit disk. Until it does so, it shouldn't ever let the preimage dissapear from
3763+ // channel B's `ChannelMonitor`
3764+ assert ! ( get_monitor!( nodes[ 1 ] , chan_b. 2 ) . get_all_current_outbound_htlcs( ) . iter( ) . any( |( _, ( _, preimage) ) | * preimage == Some ( payment_preimage) ) ) ;
3765+
3766+ // Once we complete the `ChannelMonitorUpdate` on channel A, and the `ChannelManager` processes
3767+ // background events (via `get_and_clear_pending_msg_events`), the final `ChannelMonitorUpdate`
3768+ // will fly and we'll drop the preimage from channel B's `ChannelMonitor`. We'll also release
3769+ // the `Event::PaymentForwarded`.
3770+ check_added_monitors ! ( nodes[ 1 ] , 0 ) ;
3771+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
3772+
3773+ nodes[ 1 ] . chain_monitor . complete_sole_pending_chan_update ( & chan_a. 2 ) ;
3774+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
3775+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3776+ assert ! ( !get_monitor!( nodes[ 1 ] , chan_b. 2 ) . get_all_current_outbound_htlcs( ) . iter( ) . any( |( _, ( _, preimage) ) | * preimage == Some ( payment_preimage) ) ) ;
3777+ expect_payment_forwarded ! ( nodes[ 1 ] , nodes[ 0 ] , nodes[ 2 ] , None , true , false ) ;
3778+ }
3779+
3780+ #[ test]
3781+ fn test_claim_to_closed_channel_blocks_claimed_event ( ) {
3782+ // One of the last features for async persistence we implemented was the correct blocking of
3783+ // event(s) until the preimage for a claimed HTLC is durably on disk in a ChannelMonitor for a
3784+ // closed channel.
3785+ // This tests that behavior.
3786+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
3787+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
3788+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
3789+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
3790+
3791+ // First open channels, route a payment, and force-close the first hop.
3792+ let chan_a = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 500_000_000 ) ;
3793+
3794+ let ( payment_preimage, payment_hash, ..) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1_000_000 ) ;
3795+
3796+ nodes[ 0 ] . node . force_close_broadcasting_latest_txn ( & chan_a. 2 , & nodes[ 1 ] . node . get_our_node_id ( ) , String :: new ( ) ) . unwrap ( ) ;
3797+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
3798+ let a_reason = ClosureReason :: HolderForceClosed { broadcasted_latest_txn : Some ( true ) } ;
3799+ check_closed_event ! ( nodes[ 0 ] , 1 , a_reason, [ nodes[ 1 ] . node. get_our_node_id( ) ] , 1000000 ) ;
3800+ check_closed_broadcast ! ( nodes[ 0 ] , true ) ;
3801+
3802+ let as_commit_tx = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
3803+ assert_eq ! ( as_commit_tx. len( ) , 1 ) ;
3804+
3805+ mine_transaction ( & nodes[ 1 ] , & as_commit_tx[ 0 ] ) ;
3806+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3807+ check_closed_event ! ( nodes[ 1 ] , 1 , ClosureReason :: CommitmentTxConfirmed , [ nodes[ 0 ] . node. get_our_node_id( ) ] , 1000000 ) ;
3808+ check_closed_broadcast ! ( nodes[ 1 ] , true ) ;
3809+
3810+ // Now that B has a pending payment with the inbound HTLC on a closed channel, claim the
3811+ // payment on disk, but don't let the `ChannelMonitorUpdate` complete. This should prevent the
3812+ // `Event::PaymentClaimed` from being generated.
3813+ chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: InProgress ) ;
3814+ nodes[ 1 ] . node . claim_funds ( payment_preimage) ;
3815+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
3816+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_events( ) . is_empty( ) ) ;
3817+
3818+ // Once we complete the `ChannelMonitorUpdate` the `Event::PaymentClaimed` will become
3819+ // available.
3820+ nodes[ 1 ] . chain_monitor . complete_sole_pending_chan_update ( & chan_a. 2 ) ;
3821+ expect_payment_claimed ! ( nodes[ 1 ] , payment_hash, 1_000_000 ) ;
3822+ }
0 commit comments