Skip to content

Commit 0cbce93

Browse files
committed
itest: add coverage for experimental endorsement
1 parent 8f9e465 commit 0cbce93

File tree

3 files changed

+138
-3
lines changed

3 files changed

+138
-3
lines changed

itest/list_on_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,4 +642,8 @@ var allTestCases = []*lntest.TestCase{
642642
Name: "sweep commit output and anchor",
643643
TestFunc: testSweepCommitOutputAndAnchor,
644644
},
645+
{
646+
Name: "experimental endorsement",
647+
TestFunc: testExperimentalEndorsement,
648+
},
645649
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package itest
2+
3+
import (
4+
"math"
5+
6+
"github.com/btcsuite/btcd/btcutil"
7+
"github.com/lightningnetwork/lnd/lnrpc"
8+
"github.com/lightningnetwork/lnd/lnrpc/routerrpc"
9+
"github.com/lightningnetwork/lnd/lntest"
10+
"github.com/lightningnetwork/lnd/lntest/rpc"
11+
"github.com/lightningnetwork/lnd/lntest/wait"
12+
"github.com/lightningnetwork/lnd/lntypes"
13+
"github.com/lightningnetwork/lnd/lnwire"
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
// testExperimentalEndorsement tests setting of positive and negative
18+
// experimental endorsement signals.
19+
func testExperimentalEndorsement(ht *lntest.HarnessTest) {
20+
testEndorsement(ht, true)
21+
testEndorsement(ht, false)
22+
}
23+
24+
// testEndorsement sets up a 5 hop network and tests propagation of
25+
// experimental endorsement signals.
26+
func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) {
27+
alice, bob := ht.Alice, ht.Bob
28+
carol := ht.NewNode(
29+
"carol", []string{"--protocol.no-experimental-endorsement"},
30+
)
31+
dave := ht.NewNode("dave", nil)
32+
eve := ht.NewNode("eve", nil)
33+
34+
ht.EnsureConnected(alice, bob)
35+
ht.EnsureConnected(bob, carol)
36+
ht.EnsureConnected(carol, dave)
37+
ht.EnsureConnected(dave, eve)
38+
39+
ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
40+
ht.FundCoins(btcutil.SatoshiPerBitcoin, dave)
41+
// Open and wait for channels.
42+
const chanAmt = btcutil.Amount(300000)
43+
p := lntest.OpenChannelParams{Amt: chanAmt}
44+
reqs := []*lntest.OpenChannelRequest{
45+
{Local: alice, Remote: bob, Param: p},
46+
{Local: bob, Remote: carol, Param: p},
47+
{Local: carol, Remote: dave, Param: p},
48+
{Local: dave, Remote: eve, Param: p},
49+
}
50+
resp := ht.OpenMultiChannelsAsync(reqs)
51+
cpAB, cpBC, cpCD, cpDE := resp[0], resp[1], resp[2], resp[3]
52+
53+
// Make sure Alice is aware of Bob=>Carol=>Dave=>Eve channels.
54+
ht.AssertTopologyChannelOpen(alice, cpBC)
55+
ht.AssertTopologyChannelOpen(alice, cpCD)
56+
ht.AssertTopologyChannelOpen(alice, cpDE)
57+
58+
bobIntercept, cancelBob := bob.RPC.HtlcInterceptor()
59+
defer cancelBob()
60+
61+
carolIntercept, cancelCarol := carol.RPC.HtlcInterceptor()
62+
defer cancelCarol()
63+
64+
daveIntercept, cancelDave := dave.RPC.HtlcInterceptor()
65+
defer cancelDave()
66+
67+
req := &lnrpc.Invoice{ValueMsat: 1000}
68+
addResponse := eve.RPC.AddInvoice(req)
69+
invoice := eve.RPC.LookupInvoice(addResponse.RHash)
70+
71+
sendReq := &routerrpc.SendPaymentRequest{
72+
PaymentRequest: invoice.PaymentRequest,
73+
TimeoutSeconds: int32(wait.PaymentTimeout.Seconds()),
74+
FeeLimitMsat: math.MaxInt64,
75+
}
76+
77+
expectedValue := []byte{0}
78+
if aliceEndorse {
79+
expectedValue = []byte{7}
80+
t := uint64(lnwire.ExperimentalEndorsementType)
81+
sendReq.FirstHopCustomRecords = map[uint64][]byte{
82+
t: expectedValue,
83+
}
84+
}
85+
86+
_ = alice.RPC.SendPayment(sendReq)
87+
88+
// Validate that our signal (positive or zero) propagates until carol
89+
// and then is dropped because she has disabled the feature.
90+
validateEndorsedAndResume(ht, bobIntercept, 1, expectedValue)
91+
validateEndorsedAndResume(ht, carolIntercept, 1, expectedValue)
92+
validateEndorsedAndResume(ht, daveIntercept, 0, nil)
93+
94+
var preimage lntypes.Preimage
95+
copy(preimage[:], invoice.RPreimage)
96+
ht.AssertPaymentStatus(alice, preimage, lnrpc.Payment_SUCCEEDED)
97+
98+
ht.CloseChannel(alice, cpAB)
99+
ht.CloseChannel(bob, cpBC)
100+
ht.CloseChannel(carol, cpCD)
101+
}
102+
103+
func validateEndorsedAndResume(ht *lntest.HarnessTest,
104+
interceptor rpc.InterceptorClient, expectedRecords int,
105+
expectedValue []byte) {
106+
107+
packet := ht.ReceiveHtlcInterceptor(interceptor)
108+
109+
require.Len(ht, packet.IncomingHtlcWireCustomRecords, expectedRecords)
110+
111+
if expectedRecords == 1 {
112+
t := uint64(lnwire.ExperimentalEndorsementType)
113+
value, ok := packet.IncomingHtlcWireCustomRecords[t]
114+
require.True(ht, ok)
115+
116+
require.Equal(ht, expectedValue, value)
117+
}
118+
119+
err := interceptor.Send(&routerrpc.ForwardHtlcInterceptResponse{
120+
IncomingCircuitKey: packet.IncomingCircuitKey,
121+
Action: routerrpc.ResolveHoldForwardAction_RESUME,
122+
})
123+
require.NoError(ht, err)
124+
}

