mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
added 2 flags to enable parallel EVM and set the number of speculative processes (#727)
This commit is contained in:
parent
d25aa76447
commit
9795a287d0
12 changed files with 85 additions and 16 deletions
|
|
@ -136,3 +136,7 @@ syncmode = "full"
|
||||||
# [developer]
|
# [developer]
|
||||||
# dev = false
|
# dev = false
|
||||||
# period = 0
|
# period = 0
|
||||||
|
|
||||||
|
# [parallelevm]
|
||||||
|
# enable = false
|
||||||
|
# procs = 8
|
||||||
|
|
@ -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.
|
// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
|
||||||
// Disable transaction indexing/unindexing by default.
|
// 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)
|
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Can't create BlockChain: %v", err)
|
Fatalf("Can't create BlockChain: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,12 @@ type ExecVersionView struct {
|
||||||
sender common.Address
|
sender common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var NumSpeculativeProcs int = 8
|
||||||
|
|
||||||
|
func SetProcs(specProcs int) {
|
||||||
|
NumSpeculativeProcs = specProcs
|
||||||
|
}
|
||||||
|
|
||||||
func (ev *ExecVersionView) Execute() (er ExecResult) {
|
func (ev *ExecVersionView) Execute() (er ExecResult) {
|
||||||
er.ver = ev.ver
|
er.ver = ev.ver
|
||||||
if er.err = ev.et.Execute(ev.mvh, ev.ver.Incarnation); er.err != nil {
|
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
|
AllDeps map[int]map[int]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const numGoProcs = 2
|
const numGoProcs = 1
|
||||||
const numSpeculativeProcs = 8
|
|
||||||
|
|
||||||
type ParallelExecutor struct {
|
type ParallelExecutor struct {
|
||||||
tasks []ExecTask
|
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
|
// Launch workers that execute transactions
|
||||||
for i := 0; i < numSpeculativeProcs+numGoProcs; i++ {
|
for i := 0; i < NumSpeculativeProcs+numGoProcs; i++ {
|
||||||
go func(procNum int) {
|
go func(procNum int) {
|
||||||
defer pe.workerWg.Done()
|
defer pe.workerWg.Done()
|
||||||
|
|
||||||
|
|
@ -352,7 +357,7 @@ func (pe *ParallelExecutor) Prepare() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if procNum < numSpeculativeProcs {
|
if procNum < NumSpeculativeProcs {
|
||||||
for range pe.chSpeculativeTasks {
|
for range pe.chSpeculativeTasks {
|
||||||
doWork(pe.specTaskQueue.Pop().(ExecVersionView))
|
doWork(pe.specTaskQueue.Pop().(ExecVersionView))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,11 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ParallelEVMConfig struct {
|
||||||
|
Enable bool
|
||||||
|
SpeculativeProcesses int
|
||||||
|
}
|
||||||
|
|
||||||
// StateProcessor is a basic Processor, which takes care of transitioning
|
// StateProcessor is a basic Processor, which takes care of transitioning
|
||||||
// state from one point to another.
|
// 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.
|
// transactions failed to execute due to insufficient gas it will return an error.
|
||||||
// nolint:gocognit
|
// nolint:gocognit
|
||||||
func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
|
func (p *ParallelStateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (types.Receipts, []*types.Log, uint64, error) {
|
||||||
|
blockstm.SetProcs(cfg.ParallelSpeculativeProcesses)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
receipts types.Receipts
|
receipts types.Receipts
|
||||||
header = block.Header()
|
header = block.Header()
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ type Config struct {
|
||||||
JumpTable *JumpTable // EVM instruction table, automatically populated if unset
|
JumpTable *JumpTable // EVM instruction table, automatically populated if unset
|
||||||
|
|
||||||
ExtraEips []int // Additional EIPS that are to be enabled
|
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,
|
// ScopeContext contains the things that are per-call, such as stack and memory,
|
||||||
|
|
|
||||||
|
|
@ -143,4 +143,8 @@ addr = ":3131"
|
||||||
[developer]
|
[developer]
|
||||||
dev = false
|
dev = false
|
||||||
period = 0
|
period = 0
|
||||||
|
|
||||||
|
[blockstm]
|
||||||
|
enable = false
|
||||||
|
procs = 8
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ type Ethereum struct {
|
||||||
shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully
|
shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PSP
|
||||||
// New creates a new Ethereum object (including the
|
// New creates a new Ethereum object (including the
|
||||||
// initialisation of the common Ethereum object)
|
// initialisation of the common Ethereum object)
|
||||||
func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
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 (
|
var (
|
||||||
vmConfig = vm.Config{
|
vmConfig = vm.Config{
|
||||||
EnablePreimageRecording: config.EnablePreimageRecording,
|
EnablePreimageRecording: config.EnablePreimageRecording,
|
||||||
|
ParallelEnable: config.ParallelEVM.Enable,
|
||||||
|
ParallelSpeculativeProcesses: config.ParallelEVM.SpeculativeProcesses,
|
||||||
}
|
}
|
||||||
cacheConfig = &core.CacheConfig{
|
cacheConfig = &core.CacheConfig{
|
||||||
TrieCleanLimit: config.TrieCleanCache,
|
TrieCleanLimit: config.TrieCleanCache,
|
||||||
|
|
@ -224,7 +227,14 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
|
|
||||||
checker := whitelist.NewService(10)
|
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)
|
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit, checker)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,9 @@ type Config struct {
|
||||||
// Bor logs flag
|
// Bor logs flag
|
||||||
BorLogs bool
|
BorLogs bool
|
||||||
|
|
||||||
|
// Parallel EVM (Block-STM) related config
|
||||||
|
ParallelEVM core.ParallelEVMConfig `toml:",omitempty"`
|
||||||
|
|
||||||
// Arrow Glacier block override (TODO: remove after the fork)
|
// Arrow Glacier block override (TODO: remove after the fork)
|
||||||
OverrideArrowGlacier *big.Int `toml:",omitempty"`
|
OverrideArrowGlacier *big.Int `toml:",omitempty"`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,9 @@ type Config struct {
|
||||||
|
|
||||||
// Developer has the developer mode related settings
|
// Developer has the developer mode related settings
|
||||||
Developer *DeveloperConfig `hcl:"developer,block" toml:"developer,block"`
|
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 {
|
type P2PConfig struct {
|
||||||
|
|
@ -398,6 +401,12 @@ type DeveloperConfig struct {
|
||||||
Period uint64 `hcl:"period,optional" toml:"period,optional"`
|
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 {
|
func DefaultConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Chain: "mainnet",
|
Chain: "mainnet",
|
||||||
|
|
@ -531,6 +540,10 @@ func DefaultConfig() *Config {
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
Period: 0,
|
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.BorLogs = c.BorLogs
|
||||||
n.DatabaseHandles = dbHandles
|
n.DatabaseHandles = dbHandles
|
||||||
|
|
||||||
|
n.ParallelEVM.Enable = c.ParallelEVM.Enable
|
||||||
|
n.ParallelEVM.SpeculativeProcesses = c.ParallelEVM.SpeculativeProcesses
|
||||||
|
|
||||||
return &n, nil
|
return &n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -682,5 +682,19 @@ func (c *Command) Flags() *flagset.Flagset {
|
||||||
Value: &c.cliConfig.Developer.Period,
|
Value: &c.cliConfig.Developer.Period,
|
||||||
Default: 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
|
return f
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -756,7 +756,7 @@ func BenchmarkBorMiningBlockSTMMetadata(b *testing.B) {
|
||||||
db2 := rawdb.NewMemoryDatabase()
|
db2 := rawdb.NewMemoryDatabase()
|
||||||
back.Genesis.MustCommit(db2)
|
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()
|
defer chain.Stop()
|
||||||
|
|
||||||
// Ignore empty commit here for less noise.
|
// Ignore empty commit here for less noise.
|
||||||
|
|
|
||||||
|
|
@ -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
|
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
|
blockHeader, transactions and uncleHeaders fields. If they are missing, the block is
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue