chain: batch filter fetches for neutrino chain client

This greatly speeds up wallet recovery with a neutrino backend, as we'll
avoid unnecessary round trips for each block filter fetch.
This commit is contained in:
Wilmer Paulino 2020-03-24 16:23:41 -07:00
parent 60299130c6
commit 90a0744ae4
No known key found for this signature in database
GPG key ID: 6DF57B9F9514972F

View file

@ -199,6 +199,11 @@ func (s *NeutrinoClient) FilterBlocks(
// the filter returns a positive match, the full block is then requested // the filter returns a positive match, the full block is then requested
// and scanned for addresses using the block filterer. // and scanned for addresses using the block filterer.
for i, blk := range req.Blocks { for i, blk := range req.Blocks {
// TODO(wilmer): Investigate why polling it still necessary
// here. While testing, I ran into a few instances where the
// filter was not retrieved, leading to a panic. This should not
// happen in most cases thanks to the query logic revamp within
// Neutrino, but it seems there's still an uncovered edge case.
filter, err := s.pollCFilter(&blk.Hash) filter, err := s.pollCFilter(&blk.Hash)
if err != nil { if err != nil {
return nil, err return nil, err
@ -312,7 +317,9 @@ func (s *NeutrinoClient) pollCFilter(hash *chainhash.Hash) (*gcs.Filter, error)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
} }
filter, err = s.CS.GetCFilter(*hash, wire.GCSFilterRegular) filter, err = s.CS.GetCFilter(
*hash, wire.GCSFilterRegular, neutrino.OptimisticBatch(),
)
if err != nil { if err != nil {
count++ count++
continue continue