core,les: headerchain import in batches (#21471)

* core: add test for headerchain inserts

* core, light: write headerchains in batches

* core: change to one callback per batch of inserted headers + review concerns

* core: error-check on batch write

* core: unexport writeHeaders

* core: remove callback parameter in InsertHeaderChain

The semantics of InsertHeaderChain are now much simpler: it is now an
all-or-nothing operation. The new WriteStatus return value allows
callers to check for the canonicality of the insertion. This change
simplifies use of HeaderChain in package les, where the callback was
previously used to post chain events.

* core: skip some hashing when writing headers

* core: less hashing in header validation

* core: fix headerchain flaw regarding blacklisted hashes

Co-authored-by: Felix Lange <fjl@twurst.com>
This commit is contained in:
Martin Holst Swende
2020-12-09 11:13:02 +01:00
committed by GitHub
co-authored by Felix Lange
parent bd848aad7c
commit 40b6ccf383
4 changed files with 307 additions and 138 deletions
+17 -15
View File
@@ -396,24 +396,26 @@ func (lc *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i
lc.wg.Add(1)
defer lc.wg.Done()
var events []interface{}
whFunc := func(header *types.Header) error {
status, err := lc.hc.WriteHeader(header)
status, err := lc.hc.InsertHeaderChain(chain, start)
if err != nil || len(chain) == 0 {
return 0, err
}
switch status {
case core.CanonStatTy:
log.Debug("Inserted new header", "number", header.Number, "hash", header.Hash())
events = append(events, core.ChainEvent{Block: types.NewBlockWithHeader(header), Hash: header.Hash()})
case core.SideStatTy:
log.Debug("Inserted forked header", "number", header.Number, "hash", header.Hash())
events = append(events, core.ChainSideEvent{Block: types.NewBlockWithHeader(header)})
}
return err
// Create chain event for the new head block of this insertion.
var (
events = make([]interface{}, 0, 1)
lastHeader = chain[len(chain)-1]
block = types.NewBlockWithHeader(lastHeader)
)
switch status {
case core.CanonStatTy:
events = append(events, core.ChainEvent{Block: block, Hash: block.Hash()})
case core.SideStatTy:
events = append(events, core.ChainSideEvent{Block: block})
}
i, err := lc.hc.InsertHeaderChain(chain, whFunc, start)
lc.postChainEvents(events)
return i, err
return 0, err
}
// CurrentHeader retrieves the current head header of the canonical chain. The