feat: double check ancestor RowConsumption before committing (#1022)

This commit is contained in:
Ömer Faruk Irmak 2024-09-05 16:54:12 +03:00 committed by GitHub
parent 0573f6e440
commit e0203bf9b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 10 deletions

View file

@ -331,15 +331,6 @@ func (w *worker) mainLoop() {
var err error var err error
for { for {
if _, isRetryable := err.(retryableCommitError); isRetryable {
if _, err = w.tryCommitNewWork(time.Now(), w.current.header.ParentHash, w.current.reorgReason); err != nil {
continue
}
} else if err != nil {
log.Error("failed to mine block", "err", err)
w.current = nil
}
// check for reorgs first to lower the chances of trying to handle another // check for reorgs first to lower the chances of trying to handle another
// event eventhough a reorg is pending (due to Go `select` pseudo-randomly picking a case // event eventhough a reorg is pending (due to Go `select` pseudo-randomly picking a case
// to execute if multiple of them are ready) // to execute if multiple of them are ready)
@ -347,9 +338,22 @@ func (w *worker) mainLoop() {
case trigger := <-w.reorgCh: case trigger := <-w.reorgCh:
err = w.handleReorg(&trigger) err = w.handleReorg(&trigger)
continue continue
// System stopped
case <-w.exitCh:
return
default: default:
} }
if _, isRetryable := err.(retryableCommitError); isRetryable {
log.Warn("failed to commit to a block, retrying", "err", err)
if _, err = w.tryCommitNewWork(time.Now(), w.current.header.ParentHash, w.current.reorgReason); err != nil {
continue
}
} else if err != nil {
log.Error("failed to mine block", "err", err)
w.current = nil
}
select { select {
case <-w.startCh: case <-w.startCh:
if w.isRunning() { if w.isRunning() {
@ -845,6 +849,18 @@ func (w *worker) commit(force bool) (common.Hash, error) {
) )
} }
currentHeight := w.current.header.Number.Uint64()
maxReorgDepth := uint64(w.config.CCCMaxWorkers + 1)
if currentHeight > maxReorgDepth {
ancestorHeight := currentHeight - maxReorgDepth
ancestorHash := w.chain.GetHeaderByNumber(ancestorHeight).Hash()
if rawdb.ReadBlockRowConsumption(w.chain.Database(), ancestorHash) == nil {
// reject committing to a block if its ancestor doesn't have its RC stored in DB yet.
// which may either mean that it failed CCC or it is still in the process of being checked
return common.Hash{}, retryableCommitError{inner: errors.New("ancestor doesn't have RC yet")}
}
}
// A new block event will trigger a reorg in the txpool, pause reorgs to defer this until we fetch txns for next block. // A new block event will trigger a reorg in the txpool, pause reorgs to defer this until we fetch txns for next block.
// We may end up trying to process txns that we already included in the previous block, but they will all fail the nonce check // We may end up trying to process txns that we already included in the previous block, but they will all fail the nonce check
w.eth.TxPool().PauseReorgs() w.eth.TxPool().PauseReorgs()

View file

@ -24,7 +24,7 @@ import (
const ( const (
VersionMajor = 5 // Major version component of the current release VersionMajor = 5 // Major version component of the current release
VersionMinor = 7 // Minor version component of the current release VersionMinor = 7 // Minor version component of the current release
VersionPatch = 7 // Patch version component of the current release VersionPatch = 8 // Patch version component of the current release
VersionMeta = "mainnet" // Version metadata to append to the version string VersionMeta = "mainnet" // Version metadata to append to the version string
) )