added 2 flags to enable parallel EVM and set the number of speculative processes (#727)

This commit is contained in:
Pratik Patil 2023-02-09 13:34:06 +05:30 committed by GitHub
parent d25aa76447
commit 9795a287d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 85 additions and 16 deletions

View file

@ -136,3 +136,7 @@ syncmode = "full"
# [developer]
# dev = false
# period = 0
# [parallelevm]
# enable = false
# procs = 8

View file

@ -2081,6 +2081,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
// Disable transaction indexing/unindexing by default.
// PSP - Check for config.ParallelEVM.Enable here?
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil, nil)
if err != nil {
Fatalf("Can't create BlockChain: %v", err)

View file

@ -36,6 +36,12 @@ type ExecVersionView struct {
sender common.Address
}
var NumSpeculativeProcs int = 8
func SetProcs(specProcs int) {
NumSpeculativeProcs = specProcs
}
func (ev *ExecVersionView) Execute() (er ExecResult) {
er.ver = ev.ver
if er.err = ev.et.Execute(ev.mvh, ev.ver.Incarnation); er.err != nil {
@ -157,8 +163,7 @@ type ParallelExecutionResult struct {
AllDeps map[int]map[int]bool
}
const numGoProcs = 2
const numSpeculativeProcs = 8
const numGoProcs = 1
type ParallelExecutor struct {
tasks []ExecTask
@ -315,10 +320,10 @@ func (pe *ParallelExecutor) Prepare() {
}
}
pe.workerWg.Add(numSpeculativeProcs + numGoProcs)
pe.workerWg.Add(NumSpeculativeProcs + numGoProcs)
// Launch workers that execute transactions
for i := 0; i < numSpeculativeProcs+numGoProcs; i++ {
for i := 0; i < NumSpeculativeProcs+numGoProcs; i++ {
go func(procNum int) {
defer pe.workerWg.Done()
@ -352,7 +357,7 @@ func (pe *ParallelExecutor) Prepare() {
}
}
if procNum < numSpeculativeProcs {
if procNum < NumSpeculativeProcs {
for range pe.chSpeculativeTasks {
doWork(pe.specTaskQueue.Pop().(ExecVersionView))
}

View file

@ -34,6 +34,11 @@ import (
"github.com/ethereum/go-ethereum/params"
)
type ParallelEVMConfig struct {
Enable bool
SpeculativeProcesses int
}
// StateProcessor is a basic Processor, which takes care of transitioning
// state from one point to another.
//
@ -269,6 +274,8 @@ var parallelizabilityTimer = metrics.NewRegisteredTimer("block/parallelizability
// transactions failed to execute due to insufficient gas it will return an error.
// nolint:gocognit
func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
blockstm.SetProcs(cfg.ParallelSpeculativeProcesses)
var (
receipts types.Receipts
header = block.Header()

View file

@ -34,6 +34,10 @@ type Config struct {
JumpTable *JumpTable // EVM instruction table, automatically populated if unset
ExtraEips []int // Additional EIPS that are to be enabled
// parallel EVM configs
ParallelEnable bool
ParallelSpeculativeProcesses int
}
// ScopeContext contains the things that are per-call, such as stack and memory,

View file

@ -143,4 +143,8 @@ addr = ":3131"
[developer]
dev = false
period = 0
[blockstm]
enable = false
procs = 8
```

View file

@ -108,6 +108,7 @@ type Ethereum struct {
shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully
}
// PSP
// New creates a new Ethereum object (including the
// initialisation of the common Ethereum object)
func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
@ -207,6 +208,8 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
var (
vmConfig = vm.Config{
EnablePreimageRecording: config.EnablePreimageRecording,
ParallelEnable: config.ParallelEVM.Enable,
ParallelSpeculativeProcesses: config.ParallelEVM.SpeculativeProcesses,
}
cacheConfig = &core.CacheConfig{
TrieCleanLimit: config.TrieCleanCache,
@ -224,7 +227,14 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
checker := whitelist.NewService(10)
// check if Parallel EVM is enabled
// if enabled, use parallel state processor
if config.ParallelEVM.Enable {
eth.blockchain, err = core.NewParallelBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker)
} else {
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker)
}
if err != nil {
return nil, err
}

View file

@ -224,6 +224,9 @@ type Config struct {
// Bor logs flag
BorLogs bool
// Parallel EVM (Block-STM) related config
ParallelEVM core.ParallelEVMConfig `toml:",omitempty"`
// Arrow Glacier block override (TODO: remove after the fork)
OverrideArrowGlacier *big.Int `toml:",omitempty"`

View file

@ -104,6 +104,9 @@ type Config struct {
// Developer has the developer mode related settings
Developer *DeveloperConfig `hcl:"developer,block" toml:"developer,block"`
// ParallelEVM has the parallel evm related settings
ParallelEVM *ParallelEVMConfig `hcl:"parallelevm,block" toml:"parallelevm,block"`
}
type P2PConfig struct {
@ -398,6 +401,12 @@ type DeveloperConfig struct {
Period uint64 `hcl:"period,optional" toml:"period,optional"`
}
type ParallelEVMConfig struct {
Enable bool `hcl:"enable,optional" toml:"enable,optional"`
SpeculativeProcesses int `hcl:"procs,optional" toml:"procs,optional"`
}
func DefaultConfig() *Config {
return &Config{
Chain: "mainnet",
@ -531,6 +540,10 @@ func DefaultConfig() *Config {
Enabled: false,
Period: 0,
},
ParallelEVM: &ParallelEVMConfig{
Enable: false,
SpeculativeProcesses: 8,
},
}
}
@ -893,6 +906,9 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
n.BorLogs = c.BorLogs
n.DatabaseHandles = dbHandles
n.ParallelEVM.Enable = c.ParallelEVM.Enable
n.ParallelEVM.SpeculativeProcesses = c.ParallelEVM.SpeculativeProcesses
return &n, nil
}

View file

@ -682,5 +682,19 @@ func (c *Command) Flags() *flagset.Flagset {
Value: &c.cliConfig.Developer.Period,
Default: c.cliConfig.Developer.Period,
})
// parallelevm
f.BoolFlag(&flagset.BoolFlag{
Name: "parallelevm.enable",
Usage: "Enable Block STM",
Value: &c.cliConfig.ParallelEVM.Enable,
Default: c.cliConfig.ParallelEVM.Enable,
})
f.IntFlag(&flagset.IntFlag{
Name: "parallelevm.procs",
Usage: "Number of speculative processes (cores) in Block STM",
Value: &c.cliConfig.ParallelEVM.SpeculativeProcesses,
Default: c.cliConfig.ParallelEVM.SpeculativeProcesses,
})
return f
}

View file

@ -756,7 +756,7 @@ func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
db2 := rawdb.NewMemoryDatabase()
back.Genesis.MustCommit(db2)
chain, _ := core.NewParallelBlockChain(db2, nil, back.chain.Config(), engine, vm.Config{}, nil, nil, nil)
chain, _ := core.NewParallelBlockChain(db2, nil, back.chain.Config(), engine, vm.Config{ParallelEnable: true, ParallelSpeculativeProcesses: 8}, nil, nil, nil)
defer chain.Stop()
// Ignore empty commit here for less noise.

View file

@ -176,7 +176,8 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
}
}
/* See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II
/*
See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II
Whether a block is valid or not is a bit subtle, it's defined by presence of
blockHeader, transactions and uncleHeaders fields. If they are missing, the block is