Skip to content

Commit

Permalink
chain/neutrino: only acquire mutex once in Rescan happy flow
Browse files Browse the repository at this point in the history
  • Loading branch information
cfromknecht committed Dec 8, 2020
1 parent 09647c5 commit faf925f
Showing 1 changed file with 28 additions and 29 deletions.
57 changes: 28 additions & 29 deletions chain/neutrino.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,29 @@ func (s *NeutrinoClient) pollCFilter(hash *chainhash.Hash) (*gcs.Filter, error)
func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Address,
outPoints map[wire.OutPoint]btcutil.Address) error {

bestBlock, err := s.CS.BestBlock()
if err != nil {
return fmt.Errorf("Can't get chain service's best block: %s", err)
}
header, err := s.CS.GetBlockHeader(&bestBlock.Hash)
if err != nil {
return fmt.Errorf("Can't get block header for hash %v: %s",
bestBlock.Hash, err)
}

var inputsToWatch []neutrino.InputWithScript
for op, addr := range outPoints {
addrScript, err := txscript.PayToAddrScript(addr)
if err != nil {
return err
}

inputsToWatch = append(inputsToWatch, neutrino.InputWithScript{
OutPoint: op,
PkScript: addrScript,
})
}

s.clientMtx.Lock()
if !s.started {
s.clientMtx.Unlock()
Expand Down Expand Up @@ -367,57 +390,33 @@ func (s *NeutrinoClient) Rescan(startHash *chainhash.Hash, addrs []btcutil.Addre
s.lastProgressSent = false
s.lastFilteredBlockHeader = nil
s.isRescan = true
s.clientMtx.Unlock()

bestBlock, err := s.CS.BestBlock()
if err != nil {
return fmt.Errorf("Can't get chain service's best block: %s", err)
}
header, err := s.CS.GetBlockHeader(&bestBlock.Hash)
if err != nil {
return fmt.Errorf("Can't get block header for hash %v: %s",
bestBlock.Hash, err)
}

// If the wallet is already fully caught up, or the rescan has started
// with state that indicates a "fresh" wallet, we'll send a
// notification indicating the rescan has "finished".
if header.BlockHash() == *startHash {
s.clientMtx.Lock()
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 {
case s.enqueueNotification <- &RescanFinished{
ntfn := &RescanFinished{
Hash: startHash,
Height: int32(bestBlock.Height),
Time: header.Timestamp,
}:
}
select {
case s.enqueueNotification <- ntfn:
s.clientMtx.Lock()
case <-s.quit:
return nil
case <-rescanQuit:
return nil
}
}

var inputsToWatch []neutrino.InputWithScript
for op, addr := range outPoints {
addrScript, err := txscript.PayToAddrScript(addr)
if err != nil {
return err
}

inputsToWatch = append(inputsToWatch, neutrino.InputWithScript{
OutPoint: op,
PkScript: addrScript,
})
}

s.clientMtx.Lock()
newRescan := neutrino.NewRescan(
&neutrino.RescanChainSource{
ChainService: s.CS,
Expand Down

0 comments on commit faf925f

Please sign in to comment.