Skip to content

Commit

Permalink
lsps2: add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
JssDWt committed Sep 8, 2023
1 parent f0fd2bd commit c56fd28
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 5 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/integration_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ jobs:
testLsps2GetVersions,
testLsps2GetInfo,
testLsps2Buy,
testLsps2HappyFlow
testLsps2HappyFlow,
testLsps2Cltv,
testLsps2NoBalance,
testLsps2ZeroConfUtxo
]
implementation: [
CLN
Expand Down
15 changes: 15 additions & 0 deletions itest/lspd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,19 @@ var allTestCases = []*testCase{
test: testLsps2HappyFlow,
isLsps2: true,
},
{
name: "testLsps2Cltv",
test: testLsps2Cltv,
isLsps2: true,
},
{
name: "testLsps2NoBalance",
test: testLsps2NoBalance,
isLsps2: true,
},
{
name: "testLsps2ZeroConfUtxo",
test: testLsps2ZeroConfUtxo,
isLsps2: true,
},
}
44 changes: 40 additions & 4 deletions itest/lsps2_buy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import (
"time"

"github.com/breez/lntest"
"github.com/breez/lspd/lightning"
"github.com/breez/lspd/lsps0"
"github.com/jackc/pgx/v4/pgxpool"
"github.com/stretchr/testify/assert"
)

func testLsps2Buy(p *testParams) {
Expand Down Expand Up @@ -62,20 +65,20 @@ func testLsps2Buy(p *testParams) {
Type: lsps0.Lsps0MessageType,
Data: append(append(
[]byte(`{
"method": "lsps2.get_info",
"method": "lsps2.buy",
"jsonrpc": "2.0",
"id": "example#3cad6a54d302edba4c9ade2f7ffac098",
"id": "example#3cad6a54d302edba4c9ade2f7ffac099",
"params": {
"version": 1,
"payment_size_msat": "42000",
"payment_size_msat": "42000000",
"opening_fee_params":`),
pr...),
[]byte(`}}`)...,
),
})

buyResp := p.BreezClient().ReceiveCustomMessage()
log.Print(string(resp.Data))
log.Print(string(buyResp.Data))
b := new(struct {
Result struct {
Jit_channel_scid string `json:"jit_channel_scid"`
Expand All @@ -85,4 +88,37 @@ func testLsps2Buy(p *testParams) {
})
err = json.Unmarshal(buyResp.Data, b)
lntest.CheckError(p.t, err)

pgxPool, err := pgxpool.Connect(p.h.Ctx, p.lsp.PostgresBackend().ConnectionString())
if err != nil {
p.h.T.Fatalf("Failed to connect to postgres backend: %v", err)
}
defer pgxPool.Close()

scid, err := lightning.NewShortChannelIDFromString(b.Result.Jit_channel_scid)
lntest.CheckError(p.t, err)

rows, err := pgxPool.Query(
p.h.Ctx,
`SELECT token
FROM lsps2.buy_registrations
WHERE scid = $1`,
int64(uint64(*scid)),
)
if err != nil {
p.h.T.Fatalf("Failed to query token: %v", err)
}

defer rows.Close()
if !rows.Next() {
p.h.T.Fatal("No rows found")
}

var actual string
err = rows.Scan(&actual)
if err != nil {
p.h.T.Fatalf("Failed to get token from row: %v", err)
}

assert.Equal(p.h.T, "hello", actual)
}
63 changes: 63 additions & 0 deletions itest/lsps2_cltv_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package itest

import (
"log"
"time"

"github.com/breez/lntest"
"github.com/breez/lspd/lsps2"
"github.com/stretchr/testify/assert"
)

func testLsps2Cltv(p *testParams) {
alice := lntest.NewClnNode(p.h, p.m, "Alice")
alice.Start()
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: publicChanAmount,
})
aliceLspScid := alice.WaitForChannelReady(channel)

log.Print("Connecting bob to lspd")
p.BreezClient().Node().ConnectPeer(p.lsp.LightningNode())

log.Printf("Calling lsps2.get_info")
info := Lsps2GetInfo(p.BreezClient(), p.Lsp(), lsps2.GetInfoRequest{
Token: &WorkingToken,
})

outerAmountMsat := uint64(2100000)
innerAmountMsat := lsps2CalculateInnerAmountMsat(p.lsp, outerAmountMsat, info.OpeningFeeParamsMenu[0])
p.BreezClient().SetHtlcAcceptor(innerAmountMsat)

log.Printf("Calling lsps2.buy")
buyResp := Lsps2Buy(p.BreezClient(), p.Lsp(), lsps2.BuyRequest{
OpeningFeeParams: *info.OpeningFeeParamsMenu[0],
PaymentSizeMsat: &outerAmountMsat,
})

log.Printf("Adding bob's invoices")
description := "Please pay me"
_, outerInvoice := GenerateLsps2Invoices(p.BreezClient(),
generateInvoicesRequest{
innerAmountMsat: innerAmountMsat,
outerAmountMsat: outerAmountMsat,
description: description,
lsp: p.lsp,
},
buyResp.JitChannelScid)

// 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().Node(), aliceLspScid, lntest.NewShortChanIDFromString(buyResp.JitChannelScid), outerAmountMsat)

// Increment the delay by one (should be incremented by 2), so the cltv delta is too little.
route.Hops[0].Delay++
_, err := alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route)
assert.Contains(p.t, err.Error(), "WIRE_INCORRECT_CLTV_EXPIRY")
}
4 changes: 4 additions & 0 deletions itest/lsps2_happy_flow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,8 @@ func testLsps2HappyFlow(p *testParams) {
assert.Equal(p.t, 1, len(chans))
c := chans[0]
AssertChannelCapacity(p.t, innerAmountMsat, c.CapacityMsat)

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)
}
62 changes: 62 additions & 0 deletions itest/lsps2_no_balance_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package itest