itest/lnd_forward_interceptor_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/lightningnetwork/lnd/lntest/node"
1515
"github.com/lightningnetwork/lnd/lntest/wait"
1616
"github.com/lightningnetwork/lnd/lntypes"
17+
"github.com/lightningnetwork/lnd/lnwire"
1718
"github.com/lightningnetwork/lnd/routing/route"
1819
"github.com/stretchr/testify/require"
1920
"google.golang.org/grpc/codes"
@@ -532,7 +533,8 @@ func testForwardInterceptorWireRecords(ht *lntest.HarnessTest) {
532533
// pending payment.
533534
packet := ht.ReceiveHtlcInterceptor(bobInterceptor)
534535

535-
require.Len(ht, packet.IncomingHtlcWireCustomRecords, 1)
536+
// We expect the custom record and an endorsement signal.
537+
require.Len(ht, packet.IncomingHtlcWireCustomRecords, 2)
536538

537539
val, ok := packet.IncomingHtlcWireCustomRecords[65537]
538540
require.True(ht, ok, "expected custom record")
@@ -549,9 +551,14 @@ func testForwardInterceptorWireRecords(ht *lntest.HarnessTest) {
549551
require.NoError(ht, err, "failed to send request")
550552

551553
// Assert that the Alice -> Bob custom records in update_add_htlc are
552-
// not propagated on the Bob -> Carol link.
554+
// not propagated on the Bob -> Carol link, but we do get our
555+
// experimental endorsement signal.
553556
packet = ht.ReceiveHtlcInterceptor(carolInterceptor)
554-
require.Len(ht, packet.IncomingHtlcWireCustomRecords, 0)
557+
require.Len(ht, packet.IncomingHtlcWireCustomRecords, 1)
558+
559+
t := uint64(lnwire.ExperimentalEndorsementType)
560+
_, ok = packet.IncomingHtlcWireCustomRecords[t]
561+
require.True(ht, ok)
555562

556563
// Just resume the payment on Carol.
557564
err = carolInterceptor.Send(&routerrpc.ForwardHtlcInterceptResponse{

0 commit comments

Comments
 (0)