core/bloombits: avoid crash when storing errors of different type (#23437)

This fixes a rare crash which could occur when two different errors happened
in the same bloombits.MatcherSession.
This commit is contained in:
Pedro Gomes 2021-08-24 12:32:19 +01:00 committed by GitHub
parent 8dbf261fd9
commit 8e0771c218
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -510,8 +510,9 @@ type MatcherSession struct {
closer sync.Once // Sync object to ensure we only ever close once closer sync.Once // Sync object to ensure we only ever close once
quit chan struct{} // Quit channel to request pipeline termination quit chan struct{} // Quit channel to request pipeline termination
ctx context.Context // Context used by the light client to abort filtering ctx context.Context // Context used by the light client to abort filtering
err atomic.Value // Global error to track retrieval failures deep in the chain err error // Global error to track retrieval failures deep in the chain
errLock sync.Mutex
pend sync.WaitGroup pend sync.WaitGroup
} }
@ -529,10 +530,10 @@ func (s *MatcherSession) Close() {
// Error returns any failure encountered during the matching session. // Error returns any failure encountered during the matching session.
func (s *MatcherSession) Error() error { func (s *MatcherSession) Error() error {
if err := s.err.Load(); err != nil { s.errLock.Lock()
return err.(error) defer s.errLock.Unlock()
}
return nil return s.err
} }
// allocateRetrieval assigns a bloom bit index to a client process that can either // allocateRetrieval assigns a bloom bit index to a client process that can either
@ -630,7 +631,9 @@ func (s *MatcherSession) Multiplex(batch int, wait time.Duration, mux chan chan
result := <-request result := <-request
if result.Error != nil { if result.Error != nil {
s.err.Store(result.Error) s.errLock.Lock()
s.err = result.Error
s.errLock.Unlock()
s.Close() s.Close()
} }
s.deliverSections(result.Bit, result.Sections, result.Bitsets) s.deliverSections(result.Bit, result.Sections, result.Bitsets)