diff --git a/go.mod b/go.mod index dabae4d..bdd0d90 100644 --- a/go.mod +++ b/go.mod @@ -43,6 +43,7 @@ require ( ) require ( + github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 // indirect github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect github.com/aead/siphash v1.0.1 // indirect github.com/andybalholm/brotli v1.0.3 // indirect @@ -136,6 +137,7 @@ require ( github.com/ulikunitz/xz v0.5.10 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect + gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.etcd.io/bbolt v1.3.6 // indirect go.etcd.io/etcd/api/v3 v3.5.0 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.0 // indirect diff --git a/itest/zero_conf_node.go b/itest/breez_client.go similarity index 87% rename from itest/zero_conf_node.go rename to itest/breez_client.go index 4b472f1..f872ae5 100644 --- a/itest/zero_conf_node.go +++ b/itest/breez_client.go @@ -8,19 +8,17 @@ import ( "path/filepath" "github.com/breez/lntest" - btcec "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcec/v2/ecdsa" "github.com/btcsuite/btcd/chaincfg" - "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/zpay32" ) -type ZeroConfNode struct { +type breezClient struct { name string harness *lntest.TestHarness - lightningNode *lntest.CoreLightningNode - privKey *secp256k1.PrivateKey + lightningNode lntest.LightningNode scriptDir string } @@ -50,12 +48,7 @@ pip install pyln-client > /dev/null 2>&1 python %s ` -func NewZeroConfNode(h *lntest.TestHarness, m *lntest.Miner, name string) *ZeroConfNode { - privKey, err := btcec.NewPrivateKey() - lntest.CheckError(h.T, err) - - s := privKey.Serialize() - +func newClnBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) *breezClient { scriptDir, err := os.MkdirTemp(h.Dir, name) lntest.CheckError(h.T, err) pythonFilePath := filepath.Join(scriptDir, "zero_conf_plugin.py") @@ -88,7 +81,6 @@ func NewZeroConfNode(h *lntest.TestHarness, m *lntest.Miner, name string) *ZeroC h, m, name, - fmt.Sprintf("--dev-force-privkey=%x", s), fmt.Sprintf("--plugin=%s", pluginFilePath), // NOTE: max-concurrent-htlcs is 30 on mainnet by default. In cln V22.11 // there is a check for 'all dust' commitment transactions. The max @@ -99,12 +91,20 @@ func NewZeroConfNode(h *lntest.TestHarness, m *lntest.Miner, name string) *ZeroC "--max-concurrent-htlcs=30", ) - return &ZeroConfNode{ + return &breezClient{ name: name, harness: h, lightningNode: node, scriptDir: scriptDir, - privKey: privKey, + } +} + +func newLndBreezClient(h *lntest.TestHarness, m *lntest.Miner, name string) *breezClient { + lnd := lntest.NewLndNode(h, m, name) + return &breezClient{ + name: name, + harness: h, + lightningNode: lnd, } } @@ -122,7 +122,7 @@ type invoice struct { paymentPreimage []byte } -func (n *ZeroConfNode) GenerateInvoices(req generateInvoicesRequest) (invoice, invoice) { +func (n *breezClient) GenerateInvoices(req generateInvoicesRequest) (invoice, invoice) { preimage, err := GenerateRandomBytes(32) lntest.CheckError(n.harness.T, err) @@ -153,7 +153,7 @@ func (n *ZeroConfNode) GenerateInvoices(req generateInvoicesRequest) (invoice, i outerInvoice, err := outerInvoiceRaw.Encode(zpay32.MessageSigner{ SignCompact: func(msg []byte) ([]byte, error) { hash := sha256.Sum256(msg) - return ecdsa.SignCompact(n.privKey, hash[:], true) + return ecdsa.SignCompact(n.lightningNode.PrivateKey(), hash[:], true) }, }) lntest.CheckError(n.harness.T, err) diff --git a/itest/intercept_zero_conf_test.go b/itest/intercept_zero_conf_test.go index e0e64a9..079dcf4 100644 --- a/itest/intercept_zero_conf_test.go +++ b/itest/intercept_zero_conf_test.go @@ -8,15 +8,13 @@ import ( "github.com/stretchr/testify/assert" ) -func testOpenZeroConfChannelOnReceive(h *lntest.TestHarness, lsp LspNode, miner *lntest.Miner) { - alice := lntest.NewCoreLightningNode(h, miner, "Alice") - bob := NewZeroConfNode(h, miner, "Bob") - +func testOpenZeroConfChannelOnReceive(p *testParams) { + alice := lntest.NewCoreLightningNode(p.h, p.m, "Alice") alice.Fund(10000000) - lsp.LightningNode().Fund(10000000) + p.lsp.LightningNode().Fund(10000000) log.Print("Opening channel between Alice and the lsp") - channel := alice.OpenChannel(lsp.LightningNode(), &lntest.OpenChannelOptions{ + channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{ AmountSat: 1000000, }) alice.WaitForChannelReady(channel) @@ -25,50 +23,49 @@ func testOpenZeroConfChannelOnReceive(h *lntest.TestHarness, lsp LspNode, miner outerAmountMsat := uint64(2100000) innerAmountMsat := uint64(2100000) description := "Please pay me" - innerInvoice, outerInvoice := bob.GenerateInvoices(generateInvoicesRequest{ + innerInvoice, outerInvoice := p.BreezClient().GenerateInvoices(generateInvoicesRequest{ innerAmountMsat: innerAmountMsat, outerAmountMsat: outerAmountMsat, description: description, - lsp: lsp, + lsp: p.lsp, }) log.Print("Connecting bob to lspd") - bob.lightningNode.ConnectPeer(lsp.LightningNode()) + p.BreezClient().lightningNode.ConnectPeer(p.lsp.LightningNode()) // NOTE: We pretend to be paying fees to the lsp, but actually we won't. log.Printf("Registering payment with lsp") pretendAmount := outerAmountMsat - 2000000 - RegisterPayment(lsp, &lspd.PaymentInformation{ + RegisterPayment(p.lsp, &lspd.PaymentInformation{ PaymentHash: innerInvoice.paymentHash, PaymentSecret: innerInvoice.paymentSecret, - Destination: bob.lightningNode.NodeId(), + Destination: p.BreezClient().lightningNode.NodeId(), IncomingAmountMsat: int64(outerAmountMsat), OutgoingAmountMsat: int64(pretendAmount), }) log.Printf("Alice paying") payResp := alice.Pay(outerInvoice.bolt11) - bobInvoice := bob.lightningNode.GetInvoice(payResp.PaymentHash) + bobInvoice := p.BreezClient().lightningNode.GetInvoice(payResp.PaymentHash) - assert.Equal(h.T, payResp.PaymentPreimage, bobInvoice.PaymentPreimage) - assert.Equal(h.T, outerAmountMsat, bobInvoice.AmountReceivedMsat) + assert.Equal(p.t, payResp.PaymentPreimage, bobInvoice.PaymentPreimage) + assert.Equal(p.t, outerAmountMsat, bobInvoice.AmountReceivedMsat) // Make sure capacity is correct - chans := bob.lightningNode.GetChannels() - assert.Len(h.T, chans, 1) + chans := p.BreezClient().lightningNode.GetChannels() + assert.Len(p.t, chans, 1) c := chans[0] - AssertChannelCapacity(h.T, outerAmountMsat, c.CapacityMsat) + AssertChannelCapacity(p.t, outerAmountMsat, c.CapacityMsat) } -func testOpenZeroConfSingleHtlc(h *lntest.TestHarness, lsp LspNode, miner *lntest.Miner) { - alice := lntest.NewCoreLightningNode(h, miner, "Alice") - bob := NewZeroConfNode(h, miner, "Bob") +func testOpenZeroConfSingleHtlc(p *testParams) { + alice := lntest.NewCoreLightningNode(p.h, p.m, "Alice") alice.Fund(10000000) - lsp.LightningNode().Fund(10000000) + p.lsp.LightningNode().Fund(10000000) log.Print("Opening channel between Alice and the lsp") - channel := alice.OpenChannel(lsp.LightningNode(), &lntest.OpenChannelOptions{ + channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{ AmountSat: 1000000, }) channelId := alice.WaitForChannelReady(channel) @@ -77,40 +74,40 @@ func testOpenZeroConfSingleHtlc(h *lntest.TestHarness, lsp LspNode, miner *lntes outerAmountMsat := uint64(2100000) innerAmountMsat := uint64(2100000) description := "Please pay me" - innerInvoice, outerInvoice := bob.GenerateInvoices(generateInvoicesRequest{ + innerInvoice, outerInvoice := p.BreezClient().GenerateInvoices(generateInvoicesRequest{ innerAmountMsat: innerAmountMsat, outerAmountMsat: outerAmountMsat, description: description, - lsp: lsp, + lsp: p.lsp, }) log.Print("Connecting bob to lspd") - bob.lightningNode.ConnectPeer(lsp.LightningNode()) + p.BreezClient().lightningNode.ConnectPeer(p.lsp.LightningNode()) // NOTE: We pretend to be paying fees to the lsp, but actually we won't. log.Printf("Registering payment with lsp") pretendAmount := outerAmountMsat - 2000000 - RegisterPayment(lsp, &lspd.PaymentInformation{ + RegisterPayment(p.lsp, &lspd.PaymentInformation{ PaymentHash: innerInvoice.paymentHash, PaymentSecret: innerInvoice.paymentSecret, - Destination: bob.lightningNode.NodeId(), + Destination: p.BreezClient().lightningNode.NodeId(), IncomingAmountMsat: int64(outerAmountMsat), OutgoingAmountMsat: int64(pretendAmount), }) log.Printf("Alice paying") - route := constructRoute(lsp.LightningNode(), bob.lightningNode, channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat) + route := constructRoute(p.lsp.LightningNode(), p.BreezClient().lightningNode, channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat) payResp := alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route) - bobInvoice := bob.lightningNode.GetInvoice(payResp.PaymentHash) + bobInvoice := p.BreezClient().lightningNode.GetInvoice(payResp.PaymentHash) - assert.Equal(h.T, payResp.PaymentPreimage, bobInvoice.PaymentPreimage) - assert.Equal(h.T, outerAmountMsat, bobInvoice.AmountReceivedMsat) + assert.Equal(p.t, payResp.PaymentPreimage, bobInvoice.PaymentPreimage) + assert.Equal(p.t, outerAmountMsat, bobInvoice.AmountReceivedMsat) // Make sure capacity is correct - chans := bob.lightningNode.GetChannels() - assert.Len(h.T, chans, 1) + chans := p.BreezClient().lightningNode.GetChannels() + assert.Len(p.t, chans, 1) c := chans[0] - AssertChannelCapacity(h.T, outerAmountMsat, c.CapacityMsat) + AssertChannelCapacity(p.t, outerAmountMsat, c.CapacityMsat) } func constructRoute( diff --git a/itest/lspd_test.go b/itest/lspd_test.go index 366f953..bf34d4f 100644 --- a/itest/lspd_test.go +++ b/itest/lspd_test.go @@ -13,25 +13,25 @@ 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 { - // return NewLndLspdNode(h, m, "lsp") + // 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 { - return NewClnLspdNode(h, m, "lsp") + runTests(t, testCases, "CLN-lspd", func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, *breezClient) { + return NewClnLspdNode(h, m, "lsp"), newClnBreezClient(h, m, "breez-client") }) } -func runTests(t *testing.T, testCases []*testCase, prefix string, lspFunc func(h *lntest.TestHarness, m *lntest.Miner) LspNode) { +func runTests(t *testing.T, testCases []*testCase, prefix string, nodesFunc func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, *breezClient)) { for _, testCase := range testCases { testCase := testCase t.Run(fmt.Sprintf("%s: %s", prefix, testCase.name), func(t *testing.T) { - runTest(t, testCase, prefix, lspFunc) + runTest(t, testCase, prefix, nodesFunc) }) } } -func runTest(t *testing.T, testCase *testCase, prefix string, lspFunc func(h *lntest.TestHarness, m *lntest.Miner) LspNode) { +func runTest(t *testing.T, testCase *testCase, prefix string, nodesFunc func(h *lntest.TestHarness, m *lntest.Miner) (LspNode, *breezClient)) { log.Printf("%s: Running test case '%s'", prefix, testCase.name) var dd time.Duration to := testCase.timeout @@ -42,20 +42,26 @@ func runTest(t *testing.T, testCase *testCase, prefix string, lspFunc func(h *ln deadline := time.Now().Add(to) log.Printf("Using deadline %v", deadline.String()) - harness := lntest.NewTestHarness(t, deadline) - defer harness.TearDown() + h := lntest.NewTestHarness(t, deadline) + defer h.TearDown() log.Printf("Creating miner") - miner := lntest.NewMiner(harness) + miner := lntest.NewMiner(h) log.Printf("Creating lsp") - lsp := lspFunc(harness, miner) + lsp, c := nodesFunc(h, miner) log.Printf("Run testcase") - testCase.test(harness, lsp, miner) + testCase.test(&testParams{ + t: t, + h: h, + m: miner, + c: c, + lsp: lsp, + }) } type testCase struct { name string - test func(h *lntest.TestHarness, lsp LspNode, miner *lntest.Miner) + test func(t *testParams) timeout time.Duration } diff --git a/itest/test_params.go b/itest/test_params.go new file mode 100644 index 0000000..5343940 --- /dev/null +++ b/itest/test_params.go @@ -0,0 +1,35 @@ +package itest + +import ( + "testing" + + "github.com/breez/lntest" +) + +type testParams struct { + t *testing.T + h *lntest.TestHarness + m *lntest.Miner + c *breezClient + lsp LspNode +} + +func (h *testParams) T() *testing.T { + return h.t +} + +func (h *testParams) Miner() *lntest.Miner { + return h.m +} + +func (h *testParams) Lsp() LspNode { + return h.lsp +} + +func (h *testParams) Harness() *lntest.TestHarness { + return h.h +} + +func (h *testParams) BreezClient() *breezClient { + return h.c +} diff --git a/itest/zero_reserve_test.go b/itest/zero_reserve_test.go index 36aa9d5..bc218ce 100644 --- a/itest/zero_reserve_test.go +++ b/itest/zero_reserve_test.go @@ -8,15 +8,13 @@ import ( "github.com/stretchr/testify/assert" ) -func testZeroReserve(h *lntest.TestHarness, lsp LspNode, miner *lntest.Miner) { - alice := lntest.NewCoreLightningNode(h, miner, "Alice") - bob := NewZeroConfNode(h, miner, "Bob") - +func testZeroReserve(p *testParams) { + alice := lntest.NewCoreLightningNode(p.h, p.m, "Alice") alice.Fund(10000000) - lsp.LightningNode().Fund(10000000) + p.lsp.LightningNode().Fund(10000000) log.Print("Opening channel between Alice and the lsp") - channel := alice.OpenChannel(lsp.LightningNode(), &lntest.OpenChannelOptions{ + channel := alice.OpenChannel(p.lsp.LightningNode(), &lntest.OpenChannelOptions{ AmountSat: 1000000, }) channelId := alice.WaitForChannelReady(channel) @@ -25,36 +23,36 @@ func testZeroReserve(h *lntest.TestHarness, lsp LspNode, miner *lntest.Miner) { outerAmountMsat := uint64(2100000) innerAmountMsat := uint64(2100000) description := "Please pay me" - innerInvoice, outerInvoice := bob.GenerateInvoices(generateInvoicesRequest{ + innerInvoice, outerInvoice := p.BreezClient().GenerateInvoices(generateInvoicesRequest{ innerAmountMsat: innerAmountMsat, outerAmountMsat: outerAmountMsat, description: description, - lsp: lsp, + lsp: p.lsp, }) log.Print("Connecting bob to lspd") - bob.lightningNode.ConnectPeer(lsp.LightningNode()) + p.BreezClient().lightningNode.ConnectPeer(p.lsp.LightningNode()) // NOTE: We pretend to be paying fees to the lsp, but actually we won't. log.Printf("Registering payment with lsp") pretendAmount := outerAmountMsat - 2000000 - RegisterPayment(lsp, &lspd.PaymentInformation{ + RegisterPayment(p.lsp, &lspd.PaymentInformation{ PaymentHash: innerInvoice.paymentHash, PaymentSecret: innerInvoice.paymentSecret, - Destination: bob.lightningNode.NodeId(), + Destination: p.BreezClient().lightningNode.NodeId(), IncomingAmountMsat: int64(outerAmountMsat), OutgoingAmountMsat: int64(pretendAmount), }) log.Printf("Alice paying") - route := constructRoute(lsp.LightningNode(), bob.lightningNode, channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat) + route := constructRoute(p.lsp.LightningNode(), p.BreezClient().lightningNode, channelId, lntest.NewShortChanIDFromString("1x0x0"), outerAmountMsat) alice.PayViaRoute(outerAmountMsat, outerInvoice.paymentHash, outerInvoice.paymentSecret, route) // Make sure balance is correct - chans := bob.lightningNode.GetChannels() - assert.Len(h.T, chans, 1) + chans := p.BreezClient().lightningNode.GetChannels() + assert.Len(p.t, chans, 1) c := chans[0] - assert.Equal(h.T, c.RemoteReserveMsat, c.CapacityMsat/100) - assert.Zero(h.T, c.LocalReserveMsat) + assert.Equal(p.t, c.RemoteReserveMsat, c.CapacityMsat/100) + assert.Zero(p.t, c.LocalReserveMsat) }