chainntnfs: move cache implementation to channeldb

This commit moves the `HeightHintCache` implementation to the
`channeldb` package and inverts the dependency relation between
`chainntnfs` and `channeldb`.

Many packages depend on channeldb for type definitions,
interfaces, etc. `chainntnfs` is an example of that. `chainntnfs`
defines the  `SpendHintCache` and `ConfirmHintCache` interfaces but
it also implments them (`HeightHintCache` struct). The implementation
uses logic that should not leak from channeldb (ex: bucket paths).
This makes our code highly coupled + it would not allow us to use any
of these interfaces in a package that is imported by `channeldb`
(circular dependency).
This commit is contained in:
positiveblue 2022-11-18 07:23:03 -08:00
parent 681da4b2b5
commit c602ac07e7
No known key found for this signature in database
GPG Key ID: 4FFF2510928804DC
10 changed files with 169 additions and 173 deletions

View File

@ -31,7 +31,7 @@ var (
} }
) )
func initHintCache(t *testing.T) *chainntnfs.HeightHintCache { func initHintCache(t *testing.T) *channeldb.HeightHintCache {
t.Helper() t.Helper()
db, err := channeldb.Open(t.TempDir()) db, err := channeldb.Open(t.TempDir())
@ -40,10 +40,10 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache {
require.NoError(t, db.Close()) require.NoError(t, db.Close())
}) })
testCfg := chainntnfs.CacheConfig{ testCfg := channeldb.CacheConfig{
QueryDisable: false, QueryDisable: false,
} }
hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db.Backend) hintCache, err := channeldb.NewHeightHintCache(testCfg, db.Backend)
require.NoError(t, err, "unable to create hint cache") require.NoError(t, err, "unable to create hint cache")
return hintCache return hintCache

View File

@ -29,7 +29,7 @@ var (
} }
) )
func initHintCache(t *testing.T) *chainntnfs.HeightHintCache { func initHintCache(t *testing.T) *channeldb.HeightHintCache {
t.Helper() t.Helper()
db, err := channeldb.Open(t.TempDir()) db, err := channeldb.Open(t.TempDir())
@ -38,10 +38,10 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache {
require.NoError(t, db.Close()) require.NoError(t, db.Close())
}) })
testCfg := chainntnfs.CacheConfig{ testCfg := channeldb.CacheConfig{
QueryDisable: false, QueryDisable: false,
} }
hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db.Backend) hintCache, err := channeldb.NewHeightHintCache(testCfg, db.Backend)
require.NoError(t, err, "unable to create hint cache") require.NoError(t, err, "unable to create hint cache")
return hintCache return hintCache

18
chainntnfs/errors.go Normal file
View File

@ -0,0 +1,18 @@
package chainntnfs
import "errors"
var (
// ErrCorruptedHeightHintCache indicates that the on-disk representation
// has altered since the height hint cache instance was initialized.
ErrCorruptedHeightHintCache = errors.New("height hint cache has been " +
"corrupted")
// ErrSpendHintNotFound is an error returned when a spend hint for an
// outpoint was not found.
ErrSpendHintNotFound = errors.New("spend hint not found")
// ErrConfirmHintNotFound is an error returned when a confirm hint for a
// transaction was not found.
ErrConfirmHintNotFound = errors.New("confirm hint not found")
)

View File

@ -773,3 +773,38 @@ func ConfDetailsFromTxIndex(chainConn TxIndexConn, r ConfRequest,
return nil, TxNotFoundIndex, fmt.Errorf("unable to locate "+ return nil, TxNotFoundIndex, fmt.Errorf("unable to locate "+
"tx %v in block %v", r.TxID, blockHash) "tx %v in block %v", r.TxID, blockHash)
} }
// SpendHintCache is an interface whose duty is to cache spend hints for
// outpoints. A spend hint is defined as the earliest height in the chain at
// which an outpoint could have been spent within.
type SpendHintCache interface {
// CommitSpendHint commits a spend hint for the outpoints to the cache.
CommitSpendHint(height uint32, spendRequests ...SpendRequest) error
// QuerySpendHint returns the latest spend hint for an outpoint.
// ErrSpendHintNotFound is returned if a spend hint does not exist
// within the cache for the outpoint.
QuerySpendHint(spendRequest SpendRequest) (uint32, error)
// PurgeSpendHint removes the spend hint for the outpoints from the
// cache.
PurgeSpendHint(spendRequests ...SpendRequest) error
}
// ConfirmHintCache is an interface whose duty is to cache confirm hints for
// transactions. A confirm hint is defined as the earliest height in the chain
// at which a transaction could have been included in a block.
type ConfirmHintCache interface {
// CommitConfirmHint commits a confirm hint for the transactions to the
// cache.
CommitConfirmHint(height uint32, confRequests ...ConfRequest) error
// QueryConfirmHint returns the latest confirm hint for a transaction
// hash. ErrConfirmHintNotFound is returned if a confirm hint does not
// exist within the cache for the transaction hash.
QueryConfirmHint(confRequest ConfRequest) (uint32, error)
// PurgeConfirmHint removes the confirm hint for the transactions from
// the cache.
PurgeConfirmHint(confRequests ...ConfRequest) error
}

View File

