From 9370c9128653d294a9700bf2456ae6fb8eaf97e6 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 29 Jul 2024 18:17:57 +0200 Subject: [PATCH 1/4] accounts: split mocks This is a preparation for bumping the lndclient dependency. Because each lndclient service mock now needs to implement the RawClientWithMacAuth method but with a different type, we can't implement two lndclient service mocks within a single struct, as that would require us to have two methods with the same name but different types. So we split the lnd and rounter mocks into two separate structs. --- accounts/checkers_test.go | 21 ++-- accounts/service_test.go | 213 ++++++++++++++++++++++++-------------- 2 files changed, 149 insertions(+), 85 deletions(-) diff --git a/accounts/checkers_test.go b/accounts/checkers_test.go index c2d503acf..19e3070e3 100644 --- a/accounts/checkers_test.go +++ b/accounts/checkers_test.go @@ -513,13 +513,14 @@ func testSendPayment(t *testing.T, uri string) { } lndMock := newMockLnd() + routerMock := newMockRouter() errFunc := func(err error) { lndMock.mainErrChan <- err } service, err := NewService(t.TempDir(), errFunc) require.NoError(t, err) - err = service.Start(lndMock, lndMock, chainParams) + err = service.Start(lndMock, routerMock, chainParams) require.NoError(t, err) assertBalance := func(id AccountID, expectedBalance int64) { @@ -615,7 +616,7 @@ func testSendPayment(t *testing.T, uri string) { require.NoError(t, err) assertBalance(acct.ID, 4000) - lndMock.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ + routerMock.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ testHash: {}, }) @@ -646,7 +647,7 @@ func testSendPayment(t *testing.T, uri string) { // was initiated. assertBalance(acct.ID, 4000) - lndMock.assertNoPaymentRequest(t) + routerMock.assertNoPaymentRequest(t) // The final test we will do is to have two send requests initiated // before the response for the first one has been received. @@ -708,13 +709,14 @@ func TestSendPaymentV2(t *testing.T) { } lndMock := newMockLnd() + routerMock := newMockRouter() errFunc := func(err error) { lndMock.mainErrChan <- err } service, err := NewService(t.TempDir(), errFunc) require.NoError(t, err) - err = service.Start(lndMock, lndMock, chainParams) + err = service.Start(lndMock, routerMock, chainParams) require.NoError(t, err) assertBalance := func(id AccountID, expectedBalance int64) { @@ -808,7 +810,7 @@ func TestSendPaymentV2(t *testing.T) { require.NoError(t, err) assertBalance(acct.ID, 4000) - lndMock.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ + routerMock.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ testHash: {}, }) @@ -836,7 +838,7 @@ func TestSendPaymentV2(t *testing.T) { // was initiated. assertBalance(acct.ID, 4000) - lndMock.assertNoPaymentRequest(t) + routerMock.assertNoPaymentRequest(t) // The final test we will do is to have two send requests initiated // before the response for the first one has been received. @@ -894,13 +896,14 @@ func TestSendToRouteV2(t *testing.T) { } lndMock := newMockLnd() + routerMock := newMockRouter() errFunc := func(err error) { lndMock.mainErrChan <- err } service, err := NewService(t.TempDir(), errFunc) require.NoError(t, err) - err = service.Start(lndMock, lndMock, chainParams) + err = service.Start(lndMock, routerMock, chainParams) require.NoError(t, err) assertBalance := func(id AccountID, expectedBalance int64) { @@ -998,7 +1001,7 @@ func TestSendToRouteV2(t *testing.T) { require.NoError(t, err) assertBalance(acct.ID, 4000) - lndMock.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ + routerMock.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ testHash: {}, }) @@ -1028,7 +1031,7 @@ func TestSendToRouteV2(t *testing.T) { // was initiated. assertBalance(acct.ID, 4000) - lndMock.assertNoPaymentRequest(t) + routerMock.assertNoPaymentRequest(t) // The final test we will do is to have two send requests initiated // before the response for the first one has been received. diff --git a/accounts/service_test.go b/accounts/service_test.go index 66fa5d266..2583f612e 100644 --- a/accounts/service_test.go +++ b/accounts/service_test.go @@ -10,6 +10,7 @@ import ( "github.com/lightningnetwork/lnd/channeldb" invpkg "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntypes" "github.com/stretchr/testify/require" ) @@ -31,14 +32,10 @@ type mockLnd struct { mainErrChan chan error invoiceReq chan lndclient.InvoiceSubscriptionRequest - paymentReq chan lntypes.Hash invoiceSubscriptionErr error - trackPaymentErr error invoiceErrChan chan error - paymentErrChan chan error invoiceChan chan *lndclient.Invoice - paymentChans map[lntypes.Hash]chan lndclient.PaymentStatus } func newMockLnd() *mockLnd { @@ -47,16 +44,19 @@ func newMockLnd() *mockLnd { invoiceReq: make( chan lndclient.InvoiceSubscriptionRequest, 10, ), - paymentReq: make(chan lntypes.Hash, 10), invoiceErrChan: make(chan error, 10), - paymentErrChan: make(chan error, 10), invoiceChan: make(chan *lndclient.Invoice), - paymentChans: make( - map[lntypes.Hash]chan lndclient.PaymentStatus, - ), } } +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (m *mockLnd) RawClientWithMacAuth(ctx context.Context) (context.Context, + time.Duration, lnrpc.LightningClient) { + + return ctx, 0, nil +} + func (m *mockLnd) assertNoMainErr(t *testing.T) { select { case err := <-m.mainErrChan: @@ -100,23 +100,69 @@ func (m *mockLnd) assertInvoiceRequest(t *testing.T, addIndex, } } -func (m *mockLnd) assertNoPaymentRequest(t *testing.T) { +// SubscribeInvoices allows a client to subscribe to updates of newly +// added/settled invoices. +func (m *mockLnd) SubscribeInvoices(_ context.Context, + req lndclient.InvoiceSubscriptionRequest) (<-chan *lndclient.Invoice, + <-chan error, error) { + + if m.invoiceSubscriptionErr != nil { + return nil, nil, m.invoiceSubscriptionErr + } + + m.invoiceReq <- req + + return m.invoiceChan, m.invoiceErrChan, nil +} + +type mockRouter struct { + lndclient.RouterClient + + mainErrChan chan error + + paymentReq chan lntypes.Hash + + trackPaymentErr error + paymentErrChan chan error + paymentChans map[lntypes.Hash]chan lndclient.PaymentStatus +} + +func newMockRouter() *mockRouter { + return &mockRouter{ + mainErrChan: make(chan error, 10), + paymentReq: make(chan lntypes.Hash, 10), + paymentErrChan: make(chan error, 10), + paymentChans: make( + map[lntypes.Hash]chan lndclient.PaymentStatus, + ), + } +} + +// RawClientWithMacAuth returns a context with the proper macaroon +// authentication, the default RPC timeout, and the raw client. +func (r *mockRouter) RawClientWithMacAuth(ctx context.Context) (context.Context, + time.Duration, routerrpc.RouterClient) { + + return ctx, 0, nil +} + +func (r *mockRouter) assertNoPaymentRequest(t *testing.T) { select { - case req := <-m.paymentReq: + case req := <-r.paymentReq: t.Fatalf("Expected no payment request, got %v", req) default: } } -func (m *mockLnd) assertPaymentRequests(t *testing.T, +func (r *mockRouter) assertPaymentRequests(t *testing.T, hashes map[lntypes.Hash]struct{}) { overallTimeout := time.After(testTimeout) for { select { - case hash := <-m.paymentReq: + case hash := <-r.paymentReq: require.Contains(t, hashes, hash) delete(hashes, hash) @@ -132,34 +178,19 @@ func (m *mockLnd) assertPaymentRequests(t *testing.T, } } -// SubscribeInvoices allows a client to subscribe to updates of newly -// added/settled invoices. -func (m *mockLnd) SubscribeInvoices(_ context.Context, - req lndclient.InvoiceSubscriptionRequest) (<-chan *lndclient.Invoice, - <-chan error, error) { - - if m.invoiceSubscriptionErr != nil { - return nil, nil, m.invoiceSubscriptionErr - } - - m.invoiceReq <- req - - return m.invoiceChan, m.invoiceErrChan, nil -} - // TrackPayment picks up a previously started payment and returns a payment // update stream and an error stream. -func (m *mockLnd) TrackPayment(_ context.Context, +func (r *mockRouter) TrackPayment(_ context.Context, hash lntypes.Hash) (chan lndclient.PaymentStatus, chan error, error) { - if m.trackPaymentErr != nil { - return nil, nil, m.trackPaymentErr + if r.trackPaymentErr != nil { + return nil, nil, r.trackPaymentErr } - m.paymentReq <- hash - m.paymentChans[hash] = make(chan lndclient.PaymentStatus, 1) + r.paymentReq <- hash + r.paymentChans[hash] = make(chan lndclient.PaymentStatus, 1) - return m.paymentChans[hash], m.paymentErrChan, nil + return r.paymentChans[hash], r.paymentErrChan, nil } // TestAccountService tests that the account service can track payments and @@ -169,18 +200,20 @@ func TestAccountService(t *testing.T) { testCases := []struct { name string - setup func(t *testing.T, lnd *mockLnd, + setup func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) startupErr string - validate func(t *testing.T, lnd *mockLnd, + validate func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) }{{ name: "startup err on invoice subscription", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + lnd.invoiceSubscriptionErr = testErr }, startupErr: testErr.Error(), - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { lnd.assertNoInvoiceRequest(t) @@ -188,7 +221,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "err on invoice update", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -201,7 +236,7 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { // Start by closing the store. This should cause an @@ -232,7 +267,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "err in invoice err channel", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -245,7 +282,7 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { // Ensure that the service was started successfully. require.True(t, s.IsRunning()) @@ -264,7 +301,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "goroutine err sent on main err chan", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -280,7 +319,7 @@ func TestAccountService(t *testing.T) { s.mainErrCallback(testErr) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { lnd.assertInvoiceRequest(t, 0, 0) @@ -288,7 +327,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "startup do not track completed payments", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct, err := s.store.NewAccount( 1234, testExpiration, "", ) @@ -303,18 +344,20 @@ func TestAccountService(t *testing.T) { err = s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { require.Contains(t, s.invoiceToAccount, testHash) - lnd.assertNoPaymentRequest(t) + r.assertNoPaymentRequest(t) lnd.assertInvoiceRequest(t, 0, 0) lnd.assertNoMainErr(t) require.True(t, s.IsRunning()) }, }, { name: "startup err on payment tracking", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -333,9 +376,9 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) - lnd.trackPaymentErr = testErr + r.trackPaymentErr = testErr }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { // Assert that the invoice subscription succeeded. @@ -348,11 +391,13 @@ func TestAccountService(t *testing.T) { // payment to pending payment, and that lnd isn't awaiting // the payment request. require.NotContains(t, s.pendingPayments, testHash) - lnd.assertNoPaymentRequest(t) + r.assertNoPaymentRequest(t) }, }, { name: "err on payment update", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -368,12 +413,13 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { + // Ensure that the service was started successfully, // and lnd contains the payment request. require.True(t, s.IsRunning()) - lnd.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ + r.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ testHash: {}, }) @@ -385,7 +431,7 @@ func TestAccountService(t *testing.T) { // Send an invalid payment over the payment chan // which should error and disable the service - lnd.paymentChans[testHash] <- lndclient.PaymentStatus{ + r.paymentChans[testHash] <- lndclient.PaymentStatus{ State: lnrpc.Payment_SUCCEEDED, Fee: 234, Value: 1000, @@ -402,7 +448,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "err in payment update chan", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -418,18 +466,19 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { + // Ensure that the service was started successfully, // and lnd contains the payment request. require.True(t, s.IsRunning()) - lnd.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ + r.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ testHash: {}, }) // Now let's send an error over the payment error // channel. This should disable the service. - lnd.paymentErrChan <- testErr + r.paymentErrChan <- testErr // Ensure that the service was eventually disabled. assertEventually(t, func() bool { @@ -441,7 +490,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "startup track in-flight payments", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -468,11 +519,11 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { require.Contains(t, s.invoiceToAccount, testHash) - lnd.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ + r.assertPaymentRequests(t, map[lntypes.Hash]struct{}{ testHash: {}, testHash2: {}, testHash3: {}, @@ -482,7 +533,7 @@ func TestAccountService(t *testing.T) { // Send an actual payment update and make sure the // amount is debited from the account. - lnd.paymentChans[testHash] <- lndclient.PaymentStatus{ + r.paymentChans[testHash] <- lndclient.PaymentStatus{ State: lnrpc.Payment_SUCCEEDED, Fee: 500, Value: 1500, @@ -498,7 +549,7 @@ func TestAccountService(t *testing.T) { // Remove the other payment and make sure it disappears // from the tracked payments and is also updated // correctly in the account store. - lnd.paymentChans[testHash2] <- lndclient.PaymentStatus{ + r.paymentChans[testHash2] <- lndclient.PaymentStatus{ State: lnrpc.Payment_FAILED, Fee: 0, Value: 1000, @@ -538,7 +589,7 @@ func TestAccountService(t *testing.T) { require.ErrorIs(t, err, ErrAccBalanceInsufficient) // Now signal that the payment was non-initiated. - lnd.paymentErrChan <- channeldb.ErrPaymentNotInitiated + r.paymentErrChan <- channeldb.ErrPaymentNotInitiated // Once the error is handled in the service.TrackPayment // goroutine, and therefore free up the 2000 in-flight @@ -572,11 +623,13 @@ func TestAccountService(t *testing.T) { }, }, { name: "keep track of invoice indexes", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + err := s.store.StoreLastIndexes(987_654, 555_555) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { // We expect the initial subscription to start at the @@ -621,7 +674,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "credit account", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + acct := &OffChainBalanceAccount{ ID: testID, Type: TypeInitialBalance, @@ -636,7 +691,7 @@ func TestAccountService(t *testing.T) { err := s.store.UpdateAccount(acct) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { lnd.assertInvoiceRequest(t, 0, 0) @@ -676,7 +731,9 @@ func TestAccountService(t *testing.T) { }, }, { name: "in-flight payments", - setup: func(t *testing.T, lnd *mockLnd, s *InterceptorService) { + setup: func(t *testing.T, lnd *mockLnd, r *mockRouter, + s *InterceptorService) { + // We set up two accounts with a balance of 5k msats. // The first account has two in-flight payments, one of @@ -723,7 +780,7 @@ func TestAccountService(t *testing.T) { err = s.store.UpdateAccount(acct2) require.NoError(t, err) }, - validate: func(t *testing.T, lnd *mockLnd, + validate: func(t *testing.T, lnd *mockLnd, r *mockRouter, s *InterceptorService) { // The first should be able to initiate another payment @@ -739,7 +796,7 @@ func TestAccountService(t *testing.T) { // Remove one of the payments (to simulate it failed) // and try again. - lnd.paymentChans[testHash] <- lndclient.PaymentStatus{ + r.paymentChans[testHash] <- lndclient.PaymentStatus{ State: lnrpc.Payment_FAILED, } @@ -767,6 +824,7 @@ func TestAccountService(t *testing.T) { tt.Parallel() lndMock := newMockLnd() + routerMock := newMockRouter() errFunc := func(err error) { lndMock.mainErrChan <- err } @@ -776,18 +834,21 @@ func TestAccountService(t *testing.T) { // Is a setup call required to initialize initial // conditions? if tc.setup != nil { - tc.setup(t, lndMock, service) + tc.setup(t, lndMock, routerMock, service) } // Any errors during startup expected? - err = service.Start(lndMock, lndMock, chainParams) + err = service.Start(lndMock, routerMock, chainParams) if tc.startupErr != "" { require.ErrorContains(tt, err, tc.startupErr) lndMock.assertNoMainErr(t) if tc.validate != nil { - tc.validate(tt, lndMock, service) + tc.validate( + tt, lndMock, routerMock, + service, + ) } return @@ -795,7 +856,7 @@ func TestAccountService(t *testing.T) { // Any post execution validation that we need to run? if tc.validate != nil { - tc.validate(tt, lndMock, service) + tc.validate(tt, lndMock, routerMock, service) } err = service.Stop() From 7cead0194ac775db1c69355a00a332a108dfa0c7 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 23 May 2024 13:50:07 +0200 Subject: [PATCH 2/4] make+perms: allow itest to run with dev build tag The dev flag allows us to enable some of lnd's configuration flags that are only available for testing. To speed up any wallet interaction, we also add the lowscrypt build tag that chooses weak encryption for the wallet that is much faster (a couple of milliseconds vs. multiple seconds per wallet creation). --- Makefile | 2 +- perms/mock.go | 3 ++ perms/mock_dev.go | 94 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 perms/mock_dev.go diff --git a/Makefile b/Makefile index 4a8d91e99..677be1bb5 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,7 @@ DOCKER_TOOLS = docker run \ -v $(shell bash -c "mkdir -p /tmp/go-lint-cache; echo /tmp/go-lint-cache"):/root/.cache/golangci-lint \ -v $$(pwd):/build litd-tools -ITEST_TAGS := integration itest $(LND_RELEASE_TAGS) +ITEST_TAGS := dev integration itest lowscrypt $(LND_RELEASE_TAGS) ITEST_LDFLAGS := $(call make_ldflags, $(ITEST_TAGS)) GREEN := "\\033[0;32m" diff --git a/perms/mock.go b/perms/mock.go index 06b6ee1d3..d4fea281d 100644 --- a/perms/mock.go +++ b/perms/mock.go @@ -1,3 +1,6 @@ +//go:build !dev +// +build !dev + package perms import ( diff --git a/perms/mock_dev.go b/perms/mock_dev.go new file mode 100644 index 000000000..52289f1c0 --- /dev/null +++ b/perms/mock_dev.go @@ -0,0 +1,94 @@ +//go:build dev +// +build dev + +package perms + +import ( + "net" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/lightningnetwork/lnd/autopilot" + "github.com/lightningnetwork/lnd/chainreg" + "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/lnrpc" + "github.com/lightningnetwork/lnd/lnrpc/autopilotrpc" + "github.com/lightningnetwork/lnd/lnrpc/chainrpc" + "github.com/lightningnetwork/lnd/lnrpc/devrpc" + "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc" + "github.com/lightningnetwork/lnd/lnrpc/neutrinorpc" + "github.com/lightningnetwork/lnd/lnrpc/peersrpc" + "github.com/lightningnetwork/lnd/lnrpc/routerrpc" + "github.com/lightningnetwork/lnd/lnrpc/signrpc" + "github.com/lightningnetwork/lnd/lnrpc/walletrpc" + "github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc" + "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc" + "github.com/lightningnetwork/lnd/lntest/mock" + "github.com/lightningnetwork/lnd/routing" + "github.com/lightningnetwork/lnd/sweep" +) + +// mockConfig implements lnrpc.SubServerConfigDispatcher. It provides the +// functionality required so that the lnrpc.GrpcHandler.CreateSubServer +// function can be called without panicking. +type mockConfig struct{} + +var _ lnrpc.SubServerConfigDispatcher = (*mockConfig)(nil) + +// FetchConfig is a mock implementation of lnrpc.SubServerConfigDispatcher. It +// is used as a parameter to lnrpc.GrpcHandler.CreateSubServer and allows the +// function to be called without panicking. This is useful because +// CreateSubServer can be used to extract the permissions required by each +// registered subserver. +// +// TODO(elle): remove this once the sub-server permission lists in LND have been +// exported +func (t *mockConfig) FetchConfig(subServerName string) (interface{}, bool) { + switch subServerName { + case "InvoicesRPC": + return &invoicesrpc.Config{}, true + case "WatchtowerClientRPC": + return &wtclientrpc.Config{ + Resolver: func(_, _ string) (*net.TCPAddr, error) { + return nil, nil + }, + }, true + case "AutopilotRPC": + return &autopilotrpc.Config{ + Manager: &autopilot.Manager{}, + }, true + case "ChainRPC": + return &chainrpc.Config{ + ChainNotifier: &chainreg.NoChainBackend{}, + Chain: &mock.ChainIO{}, + }, true + case "DevRPC": + return &devrpc.Config{ + ActiveNetParams: &chaincfg.RegressionNetParams, + GraphDB: &channeldb.ChannelGraph{}, + }, true + case "NeutrinoKitRPC": + return &neutrinorpc.Config{}, true + case "PeersRPC": + return &peersrpc.Config{}, true + case "RouterRPC": + return &routerrpc.Config{ + Router: &routing.ChannelRouter{}, + }, true + case "SignRPC": + return &signrpc.Config{ + Signer: &mock.DummySigner{}, + }, true + case "WalletKitRPC": + return &walletrpc.Config{ + FeeEstimator: &chainreg.NoChainBackend{}, + Wallet: &mock.WalletController{}, + KeyRing: &mock.SecretKeyRing{}, + Sweeper: &sweep.UtxoSweeper{}, + Chain: &mock.ChainIO{}, + }, true + case "WatchtowerRPC": + return &watchtowerrpc.Config{}, true + default: + return nil, false + } +} From a7aabcd21bd563d12c6c51260c4898b565df6170 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 26 Jun 2024 16:29:32 +0200 Subject: [PATCH 3/4] make: add flake-itest-only goal --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 677be1bb5..ec7eb6419 100644 --- a/Makefile +++ b/Makefile @@ -238,6 +238,10 @@ flake-unit: @$(call print, "Flake hunting unit tests.") while [ $$? -eq 0 ]; do GOTRACEBACK=all $(UNIT) -count=1; done +flake-itest-only: + @$(call print, "Flake hunting integration tests.") + while [ $$? -eq 0 ]; do make itest-only icase='${icase}'; done + # ========= # UTILITIES # ========= From f50fb91ed609c3336b29a3ca967980909ead858d Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 26 Jun 2024 22:35:03 +0200 Subject: [PATCH 4/4] GitHub: upload logs on failure --- .github/workflows/main.yml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cb4a33d7f..ded029f9f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,8 +24,8 @@ jobs: strategy: matrix: - node_version: [16.x] - os: [ubuntu-latest, windows-latest, macOS-latest] + node_version: [ 16.x ] + os: [ ubuntu-latest, windows-latest, macOS-latest ] steps: - name: git checkout @@ -63,8 +63,8 @@ jobs: strategy: matrix: - go_version: [1.18.x] - os: [ubuntu-latest, windows-latest, macOS-latest] + go_version: [ 1.18.x ] + os: [ ubuntu-latest, windows-latest, macOS-latest ] steps: - name: git checkout @@ -84,7 +84,7 @@ jobs: - name: build backend binary run: make build - + - name: build CLI binaries run: make go-install-cli @@ -244,6 +244,19 @@ jobs: - name: run check run: make itest + - name: Zip log files on failure + if: ${{ failure() }} + timeout-minutes: 5 + run: 7z a logs-itest.zip itest/**/*.log + + - name: Upload log files on failure + uses: actions/upload-artifact@v3 + if: ${{ failure() }} + with: + name: logs-itest + path: logs-itest.zip + retention-days: 5 + ######################## # check PR updates release notes ######################## @@ -256,4 +269,4 @@ jobs: uses: actions/checkout@v3 - name: release notes check - run: scripts/check-release-notes.sh \ No newline at end of file + run: scripts/check-release-notes.sh