chainntnfs: allow clients to pass in best block

Clients can optionally pass their best block known into RegisterBlockEpochNtfn. This enables the notifiers to catch up clients on blocks they may have missed.
This commit is contained in:
Valentine Wallace 2018-08-09 00:05:27 -07:00
parent 6989316b11
commit 71a81f59a9
No known key found for this signature in database
GPG Key ID: B0E55E8D1776A58D
4 changed files with 41 additions and 10 deletions

@ -805,6 +805,10 @@ type blockEpochRegistration struct {
epochQueue *chainntnfs.ConcurrentQueue epochQueue *chainntnfs.ConcurrentQueue
bestBlock *chainntnfs.BlockEpoch
errorChan chan error
cancelChan chan struct{} cancelChan chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
@ -818,13 +822,18 @@ type epochCancel struct {
// RegisterBlockEpochNtfn returns a BlockEpochEvent which subscribes the // RegisterBlockEpochNtfn returns a BlockEpochEvent which subscribes the
// caller to receive notifications, of each new block connected to the main // caller to receive notifications, of each new block connected to the main
// chain. // chain. Clients have the option of passing in their best known block, which
func (b *BitcoindNotifier) RegisterBlockEpochNtfn() (*chainntnfs.BlockEpochEvent, error) { // the notifier uses to check if they are behind on blocks and catch them up.
func (b *BitcoindNotifier) RegisterBlockEpochNtfn(
bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
reg := &blockEpochRegistration{ reg := &blockEpochRegistration{
epochQueue: chainntnfs.NewConcurrentQueue(20), epochQueue: chainntnfs.NewConcurrentQueue(20),
epochChan: make(chan *chainntnfs.BlockEpoch, 20), epochChan: make(chan *chainntnfs.BlockEpoch, 20),
cancelChan: make(chan struct{}), cancelChan: make(chan struct{}),
epochID: atomic.AddUint64(&b.epochClientCounter, 1), epochID: atomic.AddUint64(&b.epochClientCounter, 1),
bestBlock: bestBlock,
errorChan: make(chan error, 1),
} }
reg.epochQueue.Start() reg.epochQueue.Start()

@ -16,7 +16,6 @@ import (
) )
const ( const (
// notifierType uniquely identifies this concrete implementation of the // notifierType uniquely identifies this concrete implementation of the
// ChainNotifier interface. // ChainNotifier interface.
notifierType = "btcd" notifierType = "btcd"
@ -857,6 +856,10 @@ type blockEpochRegistration struct {
epochQueue *chainntnfs.ConcurrentQueue epochQueue *chainntnfs.ConcurrentQueue
bestBlock *chainntnfs.BlockEpoch
errorChan chan error
cancelChan chan struct{} cancelChan chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
@ -870,13 +873,18 @@ type epochCancel struct {
// RegisterBlockEpochNtfn returns a BlockEpochEvent which subscribes the // RegisterBlockEpochNtfn returns a BlockEpochEvent which subscribes the
// caller to receive notifications, of each new block connected to the main // caller to receive notifications, of each new block connected to the main
// chain. // chain. Clients have the option of passing in their best known block, which
func (b *BtcdNotifier) RegisterBlockEpochNtfn() (*chainntnfs.BlockEpochEvent, error) { // the notifier uses to check if they are behind on blocks and catch them up.
func (b *BtcdNotifier) RegisterBlockEpochNtfn(
bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
reg := &blockEpochRegistration{ reg := &blockEpochRegistration{
epochQueue: chainntnfs.NewConcurrentQueue(20), epochQueue: chainntnfs.NewConcurrentQueue(20),
epochChan: make(chan *chainntnfs.BlockEpoch, 20), epochChan: make(chan *chainntnfs.BlockEpoch, 20),
cancelChan: make(chan struct{}), cancelChan: make(chan struct{}),
epochID: atomic.AddUint64(&b.epochClientCounter, 1), epochID: atomic.AddUint64(&b.epochClientCounter, 1),
bestBlock: bestBlock,
errorChan: make(chan error, 1),
} }
reg.epochQueue.Start() reg.epochQueue.Start()

@ -59,7 +59,12 @@ type ChainNotifier interface {
// new block connected to the tip of the main chain. The returned // new block connected to the tip of the main chain. The returned
// BlockEpochEvent struct contains a channel which will be sent upon // BlockEpochEvent struct contains a channel which will be sent upon
// for each new block discovered. // for each new block discovered.
RegisterBlockEpochNtfn() (*BlockEpochEvent, error) //
// Clients have the option of passing in their best known block.
// If they specify a block, the ChainNotifier checks whether the client
// is behind on blocks. If they are, the ChainNotifier sends a backlog
// of block notifications for the missed blocks.
RegisterBlockEpochNtfn(*BlockEpoch) (*BlockEpochEvent, error)
// Start the ChainNotifier. Once started, the implementation should be // Start the ChainNotifier. Once started, the implementation should be
// ready, and able to receive notification registrations from clients. // ready, and able to receive notification registrations from clients.

@ -20,7 +20,6 @@ import (
) )
const ( const (
// notifierType uniquely identifies this concrete implementation of the // notifierType uniquely identifies this concrete implementation of the
// ChainNotifier interface. // ChainNotifier interface.
notifierType = "neutrino" notifierType = "neutrino"
@ -781,6 +780,10 @@ type blockEpochRegistration struct {
cancelChan chan struct{} cancelChan chan struct{}
bestBlock *chainntnfs.BlockEpoch
errorChan chan error
wg sync.WaitGroup wg sync.WaitGroup
} }
@ -790,14 +793,20 @@ type epochCancel struct {
epochID uint64 epochID uint64
} }
// RegisterBlockEpochNtfn returns a BlockEpochEvent which subscribes the caller // RegisterBlockEpochNtfn returns a BlockEpochEvent which subscribes the
// to receive notifications, of each new block connected to the main chain. // caller to receive notifications, of each new block connected to the main
func (n *NeutrinoNotifier) RegisterBlockEpochNtfn() (*chainntnfs.BlockEpochEvent, error) { // chain. Clients have the option of passing in their best known block, which
// the notifier uses to check if they are behind on blocks and catch them up.
func (n *NeutrinoNotifier) RegisterBlockEpochNtfn(
bestBlock *chainntnfs.BlockEpoch) (*chainntnfs.BlockEpochEvent, error) {
reg := &blockEpochRegistration{ reg := &blockEpochRegistration{
epochQueue: chainntnfs.NewConcurrentQueue(20), epochQueue: chainntnfs.NewConcurrentQueue(20),
epochChan: make(chan *chainntnfs.BlockEpoch, 20), epochChan: make(chan *chainntnfs.BlockEpoch, 20),
cancelChan: make(chan struct{}), cancelChan: make(chan struct{}),
epochID: atomic.AddUint64(&n.epochClientCounter, 1), epochID: atomic.AddUint64(&n.epochClientCounter, 1),
bestBlock: bestBlock,
errorChan: make(chan error, 1),
} }
reg.epochQueue.Start() reg.epochQueue.Start()