diff --git a/accounts/checkers_test.go b/accounts/checkers_test.go index 8c8c6c763..3f1f28d76 100644 --- a/accounts/checkers_test.go +++ b/accounts/checkers_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/btcsuite/btcd/chaincfg" + "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" "github.com/lightningnetwork/lnd/lntypes" @@ -523,7 +524,8 @@ func testSendPayment(t *testing.T, uri string) { errFunc := func(err error) { lndMock.mainErrChan <- err } - store := NewTestDB(t) + clock := clock.NewTestClock(time.Now()) + store := NewTestDB(t, clock) service, err := NewService(store, errFunc) require.NoError(t, err) @@ -546,7 +548,7 @@ func testSendPayment(t *testing.T, uri string) { // Create an account and add it to the context. acct, err := service.NewAccount( - ctx, 5000, time.Now().Add(time.Hour), "test", + ctx, 5000, clock.Now().Add(time.Hour), "test", ) require.NoError(t, err) @@ -720,7 +722,8 @@ func TestSendPaymentV2(t *testing.T) { errFunc := func(err error) { lndMock.mainErrChan <- err } - store := NewTestDB(t) + clock := clock.NewTestClock(time.Now()) + store := NewTestDB(t, clock) service, err := NewService(store, errFunc) require.NoError(t, err) @@ -743,7 +746,7 @@ func TestSendPaymentV2(t *testing.T) { // Create an account and add it to the context. acct, err := service.NewAccount( - ctx, 5000, time.Now().Add(time.Hour), "test", + ctx, 5000, clock.Now().Add(time.Hour), "test", ) require.NoError(t, err) @@ -908,7 +911,8 @@ func TestSendToRouteV2(t *testing.T) { errFunc := func(err error) { lndMock.mainErrChan <- err } - store := NewTestDB(t) + clock := clock.NewTestClock(time.Now()) + store := NewTestDB(t, clock) service, err := NewService(store, errFunc) require.NoError(t, err) @@ -931,7 +935,7 @@ func TestSendToRouteV2(t *testing.T) { // Create an account and add it to the context. acct, err := service.NewAccount( - ctx, 5000, time.Now().Add(time.Hour), "test", + ctx, 5000, clock.Now().Add(time.Hour), "test", ) require.NoError(t, err) diff --git a/accounts/service_test.go b/accounts/service_test.go index 0f2497710..bdf044df0 100644 --- a/accounts/service_test.go +++ b/accounts/service_test.go @@ -8,6 +8,7 @@ import ( "github.com/lightninglabs/lndclient" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/clock" invpkg "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" @@ -832,7 +833,7 @@ func TestAccountService(t *testing.T) { errFunc := func(err error) { lndMock.mainErrChan <- err } - store := NewTestDB(t) + store := NewTestDB(t, clock.NewTestClock(time.Now())) service, err := NewService(store, errFunc) require.NoError(t, err) diff --git a/accounts/store_kvdb.go b/accounts/store_kvdb.go index 54c25beb7..e6b63b2c8 100644 --- a/accounts/store_kvdb.go +++ b/accounts/store_kvdb.go @@ -12,6 +12,7 @@ import ( "time" "github.com/btcsuite/btcwallet/walletdb" + "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lnrpc" @@ -59,12 +60,13 @@ var ( // BoltStore wraps the bolt DB that stores all accounts and their balances. type BoltStore struct { - db kvdb.Backend + db kvdb.Backend + clock clock.Clock } // NewBoltStore creates a BoltStore instance and the corresponding bucket in the // bolt DB if it does not exist yet. -func NewBoltStore(dir, fileName string) (*BoltStore, error) { +func NewBoltStore(dir, fileName string, clock clock.Clock) (*BoltStore, error) { // Ensure that the path to the directory exists. if _, err := os.Stat(dir); os.IsNotExist(err) { if err := os.MkdirAll(dir, dbPathPermission); err != nil { @@ -98,7 +100,10 @@ func NewBoltStore(dir, fileName string) (*BoltStore, error) { } // Return the DB wrapped in a BoltStore object. - return &BoltStore{db: db}, nil + return &BoltStore{ + db: db, + clock: clock, + }, nil } // Close closes the underlying bolt DB. @@ -170,7 +175,7 @@ func (s *BoltStore) NewAccount(ctx context.Context, balance lnwire.MilliSatoshi, } account.ID = id - return storeAccount(bucket, account) + return s.storeAccount(bucket, account) }, func() { account.ID = zeroID }) @@ -194,7 +199,7 @@ func (s *BoltStore) UpdateAccount(_ context.Context, return ErrAccountBucketNotFound } - return storeAccount(bucket, account) + return s.storeAccount(bucket, account) }, func() {}) } @@ -365,7 +370,7 @@ func (s *BoltStore) updateAccount(id AccountID, return fmt.Errorf("error updating account, %w", err) } - err = storeAccount(bucket, account) + err = s.storeAccount(bucket, account) if err != nil { return fmt.Errorf("error storing account, %w", err) } @@ -376,10 +381,10 @@ func (s *BoltStore) updateAccount(id AccountID, // storeAccount serializes and writes the given account to the given account // bucket. -func storeAccount(accountBucket kvdb.RwBucket, +func (s *BoltStore) storeAccount(accountBucket kvdb.RwBucket, account *OffChainBalanceAccount) error { - account.LastUpdate = time.Now() + account.LastUpdate = s.clock.Now() accountBinary, err := serializeAccount(account) if err != nil { diff --git a/accounts/store_test.go b/accounts/store_test.go index a5bcbeb30..544e688f6 100644 --- a/accounts/store_test.go +++ b/accounts/store_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lntypes" @@ -17,7 +18,8 @@ func TestAccountStore(t *testing.T) { t.Parallel() ctx := context.Background() - store := NewTestDB(t) + clock := clock.NewTestClock(time.Now()) + store := NewTestDB(t, clock) // Create an account that does not expire. acct1, err := store.NewAccount(ctx, 0, time.Time{}, "foo") @@ -39,7 +41,7 @@ func TestAccountStore(t *testing.T) { // Update all values of the account that we can modify. acct1.CurrentBalance = -500 - acct1.ExpirationDate = time.Now() + acct1.ExpirationDate = clock.Now() acct1.Payments[lntypes.Hash{12, 34, 56, 78}] = &PaymentEntry{ Status: lnrpc.Payment_FAILED, FullAmount: 123456, @@ -114,7 +116,8 @@ func TestAccountUpdateMethods(t *testing.T) { ctx := context.Background() t.Run("UpdateAccountBalanceAndExpiry", func(t *testing.T) { - store := NewTestDB(t) + clock := clock.NewTestClock(time.Now()) + store := NewTestDB(t, clock) // Ensure that the function errors out if we try update an // account that does not exist. @@ -151,7 +154,7 @@ func TestAccountUpdateMethods(t *testing.T) { assertBalanceAndExpiry(newBalance, time.Time{}) // Now update just the expiry of the account. - newExpiry := time.Now().Add(time.Hour) + newExpiry := clock.Now().Add(time.Hour) err = store.UpdateAccountBalanceAndExpiry( ctx, acct.ID, fn.None[lnwire.MilliSatoshi](), fn.Some(newExpiry), @@ -161,7 +164,7 @@ func TestAccountUpdateMethods(t *testing.T) { // Update both the balance and expiry of the account. newBalance = 456 - newExpiry = time.Now().Add(2 * time.Hour) + newExpiry = clock.Now().Add(2 * time.Hour) err = store.UpdateAccountBalanceAndExpiry( ctx, acct.ID, fn.Some(newBalance), fn.Some(newExpiry), ) @@ -179,7 +182,7 @@ func TestAccountUpdateMethods(t *testing.T) { }) t.Run("AddAccountInvoice", func(t *testing.T) { - store := NewTestDB(t) + store := NewTestDB(t, clock.NewTestClock(time.Now())) acct, err := store.NewAccount(ctx, 0, time.Time{}, "foo") require.NoError(t, err) @@ -231,7 +234,7 @@ func TestAccountUpdateMethods(t *testing.T) { }) t.Run("IncreaseAccountBalance", func(t *testing.T) { - store := NewTestDB(t) + store := NewTestDB(t, clock.NewTestClock(time.Now())) // Increasing the balance of an account that doesn't exist // should error out. @@ -259,7 +262,7 @@ func TestAccountUpdateMethods(t *testing.T) { }) t.Run("Upsert and Delete AccountPayment", func(t *testing.T) { - store := NewTestDB(t) + store := NewTestDB(t, clock.NewTestClock(time.Now())) acct, err := store.NewAccount(ctx, 1000, time.Time{}, "foo") require.NoError(t, err) @@ -507,7 +510,7 @@ func TestLastInvoiceIndexes(t *testing.T) { t.Parallel() ctx := context.Background() - store := NewTestDB(t) + store := NewTestDB(t, clock.NewTestClock(time.Now())) _, _, err := store.LastIndexes(ctx) require.ErrorIs(t, err, ErrNoInvoiceIndexKnown) diff --git a/accounts/test_kvdb.go b/accounts/test_kvdb.go index b050d149c..224a8912c 100644 --- a/accounts/test_kvdb.go +++ b/accounts/test_kvdb.go @@ -4,6 +4,7 @@ import ( "errors" "testing" + "github.com/lightningnetwork/lnd/clock" "github.com/stretchr/testify/require" ) @@ -12,14 +13,16 @@ import ( var ErrDBClosed = errors.New("database not open") // NewTestDB is a helper function that creates an BBolt database for testing. -func NewTestDB(t *testing.T) *BoltStore { - return NewTestDBFromPath(t, t.TempDir()) +func NewTestDB(t *testing.T, clock clock.Clock) *BoltStore { + return NewTestDBFromPath(t, t.TempDir(), clock) } // NewTestDBFromPath is a helper function that creates a new BoltStore with a // connection to an existing BBolt database for testing. -func NewTestDBFromPath(t *testing.T, dbPath string) *BoltStore { - store, err := NewBoltStore(dbPath, DBFilename) +func NewTestDBFromPath(t *testing.T, dbPath string, + clock clock.Clock) *BoltStore { + + store, err := NewBoltStore(dbPath, DBFilename, clock) require.NoError(t, err) t.Cleanup(func() { diff --git a/go.mod b/go.mod index 53f147ec4..80547dd50 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/lightninglabs/taproot-assets v0.5.1-rc1 github.com/lightningnetwork/lnd v0.18.4-beta github.com/lightningnetwork/lnd/cert v1.2.2 + github.com/lightningnetwork/lnd/clock v1.1.1 github.com/lightningnetwork/lnd/fn v1.2.3 github.com/lightningnetwork/lnd/kvdb v1.4.10 github.com/lightningnetwork/lnd/tlv v1.2.6 @@ -137,7 +138,6 @@ require ( github.com/lightninglabs/neutrino v0.16.1-0.20240425105051-602843d34ffd // indirect github.com/lightninglabs/neutrino/cache v1.1.2 // indirect github.com/lightningnetwork/lightning-onion v1.2.1-0.20240712235311-98bd56499dfb // indirect - github.com/lightningnetwork/lnd/clock v1.1.1 // indirect github.com/lightningnetwork/lnd/healthcheck v1.2.5 // indirect github.com/lightningnetwork/lnd/queue v1.1.1 // indirect github.com/lightningnetwork/lnd/sqldb v1.0.4 // indirect diff --git a/terminal.go b/terminal.go index 84a7f42a4..e6ab91289 100644 --- a/terminal.go +++ b/terminal.go @@ -38,6 +38,7 @@ import ( "github.com/lightningnetwork/lnd" "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/chainreg" + "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/fn" "github.com/lightningnetwork/lnd/funding" "github.com/lightningnetwork/lnd/htlcswitch" @@ -415,6 +416,7 @@ func (g *LightningTerminal) start(ctx context.Context) error { g.accountsStore, err = accounts.NewBoltStore( filepath.Dir(g.cfg.MacaroonPath), accounts.DBFilename, + clock.NewDefaultClock(), ) if err != nil { return fmt.Errorf("error creating accounts store: %w", err)