@@ -2653,3 +2653,99 @@ fn test_permanent_error_during_handling_shutdown() {
26532653 check_closed_broadcast ! ( nodes[ 1 ] , true ) ;
26542654 check_added_monitors ! ( nodes[ 1 ] , 2 ) ;
26552655}
2656+
2657+ #[ test]
2658+ fn test_double_temp_error ( ) {
2659+ // Test that it's OK to have multiple `ChainMonitor::update_channel` calls fail in a row.
2660+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2661+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2662+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
2663+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2664+
2665+ let ( _, _, channel_id, _) = create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
2666+
2667+ let ( payment_preimage_1, _, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
2668+ let ( payment_preimage_2, _, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 1000000 ) ;
2669+
2670+ * nodes[ 1 ] . chain_monitor . update_ret . lock ( ) . unwrap ( ) = Some ( Err ( ChannelMonitorUpdateErr :: TemporaryFailure ) ) ;
2671+ // `claim_funds` results in a ChannelMonitorUpdate.
2672+ assert ! ( nodes[ 1 ] . node. claim_funds( payment_preimage_1) ) ;
2673+ let ( funding_tx, latest_update_1) = nodes[ 1 ] . chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & channel_id) . unwrap ( ) . clone ( ) ;
2674+
2675+ * nodes[ 1 ] . chain_monitor . update_ret . lock ( ) . unwrap ( ) = Some ( Err ( ChannelMonitorUpdateErr :: TemporaryFailure ) ) ;
2676+ // Previously, this would've panicked due to a double-call to `Channel::monitor_update_failed`,
2677+ // which had some asserts that prevented it from being called twice.
2678+ assert ! ( nodes[ 1 ] . node. claim_funds( payment_preimage_2) ) ;
2679+ * nodes[ 1 ] . chain_monitor . update_ret . lock ( ) . unwrap ( ) = Some ( Ok ( ( ) ) ) ;
2680+
2681+ let ( _, latest_update_2) = nodes[ 1 ] . chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & channel_id) . unwrap ( ) . clone ( ) ;
2682+ // TODO: should one of these `channel_monitor_updated` calls be omitted?
2683+ nodes[ 1 ] . node . channel_monitor_updated ( & funding_tx, latest_update_1) ;
2684+ check_added_monitors ! ( nodes[ 1 ] , 2 ) ;
2685+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
2686+ nodes[ 1 ] . node . channel_monitor_updated ( & funding_tx, latest_update_2) ;
2687+
2688+ // Complete the first HTLC.
2689+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2690+ assert_eq ! ( events. len( ) , 1 ) ;
2691+ let ( update_fulfill_1, commitment_signed_b1, node_id) = {
2692+ match & events[ 0 ] {
2693+ & MessageSendEvent :: UpdateHTLCs { ref node_id, updates : msgs:: CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
2694+ assert ! ( update_add_htlcs. is_empty( ) ) ;
2695+ assert_eq ! ( update_fulfill_htlcs. len( ) , 1 ) ;
2696+ assert ! ( update_fail_htlcs. is_empty( ) ) ;
2697+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
2698+ assert ! ( update_fee. is_none( ) ) ;
2699+ ( update_fulfill_htlcs[ 0 ] . clone ( ) , commitment_signed. clone ( ) , node_id. clone ( ) )
2700+ } ,
2701+ _ => panic ! ( "Unexpected event" ) ,
2702+ }
2703+ } ;
2704+ assert_eq ! ( node_id, nodes[ 0 ] . node. get_our_node_id( ) ) ;
2705+ nodes[ 0 ] . node . handle_update_fulfill_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & update_fulfill_1) ;
2706+ check_added_monitors ! ( nodes[ 0 ] , 0 ) ;
2707+ expect_payment_sent ! ( nodes[ 0 ] , payment_preimage_1) ;
2708+ nodes[ 0 ] . node . handle_commitment_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) , & commitment_signed_b1) ;
2709+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2710+ nodes[ 0 ] . node . process_pending_htlc_forwards ( ) ;
2711+ let ( raa_a1, commitment_signed_a1) = get_revoke_commit_msgs ! ( nodes[ 0 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
2712+ check_added_monitors ! ( nodes[ 1 ] , 0 ) ;
2713+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
2714+ nodes[ 1 ] . node . handle_revoke_and_ack ( & nodes[ 0 ] . node . get_our_node_id ( ) , & raa_a1) ;
2715+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2716+ nodes[ 1 ] . node . handle_commitment_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) , & commitment_signed_a1) ;
2717+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2718+
2719+ // Complete the second HTLC.
2720+ let ( ( update_fulfill_2, commitment_signed_b2) , raa_b2) = {
2721+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
2722+ assert_eq ! ( events. len( ) , 2 ) ;
2723+ ( match & events[ 0 ] {
2724+ MessageSendEvent :: UpdateHTLCs { node_id, updates } => {
2725+ assert_eq ! ( * node_id, nodes[ 0 ] . node. get_our_node_id( ) ) ;
2726+ assert ! ( updates. update_add_htlcs. is_empty( ) ) ;
2727+ assert ! ( updates. update_fail_htlcs. is_empty( ) ) ;
2728+ assert ! ( updates. update_fail_malformed_htlcs. is_empty( ) ) ;
2729+ assert ! ( updates. update_fee. is_none( ) ) ;
2730+ assert_eq ! ( updates. update_fulfill_htlcs. len( ) , 1 ) ;
2731+ ( updates. update_fulfill_htlcs [ 0 ] . clone ( ) , updates. commitment_signed . clone ( ) )
2732+ } ,
2733+ _ => panic ! ( "Unexpected event" ) ,
2734+ } ,
2735+ match events[ 1 ] {
2736+ MessageSendEvent :: SendRevokeAndACK { ref node_id, ref msg } => {
2737+ assert_eq ! ( * node_id, nodes[ 0 ] . node. get_our_node_id( ) ) ;
2738+ ( * msg) . clone ( )
2739+ } ,
2740+ _ => panic ! ( "Unexpected event" ) ,
2741+ } )
2742+ } ;
2743+ nodes[ 0 ] . node . handle_revoke_and_ack ( & nodes[ 1 ] . node . get_our_node_id ( ) , & raa_b2) ;
2744+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2745+
2746+ nodes[ 0 ] . node . handle_update_fulfill_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & update_fulfill_2) ;
2747+ check_added_monitors ! ( nodes[ 0 ] , 0 ) ;
2748+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
2749+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , commitment_signed_b2, false ) ;
2750+ expect_payment_sent ! ( nodes[ 0 ] , payment_preimage_2) ;
2751+ }
0 commit comments