diff --git a/chainntnfs/bitcoindnotify/bitcoind.go b/chainntnfs/bitcoindnotify/bitcoind.go index 49658946..b30c45dc 100644 --- a/chainntnfs/bitcoindnotify/bitcoind.go +++ b/chainntnfs/bitcoindnotify/bitcoind.go @@ -13,6 +13,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/btcsuite/btcwallet/chain" + "github.com/lightningnetwork/lnd/blockcache" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/queue" ) @@ -50,6 +51,9 @@ type BitcoindNotifier struct { bestBlock chainntnfs.BlockEpoch + // blockCache is a LRU block cache. + blockCache *blockcache.BlockCache + // spendHintCache is a cache used to query and update the latest height // hints for an outpoint. Each height hint represents the earliest // 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. func New(chainConn *chain.BitcoindConn, chainParams *chaincfg.Params, spendHintCache chainntnfs.SpendHintCache, - confirmHintCache chainntnfs.ConfirmHintCache) *BitcoindNotifier { + confirmHintCache chainntnfs.ConfirmHintCache, + blockCache *blockcache.BlockCache) *BitcoindNotifier { notifier := &BitcoindNotifier{ chainParams: chainParams, @@ -86,6 +91,8 @@ func New(chainConn *chain.BitcoindConn, chainParams *chaincfg.Params, spendHintCache: spendHintCache, confirmHintCache: confirmHintCache, + blockCache: blockCache, + quit: make(chan struct{}), } @@ -522,7 +529,7 @@ func (b *BitcoindNotifier) confDetailsManually(confRequest chainntnfs.ConfReques "with height %d", height) } - block, err := b.chainConn.GetBlock(blockHash) + block, err := b.GetBlock(blockHash) if err != nil { return nil, chainntnfs.TxNotFoundManually, 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 // transactions to determine whether any are relevant to our registered // clients. - rawBlock, err := b.chainConn.GetBlock(block.Hash) + rawBlock, err := b.GetBlock(block.Hash) if err != nil { 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 "+ "block with height %d: %v", height, err) } - block, err := b.chainConn.GetBlock(blockHash) + block, err := b.GetBlock(blockHash) if err != nil { return nil, fmt.Errorf("unable to retrieve block "+ "with hash %v: %v", blockHash, err) @@ -955,3 +962,11 @@ func (b *BitcoindNotifier) RegisterBlockEpochNtfn( }, 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) +} diff --git a/chainntnfs/bitcoindnotify/bitcoind_test.go b/chainntnfs/bitcoindnotify/bitcoind_test.go index 89c68d2e..e48423bc 100644 --- a/chainntnfs/bitcoindnotify/bitcoind_test.go +++ b/chainntnfs/bitcoindnotify/bitcoind_test.go @@ -11,6 +11,7 @@ import ( "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/integration/rpctest" "github.com/btcsuite/btcwallet/chain" + "github.com/lightningnetwork/lnd/blockcache" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" ) @@ -55,13 +56,14 @@ func initHintCache(t *testing.T) *chainntnfs.HeightHintCache { // bitcoind driver. func setUpNotifier(t *testing.T, bitcoindConn *chain.BitcoindConn, spendHintCache chainntnfs.SpendHintCache, - confirmHintCache chainntnfs.ConfirmHintCache) *BitcoindNotifier { + confirmHintCache chainntnfs.ConfirmHintCache, + blockCache *blockcache.BlockCache) *BitcoindNotifier { t.Helper() notifier := New( bitcoindConn, chainntnfs.NetParams, spendHintCache, - confirmHintCache, + confirmHintCache, blockCache, ) if err := notifier.Start(); err != nil { t.Fatalf("unable to start notifier: %v", err) @@ -116,8 +118,11 @@ func TestHistoricalConfDetailsTxIndex(t *testing.T) { defer cleanUp() hintCache := initHintCache(t) + blockCache := blockcache.NewBlockCache(10000) - notifier := setUpNotifier(t, bitcoindConn, hintCache, hintCache) + notifier := setUpNotifier( + t, bitcoindConn, hintCache, hintCache, blockCache, + ) defer notifier.Stop() syncNotifierWithMiner(t, notifier, miner) @@ -209,8 +214,11 @@ func TestHistoricalConfDetailsNoTxIndex(t *testing.T) { defer cleanUp() hintCache := initHintCache(t) + blockCache := blockcache.NewBlockCache(10000) - notifier := setUpNotifier(t, bitcoindConn, hintCache, hintCache) + notifier := setUpNotifier( + t, bitcoindConn, hintCache, hintCache, blockCache, + ) defer notifier.Stop() // Since the node has its txindex disabled, we fall back to scanning the diff --git a/chainntnfs/bitcoindnotify/driver.go b/chainntnfs/bitcoindnotify/driver.go index 6054f0de..634aa354 100644 --- a/chainntnfs/bitcoindnotify/driver.go +++ b/chainntnfs/bitcoindnotify/driver.go @@ -6,15 +6,16 @@ import ( "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcwallet/chain" + "github.com/lightningnetwork/lnd/blockcache" "github.com/lightningnetwork/lnd/chainntnfs" ) // createNewNotifier creates a new instance of the ChainNotifier interface // implemented by BitcoindNotifier. func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) { - if len(args) != 4 { + if len(args) != 5 { 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) @@ -41,7 +42,14 @@ func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) { "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 diff --git a/chainntnfs/test/test_interface.go b/chainntnfs/test/test_interface.go index 622975e1..4b5c69f3 100644 --- a/chainntnfs/test/test_interface.go +++ b/chainntnfs/test/test_interface.go @@ -19,6 +19,7 @@ import ( "github.com/btcsuite/btcwallet/chain" _ "github.com/btcsuite/btcwallet/walletdb/bdb" // Required to auto-register the boltdb walletdb implementation. "github.com/lightninglabs/neutrino" + "github.com/lightningnetwork/lnd/blockcache" "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/chainntnfs/bitcoindnotify" "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) } + blockCache := blockcache.NewBlockCache(10000) + var ( cleanUp func() newNotifier func() (chainntnfs.TestChainNotifier, error) @@ -1944,7 +1947,7 @@ func TestInterfaces(t *testing.T, targetBackEnd string) { newNotifier = func() (chainntnfs.TestChainNotifier, error) { return bitcoindnotify.New( bitcoindConn, chainntnfs.NetParams, - hintCache, hintCache, + hintCache, hintCache, blockCache, ), nil } diff --git a/chainreg/chainregistry.go b/chainreg/chainregistry.go index dda18a80..28f7e386 100644 --- a/chainreg/chainregistry.go +++ b/chainreg/chainregistry.go @@ -416,7 +416,8 @@ func NewChainControl(cfg *Config) (*ChainControl, func(), error) { } cc.ChainNotifier = bitcoindnotify.New( - bitcoindConn, cfg.ActiveNetParams.Params, hintCache, hintCache, + bitcoindConn, cfg.ActiveNetParams.Params, hintCache, + hintCache, blockCache, ) cc.ChainView = chainview.NewBitcoindFilteredChainView( bitcoindConn, blockCache,