Merge pull request #624 from wpaulino/neutrino-rescan-finished-deadlock
chain: prevent deadlock while notifying RescanFinished for NeutrinoClient
This commit is contained in:
commit
66a95921c0
1 changed files with 15 additions and 3 deletions
|
@ -322,16 +322,17 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
outPoints map[wire.OutPoint]btcutil.Address) error {
|
outPoints map[wire.OutPoint]btcutil.Address) error {
|
||||||
|
|
||||||
s.clientMtx.Lock()
|
s.clientMtx.Lock()
|
||||||
defer s.clientMtx.Unlock()
|
|
||||||
if !s.started {
|
if !s.started {
|
||||||
|
s.clientMtx.Unlock()
|
||||||
return fmt.Errorf("can't do a rescan when the chain client " +
|
return fmt.Errorf("can't do a rescan when the chain client " +
|
||||||
"is not started")
|
"is not started")
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
rescan := s.rescan
|
||||||
s.clientMtx.Unlock()
|
s.clientMtx.Unlock()
|
||||||
s.rescan.WaitForShutdown()
|
rescan.WaitForShutdown()
|
||||||
s.clientMtx.Lock()
|
s.clientMtx.Lock()
|
||||||
s.rescan = nil
|
s.rescan = nil
|
||||||
s.rescanErr = nil
|
s.rescanErr = nil
|
||||||
|
@ -342,6 +343,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
s.lastProgressSent = false
|
s.lastProgressSent = false
|
||||||
s.lastFilteredBlockHeader = nil
|
s.lastFilteredBlockHeader = nil
|
||||||
s.isRescan = true
|
s.isRescan = true
|
||||||
|
s.clientMtx.Unlock()
|
||||||
|
|
||||||
bestBlock, err := s.CS.BestBlock()
|
bestBlock, err := s.CS.BestBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -357,7 +359,14 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
// with state that indicates a "fresh" wallet, we'll send a
|
// with state that indicates a "fresh" wallet, we'll send a
|
||||||
// notification indicating the rescan has "finished".
|
// notification indicating the rescan has "finished".
|
||||||
if header.BlockHash() == *startHash {
|
if header.BlockHash() == *startHash {
|
||||||
|
s.clientMtx.Lock()
|
||||||
s.finished = true
|
s.finished = true
|
||||||
|
rescanQuit := s.rescanQuit
|
||||||
|
s.clientMtx.Unlock()
|
||||||
|
|
||||||
|
// Release the lock while dispatching the notification since
|
||||||
|
// it's possible for the notificationHandler to be waiting to
|
||||||
|
// acquire it before receiving the notification.
|
||||||
select {
|
select {
|
||||||
case s.enqueueNotification <- &RescanFinished{
|
case s.enqueueNotification <- &RescanFinished{
|
||||||
Hash: startHash,
|
Hash: startHash,
|
||||||
|
@ -366,7 +375,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
}:
|
}:
|
||||||
case <-s.quit:
|
case <-s.quit:
|
||||||
return nil
|
return nil
|
||||||
case <-s.rescanQuit:
|
case <-rescanQuit:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,6 +384,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
for op, addr := range outPoints {
|
for op, addr := range outPoints {
|
||||||
addrScript, err := txscript.PayToAddrScript(addr)
|
addrScript, err := txscript.PayToAddrScript(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
inputsToWatch = append(inputsToWatch, neutrino.InputWithScript{
|
inputsToWatch = append(inputsToWatch, neutrino.InputWithScript{
|
||||||
|
@ -383,6 +393,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.clientMtx.Lock()
|
||||||
newRescan := neutrino.NewRescan(
|
newRescan := neutrino.NewRescan(
|
||||||
&neutrino.RescanChainSource{
|
&neutrino.RescanChainSource{
|
||||||
ChainService: s.CS,
|
ChainService: s.CS,
|
||||||
|
@ -400,6 +411,7 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
|
||||||
)
|
)
|
||||||
s.rescan = newRescan
|
s.rescan = newRescan
|
||||||
s.rescanErr = s.rescan.Start()
|
s.rescanErr = s.rescan.Start()
|
||||||
|
s.clientMtx.Unlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue