@@ -3713,3 +3713,110 @@ fn test_partial_claim_mon_update_compl_actions() {
3713
3713
send_payment ( & nodes[ 2 ] , & [ & nodes[ 3 ] ] , 100_000 ) ;
3714
3714
assert ! ( !get_monitor!( nodes[ 3 ] , chan_4_id) . get_stored_preimages( ) . contains_key( & payment_hash) ) ;
3715
3715
}
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