From a72aaa3d84727d47d98159b85ffe78df8b4c519c Mon Sep 17 00:00:00 2001
From: Carla Kirk-Cohen <kirkcohenc@gmail.com>
Date: Tue, 13 Dec 2022 14:44:00 -0500
Subject: [PATCH] lntest: add setup for blinded route forwarding itest

Note: the itest is broken up into multiple commits to make it
more readable, they can be squashed post-review.
---
 itest/list_on_test.go                         |  4 +
 ...blinding.go => lnd_route_blinding_test.go} | 92 +++++++++++++++++++
 2 files changed, 96 insertions(+)
 rename itest/{lnd_route_blinding.go => lnd_route_blinding_test.go} (78%)

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)
+}