channeldb: inject clock into database

Use our standard clock mock for database time queries.
This commit is contained in:
Joost Jager 2020-01-20 10:57:34 +01:00
parent ad0a89b844
commit b600ecda86
No known key found for this signature in database
GPG Key ID: A61B9D4C393C59C7
7 changed files with 29 additions and 15 deletions

@ -16,6 +16,7 @@ import (
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
_ "github.com/btcsuite/btcwallet/walletdb/bdb" _ "github.com/btcsuite/btcwallet/walletdb/bdb"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/keychain" "github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/shachain" "github.com/lightningnetwork/lnd/shachain"
@ -68,6 +69,8 @@ var (
privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), key[:]) privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), key[:])
wireSig, _ = lnwire.NewSigFromSignature(testSig) wireSig, _ = lnwire.NewSigFromSignature(testSig)
testClock = clock.NewTestClock(testNow)
) )
// makeTestDB creates a new instance of the ChannelDB for testing purposes. A // 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. // Next, create channeldb for the first time.
cdb, err := Open(tempDirName) cdb, err := Open(tempDirName, OptionClock(testClock))
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

@ -15,6 +15,7 @@ import (
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/channeldb/migration12" "github.com/lightningnetwork/lnd/channeldb/migration12"
"github.com/lightningnetwork/lnd/channeldb/migration_01_to_11" "github.com/lightningnetwork/lnd/channeldb/migration_01_to_11"
"github.com/lightningnetwork/lnd/clock"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
) )
@ -137,8 +138,7 @@ type DB struct {
*bbolt.DB *bbolt.DB
dbPath string dbPath string
graph *ChannelGraph graph *ChannelGraph
clock clock.Clock
Now func() time.Time
} }
// Open opens an existing channeldb. Any necessary schemas migrations due to // 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{ chanDB := &DB{
DB: bdb, DB: bdb,
dbPath: dbPath, dbPath: dbPath,
Now: time.Now, clock: opts.clock,
} }
chanDB.graph = newChannelGraph( chanDB.graph = newChannelGraph(
chanDB, opts.RejectCacheSize, opts.ChannelCacheSize, chanDB, opts.RejectCacheSize, opts.ChannelCacheSize,

@ -304,7 +304,6 @@ func TestInvoiceAddTimeSeries(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to make test db: %v", err) 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 // We'll start off by creating 20 random invoices, and inserting them
// into the database. // into the database.
@ -556,7 +555,6 @@ func TestDuplicateSettleInvoice(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to make test db: %v", err) 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. // We'll start out by creating an invoice and writing it to the DB.
amt := lnwire.NewMSatFromSatoshis(1000) amt := lnwire.NewMSatFromSatoshis(1000)
@ -631,7 +629,6 @@ func TestQueryInvoices(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("unable to make test db: %v", err) 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 // 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 // assume that the index of the invoice within the database is the same

@ -1348,7 +1348,7 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucke
return &invoice, nil return &invoice, nil
} }
now := d.Now() now := d.clock.Now()
// Update invoice state if the update descriptor indicates an invoice // Update invoice state if the update descriptor indicates an invoice
// state change. // state change.

@ -1,5 +1,7 @@
package channeldb package channeldb
import "github.com/lightningnetwork/lnd/clock"
const ( const (
// DefaultRejectCacheSize is the default number of rejectCacheEntries to // DefaultRejectCacheSize is the default number of rejectCacheEntries to
// cache for use in the rejection cache of incoming gossip traffic. This // 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 // freelist to disk, resulting in improved performance at the expense of
// increased startup time. // increased startup time.
NoFreelistSync bool NoFreelistSync bool
// clock is the time source used by the database.
clock clock.Clock
} }
// DefaultOptions returns an Options populated with default values. // DefaultOptions returns an Options populated with default values.
@ -34,6 +39,7 @@ func DefaultOptions() Options {
RejectCacheSize: DefaultRejectCacheSize, RejectCacheSize: DefaultRejectCacheSize,
ChannelCacheSize: DefaultChannelCacheSize, ChannelCacheSize: DefaultChannelCacheSize,
NoFreelistSync: true, NoFreelistSync: true,
clock: clock.NewDefaultClock(),
} }
} }
@ -60,3 +66,10 @@ func OptionSetSyncFreelist(b bool) OptionModifier {
o.NoFreelistSync = !b o.NoFreelistSync = !b
} }
} }
// OptionClock sets a non-default clock dependency.
func OptionClock(clock clock.Clock) OptionModifier {
return func(o *Options) {
o.clock = clock
}
}

@ -317,7 +317,7 @@ func TestCancelInvoice(t *testing.T) {
func TestSettleHoldInvoice(t *testing.T) { func TestSettleHoldInvoice(t *testing.T) {
defer timeout()() defer timeout()()
cdb, cleanup, err := newTestChannelDB() cdb, cleanup, err := newTestChannelDB(clock.NewTestClock(time.Time{}))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -497,7 +497,7 @@ func TestSettleHoldInvoice(t *testing.T) {
func TestCancelHoldInvoice(t *testing.T) { func TestCancelHoldInvoice(t *testing.T) {
defer timeout()() defer timeout()()
cdb, cleanup, err := newTestChannelDB() cdb, cleanup, err := newTestChannelDB(clock.NewTestClock(time.Time{}))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -798,7 +798,7 @@ func TestMppPayment(t *testing.T) {
func TestInvoiceExpiryWithRegistry(t *testing.T) { func TestInvoiceExpiryWithRegistry(t *testing.T) {
t.Parallel() t.Parallel()
cdb, cleanup, err := newTestChannelDB() cdb, cleanup, err := newTestChannelDB(clock.NewTestClock(time.Time{}))
defer cleanup() defer cleanup()
if err != nil { if err != nil {

@ -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 // First, create a temporary directory to be used for the duration of
// this test. // this test.
tempDirName, err := ioutil.TempDir("", "channeldb") tempDirName, err := ioutil.TempDir("", "channeldb")
@ -119,7 +119,9 @@ func newTestChannelDB() (*channeldb.DB, func(), error) {
} }
// Next, create channeldb for the first time. // Next, create channeldb for the first time.
cdb, err := channeldb.Open(tempDirName) cdb, err := channeldb.Open(
tempDirName, channeldb.OptionClock(clock),
)
if err != nil { if err != nil {
os.RemoveAll(tempDirName) os.RemoveAll(tempDirName)
return nil, nil, err return nil, nil, err
@ -145,11 +147,10 @@ type testContext struct {
func newTestContext(t *testing.T) *testContext { func newTestContext(t *testing.T) *testContext {
clock := clock.NewTestClock(testTime) clock := clock.NewTestClock(testTime)
cdb, cleanup, err := newTestChannelDB() cdb, cleanup, err := newTestChannelDB(clock)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
cdb.Now = clock.Now
expiryWatcher := NewInvoiceExpiryWatcher(clock) expiryWatcher := NewInvoiceExpiryWatcher(clock)