Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ var (
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,
}

Expand Down Expand Up @@ -1865,7 +1865,8 @@ func setMiner(ctx *cli.Context, cfg *minerconfig.Config) {
cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name)
}
if ctx.IsSet(MinerDelayLeftoverFlag.Name) {
cfg.DelayLeftOver = ctx.Duration(MinerDelayLeftoverFlag.Name)
minerDelayLeftover := ctx.Duration(MinerDelayLeftoverFlag.Name)
cfg.DelayLeftOver = &minerDelayLeftover
}
if ctx.Bool(VotingEnabledFlag.Name) {
cfg.VoteEnable = true
Expand Down
9 changes: 9 additions & 0 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,12 @@ func CreateConsensusEngine(config *params.ChainConfig, db ethdb.Database, ee *et
}
return beacon.New(ethash.NewFaker()), nil
}

func ApplyDefaultEthConfig(cfg *Config) {
if cfg == nil {
log.Warn("ApplyDefaultEthConfig cfg == nil")
return
}

minerconfig.ApplyDefaultMinerConfig(&cfg.Miner)
}
62 changes: 30 additions & 32 deletions miner/bid_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,38 +119,36 @@ type bidSimulator struct {

func newBidSimulator(
config *minerconfig.MevConfig,
delayLeftOver time.Duration,
delayLeftOver *time.Duration,
minGasPrice *big.Int,
eth Backend,
chainConfig *params.ChainConfig,
engine consensus.Engine,
bidWorker bidWorker,
) *bidSimulator {
// Set default value
maxBids := uint32(3)
if config.MaxBidsPerBuilder > 0 {
maxBids = config.MaxBidsPerBuilder
}

b := &bidSimulator{
config: config,
delayLeftOver: delayLeftOver,
minGasPrice: minGasPrice,
chain: eth.BlockChain(),
txpool: eth.TxPool(),
chainConfig: chainConfig,
engine: engine,
bidWorker: bidWorker,
maxBidsPerBuilder: maxBids,
exitCh: make(chan struct{}),
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
builders: make(map[common.Address]*builderclient.Client),
simBidCh: make(chan *simBidReq),
newBidCh: make(chan newBidPackage, 100),
pending: make(map[uint64]map[common.Address]map[common.Hash]struct{}),
bestBid: make(map[common.Hash]*BidRuntime),
bestBidToRun: make(map[common.Hash]*types.Bid),
simulatingBid: make(map[common.Hash]*BidRuntime),
config: config,
minGasPrice: minGasPrice,
chain: eth.BlockChain(),
txpool: eth.TxPool(),
chainConfig: chainConfig,
engine: engine,
bidWorker: bidWorker,
exitCh: make(chan struct{}),
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
builders: make(map[common.Address]*builderclient.Client),
simBidCh: make(chan *simBidReq),
newBidCh: make(chan newBidPackage, 100),
pending: make(map[uint64]map[common.Address]map[common.Hash]struct{}),
bestBid: make(map[common.Hash]*BidRuntime),
bestBidToRun: make(map[common.Hash]*types.Bid),
simulatingBid: make(map[common.Hash]*BidRuntime),
}
if delayLeftOver != nil {
b.delayLeftOver = *delayLeftOver
}
if config.MaxBidsPerBuilder != nil {
b.maxBidsPerBuilder = *config.MaxBidsPerBuilder
}

b.chainHeadSub = b.chain.SubscribeChainHeadEvent(b.chainHeadCh)
Expand Down Expand Up @@ -360,7 +358,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() {
Expand Down Expand Up @@ -396,7 +394,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
Expand All @@ -408,7 +406,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",
Expand Down Expand Up @@ -494,7 +492,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() {
Expand Down Expand Up @@ -739,7 +737,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
Expand Down Expand Up @@ -786,7 +784,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)
Expand All @@ -802,7 +800,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)
}
}

