@@ -28,8 +28,13 @@ use crate::offers::invoice_request::InvoiceRequest;
28
28
use crate :: offers:: nonce:: Nonce ;
29
29
use crate :: offers:: offer:: Offer ;
30
30
use crate :: offers:: static_invoice:: StaticInvoice ;
31
- use crate :: onion_message:: async_payments:: { AsyncPaymentsMessage , AsyncPaymentsMessageHandler } ;
32
- use crate :: onion_message:: messenger:: { Destination , MessageRouter , MessageSendInstructions } ;
31
+ use crate :: onion_message:: async_payments:: {
32
+ AsyncPaymentsMessage , AsyncPaymentsMessageHandler , DEFAULT_CONFIG_PATH_RELATIVE_EXPIRY ,
33
+ REPLY_PATH_RELATIVE_EXPIRY ,
34
+ } ;
35
+ use crate :: onion_message:: messenger:: {
36
+ Destination , MessageRouter , MessageSendInstructions , PeeledOnion ,
37
+ } ;
33
38
use crate :: onion_message:: offers:: OffersMessage ;
34
39
use crate :: onion_message:: packet:: ParsedOnionMessageContents ;
35
40
use crate :: prelude:: * ;
@@ -1284,3 +1289,217 @@ fn expired_static_invoice_payment_path() {
1284
1289
1 ,
1285
1290
) ;
1286
1291
}
1292
+
1293
+ #[ cfg_attr( feature = "std" , ignore) ]
1294
+ #[ test]
1295
+ fn ignore_expired_static_invoice_server_message ( ) {
1296
+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
1297
+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
1298
+ let new_persister_1;
1299
+ let new_persister_2;
1300
+ let new_chain_monitor_1;
1301
+ let new_chain_monitor_2;
1302
+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
1303
+ let payee_node_deserialized_1;
1304
+ let payee_node_deserialized_2;
1305
+ let mut nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
1306
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
1307
+ let chan_id_1_2 =
1308
+ create_unannounced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) . 0 . channel_id ;
1309
+
1310
+ reload_payee_with_async_receive_cfg ! (
1311
+ nodes[ 1 ] ,
1312
+ nodes[ 2 ] ,
1313
+ new_persister_1,
1314
+ new_chain_monitor_1,
1315
+ payee_node_deserialized_1,
1316
+ & [ chan_id_1_2]
1317
+ ) ;
1318
+
1319
+ // If we receive an offer_paths_request over an expired path, it should be ignored.
1320
+ let offer_paths_req = nodes[ 2 ]
1321
+ . onion_messenger
1322
+ . next_onion_message_for_peer ( nodes[ 1 ] . node . get_our_node_id ( ) )
1323
+ . unwrap ( ) ;
1324
+ assert ! ( matches!(
1325
+ nodes[ 1 ] . onion_messenger. peel_onion_message( & offer_paths_req) . unwrap( ) ,
1326
+ PeeledOnion :: Receive (
1327
+ ParsedOnionMessageContents :: AsyncPayments ( AsyncPaymentsMessage :: OfferPathsRequest ( _) ) ,
1328
+ _,
1329
+ _
1330
+ )
1331
+ ) ) ;
1332
+ nodes[ 2 ] . onion_messenger . release_pending_msgs ( ) ; // Ignore redundant paths requests
1333
+
1334
+ let configured_path_absolute_expiry = ( nodes[ 1 ] . node . duration_since_epoch ( )
1335
+ + DEFAULT_CONFIG_PATH_RELATIVE_EXPIRY )
1336
+ . as_secs ( ) as u32 ;
1337
+ let block = create_dummy_block (
1338
+ nodes[ 1 ] . best_block_hash ( ) ,
1339
+ configured_path_absolute_expiry + 1u32 ,
1340
+ Vec :: new ( ) ,
1341
+ ) ;
1342
+ connect_block ( & nodes[ 1 ] , & block) ;
1343
+ connect_block ( & nodes[ 2 ] , & block) ;
1344
+
1345
+ nodes[ 1 ]
1346
+ . onion_messenger
1347
+ . handle_onion_message ( nodes[ 2 ] . node . get_our_node_id ( ) , & offer_paths_req) ;
1348
+ assert ! ( nodes[ 1 ]
1349
+ . onion_messenger
1350
+ . next_onion_message_for_peer( nodes[ 2 ] . node. get_our_node_id( ) )
1351
+ . is_none( ) ) ;
1352
+
1353
+ // The payee's configured paths are expired, so reload them again with fresh paths.
1354
+ reload_payee_with_async_receive_cfg ! (
1355
+ nodes[ 1 ] ,
1356
+ nodes[ 2 ] ,
1357
+ new_persister_2,
1358
+ new_chain_monitor_2,
1359
+ payee_node_deserialized_2,
1360
+ & [ chan_id_1_2]
1361
+ ) ;
1362
+
1363
+ // If we receive an offer_paths message over an expired reply path, it should be ignored.
1364
+ nodes[ 2 ] . node . timer_tick_occurred ( ) ;
1365
+ let offer_paths_req = nodes[ 2 ]
1366
+ . onion_messenger
1367
+ . next_onion_message_for_peer ( nodes[ 1 ] . node . get_our_node_id ( ) )
1368
+ . unwrap ( ) ;
1369
+ nodes[ 2 ] . onion_messenger . release_pending_msgs ( ) ; // Ignore redundant paths requests
1370
+ nodes[ 1 ]
1371
+ . onion_messenger
1372
+ . handle_onion_message ( nodes[ 2 ] . node . get_our_node_id ( ) , & offer_paths_req) ;
1373
+ let offer_paths = nodes[ 1 ]
1374
+ . onion_messenger
1375
+ . next_onion_message_for_peer ( nodes[ 2 ] . node . get_our_node_id ( ) )
1376
+ . unwrap ( ) ;
1377
+ assert ! ( matches!(
1378
+ nodes[ 2 ] . onion_messenger. peel_onion_message( & offer_paths) . unwrap( ) ,
1379
+ PeeledOnion :: Receive (
1380
+ ParsedOnionMessageContents :: AsyncPayments ( AsyncPaymentsMessage :: OfferPaths ( _) ) ,
1381
+ _,
1382
+ _
1383
+ )
1384
+ ) ) ;
1385
+
1386
+ let block = create_dummy_block (
1387
+ nodes[ 2 ] . best_block_hash ( ) ,
1388
+ ( nodes[ 2 ] . node . duration_since_epoch ( ) + REPLY_PATH_RELATIVE_EXPIRY ) . as_secs ( ) as u32 + 1u32 ,
1389
+ Vec :: new ( ) ,
1390
+ ) ;
1391
+ connect_block ( & nodes[ 2 ] , & block) ;
1392
+
1393
+ nodes[ 2 ] . onion_messenger . handle_onion_message ( nodes[ 1 ] . node . get_our_node_id ( ) , & offer_paths) ;
1394
+ assert ! ( nodes[ 2 ]
1395
+ . onion_messenger
1396
+ . next_onion_message_for_peer( nodes[ 1 ] . node. get_our_node_id( ) )
1397
+ . is_none( ) ) ;
1398
+
1399
+ // If we receive a serve_static_invoice message over an expired reply path, it should be ignored.
1400
+ nodes[ 2 ] . node . timer_tick_occurred ( ) ;
1401
+ let offer_paths_req = nodes[ 2 ]
1402
+ . onion_messenger
1403
+ . next_onion_message_for_peer ( nodes[ 1 ] . node . get_our_node_id ( ) )
1404
+ . unwrap ( ) ;
1405
+ nodes[ 1 ]
1406
+ . onion_messenger
1407
+ . handle_onion_message ( nodes[ 2 ] . node . get_our_node_id ( ) , & offer_paths_req) ;
1408
+ let offer_paths = nodes[ 1 ]
1409
+ . onion_messenger
1410
+ . next_onion_message_for_peer ( nodes[ 2 ] . node . get_our_node_id ( ) )
1411
+ . unwrap ( ) ;
1412
+ nodes[ 2 ] . onion_messenger . handle_onion_message ( nodes[ 1 ] . node . get_our_node_id ( ) , & offer_paths) ;
1413
+ let serve_static_invoice = nodes[ 2 ]
1414
+ . onion_messenger
1415
+ . next_onion_message_for_peer ( nodes[ 1 ] . node . get_our_node_id ( ) )
1416
+ . unwrap ( ) ;
1417
+ assert ! ( matches!(
1418
+ nodes[ 1 ] . onion_messenger. peel_onion_message( & serve_static_invoice) . unwrap( ) ,
1419
+ PeeledOnion :: Receive (
1420
+ ParsedOnionMessageContents :: AsyncPayments ( AsyncPaymentsMessage :: ServeStaticInvoice ( _) ) ,
1421
+ _,
1422
+ _
1423
+ )
1424
+ ) ) ;
1425
+
1426
+ let block = create_dummy_block (
1427
+ nodes[ 1 ] . best_block_hash ( ) ,
1428
+ ( nodes[ 1 ] . node . duration_since_epoch ( ) + REPLY_PATH_RELATIVE_EXPIRY ) . as_secs ( ) as u32 + 1u32 ,
1429
+ Vec :: new ( ) ,
1430
+ ) ;
1431
+ connect_block ( & nodes[ 1 ] , & block) ;
1432
+
1433
+ nodes[ 1 ]
1434
+ . onion_messenger
1435
+ . handle_onion_message ( nodes[ 2 ] . node . get_our_node_id ( ) , & serve_static_invoice) ;
1436
+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_events( ) . is_empty( ) ) ;
1437
+ assert ! ( nodes[ 1 ]
1438
+ . onion_messenger
1439
+ . next_onion_message_for_peer( nodes[ 2 ] . node. get_our_node_id( ) )
1440
+ . is_none( ) ) ;
1441
+
1442
+ // If we receive a static_invoice_persisted message to an expired path, it should be ignored.
1443
+ nodes[ 2 ] . node . timer_tick_occurred ( ) ;
1444
+ let offer_paths_req = nodes[ 2 ]
1445
+ . onion_messenger
1446
+ . next_onion_message_for_peer ( nodes[ 1 ] . node . get_our_node_id ( ) )
1447
+ . unwrap ( ) ;
1448
+ nodes[ 1 ]
1449
+ . onion_messenger
1450
+ . handle_onion_message ( nodes[ 2 ] . node . get_our_node_id ( ) , & offer_paths_req) ;
1451
+ let offer_paths = nodes[ 1 ]
1452
+ . onion_messenger
1453
+ . next_onion_message_for_peer ( nodes[ 2 ] . node . get_our_node_id ( ) )
1454
+ . unwrap ( ) ;
1455
+ nodes[ 2 ] . onion_messenger . handle_onion_message ( nodes[ 1 ] . node . get_our_node_id ( ) , & offer_paths) ;
1456
+ let serve_static_invoice = nodes[ 2 ]
1457
+ . onion_messenger
1458
+ . next_onion_message_for_peer ( nodes[ 1 ] . node . get_our_node_id ( ) )
1459
+ . unwrap ( ) ;
1460
+ nodes[ 1 ]
1461
+ . onion_messenger
1462
+ . handle_onion_message ( nodes[ 2 ] . node . get_our_node_id ( ) , & serve_static_invoice) ;
1463
+ let mut events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
1464
+ assert_eq ! ( events. len( ) , 1 ) ;
1465
+ let ack_paths = match events. pop ( ) . unwrap ( ) {
1466
+ Event :: PersistStaticInvoice { invoice_persisted_paths, .. } => invoice_persisted_paths,
1467
+ _ => panic ! ( ) ,
1468
+ } ;
1469
+
1470
+ nodes[ 1 ] . node . static_invoice_persisted ( ack_paths) . unwrap ( ) ;
1471
+ let invoice_persisted = nodes[ 1 ]
1472
+ . onion_messenger
1473
+ . next_onion_message_for_peer ( nodes[ 2 ] . node . get_our_node_id ( ) )
1474
+ . unwrap ( ) ;
1475
+ assert ! ( matches!(
1476
+ nodes[ 2 ] . onion_messenger. peel_onion_message( & invoice_persisted) . unwrap( ) ,
1477
+ PeeledOnion :: Receive (
1478
+ ParsedOnionMessageContents :: AsyncPayments (
1479
+ AsyncPaymentsMessage :: StaticInvoicePersisted ( _)
1480
+ ) ,
1481
+ _,
1482
+ _
1483
+ )
1484
+ ) ) ;
1485
+
1486
+ let block = create_dummy_block (
1487
+ nodes[ 2 ] . best_block_hash ( ) ,
1488
+ ( nodes[ 2 ] . node . duration_since_epoch ( ) + REPLY_PATH_RELATIVE_EXPIRY ) . as_secs ( ) as u32 + 1u32 ,
1489
+ Vec :: new ( ) ,
1490
+ ) ;
1491
+ connect_block ( & nodes[ 1 ] , & block) ;
1492
+ connect_block ( & nodes[ 2 ] , & block) ;
1493
+ nodes[ 2 ]
1494
+ . onion_messenger
1495
+ . handle_onion_message ( nodes[ 1 ] . node . get_our_node_id ( ) , & invoice_persisted) ;
1496
+ assert ! ( nodes[ 2 ] . node. get_cached_async_receive_offer( ) . is_none( ) ) ;
1497
+
1498
+ // The recipient won't try to ask for offer paths again as the maximum number of attempts has been
1499
+ // exceeded.
1500
+ nodes[ 2 ] . node . timer_tick_occurred ( ) ;
1501
+ assert ! ( nodes[ 2 ]
1502
+ . onion_messenger
1503
+ . next_onion_message_for_peer( nodes[ 1 ] . node. get_our_node_id( ) )
1504
+ . is_none( ) ) ;
1505
+ }
0 commit comments