@@ -1258,6 +1258,64 @@ fn do_manager_persisted_pre_outbound_edge_forward(intercept_htlc: bool) {
12581258 expect_payment_sent ( & nodes[ 0 ] , payment_preimage, None , true , true ) ;
12591259}
12601260
1261+ #[ test]
1262+ fn test_manager_persisted_post_outbound_edge_forward ( ) {
1263+ // Test that we will not double-forward an HTLC after restart if it has already been forwarded to
1264+ // the outbound edge, which was previously broken.
1265+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
1266+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
1267+ let persister;
1268+ let new_chain_monitor;
1269+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
1270+ let nodes_1_deserialized;
1271+ let mut nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
1272+
1273+ let chan_id_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 2 ;
1274+ let chan_id_2 = create_announced_chan_between_nodes ( & nodes, 1 , 2 ) . 2 ;
1275+
1276+ // Lock in the HTLC from node_a <> node_b.
1277+ let amt_msat = 5000 ;
1278+ let ( mut route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 2 ] , amt_msat) ;
1279+ nodes[ 0 ] . node . send_payment_with_route ( route, payment_hash, RecipientOnionFields :: secret_only ( payment_secret) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
1280+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
1281+ let updates = get_htlc_update_msgs ( & nodes[ 0 ] , & nodes[ 1 ] . node . get_our_node_id ( ) ) ;
1282+ nodes[ 1 ] . node . handle_update_add_htlc ( nodes[ 0 ] . node . get_our_node_id ( ) , & updates. update_add_htlcs [ 0 ] ) ;
1283+ do_commitment_signed_dance ( & nodes[ 1 ] , & nodes[ 0 ] , & updates. commitment_signed , false , false ) ;
1284+
1285+ // Add the HTLC to the outbound edge, node_b <> node_c.
1286+ nodes[ 1 ] . node . process_pending_htlc_forwards ( ) ;
1287+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
1288+
1289+ // Disconnect peers and reload the forwarding node_b.
1290+ nodes[ 0 ] . node . peer_disconnected ( nodes[ 1 ] . node . get_our_node_id ( ) ) ;
1291+ nodes[ 2 ] . node . peer_disconnected ( nodes[ 1 ] . node . get_our_node_id ( ) ) ;
1292+
1293+ let node_b_encoded = nodes[ 1 ] . node . encode ( ) ;
1294+ let chan_0_monitor_serialized = get_monitor ! ( nodes[ 1 ] , chan_id_1) . encode ( ) ;
1295+ let chan_1_monitor_serialized = get_monitor ! ( nodes[ 1 ] , chan_id_2) . encode ( ) ;
1296+ reload_node ! ( nodes[ 1 ] , node_b_encoded, & [ & chan_0_monitor_serialized, & chan_1_monitor_serialized] , persister, new_chain_monitor, nodes_1_deserialized) ;
1297+
1298+ reconnect_nodes ( ReconnectArgs :: new ( & nodes[ 1 ] , & nodes[ 0 ] ) ) ;
1299+ let mut args_b_c = ReconnectArgs :: new ( & nodes[ 1 ] , & nodes[ 2 ] ) ;
1300+ args_b_c. send_channel_ready = ( true , true ) ;
1301+ args_b_c. send_announcement_sigs = ( true , true ) ;
1302+ args_b_c. pending_htlc_adds = ( 0 , 1 ) ;
1303+ // While reconnecting, we re-send node_b's outbound update_add and commit the HTLC to the b<>c
1304+ // channel.
1305+ reconnect_nodes ( args_b_c) ;
1306+
1307+ // Ensure node_b won't double-forward the outbound HTLC (this was previously broken).
1308+ nodes[ 1 ] . node . process_pending_htlc_forwards ( ) ;
1309+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
1310+
1311+ // Claim the HTLC backwards to node_a.
1312+ expect_and_process_pending_htlcs ( & nodes[ 2 ] , false ) ;
1313+ expect_payment_claimable ! ( nodes[ 2 ] , payment_hash, payment_secret, amt_msat, None , nodes[ 2 ] . node. get_our_node_id( ) ) ;
1314+ let path: & [ & [ _ ] ] = & [ & [ & nodes[ 1 ] , & nodes[ 2 ] ] ] ;
1315+ do_claim_payment_along_route ( ClaimAlongRouteArgs :: new ( & nodes[ 0 ] , path, payment_preimage) ) ;
1316+ expect_payment_sent ( & nodes[ 0 ] , payment_preimage, None , true , true ) ;
1317+ }
1318+
12611319#[ test]
12621320fn test_reload_partial_funding_batch ( ) {
12631321 let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
0 commit comments