Skip to content

Commit

Permalink
chainntnfs: add block cache to NeutrinoNotifier
Browse files Browse the repository at this point in the history
This commit adds gives BtcdNotifier access to the block cache and wraps
its GetBlock method so that the block cache's mutex map for the specific
hash is used.
  • Loading branch information
ellemouton committed Apr 28, 2021
1 parent 6ad5781 commit f8de105
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
13 changes: 10 additions & 3 deletions chainntnfs/neutrinonotify/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import (
"fmt"

"github.com/lightninglabs/neutrino"
"github.com/lightningnetwork/lnd/blockcache"
"github.com/lightningnetwork/lnd/chainntnfs"
)

// createNewNotifier creates a new instance of the ChainNotifier interface
// implemented by NeutrinoNotifier.
func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) {
if len(args) != 3 {
if len(args) != 4 {
return nil, fmt.Errorf("incorrect number of arguments to "+
".New(...), expected 3, instead passed %v", len(args))
".New(...), expected 4, instead passed %v", len(args))
}

config, ok := args[0].(*neutrino.ChainService)
Expand All @@ -34,7 +35,13 @@ func createNewNotifier(args ...interface{}) (chainntnfs.ChainNotifier, error) {
"is incorrect, expected a chainntfs.ConfirmHintCache")
}

return New(config, spendHintCache, confirmHintCache), nil
blockCache, ok := args[3].(*blockcache.BlockCache)
if !ok {
return nil, errors.New("fourth argument to neutrinonotify.New " +
"is incorrect, expected a *blockcache.BlockCache")
}

return New(config, spendHintCache, confirmHintCache, blockCache), nil
}

// init registers a driver for the NeutrinoNotify concrete implementation of
Expand Down
29 changes: 26 additions & 3 deletions chainntnfs/neutrinonotify/neutrino.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
"github.com/btcsuite/btcutil/gcs/builder"
"github.com/lightninglabs/neutrino"
"github.com/lightninglabs/neutrino/headerfs"
"github.com/lightningnetwork/lnd/blockcache"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/queue"
)

Expand Down Expand Up @@ -73,6 +75,9 @@ type NeutrinoNotifier struct {
// which the transaction could have confirmed within the chain.
confirmHintCache chainntnfs.ConfirmHintCache

// blockCache is an LRU block cache.
blockCache *blockcache.BlockCache

wg sync.WaitGroup
quit chan struct{}
}
Expand All @@ -86,7 +91,8 @@ var _ chainntnfs.ChainNotifier = (*NeutrinoNotifier)(nil)
// NOTE: The passed neutrino node should already be running and active before
// being passed into this function.
func New(node *neutrino.ChainService, spendHintCache chainntnfs.SpendHintCache,
confirmHintCache chainntnfs.ConfirmHintCache) *NeutrinoNotifier {
confirmHintCache chainntnfs.ConfirmHintCache,
blockCache *blockcache.BlockCache) *NeutrinoNotifier {

return &NeutrinoNotifier{
notificationCancels: make(chan interface{}),
Expand All @@ -105,6 +111,8 @@ func New(node *neutrino.ChainService, spendHintCache chainntnfs.SpendHintCache,
spendHintCache: spendHintCache,
confirmHintCache: confirmHintCache,

blockCache: blockCache,

quit: make(chan struct{}),
}
}
Expand Down Expand Up @@ -571,7 +579,7 @@ func (n *NeutrinoNotifier) historicalConfDetails(confRequest chainntnfs.ConfRequ
// In the case that we do have a match, we'll fetch the block
// from the network so we can find the positional data required
// to send the proper response.
block, err := n.p2pNode.GetBlock(*blockHash)
block, err := n.GetBlock(*blockHash)
if err != nil {
return nil, fmt.Errorf("unable to get block from network: %v", err)
}
Expand Down Expand Up @@ -628,7 +636,7 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {

// getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.
func (n *NeutrinoNotifier) getFilteredBlock(epoch chainntnfs.BlockEpoch) (*filteredBlock, error) {
rawBlock, err := n.p2pNode.GetBlock(*epoch.Hash)
rawBlock, err := n.GetBlock(*epoch.Hash)
if err != nil {
return nil, fmt.Errorf("unable to get block: %v", err)
}
Expand Down Expand Up @@ -908,6 +916,21 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
return ntfn.Event, nil
}

// GetBlock is used to retrieve the block with the given hash. Since the block
// cache used by neutrino will be the same as that used by LND (since it is
// passed to neutrino on initialisation), the neutrino GetBlock method can be
// called directly since it already uses the block cache. However, neutrino
// does not lock the block cache mutex for the given block hash and so that is
// done here.
func (n *NeutrinoNotifier) GetBlock(hash chainhash.Hash) (
*btcutil.Block, error) {

n.blockCache.HashMutex.Lock(lntypes.Hash(hash))
defer n.blockCache.HashMutex.Unlock(lntypes.Hash(hash))

return n.p2pNode.GetBlock(hash)
}

// blockEpochRegistration represents a client's intent to receive a
// notification with each newly connected block.
type blockEpochRegistration struct {
Expand Down
1 change: 1 addition & 0 deletions chainntnfs/test/test_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -1967,6 +1967,7 @@ func TestInterfaces(t *testing.T, targetBackEnd string) {
newNotifier = func() (chainntnfs.TestChainNotifier, error) {
return neutrinonotify.New(
spvNode, hintCache, hintCache,
blockCache,
), nil
}
}
Expand Down
2 changes: 1 addition & 1 deletion chainreg/chainregistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ func NewChainControl(cfg *Config, blockCache *blockcache.BlockCache) (
// along with the wallet's ChainSource, which are all backed by
// the neutrino light client.
cc.ChainNotifier = neutrinonotify.New(
cfg.NeutrinoCS, hintCache, hintCache,
cfg.NeutrinoCS, hintCache, hintCache, blockCache,
)
cc.ChainView, err = chainview.NewCfFilteredChainView(
cfg.NeutrinoCS, blockCache,
Expand Down

0 comments on commit f8de105

Please sign in to comment.