chainntnfs: add block cache to BitcoindNotifier

This commit adds a blockcache pointer to BitcoindNotifier and wraps its
GetBlock method so that the block cache is used.
This commit is contained in:
Elle Mouton 2021-03-18 14:42:18 +02:00
parent f470946379
commit 8a33fbf11a
5 changed files with 48 additions and 13 deletions

@ -13,6 +13,7 @@ import (
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/btcsuite/btcwallet/chain" "github.com/btcsuite/btcwallet/chain"
"github.com/lightningnetwork/lnd/blockcache"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/queue" "github.com/lightningnetwork/lnd/queue"
) )
@ -50,6 +51,9 @@ type BitcoindNotifier struct {
bestBlock chainntnfs.BlockEpoch bestBlock chainntnfs.BlockEpoch
// blockCache is a LRU block cache.
blockCache *blockcache.BlockCache
// spendHintCache is a cache used to query and update the latest height // spendHintCache is a cache used to query and update the latest height
// hints for an outpoint. Each height hint represents the earliest // hints for an outpoint. Each height hint represents the earliest
// height at which the outpoint could have been spent within the chain. // height at which the outpoint could have been spent within the chain.
@ -73,7 +77,8 @@ var _ chainntnfs.ChainNotifier = (*BitcoindNotifier)(nil)
// willing to accept RPC requests and new zmq clients. // willing to accept RPC requests and new zmq clients.
func New(chainConn *chain.BitcoindConn, chainParams *chaincfg.Params, func New(chainConn *chain.BitcoindConn, chainParams *chaincfg.Params,
spendHintCache chainntnfs.SpendHintCache, spendHintCache chainntnfs.SpendHintCache,
confirmHintCache chainntnfs.ConfirmHintCache) *BitcoindNotifier { confirmHintCache chainntnfs.ConfirmHintCache,
blockCache *blockcache.BlockCache) *BitcoindNotifier {
notifier := &BitcoindNotifier{ notifier := &BitcoindNotifier{
chainParams: chainParams, chainParams: chainParams,
@ -86,6 +91,8 @@ func New(chainConn *chain.BitcoindConn, chainParams *chaincfg.Params,
spendHintCache: spendHintCache, spendHintCache: spendHintCache,
confirmHintCache: confirmHintCache, confirmHintCache: confirmHintCache,
blockCache: blockCache,
quit: make(chan struct{}), quit: make(chan struct{}),
} }
@ -522,7 +529,7 @@ func (b *BitcoindNotifier) confDetailsManually(confRequest chainntnfs.ConfReques
"with height %d", height) "with height %d", height)
} }
block, err := b.chainConn.GetBlock(blockHash) block, err := b.GetBlock(blockHash)
if err != nil { if err != nil {
return nil, chainntnfs.TxNotFoundManually, return nil, chainntnfs.TxNotFoundManually,
fmt.Errorf("unable to get block with hash "+ fmt.Errorf("unable to get block with hash "+
@ -558,7 +565,7 @@ func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) err
// First, we'll fetch the raw block as we'll need to gather all the // First, we'll fetch the raw block as we'll need to gather all the
// transactions to determine whether any are relevant to our registered // transactions to determine whether any are relevant to our registered
// clients. // clients.
rawBlock, err := b.chainConn.GetBlock(block.Hash) rawBlock, err := b.GetBlock(block.Hash)
if err != nil { if err != nil {
return fmt.Errorf("unable to get block: %v", err) return fmt.Errorf("unable to get block: %v", err)
} }
@ -777,7 +784,7 @@ func (b *BitcoindNotifier) historicalSpendDetails(
return nil, fmt.Errorf("unable to retrieve hash for "+ return nil, fmt.Errorf("unable to retrieve hash for "+
"block with height %d: %v", height, err) "block with height %d: %v", height, err)
} }
block, err := b.chainConn.GetBlock(blockHash) block, err := b.GetBlock(blockHash)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to retrieve block "+ return nil, fmt.Errorf("unable to retrieve block "+
"with hash %v: %v", blockHash, err) "with hash %v: %v", blockHash, err)
@ -955,3 +962,11 @@ func (b *BitcoindNotifier) RegisterBlockEpochNtfn(
}, nil }, nil
} }
} }
// GetBlock is used to retrieve the block with the given hash. This function
// wraps the blockCache's GetBlock function.
func (b *BitcoindNotifier) GetBlock(hash *chainhash.Hash) (*wire.MsgBlock,
error) {
return b.blockCache.GetBlock(hash, b.chainConn.GetBlock)
}

