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 diff --git a/Makefile b/Makefile index 4a8d91e99..ec7eb6419 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" @@ -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 # ========= 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() 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 + } +}