@@ -1428,25 +1428,55 @@ func testBlindedPaymentHTLCReForward(ht *lntest.HarnessTest) {
1428
1428
// pre-specified.
1429
1429
func testPartiallySpecifiedBlindedPath (ht * lntest.HarnessTest ) {
1430
1430
// Create a six hop network:
1431
- // Alice -> Bob -> Carol -> Dave -> Eve -> Frank.
1432
- chanAmt := btcutil .Amount (100000 )
1433
- cfgs := [][]string {nil , nil , nil , nil , nil , nil }
1431
+ // Alice -> Bob -> Carol -> Dave -> Eve -> Frank.
1432
+ // Carol will be the node generating invoices containing blinded paths.
1434
1433
chanPoints , nodes := ht .CreateSimpleNetwork (
1435
- cfgs , lntest.OpenChannelParams {Amt : chanAmt },
1434
+ [][]string {nil , nil , nil , nil , nil , nil },
1435
+ lntest.OpenChannelParams {
1436
+ Amt : chanAmt ,
1437
+ PushAmt : chanAmt / 2 ,
1438
+ },
1436
1439
)
1437
1440
1438
- alice , bob , carol , dave , eve := nodes [0 ], nodes [1 ], nodes [2 ], nodes [3 ],
1439
- nodes [4 ]
1440
-
1441
- chanPointAliceBob , chanPointBobCarol , chanPointCarolDave :=
1442
- chanPoints [0 ], chanPoints [1 ], chanPoints [2 ]
1441
+ var (
1442
+ alice = nodes [0 ]
1443
+ bob = nodes [1 ]
1444
+ carol = nodes [2 ]
1445
+ dave = nodes [3 ]
1446
+ eve = nodes [4 ]
1447
+ frank = nodes [5 ]
1448
+ )
1443
1449
1444
1450
// Lookup full channel info so that we have channel ids for our route.
1445
- aliceBobChan := ht .GetChannelByChanPoint (alice , chanPointAliceBob )
1446
- bobCarolChan := ht .GetChannelByChanPoint (bob , chanPointBobCarol )
1447
- carolDaveChan := ht .GetChannelByChanPoint (carol , chanPointCarolDave )
1451
+ aliceBobChan := ht .GetChannelByChanPoint (alice , chanPoints [0 ])
1452
+ bobCarolChan := ht .GetChannelByChanPoint (bob , chanPoints [1 ])
1453
+ carolDaveChan := ht .GetChannelByChanPoint (carol , chanPoints [2 ])
1454
+
1455
+ // assertPathDetails is a helper function that asserts the details of
1456
+ // the blinded paths returned in the invoice.
1457
+ assertPathDetails := func (invoice * lnrpc.AddInvoiceResponse ,
1458
+ expPathLengths int , expIntroNodes ... []byte ) {
1459
+
1460
+ payReq := carol .RPC .DecodePayReq (invoice .PaymentRequest )
1461
+ paths := payReq .BlindedPaths
1462
+
1463
+ introNodes := make ([][]byte , 0 , len (paths ))
1464
+ for _ , p := range paths {
1465
+ require .Len (
1466
+ ht , p .BlindedPath .BlindedHops , expPathLengths ,
1467
+ )
1468
+
1469
+ introNodes = append (
1470
+ introNodes , p .BlindedPath .IntroductionNode ,
1471
+ )
1472
+ }
1473
+ require .ElementsMatch (ht , introNodes , expIntroNodes )
1474
+ }
1448
1475
1449
- // Let carol set no incoming channel restrictions.
1476
+ // Let carol set no incoming channel restrictions. With a min of 1 hop,
1477
+ // we expect the following blinded paths to be included:
1478
+ // 1) Bob->Carol
1479
+ // 2) Dave->Carol
1450
1480
var (
1451
1481
minNumRealHops uint32 = 1
1452
1482
numHops uint32 = 1
@@ -1460,139 +1490,110 @@ func testPartiallySpecifiedBlindedPath(ht *lntest.HarnessTest) {
1460
1490
NumHops : & numHops ,
1461
1491
},
1462
1492
})
1493
+ assertPathDetails (invoice , 2 , bob .PubKey [:], dave .PubKey [:])
1463
1494
1464
- introNodesFound := make ([][]byte , 0 )
1465
- introNodesExpected := [][]byte {bob .PubKey [:], dave .PubKey [:]}
1466
-
1467
- // Assert that it contains two blinded path with only 2 hops each one.
1468
- payReq := carol .RPC .DecodePayReq (invoice .PaymentRequest )
1469
- require .Len (ht , payReq .BlindedPaths , 2 )
1470
- path := payReq .BlindedPaths [0 ].BlindedPath
1471
- require .Len (ht , path .BlindedHops , 2 )
1472
- introNodesFound = append (introNodesFound , path .IntroductionNode )
1473
- path = payReq .BlindedPaths [1 ].BlindedPath
1474
- require .Len (ht , path .BlindedHops , 2 )
1475
- introNodesFound = append (introNodesFound , path .IntroductionNode )
1476
-
1477
- // Assert the introduction nodes without caring about the routes order.
1478
- require .ElementsMatch (ht , introNodesExpected , introNodesFound )
1479
-
1480
- // Let carol choose the wrong incoming channel.
1481
- var (
1482
- incomingChannelList = []uint64 {aliceBobChan .ChanId }
1483
- )
1484
-
1485
- err := fmt .Sprintf ("incoming channel %v is not seen as owned by node" ,
1486
- aliceBobChan .ChanId )
1487
-
1495
+ // Let carol choose an invalid incoming channel list for the blinded
1496
+ // path. It is invalid since it does not connect to her node.
1497
+ // Assert that the expected error is returned.
1488
1498
carol .RPC .AddInvoiceAssertErr (
1489
1499
& lnrpc.Invoice {
1490
1500
Memo : "test" ,
1491
1501
ValueMsat : 10_000_000 ,
1492
1502
IsBlinded : true ,
1493
1503
BlindedPathConfig : & lnrpc.BlindedPathConfig {
1494
- MinNumRealHops : & minNumRealHops ,
1495
- NumHops : & numHops ,
1496
- IncomingChannelList : incomingChannelList ,
1504
+ MinNumRealHops : & minNumRealHops ,
1505
+ NumHops : & numHops ,
1506
+ IncomingChannelList : []uint64 {
1507
+ aliceBobChan .ChanId ,
1508
+ },
1497
1509
},
1498
1510
},
1499
- err ,
1511
+ fmt .Sprintf ("incoming channel %v is not seen as owned by node" ,
1512
+ aliceBobChan .ChanId ),
1500
1513
)
1501
1514
1502
1515
// Let Carol set the incoming channel list greater than minimum number
1503
1516
// of real hops.
1504
- incomingChannelList = []uint64 {aliceBobChan .ChanId , bobCarolChan .ChanId }
1505
- err = fmt .Sprintf ("minimum number of blinded path hops (%d) must be " +
1506
- "greater than or equal to the number of hops specified on " +
1507
- "the chained channels (%d)" , minNumRealHops ,
1508
- len (incomingChannelList ),
1509
- )
1510
-
1517
+ // Assert that the expected error is returned.
1511
1518
carol .RPC .AddInvoiceAssertErr (
1512
1519
& lnrpc.Invoice {
1513
1520
Memo : "test" ,
1514
1521
ValueMsat : 10_000_000 ,
1515
1522
IsBlinded : true ,
1516
1523
BlindedPathConfig : & lnrpc.BlindedPathConfig {
1517
- MinNumRealHops : & minNumRealHops ,
1518
- NumHops : & numHops ,
1519
- IncomingChannelList : incomingChannelList ,
1524
+ MinNumRealHops : & minNumRealHops ,
1525
+ NumHops : & numHops ,
1526
+ IncomingChannelList : []uint64 {
1527
+ aliceBobChan .ChanId ,
1528
+ bobCarolChan .ChanId ,
1529
+ },
1520
1530
},
1521
1531
},
1522
- err ,
1532
+ "must be greater than or equal to the number of hops " +
1533
+ "specified on the chained channels" ,
1523
1534
)
1524
1535
1525
1536
// Let Carol choose an incoming channel that points to a node in the
1526
1537
// omission set.
1527
- incomingChannelList = []uint64 {bobCarolChan .ChanId }
1528
- var nodeOmissionList [][]byte
1529
- nodeOmissionList = append (nodeOmissionList , bob .PubKey [:])
1530
-
1531
- err = fmt .Sprintf ("cannot simultaneously be included in the omission " +
1532
- "set and in the partially specified path" ,
1533
- )
1534
-
1535
1538
carol .RPC .AddInvoiceAssertErr (
1536
1539
& lnrpc.Invoice {
1537
1540
Memo : "test" ,
1538
1541
ValueMsat : 10_000_000 ,
1539
1542
IsBlinded : true ,
1540
1543
BlindedPathConfig : & lnrpc.BlindedPathConfig {
1541
- MinNumRealHops : & minNumRealHops ,
1542
- NumHops : & numHops ,
1543
- IncomingChannelList : incomingChannelList ,
1544
- NodeOmissionList : nodeOmissionList ,
1544
+ MinNumRealHops : & minNumRealHops ,
1545
+ NumHops : & numHops ,
1546
+ IncomingChannelList : []uint64 {
1547
+ bobCarolChan .ChanId ,
1548
+ },
1549
+ NodeOmissionList : [][]byte {
1550
+ bob .PubKey [:],
1551
+ },
1545
1552
},
1546
1553
},
1547
- err ,
1554
+ "cannot simultaneously be included in the omission set and " +
1555
+ "in the partially specified path" ,
1548
1556
)
1549
1557
1550
1558
// Let carol restrict bob as incoming channel.
1551
- incomingChannelList = []uint64 {bobCarolChan .ChanId }
1552
-
1553
1559
invoice = carol .RPC .AddInvoice (& lnrpc.Invoice {
1554
1560
Memo : "test" ,
1555
1561
ValueMsat : 10_000_000 ,
1556
1562
IsBlinded : true ,
1557
1563
BlindedPathConfig : & lnrpc.BlindedPathConfig {
1558
- MinNumRealHops : & minNumRealHops ,
1559
- NumHops : & numHops ,
1560
- IncomingChannelList : incomingChannelList ,
1564
+ MinNumRealHops : & minNumRealHops ,
1565
+ NumHops : & numHops ,
1566
+ IncomingChannelList : []uint64 {
1567
+ bobCarolChan .ChanId ,
1568
+ },
1561
1569
},
1562
1570
})
1563
1571
1564
1572
// Assert that it contains a single blinded path with only
1565
1573
// 2 hops, with bob as the introduction node.
1566
- payReq = carol .RPC .DecodePayReq (invoice .PaymentRequest )
1567
- require .Len (ht , payReq .BlindedPaths , 1 )
1568
- path = payReq .BlindedPaths [0 ].BlindedPath
1569
- require .Len (ht , path .BlindedHops , 2 )
1570
- require .EqualValues (ht , path .IntroductionNode , bob .PubKey [:])
1574
+ assertPathDetails (invoice , 2 , bob .PubKey [:])
1571
1575
1572
- // Now let alice pay the invoice.
1576
+ // Check that Alice can pay the invoice.
1573
1577
ht .CompletePaymentRequests (alice , []string {invoice .PaymentRequest })
1574
1578
1575
- // Let carol restrict dave as incoming channel and max Hops as 2
1579
+ // Let carol restrict dave as incoming channel and max hops as 2.
1576
1580
numHops = 2
1577
- incomingChannelList = []uint64 {carolDaveChan .ChanId }
1578
-
1579
1581
invoice = carol .RPC .AddInvoice (& lnrpc.Invoice {
1580
1582
Memo : "test" ,
1581
1583
ValueMsat : 10_000_000 ,
1582
1584
IsBlinded : true ,
1583
1585
BlindedPathConfig : & lnrpc.BlindedPathConfig {
1584
1586
MinNumRealHops : & minNumRealHops ,
1585
1587
NumHops : & numHops ,
1586
- IncomingChannelList : incomingChannelList ,
1588
+ IncomingChannelList : [] uint64 { carolDaveChan . ChanId } ,
1587
1589
},
1588
1590
})
1589
1591
1590
- // Assert that it contains one path with 3 hops, with dave as the
1591
- // introduction node. The path alice -> bob -> carol is discarded
1592
- // because alice is a dead-end.
1593
- payReq = carol .RPC .DecodePayReq (invoice .PaymentRequest )
1594
- require .Len (ht , payReq .BlindedPaths , 1 )
1595
- path = payReq .BlindedPaths [0 ].BlindedPath
1596
- require .Len (ht , path .BlindedHops , 3 )
1597
- require .EqualValues (ht , path .IntroductionNode , eve .PubKey [:])
1592
+ // Assert that it contains two paths: one 3 hop one starting at Eve and
1593
+ // a 3 hop one starting at Dave (this one will be padded with a dummy
1594
+ // hop) in order to keep all the paths equidistant.
1595
+ assertPathDetails (invoice , 3 , eve .PubKey [:], dave .PubKey [:])
1596
+
1597
+ // Check that Frank can pay the invoice.
1598
+ ht .CompletePaymentRequests (frank , []string {invoice .PaymentRequest })
1598
1599
}
0 commit comments