diff --git a/itest/list_on_test.go b/itest/list_on_test.go index 7a618402f..f78601a10 100644 --- a/itest/list_on_test.go +++ b/itest/list_on_test.go @@ -558,6 +558,10 @@ var allTestCases = []*lntest.TestCase{ Name: "query blinded route", TestFunc: testQueryBlindedRoutes, }, + { + Name: "forward blinded", + TestFunc: testForwardBlindedRoute, + }, { Name: "removetx", TestFunc: testRemoveTx, diff --git a/itest/lnd_route_blinding.go b/itest/lnd_route_blinding_test.go similarity index 78% rename from itest/lnd_route_blinding.go rename to itest/lnd_route_blinding_test.go index 2104cb1c8..bd053fd46 100644 --- a/itest/lnd_route_blinding.go +++ b/itest/lnd_route_blinding_test.go @@ -10,6 +10,7 @@ import ( "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntest" + "github.com/lightningnetwork/lnd/lntest/node" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -310,3 +311,94 @@ func testQueryBlindedRoutes(ht *lntest.HarnessTest) { ht.CloseChannel(alice, chanPointAliceBob) ht.CloseChannel(bob, chanPointBobCarol) } + +type blindedForwardTest struct { + ht *lntest.HarnessTest + carol *node.HarnessNode + dave *node.HarnessNode + channels []*lnrpc.ChannelPoint +} + +func newBlindedForwardTest(ht *lntest.HarnessTest) *blindedForwardTest { + return &blindedForwardTest{ + ht: ht, + } +} + +// setup spins up additional nodes needed for our test and creates a four hop +// network for testing blinded forwarding. +func (b *blindedForwardTest) setup() { + b.carol = b.ht.NewNode("Carol", nil) + b.dave = b.ht.NewNode("Dave", nil) + + b.channels = setupFourHopNetwork(b.ht, b.carol, b.dave) +} + +// cleanup tears down all channels created by the test. +func (b *blindedForwardTest) cleanup() { + b.ht.CloseChannel(b.ht.Alice, b.channels[0]) + b.ht.CloseChannel(b.ht.Bob, b.channels[1]) + b.ht.CloseChannel(b.carol, b.channels[2]) +} + +// setupFourHopNetwork creates a network with the following topology and +// liquidity: +// Alice (100k)----- Bob (100k) ----- Carol (100k) ----- Dave +// +// The funding outpoint for AB / BC / CD are returned in-order. +func setupFourHopNetwork(ht *lntest.HarnessTest, + carol, dave *node.HarnessNode) []*lnrpc.ChannelPoint { + + const chanAmt = btcutil.Amount(100000) + var networkChans []*lnrpc.ChannelPoint + + // Open a channel with 100k satoshis between Alice and Bob with Alice + // being the sole funder of the channel. + chanPointAlice := ht.OpenChannel( + ht.Alice, ht.Bob, lntest.OpenChannelParams{ + Amt: chanAmt, + }, + ) + networkChans = append(networkChans, chanPointAlice) + + // Create a channel between bob and carol. + ht.EnsureConnected(ht.Bob, carol) + chanPointBob := ht.OpenChannel( + ht.Bob, carol, lntest.OpenChannelParams{ + Amt: chanAmt, + }, + ) + networkChans = append(networkChans, chanPointBob) + + // Fund carol and connect her and dave so that she can create a channel + // between them. + ht.FundCoins(btcutil.SatoshiPerBitcoin, carol) + ht.EnsureConnected(carol, dave) + + chanPointCarol := ht.OpenChannel( + carol, dave, lntest.OpenChannelParams{ + Amt: chanAmt, + }, + ) + networkChans = append(networkChans, chanPointCarol) + + // Wait for all nodes to have seen all channels. + nodes := []*node.HarnessNode{ht.Alice, ht.Bob, carol, dave} + for _, chanPoint := range networkChans { + for _, node := range nodes { + ht.AssertTopologyChannelOpen(node, chanPoint) + } + } + + return []*lnrpc.ChannelPoint{ + chanPointAlice, + chanPointBob, + chanPointCarol, + } +} + +// testForwardBlindedRoute tests lnd's ability to forward payments in a blinded +// route. +func testForwardBlindedRoute(ht *lntest.HarnessTest) { + newBlindedForwardTest(ht) +}