import (
"log"
"time"

"github.com/breez/lntest"
"github.com/breez/lspd/lsps2"
"github.com/stretchr/testify/assert"
)

func testLsps2NoBalance(p *testParams) {
alice := lntest.NewClnNode(p.h, p.m, "Alice")
alice.Start()
alice.Fund(10000000)

log.Print("Opening channel between Alice and the lsp")
channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{
AmountSat: publicChanAmount,
})
aliceLspScid := alice.WaitForChannelReady(channel)

log.Print("Connecting bob to lspd")
p.BreezClient().Node().ConnectPeer(p.lsp.LightningNode())

log.Printf("Calling lsps2.get_info")
info := Lsps2GetInfo(p.BreezClient(), p.Lsp(), lsps2.GetInfoRequest{
Token: &WorkingToken,
})

outerAmountMsat := uint64(2100000)
innerAmountMsat := lsps2CalculateInnerAmountMsat(p.lsp, outerAmountMsat, info.OpeningFeeParamsMenu[0])
p.BreezClient().SetHtlcAcceptor(innerAmountMsat)

log.Printf("Calling lsps2.buy")
buyResp := Lsps2Buy(p.BreezClient(), p.Lsp(), lsps2.BuyRequest{
OpeningFeeParams: *info.OpeningFeeParamsMenu[0],
PaymentSizeMsat: &outerAmountMsat,
})

log.Printf("Adding bob's invoices")
description := "Please pay me"
_, outerInvoice := GenerateLsps2Invoices(p.BreezClient(),
generateInvoicesRequest{
innerAmountMsat: innerAmountMsat,
outerAmountMsat: outerAmountMsat,
description: description,
lsp: p.lsp,
},
buyResp.JitChannelScid)

// 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().Node(), aliceLspScid, lntest.NewShortChanIDFromString(buyResp.JitChannelScid), outerAmountMsat)

// Increment the delay by two to support the spec
route.Hops[0].Delay += 2
_, err := alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route)
assert.Contains(p.t, err.Error(), "WIRE_TEMPORARY_CHANNEL_FAILURE")
}
81 changes: 81 additions & 0 deletions itest/lsps2_zero_conf_utxo_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package itest

import (
"log"
"time"

"github.com/breez/lntest"
"github.com/breez/lspd/config"
"github.com/breez/lspd/lsps2"
"github.com/stretchr/testify/assert"
)

func testLsps2ZeroConfUtxo(p *testParams) {
alice := lntest.NewClnNode(p.h, p.m, "Alice")
alice.Start()
alice.Fund(10000000)

minConfs := uint32(0)
lsp := p.lspFunc(p.h, p.m, p.mem, &config.NodeConfig{MinConfs: &minConfs})
lsp.Start()

log.Print("Opening channel between Alice and the lsp")
channel := alice.OpenChannel(lsp.LightningNode(), &lntest.OpenChannelOptions{
AmountSat: publicChanAmount,
})
channelId := alice.WaitForChannelReady(channel)

tempaddr := lsp.LightningNode().GetNewAddress()
p.m.SendToAddress(tempaddr, 210000)
p.m.MineBlocks(6)
lsp.LightningNode().WaitForSync()

initialHeight := p.m.GetBlockHeight()
addr := lsp.LightningNode().GetNewAddress()
lsp.LightningNode().SendToAddress(addr, 200000)

log.Print("Connecting bob to lspd")
p.BreezClient().Node().ConnectPeer(p.lsp.LightningNode())

log.Printf("Calling lsps2.get_info")
info := Lsps2GetInfo(p.BreezClient(), p.Lsp(), lsps2.GetInfoRequest{
Token: &WorkingToken,
})

outerAmountMsat := uint64(2100000)
innerAmountMsat := lsps2CalculateInnerAmountMsat(p.lsp, outerAmountMsat, info.OpeningFeeParamsMenu[0])
p.BreezClient().SetHtlcAcceptor(innerAmountMsat)

log.Printf("Calling lsps2.buy")
buyResp := Lsps2Buy(p.BreezClient(), p.Lsp(), lsps2.BuyRequest{
OpeningFeeParams: *info.OpeningFeeParamsMenu[0],
PaymentSizeMsat: &outerAmountMsat,
})

log.Printf("Adding bob's invoices")
description := "Please pay me"
_, outerInvoice := GenerateLsps2Invoices(p.BreezClient(),
generateInvoicesRequest{
innerAmountMsat: innerAmountMsat,
outerAmountMsat: outerAmountMsat,
description: description,
lsp: p.lsp,
},
buyResp.JitChannelScid)

// 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(lsp.LightningNode(), p.BreezClient().Node(), channelId, lntest.NewShortChanIDFromString(buyResp.JitChannelScid), outerAmountMsat)
payResp, err := alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route)
lntest.CheckError(p.t, err)
bobInvoice := p.BreezClient().Node().GetInvoice(payResp.PaymentHash)

assert.Equal(p.t, payResp.PaymentPreimage, bobInvoice.PaymentPreimage)
assert.Equal(p.t, innerAmountMsat, bobInvoice.AmountReceivedMsat)

// Make sure there's not accidently a block mined in between
finalHeight := p.m.GetBlockHeight()
assert.Equal(p.t, initialHeight, finalHeight)
}

0 comments on commit c56fd28

Please sign in to comment.