@ -1836,10 +1836,10 @@ func TestInterfaces(t *testing.T, targetBackEnd string) {
if err != nil { if err != nil {
t.Fatalf("unable to create db: %v", err) t.Fatalf("unable to create db: %v", err)
} }
testCfg := chainntnfs.CacheConfig{ testCfg := channeldb.CacheConfig{
QueryDisable: false, QueryDisable: false,
} }
hintCache, err := chainntnfs.NewHeightHintCache( hintCache, err := channeldb.NewHeightHintCache(
testCfg, db.Backend, testCfg, db.Backend,
) )
if err != nil { if err != nil {

View File

@ -11,7 +11,6 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
) )
const ( const (
@ -201,21 +200,6 @@ func (r ConfRequest) String() string {
return fmt.Sprintf("script=%v", r.PkScript) return fmt.Sprintf("script=%v", r.PkScript)
} }
// ConfHintKey returns the key that will be used to index the confirmation
// request's hint within the height hint cache.
func (r ConfRequest) ConfHintKey() ([]byte, error) {
if r.TxID == ZeroHash {
return r.PkScript.Script(), nil
}
var txid bytes.Buffer
if err := channeldb.WriteElement(&txid, r.TxID); err != nil {
return nil, err
}
return txid.Bytes(), nil
}
// MatchesTx determines whether the given transaction satisfies the confirmation // MatchesTx determines whether the given transaction satisfies the confirmation
// request. If the confirmation request is for a script, then we'll check all of // request. If the confirmation request is for a script, then we'll check all of
// the outputs of the transaction to determine if it matches. Otherwise, we'll // the outputs of the transaction to determine if it matches. Otherwise, we'll
@ -369,22 +353,6 @@ func (r SpendRequest) String() string {
return fmt.Sprintf("outpoint=<zero>, script=%v", r.PkScript) return fmt.Sprintf("outpoint=<zero>, script=%v", r.PkScript)
} }
// SpendHintKey returns the key that will be used to index the spend request's
// hint within the height hint cache.
func (r SpendRequest) SpendHintKey() ([]byte, error) {
if r.OutPoint == ZeroOutPoint {
return r.PkScript.Script(), nil
}
var outpoint bytes.Buffer
err := channeldb.WriteElement(&outpoint, r.OutPoint)
if err != nil {
return nil, err
}
return outpoint.Bytes(), nil
}
// MatchesTx determines whether the given transaction satisfies the spend // MatchesTx determines whether the given transaction satisfies the spend
// request. If the spend request is for an outpoint, then we'll check all of // request. If the spend request is for an outpoint, then we'll check all of
// the outputs being spent by the inputs of the transaction to determine if it // the outputs being spent by the inputs of the transaction to determine if it

View File

@ -292,7 +292,7 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
} }
var err error var err error
heightHintCacheConfig := chainntnfs.CacheConfig{ heightHintCacheConfig := channeldb.CacheConfig{
QueryDisable: cfg.HeightHintCacheQueryDisable, QueryDisable: cfg.HeightHintCacheQueryDisable,
} }
if cfg.HeightHintCacheQueryDisable { if cfg.HeightHintCacheQueryDisable {
@ -300,7 +300,7 @@ func NewPartialChainControl(cfg *Config) (*PartialChainControl, func(), error) {
} }
// Initialize the height hint cache within the chain directory. // Initialize the height hint cache within the chain directory.
hintCache, err := chainntnfs.NewHeightHintCache( hintCache, err := channeldb.NewHeightHintCache(
heightHintCacheConfig, cfg.HeightHintDB, heightHintCacheConfig, cfg.HeightHintDB,
) )
if err != nil { if err != nil {

View File

@ -1,10 +1,9 @@
package chainntnfs package channeldb
import ( import (
"bytes" "bytes"
"errors"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/kvdb"
) )
@ -19,20 +18,6 @@ var (
// height at which its corresponding transaction could have been // height at which its corresponding transaction could have been
// confirmed within. // confirmed within.
confirmHintBucket = []byte("confirm-hints") confirmHintBucket = []byte("confirm-hints")
// ErrCorruptedHeightHintCache indicates that the on-disk bucketing
// structure has altered since the height hint cache instance was
// initialized.
ErrCorruptedHeightHintCache = errors.New("height hint cache has been " +
"corrupted")
// ErrSpendHintNotFound is an error returned when a spend hint for an
// outpoint was not found.
ErrSpendHintNotFound = errors.New("spend hint not found")
// ErrConfirmHintNotFound is an error returned when a confirm hint for a
// transaction was not found.
ErrConfirmHintNotFound = errors.New("confirm hint not found")
) )
// CacheConfig contains the HeightHintCache configuration. // CacheConfig contains the HeightHintCache configuration.
@ -44,41 +29,6 @@ type CacheConfig struct {
QueryDisable bool QueryDisable bool
} }
// SpendHintCache is an interface whose duty is to cache spend hints for
// outpoints. A spend hint is defined as the earliest height in the chain at
// which an outpoint could have been spent within.
type SpendHintCache interface {
// CommitSpendHint commits a spend hint for the outpoints to the cache.
CommitSpendHint(height uint32, spendRequests ...SpendRequest) error
// QuerySpendHint returns the latest spend hint for an outpoint.
// ErrSpendHintNotFound is returned if a spend hint does not exist
// within the cache for the outpoint.
QuerySpendHint(spendRequest SpendRequest) (uint32, error)
// PurgeSpendHint removes the spend hint for the outpoints from the
// cache.
PurgeSpendHint(spendRequests ...SpendRequest) error
}
// ConfirmHintCache is an interface whose duty is to cache confirm hints for
// transactions. A confirm hint is defined as the earliest height in the chain
// at which a transaction could have been included in a block.
type ConfirmHintCache interface {
// CommitConfirmHint commits a confirm hint for the transactions to the
// cache.
CommitConfirmHint(height uint32, confRequests ...ConfRequest) error
// QueryConfirmHint returns the latest confirm hint for a transaction
// hash. ErrConfirmHintNotFound is returned if a confirm hint does not
// exist within the cache for the transaction hash.
QueryConfirmHint(confRequest ConfRequest) (uint32, error)
// PurgeConfirmHint removes the confirm hint for the transactions from
// the cache.
PurgeConfirmHint(confRequests ...ConfRequest) error
}
// HeightHintCache is an implementation of the SpendHintCache and // HeightHintCache is an implementation of the SpendHintCache and
// ConfirmHintCache interfaces backed by a channeldb DB instance where the hints // ConfirmHintCache interfaces backed by a channeldb DB instance where the hints
// will be stored. // will be stored.
@ -89,8 +39,8 @@ type HeightHintCache struct {
// Compile-time checks to ensure HeightHintCache satisfies the SpendHintCache // Compile-time checks to ensure HeightHintCache satisfies the SpendHintCache
// and ConfirmHintCache interfaces. // and ConfirmHintCache interfaces.
var _ SpendHintCache = (*HeightHintCache)(nil) var _ chainntnfs.SpendHintCache = (*HeightHintCache)(nil)
var _ ConfirmHintCache = (*HeightHintCache)(nil) var _ chainntnfs.ConfirmHintCache = (*HeightHintCache)(nil)
// NewHeightHintCache returns a new height hint cache backed by a database. // NewHeightHintCache returns a new height hint cache backed by a database.
func NewHeightHintCache(cfg CacheConfig, db kvdb.Backend) (*HeightHintCache, func NewHeightHintCache(cfg CacheConfig, db kvdb.Backend) (*HeightHintCache,
@ -120,28 +70,29 @@ func (c *HeightHintCache) initBuckets() error {
// CommitSpendHint commits a spend hint for the outpoints to the cache. // CommitSpendHint commits a spend hint for the outpoints to the cache.
func (c *HeightHintCache) CommitSpendHint(height uint32, func (c *HeightHintCache) CommitSpendHint(height uint32,
spendRequests ...SpendRequest) error { spendRequests ...chainntnfs.SpendRequest) error {
if len(spendRequests) == 0 { if len(spendRequests) == 0 {
return nil return nil
} }
Log.Tracef("Updating spend hint to height %d for %v", height, log.Tracef("Updating spend hint to height %d for %v", height,
spendRequests) spendRequests)
return kvdb.Batch(c.db, func(tx kvdb.RwTx) error { return kvdb.Batch(c.db, func(tx kvdb.RwTx) error {
spendHints := tx.ReadWriteBucket(spendHintBucket) spendHints := tx.ReadWriteBucket(spendHintBucket)
if spendHints == nil { if spendHints == nil {
return ErrCorruptedHeightHintCache return chainntnfs.ErrCorruptedHeightHintCache
} }
var hint bytes.Buffer var hint bytes.Buffer
if err := channeldb.WriteElement(&hint, height); err != nil { if err := WriteElement(&hint, height); err != nil {
return err return err
} }
for _, spendRequest := range spendRequests { for _, spendRequest := range spendRequests {
spendHintKey, err := spendRequest.SpendHintKey() spendRequest := spendRequest
spendHintKey, err := spendHintKey(&spendRequest)
if err != nil { if err != nil {
return err return err
} }
@ -158,29 +109,31 @@ func (c *HeightHintCache) CommitSpendHint(height uint32,
// QuerySpendHint returns the latest spend hint for an outpoint. // QuerySpendHint returns the latest spend hint for an outpoint.
// ErrSpendHintNotFound is returned if a spend hint does not exist within the // ErrSpendHintNotFound is returned if a spend hint does not exist within the
// cache for the outpoint. // cache for the outpoint.
func (c *HeightHintCache) QuerySpendHint(spendRequest SpendRequest) (uint32, error) { func (c *HeightHintCache) QuerySpendHint(
spendRequest chainntnfs.SpendRequest) (uint32, error) {
var hint uint32 var hint uint32
if c.cfg.QueryDisable { if c.cfg.QueryDisable {
Log.Debugf("Ignoring spend height hint for %v (height hint cache "+ log.Debugf("Ignoring spend height hint for %v (height hint "+
"query disabled)", spendRequest) "cache query disabled)", spendRequest)
return 0, nil return 0, nil
} }
err := kvdb.View(c.db, func(tx kvdb.RTx) error { err := kvdb.View(c.db, func(tx kvdb.RTx) error {
spendHints := tx.ReadBucket(spendHintBucket) spendHints := tx.ReadBucket(spendHintBucket)
if spendHints == nil { if spendHints == nil {
return ErrCorruptedHeightHintCache return chainntnfs.ErrCorruptedHeightHintCache
} }
spendHintKey, err := spendRequest.SpendHintKey() spendHintKey, err := spendHintKey(&spendRequest)
if err != nil { if err != nil {
return err return err
} }
spendHint := spendHints.Get(spendHintKey) spendHint := spendHints.Get(spendHintKey)
if spendHint == nil { if spendHint == nil {
return ErrSpendHintNotFound return chainntnfs.ErrSpendHintNotFound
} }
return channeldb.ReadElement(bytes.NewReader(spendHint), &hint) return ReadElement(bytes.NewReader(spendHint), &hint)
}, func() { }, func() {
hint = 0 hint = 0
}) })
@ -192,21 +145,24 @@ func (c *HeightHintCache) QuerySpendHint(spendRequest SpendRequest) (uint32, err
} }
// PurgeSpendHint removes the spend hint for the outpoints from the cache. // PurgeSpendHint removes the spend hint for the outpoints from the cache.
func (c *HeightHintCache) PurgeSpendHint(spendRequests ...SpendRequest) error { func (c *HeightHintCache) PurgeSpendHint(
spendRequests ...chainntnfs.SpendRequest) error {
if len(spendRequests) == 0 { if len(spendRequests) == 0 {
return nil return nil
} }
Log.Tracef("Removing spend hints for %v", spendRequests) log.Tracef("Removing spend hints for %v", spendRequests)
return kvdb.Batch(c.db, func(tx kvdb.RwTx) error { return kvdb.Batch(c.db, func(tx kvdb.RwTx) error {
spendHints := tx.ReadWriteBucket(spendHintBucket) spendHints := tx.ReadWriteBucket(spendHintBucket)
if spendHints == nil { if spendHints == nil {
return ErrCorruptedHeightHintCache return chainntnfs.ErrCorruptedHeightHintCache
} }
for _, spendRequest := range spendRequests { for _, spendRequest := range spendRequests {
spendHintKey, err := spendRequest.SpendHintKey() spendRequest := spendRequest
spendHintKey, err := spendHintKey(&spendRequest)
if err != nil { if err != nil {
return err return err
} }
@ -221,28 +177,29 @@ func (c *HeightHintCache) PurgeSpendHint(spendRequests ...SpendRequest) error {
// CommitConfirmHint commits a confirm hint for the transactions to the cache. // CommitConfirmHint commits a confirm hint for the transactions to the cache.
func (c *HeightHintCache) CommitConfirmHint(height uint32, func (c *HeightHintCache) CommitConfirmHint(height uint32,
confRequests ...ConfRequest) error { confRequests ...chainntnfs.ConfRequest) error {
if len(confRequests) == 0 { if len(confRequests) == 0 {
return nil return nil
} }
Log.Tracef("Updating confirm hints to height %d for %v", height, log.Tracef("Updating confirm hints to height %d for %v", height,
confRequests) confRequests)
return kvdb.Batch(c.db, func(tx kvdb.RwTx) error { return kvdb.Batch(c.db, func(tx kvdb.RwTx) error {
confirmHints := tx.ReadWriteBucket(confirmHintBucket) confirmHints := tx.ReadWriteBucket(confirmHintBucket)
if confirmHints == nil { if confirmHints == nil {
return ErrCorruptedHeightHintCache return chainntnfs.ErrCorruptedHeightHintCache
} }
var hint bytes.Buffer var hint bytes.Buffer
if err := channeldb.WriteElement(&hint, height); err != nil { if err := WriteElement(&hint, height); err != nil {
return err return err
} }
for _, confRequest := range confRequests { for _, confRequest := range confRequests {
confHintKey, err := confRequest.ConfHintKey() confRequest := confRequest
confHintKey, err := confHintKey(&confRequest)
if err != nil { if err != nil {
return err return err
} }
@ -259,29 +216,31 @@ func (c *HeightHintCache) CommitConfirmHint(height uint32,
// QueryConfirmHint returns the latest confirm hint for a transaction hash. // QueryConfirmHint returns the latest confirm hint for a transaction hash.
// ErrConfirmHintNotFound is returned if a confirm hint does not exist within // ErrConfirmHintNotFound is returned if a confirm hint does not exist within
// the cache for the transaction hash. // the cache for the transaction hash.
func (c *HeightHintCache) QueryConfirmHint(confRequest ConfRequest) (uint32, error) { func (c *HeightHintCache) QueryConfirmHint(
confRequest chainntnfs.ConfRequest) (uint32, error) {
var hint uint32 var hint uint32
if c.cfg.QueryDisable { if c.cfg.QueryDisable {
Log.Debugf("Ignoring confirmation height hint for %v (height hint "+ log.Debugf("Ignoring confirmation height hint for %v (height "+
"cache query disabled)", confRequest) "hint cache query disabled)", confRequest)
return 0, nil return 0, nil
} }
err := kvdb.View(c.db, func(tx kvdb.RTx) error { err := kvdb.View(c.db, func(tx kvdb.RTx) error {
confirmHints := tx.ReadBucket(confirmHintBucket) confirmHints := tx.ReadBucket(confirmHintBucket)
if confirmHints == nil { if confirmHints == nil {
return ErrCorruptedHeightHintCache return chainntnfs.ErrCorruptedHeightHintCache
} }
confHintKey, err := confRequest.ConfHintKey() confHintKey, err := confHintKey(&confRequest)
if err != nil { if err != nil {
return err return err
} }
confirmHint := confirmHints.Get(confHintKey) confirmHint := confirmHints.Get(confHintKey)
if confirmHint == nil { if confirmHint == nil {
return ErrConfirmHintNotFound return chainntnfs.ErrConfirmHintNotFound
} }
return channeldb.ReadElement(bytes.NewReader(confirmHint), &hint) return ReadElement(bytes.NewReader(confirmHint), &hint)
}, func() { }, func() {
hint = 0 hint = 0
}) })
@ -294,21 +253,24 @@ func (c *HeightHintCache) QueryConfirmHint(confRequest ConfRequest) (uint32, err
// PurgeConfirmHint removes the confirm hint for the transactions from the // PurgeConfirmHint removes the confirm hint for the transactions from the
// cache. // cache.
func (c *HeightHintCache) PurgeConfirmHint(confRequests ...ConfRequest) error { func (c *HeightHintCache) PurgeConfirmHint(
confRequests ...chainntnfs.ConfRequest) error {
if len(confRequests) == 0 { if len(confRequests) == 0 {
return nil return nil
} }
Log.Tracef("Removing confirm hints for %v", confRequests) log.Tracef("Removing confirm hints for %v", confRequests)
return kvdb.Batch(c.db, func(tx kvdb.RwTx) error { return kvdb.Batch(c.db, func(tx kvdb.RwTx) error {
confirmHints := tx.ReadWriteBucket(confirmHintBucket) confirmHints := tx.ReadWriteBucket(confirmHintBucket)
if confirmHints == nil { if confirmHints == nil {
return ErrCorruptedHeightHintCache return chainntnfs.ErrCorruptedHeightHintCache
} }
for _, confRequest := range confRequests { for _, confRequest := range confRequests {
confHintKey, err := confRequest.ConfHintKey() confRequest := confRequest
confHintKey, err := confHintKey(&confRequest)
if err != nil { if err != nil {
return err return err
} }
@ -320,3 +282,34 @@ func (c *HeightHintCache) PurgeConfirmHint(confRequests ...ConfRequest) error {
return nil return nil
}) })
} }
// confHintKey returns the key that will be used to index the confirmation
// request's hint within the height hint cache.
func confHintKey(r *chainntnfs.ConfRequest) ([]byte, error) {
if r.TxID == chainntnfs.ZeroHash {
return r.PkScript.Script(), nil
}
var txid bytes.Buffer
if err := WriteElement(&txid, r.TxID); err != nil {
return nil, err
}
return txid.Bytes(), nil
}
// spendHintKey returns the key that will be used to index the spend request's
// hint within the height hint cache.
func spendHintKey(r *chainntnfs.SpendRequest) ([]byte, error) {
if r.OutPoint == chainntnfs.ZeroOutPoint {
return r.PkScript.Script(), nil
}
var outpoint bytes.Buffer
err := WriteElement(&outpoint, r.OutPoint)
if err != nil {
return nil, err
}
return outpoint.Bytes(), nil
}

View File

@ -1,4 +1,4 @@
package chainntnfs package channeldb
import ( import (
"bytes" "bytes"
@ -6,7 +6,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -23,7 +23,7 @@ func initHintCache(t *testing.T) *HeightHintCache {
func initHintCacheWithConfig(t *testing.T, cfg CacheConfig) *HeightHintCache { func initHintCacheWithConfig(t *testing.T, cfg CacheConfig) *HeightHintCache {
t.Helper() t.Helper()
db, err := channeldb.Open(t.TempDir()) db, err := Open(t.TempDir())
require.NoError(t, err, "unable to create db") require.NoError(t, err, "unable to create db")
hintCache, err := NewHeightHintCache(cfg, db.Backend) hintCache, err := NewHeightHintCache(cfg, db.Backend)
require.NoError(t, err, "unable to create hint cache") require.NoError(t, err, "unable to create hint cache")
@ -46,21 +46,19 @@ func TestHeightHintCacheConfirms(t *testing.T) {
// return an error indication so. // return an error indication so.
var unknownHash chainhash.Hash var unknownHash chainhash.Hash
copy(unknownHash[:], bytes.Repeat([]byte{0x01}, 32)) copy(unknownHash[:], bytes.Repeat([]byte{0x01}, 32))
unknownConfRequest := ConfRequest{TxID: unknownHash} unknownConfRequest := chainntnfs.ConfRequest{TxID: unknownHash}
_, err := hintCache.QueryConfirmHint(unknownConfRequest) _, err := hintCache.QueryConfirmHint(unknownConfRequest)
if err != ErrConfirmHintNotFound { require.ErrorIs(t, err, chainntnfs.ErrConfirmHintNotFound)
t.Fatalf("expected ErrConfirmHintNotFound, got: %v", err)
}
// Now, we'll create some transaction hashes and commit them to the // Now, we'll create some transaction hashes and commit them to the
// cache with the same confirm hint. // cache with the same confirm hint.
const height = 100 const height = 100
const numHashes = 5 const numHashes = 5
confRequests := make([]ConfRequest, numHashes) confRequests := make([]chainntnfs.ConfRequest, numHashes)
for i := 0; i < numHashes; i++ { for i := 0; i < numHashes; i++ {
var txHash chainhash.Hash var txHash chainhash.Hash
copy(txHash[:], bytes.Repeat([]byte{byte(i + 1)}, 32)) copy(txHash[:], bytes.Repeat([]byte{byte(i + 1)}, 32))
confRequests[i] = ConfRequest{TxID: txHash} confRequests[i] = chainntnfs.ConfRequest{TxID: txHash}
} }
err = hintCache.CommitConfirmHint(height, confRequests...) err = hintCache.CommitConfirmHint(height, confRequests...)
@ -70,28 +68,20 @@ func TestHeightHintCacheConfirms(t *testing.T) {
// we're able to properly retrieve the confirm hints. // we're able to properly retrieve the confirm hints.
for _, confRequest := range confRequests { for _, confRequest := range confRequests {
confirmHint, err := hintCache.QueryConfirmHint(confRequest) confirmHint, err := hintCache.QueryConfirmHint(confRequest)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to query for hint of %v: %v", confRequest, err) require.EqualValues(t, height, confirmHint)
}
if confirmHint != height {
t.Fatalf("expected confirm hint %d, got %d", height,
confirmHint)
}
} }
// We'll also attempt to purge all of them in a single database // We'll also attempt to purge all of them in a single database
// transaction. // transaction.
if err := hintCache.PurgeConfirmHint(confRequests...); err != nil { err = hintCache.PurgeConfirmHint(confRequests...)
t.Fatalf("unable to remove confirm hints: %v", err) require.NoError(t, err)
}
// Finally, we'll attempt to query for each hash. We should expect not // Finally, we'll attempt to query for each hash. We should expect not
// to find a hint for any of them. // to find a hint for any of them.
for _, confRequest := range confRequests { for _, confRequest := range confRequests {
_, err := hintCache.QueryConfirmHint(confRequest) _, err := hintCache.QueryConfirmHint(confRequest)
if err != ErrConfirmHintNotFound { require.ErrorIs(t, err, chainntnfs.ErrConfirmHintNotFound)
t.Fatalf("expected ErrConfirmHintNotFound, got :%v", err)
}
} }
} }
@ -105,19 +95,19 @@ func TestHeightHintCacheSpends(t *testing.T) {
// Querying for an outpoint not found within the cache should return an // Querying for an outpoint not found within the cache should return an
// error indication so. // error indication so.
unknownOutPoint := wire.OutPoint{Index: 1} unknownOutPoint := wire.OutPoint{Index: 1}
unknownSpendRequest := SpendRequest{OutPoint: unknownOutPoint} unknownSpendRequest := chainntnfs.SpendRequest{
_, err := hintCache.QuerySpendHint(unknownSpendRequest) OutPoint: unknownOutPoint,
if err != ErrSpendHintNotFound {
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
} }
_, err := hintCache.QuerySpendHint(unknownSpendRequest)
require.ErrorIs(t, err, chainntnfs.ErrSpendHintNotFound)
// Now, we'll create some outpoints and commit them to the cache with // Now, we'll create some outpoints and commit them to the cache with
// the same spend hint. // the same spend hint.
const height = 100 const height = 100
const numOutpoints = 5 const numOutpoints = 5
spendRequests := make([]SpendRequest, numOutpoints) spendRequests := make([]chainntnfs.SpendRequest, numOutpoints)
for i := uint32(0); i < numOutpoints; i++ { for i := uint32(0); i < numOutpoints; i++ {
spendRequests[i] = SpendRequest{ spendRequests[i] = chainntnfs.SpendRequest{
OutPoint: wire.OutPoint{Index: i + 1}, OutPoint: wire.OutPoint{Index: i + 1},
} }
} }
@ -129,28 +119,20 @@ func TestHeightHintCacheSpends(t *testing.T) {
// that we're able to properly retrieve the confirm hints. // that we're able to properly retrieve the confirm hints.
for _, spendRequest := range spendRequests { for _, spendRequest := range spendRequests {
spendHint, err := hintCache.QuerySpendHint(spendRequest) spendHint, err := hintCache.QuerySpendHint(spendRequest)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to query for hint: %v", err) require.EqualValues(t, height, spendHint)
}
if spendHint != height {
t.Fatalf("expected spend hint %d, got %d", height,
spendHint)
}
} }
// We'll also attempt to purge all of them in a single database // We'll also attempt to purge all of them in a single database
// transaction. // transaction.
if err := hintCache.PurgeSpendHint(spendRequests...); err != nil { err = hintCache.PurgeSpendHint(spendRequests...)
t.Fatalf("unable to remove spend hint: %v", err) require.NoError(t, err)
}
// Finally, we'll attempt to query for each outpoint. We should expect // Finally, we'll attempt to query for each outpoint. We should expect
// not to find a hint for any of them. // not to find a hint for any of them.
for _, spendRequest := range spendRequests { for _, spendRequest := range spendRequests {
_, err = hintCache.QuerySpendHint(spendRequest) _, err = hintCache.QuerySpendHint(spendRequest)
if err != ErrSpendHintNotFound { require.ErrorIs(t, err, chainntnfs.ErrSpendHintNotFound)
t.Fatalf("expected ErrSpendHintNotFound, got: %v", err)
}
} }
} }
@ -165,7 +147,7 @@ func TestQueryDisable(t *testing.T) {
// Insert a new confirmation hint with a non-zero height. // Insert a new confirmation hint with a non-zero height.
const confHeight = 100 const confHeight = 100
confRequest := ConfRequest{ confRequest := chainntnfs.ConfRequest{
TxID: chainhash.Hash{0x01, 0x02, 0x03}, TxID: chainhash.Hash{0x01, 0x02, 0x03},
} }
err := hintCache.CommitConfirmHint(confHeight, confRequest) err := hintCache.CommitConfirmHint(confHeight, confRequest)
@ -178,7 +160,7 @@ func TestQueryDisable(t *testing.T) {
// Insert a new spend hint with a non-zero height. // Insert a new spend hint with a non-zero height.
const spendHeight = 200 const spendHeight = 200
spendRequest := SpendRequest{ spendRequest := chainntnfs.SpendRequest{
OutPoint: wire.OutPoint{ OutPoint: wire.OutPoint{
Hash: chainhash.Hash{0x4, 0x05, 0x06}, Hash: chainhash.Hash{0x4, 0x05, 0x06},
Index: 42, Index: 42,

View File

@ -3055,10 +3055,10 @@ func TestLightningWallet(t *testing.T, targetBackEnd string) {
tempDir := t.TempDir() tempDir := t.TempDir()
db, err := channeldb.Open(tempDir) db, err := channeldb.Open(tempDir)
require.NoError(t, err, "unable to create db") require.NoError(t, err, "unable to create db")
testCfg := chainntnfs.CacheConfig{ testCfg := channeldb.CacheConfig{
QueryDisable: false, QueryDisable: false,
} }
hintCache, err := chainntnfs.NewHeightHintCache(testCfg, db.Backend) hintCache, err := channeldb.NewHeightHintCache(testCfg, db.Backend)
require.NoError(t, err, "unable to create height hint cache") require.NoError(t, err, "unable to create height hint cache")
blockCache := blockcache.NewBlockCache(10000) blockCache := blockcache.NewBlockCache(10000)
chainNotifier, err := btcdnotify.New( chainNotifier, err := btcdnotify.New(