chain/neutrino: fix data races due to not using pointer for rescan

This commit is contained in:
Alex 2018-01-11 03:21:49 -07:00 committed by Olaoluwa Osuntokun
parent 78a69b4802
commit a16bfd7775

View file

@ -20,7 +20,7 @@ type NeutrinoClient struct {
CS *neutrino.ChainService
// We currently support one rescan/notifiction goroutine per client
rescan neutrino.Rescan
rescan *neutrino.Rescan
enqueueNotification chan interface{}
dequeueNotification chan interface{}
@ -181,6 +181,8 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
s.clientMtx.Unlock()
s.rescan.WaitForShutdown()
s.clientMtx.Lock()
s.rescan = nil
s.rescanErr = nil
}
s.rescanQuit = make(chan struct{})
s.scanning = true
@ -214,7 +216,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
}
}
s.rescan = s.CS.NewRescan(
newRescan := s.CS.NewRescan(
neutrino.NotificationHandlers(rpcclient.NotificationHandlers{
OnBlockConnected: s.onBlockConnected,
OnFilteredBlockConnected: s.onFilteredBlockConnected,
@ -226,6 +228,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
neutrino.WatchAddrs(addrs...),
neutrino.WatchOutPoints(watchOutPoints...),
)
s.rescan = &newRescan
s.rescanErr = s.rescan.Start()
return nil
@ -263,7 +266,7 @@ func (s *NeutrinoClient) NotifyReceived(addrs []btcutil.Address) error {
s.lastProgressSent = true
// Rescan with just the specified addresses.
s.rescan = s.CS.NewRescan(
newRescan := s.CS.NewRescan(
neutrino.NotificationHandlers(rpcclient.NotificationHandlers{
OnBlockConnected: s.onBlockConnected,
OnFilteredBlockConnected: s.onFilteredBlockConnected,
@ -273,6 +276,7 @@ func (s *NeutrinoClient) NotifyReceived(addrs []btcutil.Address) error {
neutrino.QuitChan(s.rescanQuit),
neutrino.WatchAddrs(addrs...),
)
s.rescan = &newRescan
s.rescanErr = s.rescan.Start()
s.clientMtx.Unlock()
return nil
@ -467,6 +471,9 @@ func (s *NeutrinoClient) notificationHandler() {
var next interface{}
out:
for {
s.clientMtx.Lock()
rescanErr := s.rescanErr
s.clientMtx.Unlock()
select {
case n, ok := <-enqueue:
if !ok {
@ -506,7 +513,7 @@ out:
dequeue = nil
}
case err := <-s.rescanErr:
case err := <-rescanErr:
if err != nil {
log.Errorf("Neutrino rescan ended with error: %s", err)
}