chain: wait for rescan exit before re-creating, ensure thread safety

This commit is contained in:
Olaoluwa Osuntokun 2017-06-13 11:15:50 +02:00
parent dcc7bbc14d
commit 4ac75773d7

View file

@ -6,13 +6,13 @@ import (
"sync" "sync"
"time" "time"
"github.com/lightninglabs/neutrino"
"github.com/roasbeef/btcd/chaincfg/chainhash" "github.com/roasbeef/btcd/chaincfg/chainhash"
"github.com/roasbeef/btcd/wire" "github.com/roasbeef/btcd/wire"
"github.com/roasbeef/btcrpcclient" "github.com/roasbeef/btcrpcclient"
"github.com/roasbeef/btcutil" "github.com/roasbeef/btcutil"
"github.com/roasbeef/btcwallet/waddrmgr" "github.com/roasbeef/btcwallet/waddrmgr"
"github.com/roasbeef/btcwallet/wtxmgr" "github.com/roasbeef/btcwallet/wtxmgr"
"github.com/lightninglabs/neutrino"
) )
// NeutrinoClient is an implementation of the btcwalet chain.Interface interface. // NeutrinoClient is an implementation of the btcwalet chain.Interface interface.
@ -151,6 +151,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
if s.scanning { if s.scanning {
// Restart the rescan by killing the existing rescan. // Restart the rescan by killing the existing rescan.
close(s.rescanQuit) close(s.rescanQuit)
s.rescan.WaitForShutdown()
} }
s.rescanQuit = make(chan struct{}) s.rescanQuit = make(chan struct{})
s.scanning = true s.scanning = true
@ -213,18 +214,22 @@ func (s *NeutrinoClient) NotifyBlocks() error {
// NotifyReceived replicates the RPC client's NotifyReceived command. // NotifyReceived replicates the RPC client's NotifyReceived command.
func (s *NeutrinoClient) NotifyReceived(addrs []btcutil.Address) error { func (s *NeutrinoClient) NotifyReceived(addrs []btcutil.Address) error {
s.clientMtx.Lock()
defer s.clientMtx.Unlock()
// If we have a rescan running, we just need to add the appropriate // If we have a rescan running, we just need to add the appropriate
// addresses to the watch list. // addresses to the watch list.
s.clientMtx.Lock()
if s.scanning { if s.scanning {
s.clientMtx.Unlock() s.clientMtx.Unlock()
return s.rescan.Update(neutrino.AddAddrs(addrs...)) return s.rescan.Update(neutrino.AddAddrs(addrs...))
} }
s.rescanQuit = make(chan struct{}) s.rescanQuit = make(chan struct{})
s.scanning = true s.scanning = true
// Don't need RescanFinished notifications. // Don't need RescanFinished notifications.
s.finished = true s.finished = true
s.clientMtx.Unlock()
// Rescan with just the specified addresses. // Rescan with just the specified addresses.
s.rescan = s.CS.NewRescan( s.rescan = s.CS.NewRescan(
neutrino.NotificationHandlers(btcrpcclient.NotificationHandlers{ neutrino.NotificationHandlers(btcrpcclient.NotificationHandlers{