diff --git a/chainntnfs/bitcoindnotify/bitcoind_test.go b/chainntnfs/bitcoindnotify/bitcoind_test.go index 073c516e9..b755b7259 100644 --- a/chainntnfs/bitcoindnotify/bitcoind_test.go +++ b/chainntnfs/bitcoindnotify/bitcoind_test.go @@ -40,8 +40,8 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache { if err != nil { t.Fatalf("unable to create db: %v", err) } - testCfg := chainntnfs.Config{ - HeightHintCacheQueryDisable: false, + testCfg := chainntnfs.CacheConfig{ + QueryDisable: false, } hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db) if err != nil { diff --git a/chainntnfs/btcdnotify/btcd_test.go b/chainntnfs/btcdnotify/btcd_test.go index df0996466..2e8a99c50 100644 --- a/chainntnfs/btcdnotify/btcd_test.go +++ b/chainntnfs/btcdnotify/btcd_test.go @@ -38,8 +38,8 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache { if err != nil { t.Fatalf("unable to create db: %v", err) } - testCfg := chainntnfs.Config{ - HeightHintCacheQueryDisable: false, + testCfg := chainntnfs.CacheConfig{ + QueryDisable: false, } hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db) if err != nil { diff --git a/chainntnfs/height_hint_cache.go b/chainntnfs/height_hint_cache.go index cb9344d13..018afbefd 100644 --- a/chainntnfs/height_hint_cache.go +++ b/chainntnfs/height_hint_cache.go @@ -35,13 +35,13 @@ var ( ErrConfirmHintNotFound = errors.New("confirm hint not found") ) -// Config contains the HeightHintCache configuration -type Config struct { - // HeightHintCacheQueryDisable prevents reliance on the Height Hint Cache. - // This is necessary to recover from an edge case when the height - // recorded in the cache is higher than the actual height of a spend, - // causing a channel to become "stuck" in a pending close state. - HeightHintCacheQueryDisable bool +// CacheConfig contains the HeightHintCache configuration +type CacheConfig struct { + // QueryDisable prevents reliance on the Height Hint Cache. This is + // necessary to recover from an edge case when the height recorded in + // the cache is higher than the actual height of a spend, causing a + // channel to become "stuck" in a pending close state. + QueryDisable bool } // SpendHintCache is an interface whose duty is to cache spend hints for @@ -83,7 +83,7 @@ type ConfirmHintCache interface { // ConfirmHintCache interfaces backed by a channeldb DB instance where the hints // will be stored. type HeightHintCache struct { - cfg Config + cfg CacheConfig db *channeldb.DB } @@ -93,7 +93,7 @@ var _ SpendHintCache = (*HeightHintCache)(nil) var _ ConfirmHintCache = (*HeightHintCache)(nil) // NewHeightHintCache returns a new height hint cache backed by a database. -func NewHeightHintCache(cfg Config, db *channeldb.DB) (*HeightHintCache, error) { +func NewHeightHintCache(cfg CacheConfig, db *channeldb.DB) (*HeightHintCache, error) { cache := &HeightHintCache{cfg, db} if err := cache.initBuckets(); err != nil { return nil, err @@ -158,8 +158,9 @@ func (c *HeightHintCache) CommitSpendHint(height uint32, // cache for the outpoint. func (c *HeightHintCache) QuerySpendHint(spendRequest SpendRequest) (uint32, error) { var hint uint32 - if c.cfg.HeightHintCacheQueryDisable { - Log.Debugf("Ignoring spend height hint for %v (height hint cache query disabled)", spendRequest) + if c.cfg.QueryDisable { + Log.Debugf("Ignoring spend height hint for %v (height hint cache "+ + "query disabled)", spendRequest) return 0, nil } err := kvdb.View(c.db, func(tx kvdb.RTx) error { @@ -256,8 +257,9 @@ func (c *HeightHintCache) CommitConfirmHint(height uint32, // the cache for the transaction hash. func (c *HeightHintCache) QueryConfirmHint(confRequest ConfRequest) (uint32, error) { var hint uint32 - if c.cfg.HeightHintCacheQueryDisable { - Log.Debugf("Ignoring confirmation height hint for %v (height hint cache query disabled)", confRequest) + if c.cfg.QueryDisable { + Log.Debugf("Ignoring confirmation height hint for %v (height hint "+ + "cache query disabled)", confRequest) return 0, nil } err := kvdb.View(c.db, func(tx kvdb.RTx) error { diff --git a/chainntnfs/height_hint_cache_test.go b/chainntnfs/height_hint_cache_test.go index 21ac5c7a3..7909f82f1 100644 --- a/chainntnfs/height_hint_cache_test.go +++ b/chainntnfs/height_hint_cache_test.go @@ -8,11 +8,22 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/wire" "github.com/lightningnetwork/lnd/channeldb" + "github.com/stretchr/testify/require" ) func initHintCache(t *testing.T) *HeightHintCache { t.Helper() + defaultCfg := CacheConfig{ + QueryDisable: false, + } + + return initHintCacheWithConfig(t, defaultCfg) +} + +func initHintCacheWithConfig(t *testing.T, cfg CacheConfig) *HeightHintCache { + t.Helper() + tempDir, err := ioutil.TempDir("", "kek") if err != nil { t.Fatalf("unable to create temp dir: %v", err) @@ -21,10 +32,7 @@ func initHintCache(t *testing.T) *HeightHintCache { if err != nil { t.Fatalf("unable to create db: %v", err) } - testCfg := Config{ - HeightHintCacheQueryDisable: false, - } - hintCache, err := NewHeightHintCache(testCfg, db) + hintCache, err := NewHeightHintCache(cfg, db) if err != nil { t.Fatalf("unable to create hint cache: %v", err) } @@ -154,3 +162,42 @@ func TestHeightHintCacheSpends(t *testing.T) { } } } + +// TestQueryDisable asserts querying for confirmation or spend hints always +// return height zero when QueryDisabled is set to true in the CacheConfig. +func TestQueryDisable(t *testing.T) { + cfg := CacheConfig{ + QueryDisable: true, + } + + hintCache := initHintCacheWithConfig(t, cfg) + + // Insert a new confirmation hint with a non-zero height. + const confHeight = 100 + confRequest := ConfRequest{ + TxID: chainhash.Hash{0x01, 0x02, 0x03}, + } + err := hintCache.CommitConfirmHint(confHeight, confRequest) + require.Nil(t, err) + + // Query for the confirmation hint, which should return zero. + cachedConfHeight, err := hintCache.QueryConfirmHint(confRequest) + require.Nil(t, err) + require.Equal(t, uint32(0), cachedConfHeight) + + // Insert a new spend hint with a non-zero height. + const spendHeight = 200 + spendRequest := SpendRequest{ + OutPoint: wire.OutPoint{ + Hash: chainhash.Hash{0x4, 0x05, 0x06}, + Index: 42, + }, + } + err = hintCache.CommitSpendHint(spendHeight, spendRequest) + require.Nil(t, err) + + // Query for the spend hint, which should return zero. + cachedSpendHeight, err := hintCache.QuerySpendHint(spendRequest) + require.Nil(t, err) + require.Equal(t, uint32(0), cachedSpendHeight) +} diff --git a/chainntnfs/interface_test.go b/chainntnfs/interface_test.go index fb849655f..504f19dc4 100644 --- a/chainntnfs/interface_test.go +++ b/chainntnfs/interface_test.go @@ -1911,8 +1911,8 @@ func TestInterfaces(t *testing.T) { if err != nil { t.Fatalf("unable to create db: %v", err) } - testCfg := chainntnfs.Config{ - HeightHintCacheQueryDisable: false, + testCfg := chainntnfs.CacheConfig{ + QueryDisable: false, } hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db) if err != nil { diff --git a/chainregistry.go b/chainregistry.go index db466e56e..3d750a3e6 100644 --- a/chainregistry.go +++ b/chainregistry.go @@ -219,8 +219,8 @@ func newChainControlFromConfig(cfg *Config, chanDB *channeldb.DB, var err error - heightHintCacheConfig := chainntnfs.Config{ - HeightHintCacheQueryDisable: cfg.HeightHintCacheQueryDisable, + heightHintCacheConfig := chainntnfs.CacheConfig{ + QueryDisable: cfg.HeightHintCacheQueryDisable, } if cfg.HeightHintCacheQueryDisable { ltndLog.Infof("Height Hint Cache Queries disabled") diff --git a/lnwallet/interface_test.go b/lnwallet/interface_test.go index 7ee15a6ff..6861fc893 100644 --- a/lnwallet/interface_test.go +++ b/lnwallet/interface_test.go @@ -3014,8 +3014,8 @@ func TestLightningWallet(t *testing.T) { if err != nil { t.Fatalf("unable to create db: %v", err) } - testCfg := chainntnfs.Config{ - HeightHintCacheQueryDisable: false, + testCfg := chainntnfs.CacheConfig{ + QueryDisable: false, } hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db) if err != nil {