mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-21 14:10:35 +02:00
lntest: add route construction to blinded forwarding test
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package itest
|
package itest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
@@ -321,28 +322,111 @@ type blindedForwardTest struct {
|
|||||||
carol *node.HarnessNode
|
carol *node.HarnessNode
|
||||||
dave *node.HarnessNode
|
dave *node.HarnessNode
|
||||||
channels []*lnrpc.ChannelPoint
|
channels []*lnrpc.ChannelPoint
|
||||||
|
|
||||||
|
// cancel will cancel the test's top level context.
|
||||||
|
cancel func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBlindedForwardTest(ht *lntest.HarnessTest) *blindedForwardTest {
|
func newBlindedForwardTest(ht *lntest.HarnessTest) (context.Context,
|
||||||
return &blindedForwardTest{
|
*blindedForwardTest) {
|
||||||
ht: ht,
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
|
return ctx, &blindedForwardTest{
|
||||||
|
ht: ht,
|
||||||
|
cancel: cancel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup spins up additional nodes needed for our test and creates a four hop
|
// setup spins up additional nodes needed for our test and creates a four hop
|
||||||
// network for testing blinded forwarding.
|
// network for testing blinded forwarding and returns a blinded route from
|
||||||
func (b *blindedForwardTest) setup() {
|
// Bob -> Carol -> Dave, with Bob acting as the introduction point.
|
||||||
|
func (b *blindedForwardTest) setup() *routing.BlindedPayment {
|
||||||
b.carol = b.ht.NewNode("Carol", nil)
|
b.carol = b.ht.NewNode("Carol", nil)
|
||||||
b.dave = b.ht.NewNode("Dave", nil)
|
b.dave = b.ht.NewNode("Dave", nil)
|
||||||
|
|
||||||
b.channels = setupFourHopNetwork(b.ht, b.carol, b.dave)
|
b.channels = setupFourHopNetwork(b.ht, b.carol, b.dave)
|
||||||
|
|
||||||
|
// Create a blinded route to Dave via Bob --- Carol --- Dave:
|
||||||
|
bobChan := b.ht.GetChannelByChanPoint(b.ht.Bob, b.channels[1])
|
||||||
|
carolChan := b.ht.GetChannelByChanPoint(b.carol, b.channels[2])
|
||||||
|
|
||||||
|
edges := []*forwardingEdge{
|
||||||
|
getForwardingEdge(b.ht, b.ht.Bob, bobChan.ChanId),
|
||||||
|
getForwardingEdge(b.ht, b.carol, carolChan.ChanId),
|
||||||
|
}
|
||||||
|
|
||||||
|
davePk, err := btcec.ParsePubKey(b.dave.PubKey[:])
|
||||||
|
require.NoError(b.ht, err, "dave pubkey")
|
||||||
|
|
||||||
|
return b.createBlindedRoute(edges, davePk, 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup tears down all channels created by the test.
|
// cleanup tears down all channels created by the test and cancels the top
|
||||||
|
// level context used in the test.
|
||||||
func (b *blindedForwardTest) cleanup() {
|
func (b *blindedForwardTest) cleanup() {
|
||||||
b.ht.CloseChannel(b.ht.Alice, b.channels[0])
|
b.ht.CloseChannel(b.ht.Alice, b.channels[0])
|
||||||
b.ht.CloseChannel(b.ht.Bob, b.channels[1])
|
b.ht.CloseChannel(b.ht.Bob, b.channels[1])
|
||||||
b.ht.CloseChannel(b.carol, b.channels[2])
|
b.ht.CloseChannel(b.carol, b.channels[2])
|
||||||
|
|
||||||
|
b.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// createRouteToBlinded queries for a route from alice to the blinded path
|
||||||
|
// provided.
|
||||||
|
//
|
||||||
|
//nolint:gomnd
|
||||||
|
func (b *blindedForwardTest) createRouteToBlinded(paymentAmt int64,
|
||||||
|
route *routing.BlindedPayment) *lnrpc.Route {
|
||||||
|
|
||||||
|
intro := route.BlindedPath.IntroductionPoint.SerializeCompressed()
|
||||||
|
blinding := route.BlindedPath.BlindingPoint.SerializeCompressed()
|
||||||
|
|
||||||
|
blindedRoute := &lnrpc.BlindedPath{
|
||||||
|
IntroductionNode: intro,
|
||||||
|
BlindingPoint: blinding,
|
||||||
|
BlindedHops: make(
|
||||||
|
[]*lnrpc.BlindedHop,
|
||||||
|
len(route.BlindedPath.BlindedHops),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, hop := range route.BlindedPath.BlindedHops {
|
||||||
|
blindedRoute.BlindedHops[i] = &lnrpc.BlindedHop{
|
||||||
|
BlindedNode: hop.BlindedNodePub.SerializeCompressed(),
|
||||||
|
EncryptedData: hop.CipherText,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blindedPath := &lnrpc.BlindedPaymentPath{
|
||||||
|
BlindedPath: blindedRoute,
|
||||||
|
BaseFeeMsat: uint64(
|
||||||
|
route.BaseFee,
|
||||||
|
),
|
||||||
|
ProportionalFeeRate: route.ProportionalFeeRate,
|
||||||
|
TotalCltvDelta: uint32(
|
||||||
|
route.CltvExpiryDelta,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &lnrpc.QueryRoutesRequest{
|
||||||
|
AmtMsat: paymentAmt,
|
||||||
|
// Our fee limit doesn't really matter, we just want to
|
||||||
|
// be able to make the payment.
|
||||||
|
FeeLimit: &lnrpc.FeeLimit{
|
||||||
|
Limit: &lnrpc.FeeLimit_Percent{
|
||||||
|
Percent: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
BlindedPaymentPaths: []*lnrpc.BlindedPaymentPath{
|
||||||
|
blindedPath,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := b.ht.Alice.RPC.QueryRoutes(req)
|
||||||
|
require.Greater(b.ht, len(resp.Routes), 0, "no routes")
|
||||||
|
require.Len(b.ht, resp.Routes[0].Hops, 3, "unexpected route length")
|
||||||
|
|
||||||
|
return resp.Routes[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupFourHopNetwork creates a network with the following topology and
|
// setupFourHopNetwork creates a network with the following topology and
|
||||||
@@ -540,8 +624,39 @@ type forwardingEdge struct {
|
|||||||
edge *lnrpc.RoutingPolicy
|
edge *lnrpc.RoutingPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getForwardingEdge(ht *lntest.HarnessTest,
|
||||||
|
node *node.HarnessNode, chanID uint64) *forwardingEdge {
|
||||||
|
|
||||||
|
chanInfo := node.RPC.GetChanInfo(&lnrpc.ChanInfoRequest{
|
||||||
|
ChanId: chanID,
|
||||||
|
})
|
||||||
|
|
||||||
|
pubkey, err := btcec.ParsePubKey(node.PubKey[:])
|
||||||
|
require.NoError(ht, err, "%v pubkey", node.Cfg.Name)
|
||||||
|
|
||||||
|
fwdEdge := &forwardingEdge{
|
||||||
|
pubkey: pubkey,
|
||||||
|
channelID: lnwire.NewShortChanIDFromInt(chanID),
|
||||||
|
}
|
||||||
|
|
||||||
|
if chanInfo.Node1Pub == node.PubKeyStr {
|
||||||
|
fwdEdge.edge = chanInfo.Node1Policy
|
||||||
|
} else {
|
||||||
|
require.Equal(ht, node.PubKeyStr, chanInfo.Node2Pub,
|
||||||
|
"policy edge sanity check")
|
||||||
|
|
||||||
|
fwdEdge.edge = chanInfo.Node2Policy
|
||||||
|
}
|
||||||
|
|
||||||
|
return fwdEdge
|
||||||
|
}
|
||||||
|
|
||||||
// testForwardBlindedRoute tests lnd's ability to forward payments in a blinded
|
// testForwardBlindedRoute tests lnd's ability to forward payments in a blinded
|
||||||
// route.
|
// route.
|
||||||
func testForwardBlindedRoute(ht *lntest.HarnessTest) {
|
func testForwardBlindedRoute(ht *lntest.HarnessTest) {
|
||||||
newBlindedForwardTest(ht)
|
_, testCase := newBlindedForwardTest(ht)
|
||||||
|
defer testCase.cleanup()
|
||||||
|
|
||||||
|
route := testCase.setup()
|
||||||
|
testCase.createRouteToBlinded(100_000, route)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user