make LND tests work

This commit is contained in:
Jesse de Wit
2022-12-16 10:32:30 +01:00
parent 4b6eaf3773
commit 08f2f73b5d
7 changed files with 99 additions and 24 deletions

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.19
require (
github.com/aws/aws-sdk-go v1.30.20
github.com/breez/lntest v0.0.9
github.com/breez/lntest v0.0.10
github.com/btcsuite/btcd v0.23.3
github.com/btcsuite/btcd/btcec/v2 v2.2.1
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1

View File

@@ -3,11 +3,13 @@ package itest
import (
"bufio"
"crypto/sha256"
"flag"
"fmt"
"os"
"path/filepath"
"github.com/breez/lntest"
"github.com/breez/lntest/lnd"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/chaincfg"
@@ -77,7 +79,7 @@ func newClnBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) *bre
lntest.CheckError(h.T, err)
pluginFile.Close()
node := lntest.NewCoreLightningNode(
node := lntest.NewClnNode(
h,
m,
name,
@@ -99,8 +101,19 @@ func newClnBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) *bre
}
}
var lndMobileExecutable = flag.String(
"lndmobileexec", "", "full path to lnd mobile binary",
)
func newLndBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) *breezClient {
lnd := lntest.NewLndNode(h, m, name)
lnd := lntest.NewLndNodeFromBinary(h, m, name, *lndMobileExecutable,
"--protocol.zero-conf",
"--protocol.option-scid-alias",
"--bitcoin.defaultchanconfs=0",
)
go startChannelAcceptor(h, lnd)
return &breezClient{
name: name,
harness: h,
@@ -108,6 +121,31 @@ func newLndBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) *bre
}
}
func startChannelAcceptor(h *lntest.TestHarness, n *lntest.LndNode) error {
client, err := n.LightningClient().ChannelAcceptor(h.Ctx)
lntest.CheckError(h.T, err)
for {
request, err := client.Recv()
if err != nil {
return err
}
private := request.ChannelFlags&uint32(lnwire.FFAnnounceChannel) == 0
resp := &lnd.ChannelAcceptResponse{
PendingChanId: request.PendingChanId,
Accept: private,
}
if request.WantsZeroConf {
resp.MinAcceptDepth = 0
resp.ZeroConf = true
}
err = client.Send(resp)
lntest.CheckError(h.T, err)
}
}
type generateInvoicesRequest struct {
innerAmountMsat uint64
outerAmountMsat uint64

View File

@@ -2,26 +2,29 @@ package itest
import (
"log"
"time"
"github.com/breez/lntest"
lspd "github.com/breez/lspd/rpc"
"github.com/stretchr/testify/assert"
)
var htlcInterceptorDelay = time.Second * 7
func testOpenZeroConfChannelOnReceive(p *testParams) {
alice := lntest.NewCoreLightningNode(p.h, p.m, "Alice")
alice := lntest.NewClnNode(p.h, p.m, "Alice")
alice.Fund(10000000)
p.lsp.LightningNode().Fund(10000000)
log.Print("Opening channel between Alice and the lsp")
channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{
AmountSat: 1000000,
AmountSat: publicChanAmount,
})
alice.WaitForChannelReady(channel)
log.Printf("Adding bob's invoices")
outerAmountMsat := uint64(2100000)
innerAmountMsat := uint64(2100000)
innerAmountMsat := calculateInnerAmountMsat(p.lsp, outerAmountMsat)
description := "Please pay me"
innerInvoice, outerInvoice := p.BreezClient().GenerateInvoices(generateInvoicesRequest{
innerAmountMsat: innerAmountMsat,
@@ -44,12 +47,15 @@ func testOpenZeroConfChannelOnReceive(p *testParams) {
OutgoingAmountMsat: int64(pretendAmount),
})
// TODO: Fix race waiting for htlc interceptor.
log.Printf("Waiting %v to allow htlc interceptor to activate.", htlcInterceptorDelay)
<-time.After(htlcInterceptorDelay)
log.Printf("Alice paying")
payResp := alice.Pay(outerInvoice.bolt11)
bobInvoice := p.BreezClient().lightningNode.GetInvoice(payResp.PaymentHash)
assert.Equal(p.t, payResp.PaymentPreimage, bobInvoice.PaymentPreimage)
assert.Equal(p.t, outerAmountMsat, bobInvoice.AmountReceivedMsat)
assert.Equal(p.t, innerAmountMsat, bobInvoice.AmountReceivedMsat)
// Make sure capacity is correct
chans := p.BreezClient().lightningNode.GetChannels()
@@ -59,20 +65,20 @@ func testOpenZeroConfChannelOnReceive(p *testParams) {
}
func testOpenZeroConfSingleHtlc(p *testParams) {
alice := lntest.NewCoreLightningNode(p.h, p.m, "Alice")
alice := lntest.NewClnNode(p.h, p.m, "Alice")
alice.Fund(10000000)
p.lsp.LightningNode().Fund(10000000)
log.Print("Opening channel between Alice and the lsp")
channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{
AmountSat: 1000000,
AmountSat: publicChanAmount,
})
channelId := alice.WaitForChannelReady(channel)
log.Printf("Adding bob's invoices")
outerAmountMsat := uint64(2100000)
innerAmountMsat := uint64(2100000)
innerAmountMsat := calculateInnerAmountMsat(p.lsp, outerAmountMsat)
description := "Please pay me"
innerInvoice, outerInvoice := p.BreezClient().GenerateInvoices(generateInvoicesRequest{
innerAmountMsat: innerAmountMsat,
@@ -95,13 +101,16 @@ func testOpenZeroConfSingleHtlc(p *testParams) {
OutgoingAmountMsat: int64(pretendAmount),
})
// TODO: Fix race waiting for htlc interceptor.
log.Printf("Waiting %v to allow htlc interceptor to activate.", htlcInterceptorDelay)
<-time.After(htlcInterceptorDelay)
log.Printf("Alice paying")
route := constructRoute(p.lsp.LightningNode(), p.BreezClient().lightningNode, channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat)
payResp := alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route)
bobInvoice := p.BreezClient().lightningNode.GetInvoice(payResp.PaymentHash)
assert.Equal(p.t, payResp.PaymentPreimage, bobInvoice.PaymentPreimage)
assert.Equal(p.t, outerAmountMsat, bobInvoice.AmountReceivedMsat)
assert.Equal(p.t, innerAmountMsat, bobInvoice.AmountReceivedMsat)
// Make sure capacity is correct
chans := p.BreezClient().lightningNode.GetChannels()

View File

@@ -43,11 +43,12 @@ type LspNode interface {
Rpc() lspd.ChannelOpenerClient
NodeId() []byte
LightningNode() lntest.LightningNode
SupportsChargingFees() bool
}
type ClnLspNode struct {
harness *lntest.TestHarness
lightningNode *lntest.CoreLightningNode
lightningNode *lntest.ClnNode
rpc lspd.ChannelOpenerClient
publicKey btcec.PublicKey
eciesPublicKey ecies.PublicKey
@@ -72,11 +73,11 @@ func (c *ClnLspNode) Rpc() lspd.ChannelOpenerClient {
func (l *ClnLspNode) TearDown() error {
// NOTE: The lightningnode will be torn down on its own.
return l.postgresBackend.Shutdown(l.harness.Ctx)
return l.postgresBackend.Shutdown(context.Background())
}
func (l *ClnLspNode) Cleanup() error {
return l.postgresBackend.Cleanup(l.harness.Ctx)
return l.postgresBackend.Cleanup(context.Background())
}
func (l *ClnLspNode) NodeId() []byte {
@@ -87,6 +88,10 @@ func (l *ClnLspNode) LightningNode() lntest.LightningNode {
return l.lightningNode
}
func (l *ClnLspNode) SupportsChargingFees() bool {
return false
}
type LndLspNode struct {
harness *lntest.TestHarness
lightningNode *lntest.LndNode
@@ -113,6 +118,9 @@ func (c *LndLspNode) EciesPublicKey() *ecies.PublicKey {
func (c *LndLspNode) Rpc() lspd.ChannelOpenerClient {
return c.rpc
}
func (l *LndLspNode) SupportsChargingFees() bool {
return true
}
func (l *LndLspNode) TearDown() error {
// NOTE: The lightningnode will be torn down on its own.
@@ -130,11 +138,11 @@ func (l *LndLspNode) TearDown() error {
}
}
return l.postgresBackend.Shutdown(l.harness.Ctx)
return l.postgresBackend.Shutdown(context.Background())
}
func (l *LndLspNode) Cleanup() error {
return l.postgresBackend.Cleanup(l.harness.Ctx)
return l.postgresBackend.Cleanup(context.Background())
}
func (l *LndLspNode) NodeId() []byte {
@@ -156,7 +164,7 @@ func NewClnLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string) LspNode
"--dev-allowdustreserve=true",
}
lightningNode := lntest.NewCoreLightningNode(h, m, name, args...)
lightningNode := lntest.NewClnNode(h, m, name, args...)
conn, err := grpc.Dial(
grpcAddress,
@@ -187,7 +195,7 @@ func NewLndLspdNode(h *lntest.TestHarness, m *lntest.Miner, name string) LspNode
"--protocol.option-scid-alias",
"--requireinterceptor",
"--bitcoin.defaultchanconfs=0",
"--bitcoin.chanreservescript=\"0\"",
fmt.Sprintf("--bitcoin.chanreservescript=\"0 if (chanAmt != %d) else chanAmt/100\"", publicChanAmount),
fmt.Sprintf("--bitcoin.basefee=%d", lspBaseFeeMsat),
fmt.Sprintf("--bitcoin.feerate=%d", lspFeeRatePpm),
fmt.Sprintf("--bitcoin.timelockdelta=%d", lspCltvDelta),

View File

@@ -13,9 +13,9 @@ var defaultTimeout time.Duration = time.Second * 120
func TestLspd(t *testing.T) {
testCases := allTestCases
// runTests(t, testCases, "LND-lspd", func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, *breezClient) {
// return NewLndLspdNode(h, m, "lsp"), newLndBreezClient(h, m, "breez-client")
// })
runTests(t, testCases, "LND-lspd", func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, *breezClient) {
return NewLndLspdNode(h, m, "lsp"), newLndBreezClient(h, m, "breez-client")
})
runTests(t, testCases, "CLN-lspd", func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, *breezClient) {
return NewClnLspdNode(h, m, "lsp"), newClnBreezClient(h, m, "breez-client")

View File

@@ -25,3 +25,18 @@ func AssertChannelCapacity(
) {
assert.Equal(t, ((outerAmountMsat/1000)+100000)*1000, capacityMsat)
}
func calculateInnerAmountMsat(lsp LspNode, outerAmountMsat uint64) uint64 {
if lsp.SupportsChargingFees() {
fee := outerAmountMsat * 40 / 10_000 / 1_000 * 1_000
if fee < 2000000 {
fee = 2000000
}
return outerAmountMsat - fee
} else {
return outerAmountMsat
}
}
var publicChanAmount uint64 = 1000183

View File

@@ -2,6 +2,7 @@ package itest
import (
"log"
"time"
"github.com/breez/lntest"
lspd "github.com/breez/lspd/rpc"
@@ -9,19 +10,19 @@ import (
)
func testZeroReserve(p *testParams) {
alice := lntest.NewCoreLightningNode(p.h, p.m, "Alice")
alice := lntest.NewClnNode(p.h, p.m, "Alice")
alice.Fund(10000000)
p.lsp.LightningNode().Fund(10000000)
log.Print("Opening channel between Alice and the lsp")
channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{
AmountSat: 1000000,
AmountSat: publicChanAmount,
})
channelId := alice.WaitForChannelReady(channel)
log.Printf("Adding bob's invoices")
outerAmountMsat := uint64(2100000)
innerAmountMsat := uint64(2100000)
innerAmountMsat := calculateInnerAmountMsat(p.lsp, outerAmountMsat)
description := "Please pay me"
innerInvoice, outerInvoice := p.BreezClient().GenerateInvoices(generateInvoicesRequest{
innerAmountMsat: innerAmountMsat,
@@ -44,6 +45,9 @@ func testZeroReserve(p *testParams) {
OutgoingAmountMsat: int64(pretendAmount),
})
// TODO: Fix race waiting for htlc interceptor.
log.Printf("Waiting %v to allow htlc interceptor to activate.", htlcInterceptorDelay)
<-time.After(htlcInterceptorDelay)
log.Printf("Alice paying")
route := constructRoute(p.lsp.LightningNode(), p.BreezClient().lightningNode, channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat)
alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route)
@@ -54,5 +58,6 @@ func testZeroReserve(p *testParams) {
c := chans[0]
assert.Equal(p.t, c.RemoteReserveMsat, c.CapacityMsat/100)
log.Printf("local reserve: %d, remote reserve: %d", c.LocalReserveMsat, c.RemoteReserveMsat)
assert.Zero(p.t, c.LocalReserveMsat)
}