Add ParallelExecFailedError

Parallel execution can fail due to bad dependencies. In the case of bad
dependencies, the result of serial execution should be used.
This commit is contained in:
Jerry 2023-04-25 12:03:04 -07:00
parent 01fc7e3a53
commit f9171c4946
No known key found for this signature in database
GPG key ID: 5B33FA23CB103211
2 changed files with 22 additions and 1 deletions

View file

@ -42,6 +42,7 @@ import (
"github.com/ethereum/go-ethereum/common/prque" "github.com/ethereum/go-ethereum/common/prque"
"github.com/ethereum/go-ethereum/common/tracing" "github.com/ethereum/go-ethereum/common/tracing"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/core/blockstm"
"github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/state/snapshot"
@ -500,6 +501,18 @@ func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header) (ty
} }
result := <-resultChan result := <-resultChan
if _, ok := result.err.(blockstm.ParallelExecFailedError); ok {
log.Warn("Parallel state processor failed", "err", result.err)
// If the parallel processor failed, we will fallback to the serial processor if enabled
if processorCount == 2 {
result.statedb.StopPrefetcher()
result = <-resultChan
processorCount--
}
}
result.counter.Inc(1) result.counter.Inc(1)
// Make sure we are not leaking any prefetchers // Make sure we are not leaking any prefetchers

View file

@ -69,6 +69,14 @@ func (e ErrExecAbortError) Error() string {
} }
} }
type ParallelExecFailedError struct {
Msg string
}
func (e ParallelExecFailedError) Error() string {
return e.Msg
}
type IntHeap []int type IntHeap []int
func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Len() int { return len(h) }
@ -384,7 +392,7 @@ func (pe *ParallelExecutor) Prepare() error {
tx := pe.execTasks.takeNextPending() tx := pe.execTasks.takeNextPending()
if tx == -1 { if tx == -1 {
return fmt.Errorf("no transaction to execute") return ParallelExecFailedError{"no executable transactions due to bad dependency"}
} }
pe.cntExec++ pe.cntExec++