@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/integration/rpctest" "github.com/btcsuite/btcd/integration/rpctest"
"github.com/btcsuite/btcwallet/chain" "github.com/btcsuite/btcwallet/chain"
"github.com/lightningnetwork/lnd/blockcache"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/channeldb"
) )
@ -55,13 +56,14 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache {
// bitcoind driver. // bitcoind driver.
func setUpNotifier(t *testing.T, bitcoindConn *chain.BitcoindConn, func setUpNotifier(t *testing.T, bitcoindConn *chain.BitcoindConn,
spendHintCache chainntnfs.SpendHintCache, spendHintCache chainntnfs.SpendHintCache,
confirmHintCache chainntnfs.ConfirmHintCache) *BitcoindNotifier { confirmHintCache chainntnfs.ConfirmHintCache,
blockCache *blockcache.BlockCache) *BitcoindNotifier {
t.Helper() t.Helper()
notifier := New( notifier := New(
bitcoindConn, chainntnfs.NetParams, spendHintCache, bitcoindConn, chainntnfs.NetParams, spendHintCache,
confirmHintCache, confirmHintCache, blockCache,
) )
if err := notifier.Start(); err != nil { if err := notifier.Start(); err != nil {
t.Fatalf("unable to start notifier: %v", err) t.Fatalf("unable to start notifier: %v", err)
@ -116,8 +118,11 @@ func TestHistoricalConfDetailsTxIndex(t *testing.T) {
defer cleanUp() defer cleanUp()
hintCache := initHintCache(t) hintCache := initHintCache(t)
blockCache := blockcache.NewBlockCache(10000)
notifier := setUpNotifier(t, bitcoindConn, hintCache, hintCache) notifier := setUpNotifier(
t, bitcoindConn, hintCache, hintCache, blockCache,
)
defer notifier.Stop() defer notifier.Stop()
syncNotifierWithMiner(t, notifier, miner) syncNotifierWithMiner(t, notifier, miner)
@ -209,8 +214,11 @@ func TestHistoricalConfDetailsNoTxIndex(t *testing.T) {
defer cleanUp() defer cleanUp()
hintCache := initHintCache(t) hintCache := initHintCache(t)
blockCache := blockcache.NewBlockCache(10000)
notifier := setUpNotifier(t, bitcoindConn, hintCache, hintCache) notifier := setUpNotifier(
t, bitcoindConn, hintCache, hintCache, blockCache,
)
defer notifier.Stop() defer notifier.Stop()
// Since the node has its txindex disabled, we fall back to scanning the // Since the node has its txindex disabled, we fall back to scanning the

@ -6,15 +6,16 @@ import (
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcwallet/chain" "github.com/btcsuite/btcwallet/chain"
"github.com/lightningnetwork/lnd/blockcache"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
) )
// createNewNotifier creates a new instance of the ChainNotifier interface // createNewNotifier creates a new instance of the ChainNotifier interface
// implemented by BitcoindNotifier. // implemented by BitcoindNotifier.
func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) { func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) {
if len(args) != 4 { if len(args) != 5 {
return nil, fmt.Errorf("incorrect number of arguments to "+ return nil, fmt.Errorf("incorrect number of arguments to "+
".New(...), expected 4, instead passed %v", len(args)) ".New(...), expected 5, instead passed %v", len(args))
} }
chainConn, ok := args[0].(*chain.BitcoindConn) chainConn, ok := args[0].(*chain.BitcoindConn)
@ -41,7 +42,14 @@ func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) {
"is incorrect, expected a chainntnfs.ConfirmHintCache") "is incorrect, expected a chainntnfs.ConfirmHintCache")
} }
return New(chainConn, chainParams, spendHintCache, confirmHintCache), nil blockCache, ok := args[4].(*blockcache.BlockCache)
if !ok {
return nil, errors.New("fifth argument to bitcoindnotify.New " +
"is incorrect, expected a *blockcache.BlockCache")
}
return New(chainConn, chainParams, spendHintCache,
confirmHintCache, blockCache), nil
} }
// init registers a driver for the BtcdNotifier concrete implementation of the // init registers a driver for the BtcdNotifier concrete implementation of the

@ -19,6 +19,7 @@ import (
"github.com/btcsuite/btcwallet/chain" "github.com/btcsuite/btcwallet/chain"
_ "github.com/btcsuite/btcwallet/walletdb/bdb" // Required to auto-register the boltdb walletdb implementation. _ "github.com/btcsuite/btcwallet/walletdb/bdb" // Required to auto-register the boltdb walletdb implementation.
"github.com/lightninglabs/neutrino" "github.com/lightninglabs/neutrino"
"github.com/lightningnetwork/lnd/blockcache"
"github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/chainntnfs/bitcoindnotify" "github.com/lightningnetwork/lnd/chainntnfs/bitcoindnotify"
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify" "github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
@ -1930,6 +1931,8 @@ func TestInterfaces(t *testing.T, targetBackEnd string) {
t.Fatalf("unable to create height hint cache: %v", err) t.Fatalf("unable to create height hint cache: %v", err)
} }
blockCache := blockcache.NewBlockCache(10000)
var ( var (
cleanUp func() cleanUp func()
newNotifier func() (chainntnfs.TestChainNotifier, error) newNotifier func() (chainntnfs.TestChainNotifier, error)
@ -1944,7 +1947,7 @@ func TestInterfaces(t *testing.T, targetBackEnd string) {
newNotifier = func() (chainntnfs.TestChainNotifier, error) { newNotifier = func() (chainntnfs.TestChainNotifier, error) {
return bitcoindnotify.New( return bitcoindnotify.New(
bitcoindConn, chainntnfs.NetParams, bitcoindConn, chainntnfs.NetParams,
hintCache, hintCache, hintCache, hintCache, blockCache,
), nil ), nil
} }

@ -416,7 +416,8 @@ func NewChainControl(cfg *Config) (*ChainControl, func(), error) {
} }
cc.ChainNotifier = bitcoindnotify.New( cc.ChainNotifier = bitcoindnotify.New(
bitcoindConn, cfg.ActiveNetParams.Params, hintCache, hintCache, bitcoindConn, cfg.ActiveNetParams.Params, hintCache,
hintCache, blockCache,
) )
cc.ChainView = chainview.NewBitcoindFilteredChainView( cc.ChainView = chainview.NewBitcoindFilteredChainView(
bitcoindConn, blockCache, bitcoindConn, blockCache,