chain: return err when updating the rescan filter while shutting down

This commit is contained in:
Wilmer Paulino 2018-06-25 18:14:21 -07:00
parent 0b269d799e
commit 27e22b1f79

View file

@ -5,6 +5,7 @@ import (
"container/list" "container/list"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
"net" "net"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -22,6 +23,13 @@ import (
"github.com/lightninglabs/gozmq" "github.com/lightninglabs/gozmq"
) )
var (
// ErrBitcoindClientShuttingDown is an error returned when we attempt
// to receive a notification for a specific item and the bitcoind client
// is in the middle of shutting down.
ErrBitcoindClientShuttingDown = errors.New("client is shutting down")
)
// BitcoindClient represents a persistent client connection to a bitcoind server // BitcoindClient represents a persistent client connection to a bitcoind server
// for information regarding the current best block chain. // for information regarding the current best block chain.
type BitcoindClient struct { type BitcoindClient struct {
@ -191,7 +199,9 @@ func (c *BitcoindClient) NotifyReceived(addrs []btcutil.Address) error {
select { select {
case c.rescanUpdate <- addrs: case c.rescanUpdate <- addrs:
case <-c.quit: case <-c.quit:
return ErrBitcoindClientShuttingDown
} }
return nil return nil
} }
@ -201,7 +211,9 @@ func (c *BitcoindClient) NotifySpent(outPoints []*wire.OutPoint) error {
select { select {
case c.rescanUpdate <- outPoints: case c.rescanUpdate <- outPoints:
case <-c.quit: case <-c.quit:
return ErrBitcoindClientShuttingDown
} }
return nil return nil
} }
@ -211,7 +223,9 @@ func (c *BitcoindClient) NotifyTxIDs(txids []chainhash.Hash) error {
select { select {
case c.rescanUpdate <- txids: case c.rescanUpdate <- txids:
case <-c.quit: case <-c.quit:
return ErrBitcoindClientShuttingDown
} }
return nil return nil
} }
@ -238,45 +252,54 @@ func (c *BitcoindClient) LoadTxFilter(reset bool,
select { select {
case c.rescanUpdate <- struct{}{}: case c.rescanUpdate <- struct{}{}:
case <-c.quit: case <-c.quit:
return nil return ErrBitcoindClientShuttingDown
} }
} }
// This helper function will send an update to the filter. If the quit // This helper function will send an update to the filter. If the quit
// channel is closed, it will allow the outer loop below to finish, // channel is closed, it will allow the outer loop below to finish,
// but skip over any updates as the quit case is triggered each time. // but skip over any updates as the quit case is triggered each time.
sendList := func(list interface{}) { sendList := func(list interface{}) error {
select { select {
case c.rescanUpdate <- list: case c.rescanUpdate <- list:
case <-c.quit: case <-c.quit:
} return ErrBitcoindClientShuttingDown
} }
return nil
}
var err error
for _, watchList := range watchLists { for _, watchList := range watchLists {
switch list := watchList.(type) { switch list := watchList.(type) {
case map[wire.OutPoint]btcutil.Address: case map[wire.OutPoint]btcutil.Address:
sendList(list) err = sendList(list)
case []wire.OutPoint: case []wire.OutPoint:
sendList(list) err = sendList(list)
case []*wire.OutPoint: case []*wire.OutPoint:
sendList(list) err = sendList(list)
case []btcutil.Address: case []btcutil.Address:
sendList(list) err = sendList(list)
case []chainhash.Hash: case []chainhash.Hash:
sendList(list) err = sendList(list)
case []*chainhash.Hash: case []*chainhash.Hash:
sendList(list) err = sendList(list)
default: default:
log.Warnf("Couldn't add item to filter: unknown type") return fmt.Errorf("unable to update filter: unknown "+
"type %T", list)
}
if err != nil {
return err
} }
} }
return nil return nil
} }
@ -332,21 +355,21 @@ func (c *BitcoindClient) Rescan(blockHash *chainhash.Hash,
select { select {
case c.rescanUpdate <- addrs: case c.rescanUpdate <- addrs:
case <-c.quit: case <-c.quit:
return nil return ErrBitcoindClientShuttingDown
} }
// Update outpoints. // Update outpoints.
select { select {
case c.rescanUpdate <- outPoints: case c.rescanUpdate <- outPoints:
case <-c.quit: case <-c.quit:
return nil return ErrBitcoindClientShuttingDown
} }
// Kick off the rescan with the starting block hash. // Kick off the rescan with the starting block hash.
select { select {
case c.rescanUpdate <- blockHash: case c.rescanUpdate <- blockHash:
case <-c.quit: case <-c.quit:
return nil return ErrBitcoindClientShuttingDown
} }
return nil return nil