From 8a1e0ec1255131db86a65505059646bb14ef5e95 Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 30 Jan 2025 23:01:27 +0530 Subject: [PATCH] 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 --- builder/files/config.toml | 1 + core/blockchain.go | 13 ++++++++++--- core/blockchain_test.go | 11 ++++++++--- core/parallel_state_processor.go | 1 + docs/cli/example_config.toml | 5 +++++ docs/cli/server.md | 2 ++ eth/backend.go | 2 +- internal/cli/server/config.go | 4 ++++ internal/cli/server/flags.go | 7 +++++++ internal/cli/server/testdata/default.toml | 1 + miner/worker_test.go | 2 +- packaging/templates/mainnet-v1/archive/config.toml | 5 +++++ .../mainnet-v1/sentry/sentry/bor/config.toml | 5 +++++ .../mainnet-v1/sentry/sentry/bor/pbss_config.toml | 5 +++++ .../mainnet-v1/sentry/validator/bor/config.toml | 5 +++++ .../sentry/validator/bor/pbss_config.toml | 5 +++++ .../mainnet-v1/without-sentry/bor/config.toml | 5 +++++ .../mainnet-v1/without-sentry/bor/pbss_config.toml | 5 +++++ .../templates/testnet-amoy/archive/config.toml | 5 +++++ .../testnet-amoy/sentry/sentry/bor/config.toml | 5 +++++ .../testnet-amoy/sentry/sentry/bor/pbss_config.toml | 5 +++++ .../testnet-amoy/sentry/validator/bor/config.toml | 5 +++++ .../sentry/validator/bor/pbss_config.toml | 5 +++++ .../testnet-amoy/without-sentry/bor/config.toml | 5 +++++ .../without-sentry/bor/pbss_config.toml | 5 +++++ 25 files changed, 111 insertions(+), 8 deletions(-) diff --git a/builder/files/config.toml b/builder/files/config.toml index a903735e9c..a875a237e3 100644 --- a/builder/files/config.toml +++ b/builder/files/config.toml @@ -179,6 +179,7 @@ syncmode = "full" # [parallelevm] # enable = true # procs = 8 + # enforce = false # [pprof] # pprof = false diff --git a/core/blockchain.go b/core/blockchain.go index a37e4a5f1e..b293f8d4ef 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -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 diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 47738f2bc6..2ce78bc936 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -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()) diff --git a/core/parallel_state_processor.go b/core/parallel_state_processor.go index f521764d28..33ca8595e9 100644 --- a/core/parallel_state_processor.go +++ b/core/parallel_state_processor.go @@ -40,6 +40,7 @@ import ( type ParallelEVMConfig struct { Enable bool SpeculativeProcesses int + Enforce bool } // StateProcessor is a basic Processor, which takes care of transitioning diff --git a/docs/cli/example_config.toml b/docs/cli/example_config.toml index b656a6dc3f..ffc822cc64 100644 --- a/docs/cli/example_config.toml +++ b/docs/cli/example_config.toml @@ -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 diff --git a/docs/cli/server.md b/docs/cli/server.md index 530ca22975..4c4c86b004 100644 --- a/docs/cli/server.md +++ b/docs/cli/server.md @@ -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) diff --git a/eth/backend.go b/eth/backend.go index 818d45cb73..ec50394ca0 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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) } diff --git a/internal/cli/server/config.go b/internal/cli/server/config.go index 42ad1f20af..1f6e451dbf 100644 --- a/internal/cli/server/config.go +++ b/internal/cli/server/config.go @@ -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 != "" { diff --git a/internal/cli/server/flags.go b/internal/cli/server/flags.go index 0cf8919b9d..25fc6ce7ba 100644 --- a/internal/cli/server/flags.go +++ b/internal/cli/server/flags.go @@ -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", diff --git a/internal/cli/server/testdata/default.toml b/internal/cli/server/testdata/default.toml index fc4c04ab86..5f95769546 100644 --- a/internal/cli/server/testdata/default.toml +++ b/internal/cli/server/testdata/default.toml @@ -185,6 +185,7 @@ devfakeauthor = false [parallelevm] enable = true procs = 8 + enforce = false [pprof] pprof = false diff --git a/miner/worker_test.go b/miner/worker_test.go index 1f90c79ec1..1d1fcc32f5 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -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. diff --git a/packaging/templates/mainnet-v1/archive/config.toml b/packaging/templates/mainnet-v1/archive/config.toml index 311c4bc782..0a5c0e1017 100644 --- a/packaging/templates/mainnet-v1/archive/config.toml +++ b/packaging/templates/mainnet-v1/archive/config.toml @@ -169,6 +169,11 @@ gcmode = "archive" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/mainnet-v1/sentry/sentry/bor/config.toml b/packaging/templates/mainnet-v1/sentry/sentry/bor/config.toml index 556c551092..d4fd25e863 100644 --- a/packaging/templates/mainnet-v1/sentry/sentry/bor/config.toml +++ b/packaging/templates/mainnet-v1/sentry/sentry/bor/config.toml @@ -168,6 +168,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/mainnet-v1/sentry/sentry/bor/pbss_config.toml b/packaging/templates/mainnet-v1/sentry/sentry/bor/pbss_config.toml index 7a11e6a7d2..20edf749dc 100644 --- a/packaging/templates/mainnet-v1/sentry/sentry/bor/pbss_config.toml +++ b/packaging/templates/mainnet-v1/sentry/sentry/bor/pbss_config.toml @@ -170,6 +170,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/mainnet-v1/sentry/validator/bor/config.toml b/packaging/templates/mainnet-v1/sentry/validator/bor/config.toml index 12d27d2537..a839551c02 100644 --- a/packaging/templates/mainnet-v1/sentry/validator/bor/config.toml +++ b/packaging/templates/mainnet-v1/sentry/validator/bor/config.toml @@ -170,6 +170,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/mainnet-v1/sentry/validator/bor/pbss_config.toml b/packaging/templates/mainnet-v1/sentry/validator/bor/pbss_config.toml index 75954b38e6..3f4da5d4f8 100644 --- a/packaging/templates/mainnet-v1/sentry/validator/bor/pbss_config.toml +++ b/packaging/templates/mainnet-v1/sentry/validator/bor/pbss_config.toml @@ -172,6 +172,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/mainnet-v1/without-sentry/bor/config.toml b/packaging/templates/mainnet-v1/without-sentry/bor/config.toml index e77c368459..564dc6bbaa 100644 --- a/packaging/templates/mainnet-v1/without-sentry/bor/config.toml +++ b/packaging/templates/mainnet-v1/without-sentry/bor/config.toml @@ -170,6 +170,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/mainnet-v1/without-sentry/bor/pbss_config.toml b/packaging/templates/mainnet-v1/without-sentry/bor/pbss_config.toml index 20a5b02f0a..06c4b6b018 100644 --- a/packaging/templates/mainnet-v1/without-sentry/bor/pbss_config.toml +++ b/packaging/templates/mainnet-v1/without-sentry/bor/pbss_config.toml @@ -171,6 +171,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/testnet-amoy/archive/config.toml b/packaging/templates/testnet-amoy/archive/config.toml index 7fb2f21476..b571074496 100644 --- a/packaging/templates/testnet-amoy/archive/config.toml +++ b/packaging/templates/testnet-amoy/archive/config.toml @@ -168,6 +168,11 @@ gcmode = "archive" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/testnet-amoy/sentry/sentry/bor/config.toml b/packaging/templates/testnet-amoy/sentry/sentry/bor/config.toml index 0007e22955..2b98c30cb3 100644 --- a/packaging/templates/testnet-amoy/sentry/sentry/bor/config.toml +++ b/packaging/templates/testnet-amoy/sentry/sentry/bor/config.toml @@ -167,6 +167,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/testnet-amoy/sentry/sentry/bor/pbss_config.toml b/packaging/templates/testnet-amoy/sentry/sentry/bor/pbss_config.toml index 6f72c5a3b2..f1b8cabbfe 100644 --- a/packaging/templates/testnet-amoy/sentry/sentry/bor/pbss_config.toml +++ b/packaging/templates/testnet-amoy/sentry/sentry/bor/pbss_config.toml @@ -168,6 +168,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/testnet-amoy/sentry/validator/bor/config.toml b/packaging/templates/testnet-amoy/sentry/validator/bor/config.toml index 9e0eec562a..c4db9aed12 100644 --- a/packaging/templates/testnet-amoy/sentry/validator/bor/config.toml +++ b/packaging/templates/testnet-amoy/sentry/validator/bor/config.toml @@ -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" diff --git a/packaging/templates/testnet-amoy/sentry/validator/bor/pbss_config.toml b/packaging/templates/testnet-amoy/sentry/validator/bor/pbss_config.toml index 5a58afd786..bbe422907a 100644 --- a/packaging/templates/testnet-amoy/sentry/validator/bor/pbss_config.toml +++ b/packaging/templates/testnet-amoy/sentry/validator/bor/pbss_config.toml @@ -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" diff --git a/packaging/templates/testnet-amoy/without-sentry/bor/config.toml b/packaging/templates/testnet-amoy/without-sentry/bor/config.toml index fa9f1970e8..cd8f6ef2a8 100644 --- a/packaging/templates/testnet-amoy/without-sentry/bor/config.toml +++ b/packaging/templates/testnet-amoy/without-sentry/bor/config.toml @@ -169,6 +169,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060 diff --git a/packaging/templates/testnet-amoy/without-sentry/bor/pbss_config.toml b/packaging/templates/testnet-amoy/without-sentry/bor/pbss_config.toml index 9b16fd2035..8ea23b8870 100644 --- a/packaging/templates/testnet-amoy/without-sentry/bor/pbss_config.toml +++ b/packaging/templates/testnet-amoy/without-sentry/bor/pbss_config.toml @@ -170,6 +170,11 @@ syncmode = "full" # period = 0 # gaslimit = 11500000 +# [parallelevm] + # enable = true + # procs = 8 + # enforce = false + # [pprof] # pprof = false # port = 6060