Expand Down
6 changes: 3 additions & 3 deletions miner/miner_mev.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
69 changes: 57 additions & 12 deletions miner/minerconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,25 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
)

var (
defaultDelayLeftOver = 50 * time.Millisecond
// default confogurations for MEV
defaultGreedyMergeTx bool = true
defaultValidatorCommission uint64 = 100
defaultBidSimulationLeftOver = 50 * time.Millisecond
defaultNoInterruptLeftOver = 400 * time.Millisecond
defaultMaxBidsPerBuilder uint32 = 3
)

// 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...)
DelayLeftOver *time.Duration `toml:",omitempty"` // Time reserved to finalize a block(calculate root, distribute income...)
GasFloor uint64 // Target gas floor for mined blocks.
GasCeil uint64 // Target gas ceiling for mined blocks.
GasPrice *big.Int // Minimum gas price for mining a transaction
Expand All @@ -53,7 +64,7 @@ var DefaultConfig = Config{
// for payload generation. It should be enough for Geth to
// run 3 rounds.
Recommit: 3 * time.Second,
DelayLeftOver: 50 * time.Millisecond,
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.
Expand All @@ -69,23 +80,57 @@ 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 `toml:",omitempty"` // 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 `toml:",omitempty"` // 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,
MaxBidsPerBuilder: 3,
ValidatorCommission: &defaultValidatorCommission,
BidSimulationLeftOver: &defaultBidSimulationLeftOver,
NoInterruptLeftOver: &defaultNoInterruptLeftOver,
MaxBidsPerBuilder: &defaultMaxBidsPerBuilder,
}

func ApplyDefaultMinerConfig(cfg *Config) {
if cfg == nil {
log.Warn("ApplyDefaultMinerConfig cfg == nil")
return
}
// check [Eth.Miner]
if cfg.DelayLeftOver == nil {
cfg.DelayLeftOver = &defaultDelayLeftOver
log.Info("ApplyDefaultMinerConfig", "DelayLeftOver", *cfg.DelayLeftOver)
}

// check [Eth.Miner.Mev]
if cfg.Mev.GreedyMergeTx == nil {
cfg.Mev.GreedyMergeTx = &defaultGreedyMergeTx
log.Info("ApplyDefaultMinerConfig", "Mev.GreedyMergeTx", *cfg.Mev.GreedyMergeTx)
}
if cfg.Mev.ValidatorCommission == nil {
cfg.Mev.ValidatorCommission = &defaultValidatorCommission
log.Info("ApplyDefaultMinerConfig", "Mev.ValidatorCommission", *cfg.Mev.ValidatorCommission)
}
if cfg.Mev.BidSimulationLeftOver == nil {
cfg.Mev.BidSimulationLeftOver = &defaultBidSimulationLeftOver
log.Info("ApplyDefaultMinerConfig", "Mev.BidSimulationLeftOver", *cfg.Mev.BidSimulationLeftOver)
}
if cfg.Mev.NoInterruptLeftOver == nil {
cfg.Mev.NoInterruptLeftOver = &defaultNoInterruptLeftOver
log.Info("ApplyDefaultMinerConfig", "Mev.NoInterruptLeftOver", *cfg.Mev.NoInterruptLeftOver)
}
if cfg.Mev.MaxBidsPerBuilder == nil {
cfg.Mev.MaxBidsPerBuilder = &defaultMaxBidsPerBuilder
log.Info("ApplyDefaultMinerConfig", "Mev.MaxBidsPerBuilder", *cfg.Mev.MaxBidsPerBuilder)
}
}
10 changes: 5 additions & 5 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -1292,7 +1292,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
Expand Down Expand Up @@ -1345,7 +1345,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 {
Expand All @@ -1356,7 +1356,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))
Expand Down Expand Up @@ -1411,7 +1411,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
Expand Down Expand Up @@ -1441,7 +1441,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(),
Expand Down