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