Enforce parallel evm via flag (#1425)

* (feat): implement --parallelevm.enforce to force using block-stm

* core: debug log

* docs: update docs with new flag

* update all config files

* core: modify chain import test to enforce parallel processing
This commit is contained in:
Manav Darji 2025-01-30 23:01:27 +05:30 committed by GitHub
parent 9da0432ec2
commit 8a1e0ec125
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 111 additions and 8 deletions

View file

@ -179,6 +179,7 @@ syncmode = "full"
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false

View file

@ -281,6 +281,7 @@ type BlockChain struct {
processor Processor // Block transaction processor interface
parallelProcessor Processor // Parallel block transaction processor interface
parallelSpeculativeProcesses int // Number of parallel speculative processes
enforceParallelProcessor bool
forker *ForkChoice
vmConfig vm.Config
logger *tracing.Hooks
@ -551,7 +552,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
}
// NewParallelBlockChain , similar to NewBlockChain, creates a new blockchain object, but with a parallel state processor
func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64, checker ethereum.ChainValidator, numprocs int) (*BlockChain, error) {
func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64, checker ethereum.ChainValidator, numprocs int, enforce bool) (*BlockChain, error) {
bc, err := NewBlockChain(db, cacheConfig, genesis, overrides, engine, vmConfig, shouldPreserve, txLookupLimit, checker)
if err != nil {
@ -569,6 +570,7 @@ func NewParallelBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis
bc.parallelProcessor = NewParallelStateProcessor(chainConfig, bc, engine)
bc.parallelSpeculativeProcesses = numprocs
bc.enforceParallelProcessor = enforce
return bc, nil
}
@ -604,7 +606,12 @@ func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header) (_
parallel bool
}
resultChan := make(chan Result, 2)
var resultChanLen int = 2
if bc.enforceParallelProcessor {
log.Debug("Processing block using Block STM only", "number", block.NumberU64())
resultChanLen = 1
}
resultChan := make(chan Result, resultChanLen)
processorCount := 0
@ -631,7 +638,7 @@ func (bc *BlockChain) ProcessBlock(block *types.Block, parent *types.Header) (_
}()
}
if bc.processor != nil {
if bc.processor != nil && !bc.enforceParallelProcessor {
statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
if err != nil {
return nil, nil, 0, nil, 0, err

View file

@ -195,11 +195,14 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
func TestParallelBlockChainImport(t *testing.T) {
t.Parallel()
testParallelBlockChainImport(t, rawdb.HashScheme)
testParallelBlockChainImport(t, rawdb.PathScheme)
testParallelBlockChainImport(t, rawdb.HashScheme, false)
testParallelBlockChainImport(t, rawdb.PathScheme, false)
testParallelBlockChainImport(t, rawdb.HashScheme, true)
testParallelBlockChainImport(t, rawdb.PathScheme, true)
}
func testParallelBlockChainImport(t *testing.T, scheme string) {
func testParallelBlockChainImport(t *testing.T, scheme string, enforceParallelProcessor bool) {
db, _, blockchain, err := newCanonical(ethash.NewFaker(), 10, true, scheme)
blockchain.parallelProcessor = NewParallelStateProcessor(blockchain.chainConfig, blockchain, blockchain.engine)
@ -207,6 +210,8 @@ func testParallelBlockChainImport(t *testing.T, scheme string) {
t.Fatalf("failed to make new canonical chain: %v", err)
}
// If required, enforce parallel block processing and skip serial processing completely
blockchain.enforceParallelProcessor = enforceParallelProcessor
defer blockchain.Stop()
block := blockchain.GetBlockByHash(blockchain.CurrentBlock().Hash())

View file

@ -40,6 +40,7 @@ import (
type ParallelEVMConfig struct {
Enable bool
SpeculativeProcesses int
Enforce bool
}
// StateProcessor is a basic Processor, which takes care of transitioning

View file

@ -181,6 +181,11 @@ devfakeauthor = false # Run miner without validator set authorization
period = 0 # Block period to use in developer mode (0 = mine only if transaction pending)
gaslimit = 11500000 # Initial block gas limit
[parallelevm]
enable = true # Enables parallel execution using Block STM
procs = 8 # Number of speculative processes (cores) in Block STM
enforce = false # Use only Block STM for execution and skip serial execution
[pprof]
pprof = false # Enable the pprof HTTP server
port = 6060 # pprof HTTP server listening port

View file

@ -66,6 +66,8 @@ The ```bor server``` command runs the Bor client.
- ```parallelevm.enable```: Enable Block STM (default: true)
- ```parallelevm.enforce```: Enforce block processing via Block STM (default: false)
- ```parallelevm.procs```: Number of speculative processes (cores) in Block STM (default: 8)
- ```pprof```: Enable the pprof HTTP server (default: false)

View file

@ -258,7 +258,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
// check if Parallel EVM is enabled
// if enabled, use parallel state processor
if config.ParallelEVM.Enable {
eth.blockchain, err = core.NewParallelBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker, config.ParallelEVM.SpeculativeProcesses)
eth.blockchain, err = core.NewParallelBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker, config.ParallelEVM.SpeculativeProcesses, config.ParallelEVM.Enforce)
} else {
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, config.Genesis, &overrides, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker)
}

View file

@ -597,6 +597,8 @@ type ParallelEVMConfig struct {
Enable bool `hcl:"enable,optional" toml:"enable,optional"`
SpeculativeProcesses int `hcl:"procs,optional" toml:"procs,optional"`
Enforce bool `hcl:"enforce,optional" toml:"enforce,optional"`
}
func DefaultConfig() *Config {
@ -794,6 +796,7 @@ func DefaultConfig() *Config {
ParallelEVM: &ParallelEVMConfig{
Enable: true,
SpeculativeProcesses: 8,
Enforce: false,
},
}
}
@ -1199,6 +1202,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
n.ParallelEVM.Enable = c.ParallelEVM.Enable
n.ParallelEVM.SpeculativeProcesses = c.ParallelEVM.SpeculativeProcesses
n.ParallelEVM.Enforce = c.ParallelEVM.Enforce
n.RPCReturnDataLimit = c.RPCReturnDataLimit
if c.Ancient != "" {

View file

@ -986,6 +986,13 @@ func (c *Command) Flags(config *Config) *flagset.Flagset {
Value: &c.cliConfig.ParallelEVM.SpeculativeProcesses,
Default: c.cliConfig.ParallelEVM.SpeculativeProcesses,
})
f.BoolFlag(&flagset.BoolFlag{
Name: "parallelevm.enforce",
Usage: "Enforce block processing via Block STM",
Value: &c.cliConfig.ParallelEVM.Enforce,
Default: c.cliConfig.ParallelEVM.Enforce,
})
f.Uint64Flag(&flagset.Uint64Flag{
Name: "dev.gaslimit",
Usage: "Initial block gas limit",

View file

@ -185,6 +185,7 @@ devfakeauthor = false
[parallelevm]
enable = true
procs = 8
enforce = false
[pprof]
pprof = false

View file

@ -973,7 +973,7 @@ func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
db2 := rawdb.NewMemoryDatabase()
back.genesis.MustCommit(db2, triedb.NewDatabase(db2, triedb.HashDefaults))
chain, _ := core.NewParallelBlockChain(db2, nil, back.genesis, nil, engine, vm.Config{}, nil, nil, nil, 8)
chain, _ := core.NewParallelBlockChain(db2, nil, back.genesis, nil, engine, vm.Config{}, nil, nil, nil, 8, false)
defer chain.Stop()
// Ignore empty commit here for less noise.

View file

@ -169,6 +169,11 @@ gcmode = "archive"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -168,6 +168,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -170,6 +170,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -170,6 +170,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -172,6 +172,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -170,6 +170,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -171,6 +171,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -168,6 +168,11 @@ gcmode = "archive"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -167,6 +167,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -168,6 +168,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -169,6 +169,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# pprof = false
# port = 6060
# addr = "127.0.0.1"

View file

@ -170,6 +170,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# pprof = false
# port = 6060
# addr = "127.0.0.1"

View file

@ -169,6 +169,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060

View file

@ -170,6 +170,11 @@ syncmode = "full"
# period = 0
# gaslimit = 11500000
# [parallelevm]
# enable = true
# procs = 8
# enforce = false
# [pprof]
# pprof = false
# port = 6060