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 Mar 30, 2021
1 parent b9bba07 commit a8000b7
Show file tree
Hide file tree
Showing 4 changed files with 31 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
22 changes: 19 additions & 3 deletions chainntnfs/neutrinonotify/neutrino.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ 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/queue"
)
Expand Down Expand Up @@ -73,6 +74,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 +90,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 +110,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 +578,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 +635,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 @@ -896,6 +903,15 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
return ntfn.Event, nil
}

// GetBlock is used to retrieve the block with the given hash.
func (n *NeutrinoNotifier) GetBlock(hash chainhash.Hash) (
*btcutil.Block, error) {
n.blockCache.LockHash(hash)
defer n.blockCache.UnlockHash(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 @@ -312,7 +312,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 a8000b7

Please sign in to comment.