diff --git a/cmd/devp2p/internal/ethtest/suite_test.go b/cmd/devp2p/internal/ethtest/suite_test.go index a1b1f89e6c..34bfb83da2 100644 --- a/cmd/devp2p/internal/ethtest/suite_test.go +++ b/cmd/devp2p/internal/ethtest/suite_test.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/eth/catalyst" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/utesting" + "github.com/ethereum/go-ethereum/miner/minerconfig" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/p2p" ) @@ -143,6 +144,7 @@ func setupGeth(stack *node.Node, dir string) error { TrieTimeout: 60 * time.Minute, SnapshotCache: 10, TriesInMemory: 128, + Miner: &minerconfig.Config{}, }) if err != nil { return err diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 26e28d43db..c11a15a91f 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -155,6 +155,9 @@ func loadBaseConfig(ctx *cli.Context) gethConfig { if err := loadConfig(file, &cfg); err != nil { utils.Fatalf("%v", err) } + // some default options could be overwritten after `loadConfig()` + // apply the default value if the options are not specified in config.toml file. + ethconfig.ApplyDefaultEthConfig(&cfg.Eth) } scheme := cfg.Eth.StateScheme @@ -276,7 +279,7 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { git, _ := version.VCS() utils.SetupMetrics(&cfg.Metrics, utils.EnableBuildInfo(git.Commit, git.Date), - utils.EnableMinerInfo(ctx, &cfg.Eth.Miner), + utils.EnableMinerInfo(ctx, cfg.Eth.Miner), utils.EnableNodeInfo(&cfg.Eth.TxPool, stack.Server().NodeInfo()), utils.EnableNodeTrack(ctx, &cfg.Eth, stack), ) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ec38bd8516..9c3eff02d1 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -641,13 +641,13 @@ var ( MinerRecommitIntervalFlag = &cli.DurationFlag{ Name: "miner.recommit", Usage: "Time interval to recreate the block being mined", - Value: ethconfig.Defaults.Miner.Recommit, + Value: *ethconfig.Defaults.Miner.Recommit, Category: flags.MinerCategory, } MinerDelayLeftoverFlag = &cli.DurationFlag{ Name: "miner.delayleftover", Usage: "Time reserved to finalize a block", - Value: ethconfig.Defaults.Miner.DelayLeftOver, + Value: *ethconfig.Defaults.Miner.DelayLeftOver, Category: flags.MinerCategory, } @@ -1862,17 +1862,20 @@ func setMiner(ctx *cli.Context, cfg *minerconfig.Config) { cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name) } if ctx.IsSet(MinerRecommitIntervalFlag.Name) { - cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name) + recommit := ctx.Duration(MinerRecommitIntervalFlag.Name) + cfg.Recommit = &recommit } if ctx.IsSet(MinerDelayLeftoverFlag.Name) { - cfg.DelayLeftOver = ctx.Duration(MinerDelayLeftoverFlag.Name) + delayLeftOver := ctx.Duration(MinerDelayLeftoverFlag.Name) + cfg.DelayLeftOver = &delayLeftOver } if ctx.Bool(VotingEnabledFlag.Name) { cfg.VoteEnable = true } if ctx.IsSet(MinerNewPayloadTimeoutFlag.Name) { log.Warn("The flag --miner.newpayload-timeout is deprecated and will be removed, please use --miner.recommit") - cfg.Recommit = ctx.Duration(MinerNewPayloadTimeoutFlag.Name) + recommit := ctx.Duration(MinerNewPayloadTimeoutFlag.Name) + cfg.Recommit = &recommit } if ctx.Bool(DisableVoteAttestationFlag.Name) { cfg.DisableVoteAttestation = true @@ -1959,7 +1962,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.TxPool) setBlobPool(ctx, &cfg.BlobPool) - setMiner(ctx, &cfg.Miner) + setMiner(ctx, cfg.Miner) setRequiredBlocks(ctx, cfg) setLes(ctx, cfg) diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go index f1a91515b7..4e46b058c8 100644 --- a/cmd/utils/flags_legacy.go +++ b/cmd/utils/flags_legacy.go @@ -133,7 +133,7 @@ var ( MinerNewPayloadTimeoutFlag = &cli.DurationFlag{ Name: "miner.newpayload-timeout", Usage: "Specify the maximum time allowance for creating a new payload (deprecated)", - Value: ethconfig.Defaults.Miner.Recommit, + Value: *ethconfig.Defaults.Miner.Recommit, Category: flags.DeprecatedCategory, } MetricsEnabledExpensiveFlag = &cli.BoolFlag{ diff --git a/console/console_test.go b/console/console_test.go index 1442440991..1faeda9864 100644 --- a/console/console_test.go +++ b/console/console_test.go @@ -95,7 +95,7 @@ func newTester(t *testing.T, confOverride func(*ethconfig.Config)) *tester { } ethConf := ðconfig.Config{ Genesis: core.DeveloperGenesisBlock(11_500_000, nil), - Miner: minerconfig.Config{ + Miner: &minerconfig.Config{ Etherbase: common.HexToAddress(testAddress), }, } diff --git a/eth/backend.go b/eth/backend.go index 9c84faeee9..1dfd288288 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -388,7 +388,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return nil, err } - eth.miner = miner.New(eth, &config.Miner, eth.EventMux(), eth.engine) + eth.miner = miner.New(eth, config.Miner, eth.EventMux(), eth.engine) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) eth.miner.SetPrioAddresses(config.TxPool.Locals) diff --git a/eth/catalyst/simulated_beacon_test.go b/eth/catalyst/simulated_beacon_test.go index 2975fc3bbb..87c6c97663 100644 --- a/eth/catalyst/simulated_beacon_test.go +++ b/eth/catalyst/simulated_beacon_test.go @@ -49,7 +49,7 @@ func startSimulatedBeaconEthService(t *testing.T, genesis *core.Genesis, period t.Fatal("can't create node:", err) } - ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: ethconfig.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: minerconfig.DefaultConfig} + ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: ethconfig.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: &minerconfig.DefaultConfig} ethservice, err := eth.New(n, ethcfg) if err != nil { t.Fatal("can't create eth service:", err) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 40d118748e..314eb0e41e 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -63,7 +63,7 @@ var Defaults = Config{ SnapshotCache: 102, DiffBlock: uint64(86400), FilterLogCacheSize: 32, - Miner: minerconfig.DefaultConfig, + Miner: &minerconfig.DefaultConfig, TxPool: legacypool.DefaultConfig, BlobPool: blobpool.DefaultConfig, RPCGasCap: 50000000, @@ -156,7 +156,7 @@ type Config struct { FilterLogCacheSize int // Mining options - Miner minerconfig.Config + Miner *minerconfig.Config // Transaction pool options TxPool legacypool.Config @@ -215,3 +215,13 @@ func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database, ee *et } return beacon.New(ethash.NewFaker()), nil } + +func ApplyDefaultEthConfig(cfg *Config) { + if cfg == nil { + // [Eth] is a mandatory option in config.toml, it should never be nil + log.Error("ApplyDefaultEthConfig cfg should not be nil") + return + } + + cfg.Miner = cfg.Miner.ApplyDefaultMinerConfig() +} diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index b834241706..69d48a7524 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -53,7 +53,7 @@ func (c Config) MarshalTOML() (interface{}, error) { TriesVerifyMode core.VerifyMode Preimages bool FilterLogCacheSize int - Miner minerconfig.Config + Miner *minerconfig.Config TxPool legacypool.Config BlobPool blobpool.Config GPO gasprice.Config @@ -297,7 +297,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { c.FilterLogCacheSize = *dec.FilterLogCacheSize } if dec.Miner != nil { - c.Miner = *dec.Miner + c.Miner = dec.Miner } if dec.TxPool != nil { c.TxPool = *dec.TxPool diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 2f39199337..4f2907a47c 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -37,6 +37,7 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/miner/minerconfig" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" @@ -195,7 +196,7 @@ func newTestBackend(config *node.Config) (*node.Node, []*types.Block, error) { return nil, nil, fmt.Errorf("can't create new node: %v", err) } // Create Ethereum Service - ecfg := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000} + ecfg := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000, Miner: &minerconfig.Config{}} ecfg.SnapshotCache = 256 ecfg.TriesInMemory = 128 ethservice, err := eth.New(n, ecfg) diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go index e75607bce1..0178970f77 100644 --- a/ethclient/gethclient/gethclient_test.go +++ b/ethclient/gethclient/gethclient_test.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/miner/minerconfig" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" @@ -58,7 +59,7 @@ func newTestBackend(t *testing.T) (*node.Node, []*types.Block) { t.Fatalf("can't create new node: %v", err) } // Create Ethereum Service - config := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000} + config := ðconfig.Config{Genesis: genesis, RPCGasCap: 1000000, Miner: &minerconfig.Config{}} ethservice, err := eth.New(n, config) if err != nil { t.Fatalf("can't create new ethereum service: %v", err) diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index bfe78b6c11..294150c9e2 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -39,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/filters" + "github.com/ethereum/go-ethereum/miner/minerconfig" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" @@ -455,6 +456,7 @@ func newGQLService(t *testing.T, stack *node.Node, shanghai bool, gspec *core.Ge SnapshotCache: 5, RPCGasCap: 1000000, StateScheme: rawdb.HashScheme, + Miner: &minerconfig.Config{}, } var engine consensus.Engine = ethash.NewFaker() if shanghai { diff --git a/miner/bid_simulator.go b/miner/bid_simulator.go index 8068fd6261..8240545855 100644 --- a/miner/bid_simulator.go +++ b/miner/bid_simulator.go @@ -360,7 +360,7 @@ func (b *bidSimulator) canBeInterrupted(targetTime uint64) bool { return true } left := time.Until(time.UnixMilli(int64(targetTime))) - return left >= b.config.NoInterruptLeftOver + return left >= *b.config.NoInterruptLeftOver } func (b *bidSimulator) newBidLoop() { @@ -396,7 +396,7 @@ func (b *bidSimulator) newBidLoop() { continue } - bidRuntime, err := newBidRuntime(newBid.bid, b.config.ValidatorCommission) + bidRuntime, err := newBidRuntime(newBid.bid, *b.config.ValidatorCommission) if err != nil { if newBid.feedback != nil { newBid.feedback <- err @@ -408,7 +408,7 @@ func (b *bidSimulator) newBidLoop() { toCommit := true bestBidToRun := b.GetBestBidToRun(newBid.bid.ParentHash) if bestBidToRun != nil { - bestBidRuntime, _ := newBidRuntime(bestBidToRun, b.config.ValidatorCommission) + bestBidRuntime, _ := newBidRuntime(bestBidToRun, *b.config.ValidatorCommission) if bidRuntime.isExpectedBetterThan(bestBidRuntime) { // new bid has better expectedBlockReward, use bidRuntime log.Debug("new bid has better expectedBlockReward", @@ -494,7 +494,7 @@ func (b *bidSimulator) getBlockInterval(parentHeader *types.Header) uint64 { func (b *bidSimulator) bidBetterBefore(parentHash common.Hash) time.Time { parentHeader := b.chain.GetHeaderByHash(parentHash) - return bidutil.BidBetterBefore(parentHeader, b.getBlockInterval(parentHeader), b.delayLeftOver, b.config.BidSimulationLeftOver) + return bidutil.BidBetterBefore(parentHeader, b.getBlockInterval(parentHeader), b.delayLeftOver, *b.config.BidSimulationLeftOver) } func (b *bidSimulator) clearLoop() { @@ -739,7 +739,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { // check if bid reward is valid { - bidRuntime.packReward(b.config.ValidatorCommission) + bidRuntime.packReward(*b.config.ValidatorCommission) if !bidRuntime.validReward() { err = errors.New("reward does not achieve the expectation") return @@ -786,7 +786,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { } // if enable greedy merge, fill bid env with transactions from mempool - if b.config.GreedyMergeTx { + if *b.config.GreedyMergeTx { endingBidsExtra := 20 * time.Millisecond // Add a buffer to ensure ending bids before `delayLeftOver` minTimeLeftForEndingBids := b.delayLeftOver + endingBidsExtra delay := b.engine.Delay(b.chain, bidRuntime.env.header, &minTimeLeftForEndingBids) @@ -802,7 +802,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { "builder", bidRuntime.bid.Builder, "tx count", bidRuntime.env.tcount-bidTxLen+1, "err", fillErr) // recalculate the packed reward - bidRuntime.packReward(b.config.ValidatorCommission) + bidRuntime.packReward(*b.config.ValidatorCommission) } } @@ -838,6 +838,7 @@ func (b *bidSimulator) simBid(interruptCh chan int32, bidRuntime *BidRuntime) { } if bidRuntime.bid.Hash() != bestBid.bid.Hash() { + // will stop recommit..., the bestBidToRun will be cleaned. log.Info("[BID RESULT]", "win", bidRuntime.packedBlockReward.Cmp(bestBid.packedBlockReward) >= 0, diff --git a/miner/miner.go b/miner/miner.go index cd2f75d214..7ad4d6165e 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -69,8 +69,24 @@ func New(eth Backend, config *minerconfig.Config, mux *event.TypeMux, engine con stopCh: make(chan struct{}), worker: newWorker(config, engine, eth, mux, false), } + mev := config.Mev + if mev == nil { + // for unit test, it could be nil, as it is not initialized + mev = &minerconfig.MevConfig{} + } + + delayLeftOver := config.DelayLeftOver + if delayLeftOver == nil { + // for unit test, it could be nil, as it is not initialized + delayLeftOver = new(time.Duration) + } + gasPrice := config.GasPrice + if gasPrice == nil { + // for unit test, it could be nil, as it is not initialized + gasPrice = new(big.Int) + } - miner.bidSimulator = newBidSimulator(&config.Mev, config.DelayLeftOver, config.GasPrice, eth, eth.BlockChain().Config(), engine, miner.worker) + miner.bidSimulator = newBidSimulator(mev, *delayLeftOver, gasPrice, eth, eth.BlockChain().Config(), engine, miner.worker) miner.worker.setBestBidFetcher(miner.bidSimulator) miner.wg.Add(1) diff --git a/miner/miner_mev.go b/miner/miner_mev.go index 9e5619a9ce..17b8cc98c0 100644 --- a/miner/miner_mev.go +++ b/miner/miner_mev.go @@ -97,9 +97,9 @@ func (miner *Miner) MevParams() *types.MevParams { } return &types.MevParams{ - ValidatorCommission: miner.worker.config.Mev.ValidatorCommission, - BidSimulationLeftOver: miner.worker.config.Mev.BidSimulationLeftOver, - NoInterruptLeftOver: miner.worker.config.Mev.NoInterruptLeftOver, + ValidatorCommission: *miner.worker.config.Mev.ValidatorCommission, + BidSimulationLeftOver: *miner.worker.config.Mev.BidSimulationLeftOver, + NoInterruptLeftOver: *miner.worker.config.Mev.NoInterruptLeftOver, GasCeil: miner.worker.config.GasCeil, GasPrice: miner.worker.config.GasPrice, BuilderFeeCeil: builderFeeCeil, diff --git a/miner/miner_test.go b/miner/miner_test.go index 023a35ac74..f0f06e3f52 100644 --- a/miner/miner_test.go +++ b/miner/miner_test.go @@ -299,6 +299,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux, func(skipMiner bool)) { // Create Ethash config config := minerconfig.Config{ Etherbase: common.HexToAddress("123456789"), + Recommit: new(time.Duration), } // Create chainConfig chainDB := rawdb.NewMemoryDatabase() diff --git a/miner/minerconfig/config.go b/miner/minerconfig/config.go index 00dc7b6b88..56cfa20cde 100644 --- a/miner/minerconfig/config.go +++ b/miner/minerconfig/config.go @@ -26,21 +26,32 @@ import ( "github.com/ethereum/go-ethereum/params" ) +var ( + defaultRecommit = 3 * time.Second + defaultDelayLeftOver = 50 * time.Millisecond + defaultMaxWaitProposalInSecs uint64 = 30 + // default confogurations for MEV + defaultGreedyMergeTx bool = true + defaultValidatorCommission uint64 = 100 + defaultBidSimulationLeftOver = 50 * time.Millisecond + defaultNoInterruptLeftOver = 400 * time.Millisecond +) + // Config is the configuration parameters of mining. type Config struct { Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner - DelayLeftOver time.Duration // Time reserved to finalize a block(calculate root, distribute income...) - GasFloor uint64 // Target gas floor for mined blocks. + DelayLeftOver *time.Duration `toml:",omitempty"` // Time reserved to finalize a block(calculate root, distribute income...) + GasFloor uint64 // Target gas floor for mined blocks. (deprecated) GasCeil uint64 // Target gas ceiling for mined blocks. - GasPrice *big.Int // Minimum gas price for mining a transaction - Recommit time.Duration // The time interval for miner to re-create mining work. + GasPrice *big.Int `toml:",omitempty"` // Minimum gas price for mining a transaction + Recommit *time.Duration `toml:",omitempty"` // The time interval for miner to re-create mining work. VoteEnable bool // Whether to vote when mining - MaxWaitProposalInSecs uint64 // The maximum time to wait for the proposal to be done, it's aimed to prevent validator being slashed when restarting + MaxWaitProposalInSecs *uint64 `toml:",omitempty"` // The maximum time to wait for the proposal to be done, it's aimed to prevent validator being slashed when restarting DisableVoteAttestation bool // Whether to skip assembling vote attestation - Mev MevConfig // Mev configuration + Mev *MevConfig `toml:",omitempty"` // Mev configuration } // DefaultConfig contains default settings for miner. @@ -52,14 +63,14 @@ var DefaultConfig = Config{ // consensus-layer usually will wait a half slot of time(6s) // for payload generation. It should be enough for Geth to // run 3 rounds. - Recommit: 3 * time.Second, - DelayLeftOver: 50 * time.Millisecond, + Recommit: &defaultRecommit, + DelayLeftOver: &defaultDelayLeftOver, // The default value is set to 30 seconds. // Because the avg restart time in mainnet is around 30s, so the node try to wait for the next multi-proposals to be done. - MaxWaitProposalInSecs: 30, + MaxWaitProposalInSecs: &defaultMaxWaitProposalInSecs, - Mev: DefaultMevConfig, + Mev: &DefaultMevConfig, } type BuilderConfig struct { @@ -69,23 +80,61 @@ type BuilderConfig struct { type MevConfig struct { Enabled bool // Whether to enable Mev or not - GreedyMergeTx bool // Whether to merge local transactions to the bid + GreedyMergeTx *bool // Whether to merge local transactions to the bid BuilderFeeCeil string // The maximum builder fee of a bid SentryURL string // The url of Mev sentry Builders []BuilderConfig // The list of builders - ValidatorCommission uint64 // 100 means the validator claims 1% from block reward - BidSimulationLeftOver time.Duration - NoInterruptLeftOver time.Duration - MaxBidsPerBuilder uint32 // Maximum number of bids allowed per builder per block + ValidatorCommission *uint64 `toml:",omitempty"` // 100 means the validator claims 1% from block reward + BidSimulationLeftOver *time.Duration `toml:",omitempty"` + NoInterruptLeftOver *time.Duration `toml:",omitempty"` + MaxBidsPerBuilder uint32 // Maximum number of bids allowed per builder per block } var DefaultMevConfig = MevConfig{ Enabled: false, - GreedyMergeTx: true, + GreedyMergeTx: &defaultGreedyMergeTx, SentryURL: "", Builders: nil, - ValidatorCommission: 100, - BidSimulationLeftOver: 50 * time.Millisecond, - NoInterruptLeftOver: 400 * time.Millisecond, + ValidatorCommission: &defaultValidatorCommission, + BidSimulationLeftOver: &defaultBidSimulationLeftOver, + NoInterruptLeftOver: &defaultNoInterruptLeftOver, MaxBidsPerBuilder: 3, } + +func (cfg *Config) ApplyDefaultMinerConfig() *Config { + if cfg == nil { + // [Eth.Miner] is not specified in config.toml + return &DefaultConfig + } + // `[Eth.Miner]` is specified in config file, check the default Miner option + if cfg.Recommit == nil { + cfg.Recommit = &defaultRecommit + } + if cfg.DelayLeftOver == nil { + cfg.DelayLeftOver = &defaultDelayLeftOver + } + if cfg.MaxWaitProposalInSecs == nil { + cfg.MaxWaitProposalInSecs = &defaultMaxWaitProposalInSecs + } + + // check Miner's MEV options + if cfg.Mev == nil { + // [Eth.Miner.Mev] is not specified in config.toml + cfg.Mev = &DefaultMevConfig + return cfg + } + // `[Eth.Miner.Mev]` is specified in config file, check the default value + if cfg.Mev.GreedyMergeTx == nil { + cfg.Mev.GreedyMergeTx = &defaultGreedyMergeTx + } + if cfg.Mev.ValidatorCommission == nil { + cfg.Mev.ValidatorCommission = &defaultValidatorCommission + } + if cfg.Mev.BidSimulationLeftOver == nil { + cfg.Mev.BidSimulationLeftOver = &defaultBidSimulationLeftOver + } + if cfg.Mev.NoInterruptLeftOver == nil { + cfg.Mev.NoInterruptLeftOver = &defaultNoInterruptLeftOver + } + return cfg +} diff --git a/miner/worker.go b/miner/worker.go index 89dedca337..86f47b55a3 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -291,15 +291,18 @@ func newWorker(config *minerconfig.Config, engine consensus.Engine, eth Backend, // Sanitize recommit interval if the user-specified one is too short. recommit := worker.config.Recommit - if recommit < minRecommitInterval { + if recommit == nil { + recommit = new(time.Duration) + } + if *recommit < minRecommitInterval { log.Warn("Sanitizing miner recommit interval", "provided", recommit, "updated", minRecommitInterval) - recommit = minRecommitInterval + *recommit = minRecommitInterval } - worker.recommit = recommit + worker.recommit = *recommit worker.wg.Add(4) go worker.mainLoop() - go worker.newWorkLoop(recommit) + go worker.newWorkLoop(*recommit) go worker.resultLoop() go worker.taskLoop() @@ -1187,7 +1190,7 @@ func (w *worker) generateWork(params *generateParams, witness bool) *newPayloadR if !params.noTxs { interrupt := new(atomic.Int32) - timer := time.AfterFunc(w.config.Recommit, func() { + timer := time.AfterFunc(*w.config.Recommit, func() { interrupt.Store(commitInterruptTimeout) }) defer timer.Stop() @@ -1292,7 +1295,7 @@ LOOP: prevWork = work workList = append(workList, work) - delay := w.engine.Delay(w.chain, work.header, &w.config.DelayLeftOver) + delay := w.engine.Delay(w.chain, work.header, w.config.DelayLeftOver) if delay == nil { log.Warn("commitWork delay is nil, something is wrong") stopTimer = nil @@ -1345,7 +1348,7 @@ LOOP: newTxsNum := 0 // stopTimer was the maximum delay for each fillTransactions // but now it is used to wait until (head.Time - DelayLeftOver) is reached. - stopTimer.Reset(time.Until(time.UnixMilli(int64(work.header.MilliTimestamp()))) - w.config.DelayLeftOver) + stopTimer.Reset(time.Until(time.UnixMilli(int64(work.header.MilliTimestamp()))) - *w.config.DelayLeftOver) LOOP_WAIT: for { select { @@ -1356,7 +1359,7 @@ LOOP: log.Debug("commitWork interruptCh closed, new block imported or resubmit triggered") return case ev := <-txsCh: - delay := w.engine.Delay(w.chain, work.header, &w.config.DelayLeftOver) + delay := w.engine.Delay(w.chain, work.header, w.config.DelayLeftOver) log.Debug("commitWork txsCh arrived", "fillDuration", fillDuration.String(), "delay", delay.String(), "work.tcount", work.tcount, "newTxsNum", newTxsNum, "len(ev.Txs)", len(ev.Txs)) @@ -1411,7 +1414,7 @@ LOOP: inturnBlocksGauge.Inc(1) // We want to start sealing the block as late as possible here if mev is enabled, so we could give builder the chance to send their final bid. // Time left till sealing the block. - tillSealingTime := time.Until(time.UnixMilli(int64(bestWork.header.MilliTimestamp()))) - w.config.DelayLeftOver + tillSealingTime := time.Until(time.UnixMilli(int64(bestWork.header.MilliTimestamp()))) - *w.config.DelayLeftOver if tillSealingTime > 0 { // Still some time left, wait for the best bid. // This happens during the peak time of the network, the local block building LOOP would break earlier than @@ -1441,7 +1444,7 @@ LOOP: if bestBid != nil && bestReward.CmpBig(bestBid.packedBlockReward) < 0 { // localValidatorReward is the reward for the validator self by the local block. - localValidatorReward := new(uint256.Int).Mul(bestReward, uint256.NewInt(w.config.Mev.ValidatorCommission)) + localValidatorReward := new(uint256.Int).Mul(bestReward, uint256.NewInt(*w.config.Mev.ValidatorCommission)) localValidatorReward.Div(localValidatorReward, uint256.NewInt(10000)) log.Debug("BidSimulator: final compare", "block", bestWork.header.Number.Uint64(), @@ -1575,7 +1578,7 @@ func (w *worker) tryWaitProposalDoneWhenStopping() { if err != nil { log.Debug("failed to get BlockInterval when tryWaitProposalDoneWhenStopping") } - if startBlock > currentBlock && ((startBlock-currentBlock)*blockInterval/1000) > w.config.MaxWaitProposalInSecs { + if startBlock > currentBlock && ((startBlock-currentBlock)*blockInterval/1000) > *w.config.MaxWaitProposalInSecs { log.Warn("the next proposal start block is too far, just skip waiting") return } diff --git a/miner/worker_test.go b/miner/worker_test.go index 47d63105d6..52ec329283 100644 --- a/miner/worker_test.go +++ b/miner/worker_test.go @@ -64,11 +64,11 @@ var ( testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey) // Test transactions - pendingTxs []*types.Transaction - newTxs []*types.Transaction - - testConfig = &minerconfig.Config{ - Recommit: time.Second, + pendingTxs []*types.Transaction + newTxs []*types.Transaction + reCommitTime time.Duration = time.Second + testConfig = &minerconfig.Config{ + Recommit: &reCommitTime, GasCeil: params.GenesisGasLimit, } )