mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-26 17:52:25 +01:00
itest: refactor testSendToRouteErrorPropagation
This commit is contained in:
parent
787883870b
commit
25b6ff3336
@ -2042,3 +2042,35 @@ func (h *HarnessTest) AssertNumInvoices(hn *node.HarnessNode,
|
||||
|
||||
return invoices
|
||||
}
|
||||
|
||||
// ReceiveSendToRouteUpdate waits until a message is received on the
|
||||
// SendToRoute client stream or the timeout is reached.
|
||||
func (h *HarnessTest) ReceiveSendToRouteUpdate(
|
||||
stream rpc.SendToRouteClient) (*lnrpc.SendResponse, error) {
|
||||
|
||||
chanMsg := make(chan *lnrpc.SendResponse, 1)
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
// Consume one message. This will block until the message is
|
||||
// received.
|
||||
resp, err := stream.Recv()
|
||||
if err != nil {
|
||||
errChan <- err
|
||||
|
||||
return
|
||||
}
|
||||
chanMsg <- resp
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-time.After(DefaultTimeout):
|
||||
require.Fail(h, "timeout", "timeout waiting for send resp")
|
||||
return nil, nil
|
||||
|
||||
case err := <-errChan:
|
||||
return nil, err
|
||||
|
||||
case updateMsg := <-chanMsg:
|
||||
return updateMsg, nil
|
||||
}
|
||||
}
|
||||
|
@ -481,8 +481,10 @@ func (h *HarnessRPC) QueryRoutes(
|
||||
return routes
|
||||
}
|
||||
|
||||
type SendToRouteClient lnrpc.Lightning_SendToRouteClient
|
||||
|
||||
// SendToRoute makes a RPC call to SendToRoute and asserts.
|
||||
func (h *HarnessRPC) SendToRoute() lnrpc.Lightning_SendToRouteClient {
|
||||
func (h *HarnessRPC) SendToRoute() SendToRouteClient {
|
||||
// SendToRoute needs to have the context alive for the entire test case
|
||||
// as the returned client will be used for send and receive payment
|
||||
// stream. Thus we use runCtx here instead of a timeout context.
|
||||
|
@ -317,4 +317,8 @@ var allTestCasesTemp = []*lntemp.TestCase{
|
||||
Name: "multi-hop send to route",
|
||||
TestFunc: testMultiHopSendToRoute,
|
||||
},
|
||||
{
|
||||
Name: "send to route error propagation",
|
||||
TestFunc: testSendToRouteErrorPropagation,
|
||||
},
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -410,54 +409,32 @@ func runMultiHopSendToRoute(ht *lntemp.HarnessTest, useGraphCache bool) {
|
||||
|
||||
// testSendToRouteErrorPropagation tests propagation of errors that occur
|
||||
// while processing a multi-hop payment through an unknown route.
|
||||
func testSendToRouteErrorPropagation(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
ctxb := context.Background()
|
||||
|
||||
func testSendToRouteErrorPropagation(ht *lntemp.HarnessTest) {
|
||||
const chanAmt = btcutil.Amount(100000)
|
||||
|
||||
// Open a channel with 100k satoshis between Alice and Bob with Alice
|
||||
// being the sole funder of the channel.
|
||||
chanPointAlice := openChannelAndAssert(
|
||||
t, net, net.Alice, net.Bob,
|
||||
lntest.OpenChannelParams{
|
||||
Amt: chanAmt,
|
||||
},
|
||||
alice, bob := ht.Alice, ht.Bob
|
||||
chanPointAlice := ht.OpenChannel(
|
||||
alice, bob, lntemp.OpenChannelParams{Amt: chanAmt},
|
||||
)
|
||||
|
||||
err := net.Alice.WaitForNetworkChannelOpen(chanPointAlice)
|
||||
if err != nil {
|
||||
t.Fatalf("alice didn't advertise her channel: %v", err)
|
||||
}
|
||||
|
||||
// Create a new nodes (Carol and Charlie), load her with some funds,
|
||||
// then establish a connection between Carol and Charlie with a channel
|
||||
// that has identical capacity to the one created above.Then we will
|
||||
// get route via queryroutes call which will be fake route for Alice ->
|
||||
// Bob graph.
|
||||
//
|
||||
// The network topology should now look like: Alice -> Bob; Carol -> Charlie.
|
||||
carol := net.NewNode(t.t, "Carol", nil)
|
||||
defer shutdownAndAssert(net, t, carol)
|
||||
// The network topology should now look like:
|
||||
// Alice -> Bob; Carol -> Charlie.
|
||||
carol := ht.NewNode("Carol", nil)
|
||||
ht.FundCoins(btcutil.SatoshiPerBitcoin, carol)
|
||||
|
||||
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, carol)
|
||||
charlie := ht.NewNode("Charlie", nil)
|
||||
ht.FundCoins(btcutil.SatoshiPerBitcoin, charlie)
|
||||
|
||||
charlie := net.NewNode(t.t, "Charlie", nil)
|
||||
defer shutdownAndAssert(net, t, charlie)
|
||||
|
||||
net.SendCoins(t.t, btcutil.SatoshiPerBitcoin, charlie)
|
||||
|
||||
net.ConnectNodes(t.t, carol, charlie)
|
||||
|
||||
chanPointCarol := openChannelAndAssert(
|
||||
t, net, carol, charlie,
|
||||
lntest.OpenChannelParams{
|
||||
Amt: chanAmt,
|
||||
},
|
||||
)
|
||||
err = carol.WaitForNetworkChannelOpen(chanPointCarol)
|
||||
if err != nil {
|
||||
t.Fatalf("carol didn't advertise her channel: %v", err)
|
||||
}
|
||||
ht.ConnectNodes(carol, charlie)
|
||||
ht.OpenChannel(carol, charlie, lntemp.OpenChannelParams{Amt: chanAmt})
|
||||
|
||||
// Query routes from Carol to Charlie which will be an invalid route
|
||||
// for Alice -> Bob.
|
||||
@ -465,54 +442,37 @@ func testSendToRouteErrorPropagation(net *lntest.NetworkHarness, t *harnessTest)
|
||||
PubKey: charlie.PubKeyStr,
|
||||
Amt: int64(1),
|
||||
}
|
||||
ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
|
||||
fakeRoute, err := carol.QueryRoutes(ctxt, fakeReq)
|
||||
if err != nil {
|
||||
t.Fatalf("unable get fake route: %v", err)
|
||||
}
|
||||
fakeRoute := carol.RPC.QueryRoutes(fakeReq)
|
||||
|
||||
// Create 1 invoices for Bob, which expect a payment from Alice for 1k
|
||||
// satoshis
|
||||
// Create 1 invoice for Bob, which expect a payment from Alice for 1k
|
||||
// satoshis.
|
||||
const paymentAmt = 1000
|
||||
|
||||
invoice := &lnrpc.Invoice{
|
||||
Memo: "testing",
|
||||
Value: paymentAmt,
|
||||
}
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
resp, err := net.Bob.AddInvoice(ctxt, invoice)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to add invoice: %v", err)
|
||||
}
|
||||
|
||||
resp := bob.RPC.AddInvoice(invoice)
|
||||
rHash := resp.RHash
|
||||
|
||||
// Using Alice as the source, pay to the 5 invoices from Bob created above.
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
alicePayStream, err := net.Alice.SendToRoute(ctxt) // nolint:staticcheck
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create payment stream for alice: %v", err)
|
||||
}
|
||||
// Using Alice as the source, pay to the invoice from Bob.
|
||||
alicePayStream := alice.RPC.SendToRoute()
|
||||
|
||||
sendReq := &lnrpc.SendToRouteRequest{
|
||||
PaymentHash: rHash,
|
||||
Route: fakeRoute.Routes[0],
|
||||
}
|
||||
|
||||
if err := alicePayStream.Send(sendReq); err != nil {
|
||||
t.Fatalf("unable to send payment: %v", err)
|
||||
}
|
||||
err := alicePayStream.Send(sendReq)
|
||||
require.NoError(ht, err, "unable to send payment")
|
||||
|
||||
// At this place we should get an rpc error with notification
|
||||
// that edge is not found on hop(0)
|
||||
_, err = alicePayStream.Recv()
|
||||
if err != nil && strings.Contains(err.Error(), "edge not found") {
|
||||
} else if err != nil {
|
||||
t.Fatalf("payment stream has been closed but fake route has consumed: %v", err)
|
||||
}
|
||||
event, err := ht.ReceiveSendToRouteUpdate(alicePayStream)
|
||||
require.NoError(ht, err, "payment stream has been closed but fake "+
|
||||
"route has consumed")
|
||||
require.Contains(ht, event.PaymentError, "UnknownNextPeer")
|
||||
|
||||
closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false)
|
||||
closeChannelAndAssert(t, net, carol, chanPointCarol, false)
|
||||
ht.CloseChannel(alice, chanPointAlice)
|
||||
}
|
||||
|
||||
// testPrivateChannels tests that a private channel can be used for
|
||||
|
@ -8,10 +8,6 @@ var allTestCases = []*testCase{
|
||||
name: "single hop invoice",
|
||||
test: testSingleHopInvoice,
|
||||
},
|
||||
{
|
||||
name: "send to route error propagation",
|
||||
test: testSendToRouteErrorPropagation,
|
||||
},
|
||||
{
|
||||
name: "private channels",
|
||||
test: testPrivateChannels,
|
||||
|
Loading…
x
Reference in New Issue
Block a user