core, eth/downloader: handle spurious junk bodies from racey rollbacks (#25578)

* eth/downloader: handle junkbodies/receipts in the beacon sync

* core: check for header presence when checking for blocks
This commit is contained in:
Péter Szilágyi 2022-08-23 14:02:51 +03:00 committed by GitHub
parent 6d711f0c00
commit 81bd998353
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 6 deletions

View File

@ -137,6 +137,9 @@ func (bc *BlockChain) HasBlock(hash common.Hash, number uint64) bool {
if bc.blockCache.Contains(hash) { if bc.blockCache.Contains(hash) {
return true return true
} }
if !bc.HasHeader(hash, number) {
return false
}
return rawdb.HasBody(bc.db, hash, number) return rawdb.HasBody(bc.db, hash, number)
} }

View File

@ -358,6 +358,7 @@ func (s *skeleton) sync(head *types.Header) (*types.Header, error) {
// If the sync is already done, resume the backfiller. When the loop stops, // If the sync is already done, resume the backfiller. When the loop stops,
// terminate the backfiller too. // terminate the backfiller too.
linked := len(s.progress.Subchains) == 1 && linked := len(s.progress.Subchains) == 1 &&
rawdb.HasHeader(s.db, s.progress.Subchains[0].Next, s.scratchHead) &&
rawdb.HasBody(s.db, s.progress.Subchains[0].Next, s.scratchHead) && rawdb.HasBody(s.db, s.progress.Subchains[0].Next, s.scratchHead) &&
rawdb.HasReceipts(s.db, s.progress.Subchains[0].Next, s.scratchHead) rawdb.HasReceipts(s.db, s.progress.Subchains[0].Next, s.scratchHead)
if linked { if linked {
@ -946,12 +947,12 @@ func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged boo
// In the case of full sync it would be enough to check for the body, // In the case of full sync it would be enough to check for the body,
// but even a full syncing node will generate a receipt once block // but even a full syncing node will generate a receipt once block
// processing is done, so it's just one more "needless" check. // processing is done, so it's just one more "needless" check.
var ( //
hasBody = rawdb.HasBody(s.db, header.ParentHash, header.Number.Uint64()-1) // The weird cascading checks are done to minimize the database reads.
hasReceipt = rawdb.HasReceipts(s.db, header.ParentHash, header.Number.Uint64()-1) linked = rawdb.HasHeader(s.db, header.ParentHash, header.Number.Uint64()-1) &&
) rawdb.HasBody(s.db, header.ParentHash, header.Number.Uint64()-1) &&
if hasBody && hasReceipt { rawdb.HasReceipts(s.db, header.ParentHash, header.Number.Uint64()-1)
linked = true if linked {
break break
} }
} }