From b600ecda86047288f4a93ca4be61e36abe4d74a5 Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Mon, 20 Jan 2020 10:57:34 +0100 Subject: [PATCH] channeldb: inject clock into database Use our standard clock mock for database time queries. --- channeldb/channel_test.go | 5 ++++- channeldb/db.go | 6 +++--- channeldb/invoice_test.go | 3 --- channeldb/invoices.go | 2 +- channeldb/options.go | 13 +++++++++++++ invoices/invoiceregistry_test.go | 6 +++--- invoices/test_utils_test.go | 9 +++++---- 7 files changed, 29 insertions(+), 15 deletions(-) diff --git a/channeldb/channel_test.go b/channeldb/channel_test.go index 525b2489..7f82e9d3 100644 --- a/channeldb/channel_test.go +++ b/channeldb/channel_test.go @@ -16,6 +16,7 @@ import ( "github.com/btcsuite/btcutil" _ "github.com/btcsuite/btcwallet/walletdb/bdb" "github.com/davecgh/go-spew/spew" + "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/shachain" @@ -68,6 +69,8 @@ var ( privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), key[:]) wireSig, _ = lnwire.NewSigFromSignature(testSig) + + testClock = clock.NewTestClock(testNow) ) // makeTestDB creates a new instance of the ChannelDB for testing purposes. A @@ -82,7 +85,7 @@ func makeTestDB() (*DB, func(), error) { } // Next, create channeldb for the first time. - cdb, err := Open(tempDirName) + cdb, err := Open(tempDirName, OptionClock(testClock)) if err != nil { return nil, nil, err } diff --git a/channeldb/db.go b/channeldb/db.go index c3f63234..c9410bfb 100644 --- a/channeldb/db.go +++ b/channeldb/db.go @@ -15,6 +15,7 @@ import ( "github.com/go-errors/errors" "github.com/lightningnetwork/lnd/channeldb/migration12" "github.com/lightningnetwork/lnd/channeldb/migration_01_to_11" + "github.com/lightningnetwork/lnd/clock" "github.com/lightningnetwork/lnd/lnwire" ) @@ -137,8 +138,7 @@ type DB struct { *bbolt.DB dbPath string graph *ChannelGraph - - Now func() time.Time + clock clock.Clock } // Open opens an existing channeldb. Any necessary schemas migrations due to @@ -172,7 +172,7 @@ func Open(dbPath string, modifiers ...OptionModifier) (*DB, error) { chanDB := &DB{ DB: bdb, dbPath: dbPath, - Now: time.Now, + clock: opts.clock, } chanDB.graph = newChannelGraph( chanDB, opts.RejectCacheSize, opts.ChannelCacheSize, diff --git a/channeldb/invoice_test.go b/channeldb/invoice_test.go index 922239e5..26807894 100644 --- a/channeldb/invoice_test.go +++ b/channeldb/invoice_test.go @@ -304,7 +304,6 @@ func TestInvoiceAddTimeSeries(t *testing.T) { if err != nil { t.Fatalf("unable to make test db: %v", err) } - db.Now = func() time.Time { return testNow } // We'll start off by creating 20 random invoices, and inserting them // into the database. @@ -556,7 +555,6 @@ func TestDuplicateSettleInvoice(t *testing.T) { if err != nil { t.Fatalf("unable to make test db: %v", err) } - db.Now = func() time.Time { return testNow } // We'll start out by creating an invoice and writing it to the DB. amt := lnwire.NewMSatFromSatoshis(1000) @@ -631,7 +629,6 @@ func TestQueryInvoices(t *testing.T) { if err != nil { t.Fatalf("unable to make test db: %v", err) } - db.Now = func() time.Time { return testNow } // To begin the test, we'll add 50 invoices to the database. We'll // assume that the index of the invoice within the database is the same diff --git a/channeldb/invoices.go b/channeldb/invoices.go index c2969a4a..66363fe1 100644 --- a/channeldb/invoices.go +++ b/channeldb/invoices.go @@ -1348,7 +1348,7 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucke return &invoice, nil } - now := d.Now() + now := d.clock.Now() // Update invoice state if the update descriptor indicates an invoice // state change. diff --git a/channeldb/options.go b/channeldb/options.go index 38ac05ef..90185f2c 100644 --- a/channeldb/options.go +++ b/channeldb/options.go @@ -1,5 +1,7 @@ package channeldb +import "github.com/lightningnetwork/lnd/clock" + const ( // DefaultRejectCacheSize is the default number of rejectCacheEntries to // cache for use in the rejection cache of incoming gossip traffic. This @@ -26,6 +28,9 @@ type Options struct { // freelist to disk, resulting in improved performance at the expense of // increased startup time. NoFreelistSync bool + + // clock is the time source used by the database. + clock clock.Clock } // DefaultOptions returns an Options populated with default values. @@ -34,6 +39,7 @@ func DefaultOptions() Options { RejectCacheSize: DefaultRejectCacheSize, ChannelCacheSize: DefaultChannelCacheSize, NoFreelistSync: true, + clock: clock.NewDefaultClock(), } } @@ -60,3 +66,10 @@ func OptionSetSyncFreelist(b bool) OptionModifier { o.NoFreelistSync = !b } } + +// OptionClock sets a non-default clock dependency. +func OptionClock(clock clock.Clock) OptionModifier { + return func(o *Options) { + o.clock = clock + } +} diff --git a/invoices/invoiceregistry_test.go b/invoices/invoiceregistry_test.go index b9fbe4b6..9f360e26 100644 --- a/invoices/invoiceregistry_test.go +++ b/invoices/invoiceregistry_test.go @@ -317,7 +317,7 @@ func TestCancelInvoice(t *testing.T) { func TestSettleHoldInvoice(t *testing.T) { defer timeout()() - cdb, cleanup, err := newTestChannelDB() + cdb, cleanup, err := newTestChannelDB(clock.NewTestClock(time.Time{})) if err != nil { t.Fatal(err) } @@ -497,7 +497,7 @@ func TestSettleHoldInvoice(t *testing.T) { func TestCancelHoldInvoice(t *testing.T) { defer timeout()() - cdb, cleanup, err := newTestChannelDB() + cdb, cleanup, err := newTestChannelDB(clock.NewTestClock(time.Time{})) if err != nil { t.Fatal(err) } @@ -798,7 +798,7 @@ func TestMppPayment(t *testing.T) { func TestInvoiceExpiryWithRegistry(t *testing.T) { t.Parallel() - cdb, cleanup, err := newTestChannelDB() + cdb, cleanup, err := newTestChannelDB(clock.NewTestClock(time.Time{})) defer cleanup() if err != nil { diff --git a/invoices/test_utils_test.go b/invoices/test_utils_test.go index a1f84e26..cf0f14ea 100644 --- a/invoices/test_utils_test.go +++ b/invoices/test_utils_test.go @@ -110,7 +110,7 @@ var ( } ) -func newTestChannelDB() (*channeldb.DB, func(), error) { +func newTestChannelDB(clock clock.Clock) (*channeldb.DB, func(), error) { // First, create a temporary directory to be used for the duration of // this test. tempDirName, err := ioutil.TempDir("", "channeldb") @@ -119,7 +119,9 @@ func newTestChannelDB() (*channeldb.DB, func(), error) { } // Next, create channeldb for the first time. - cdb, err := channeldb.Open(tempDirName) + cdb, err := channeldb.Open( + tempDirName, channeldb.OptionClock(clock), + ) if err != nil { os.RemoveAll(tempDirName) return nil, nil, err @@ -145,11 +147,10 @@ type testContext struct { func newTestContext(t *testing.T) *testContext { clock := clock.NewTestClock(testTime) - cdb, cleanup, err := newTestChannelDB() + cdb, cleanup, err := newTestChannelDB(clock) if err != nil { t.Fatal(err) } - cdb.Now = clock.Now expiryWatcher := NewInvoiceExpiryWatcher(clock)