Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: avoid producing empty block when pending transactions is high #195

Merged
merged 1 commit into from
Jan 16, 2023
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
1 change: 1 addition & 0 deletions cmd/ronin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ var (
utils.MinerExtraDataFlag,
utils.MinerRecommitIntervalFlag,
utils.MinerNoVerifyFlag,
utils.MinerBlockProduceLeftoverFlag,
utils.NATFlag,
utils.NoDiscoverFlag,
utils.DiscoveryV5Flag,
Expand Down
1 change: 1 addition & 0 deletions cmd/ronin/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.MinerExtraDataFlag,
utils.MinerRecommitIntervalFlag,
utils.MinerNoVerifyFlag,
utils.MinerBlockProduceLeftoverFlag,
},
},
{
Expand Down
8 changes: 8 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,11 @@ var (
Name: "miner.noverify",
Usage: "Disable remote sealing verification",
}
MinerBlockProduceLeftoverFlag = cli.DurationFlag{
Name: "miner.leftover",
Usage: "The interval block with transactions needs committing before empty block is produced",
Value: ethconfig.Defaults.Miner.BlockProduceLeftOver,
}
// Account settings
UnlockedAccountFlag = cli.StringFlag{
Name: "unlock",
Expand Down Expand Up @@ -1490,6 +1495,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) {
if ctx.GlobalIsSet(MinerNoVerifyFlag.Name) {
cfg.Noverify = ctx.GlobalBool(MinerNoVerifyFlag.Name)
}
if ctx.GlobalIsSet(MinerBlockProduceLeftoverFlag.Name) {
cfg.BlockProduceLeftOver = ctx.GlobalDuration(MinerBlockProduceLeftoverFlag.Name)
}
if ctx.GlobalIsSet(LegacyMinerGasTargetFlag.Name) {
log.Warn("The generic --miner.gastarget flag is deprecated and will be removed in the future!")
}
Expand Down
5 changes: 5 additions & 0 deletions eth/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ func (api *PrivateMinerAPI) SetRecommitInterval(interval int) {
api.e.Miner().SetRecommitInterval(time.Duration(interval) * time.Millisecond)
}

// SetBlockProducerLeftover updates the interval for block producer leftover in milliseconds
func (api *PrivateMinerAPI) SetBlockProducerLeftover(interval int) {
api.e.Miner().SetBlockProducerLeftover(time.Duration(interval) * time.Millisecond)
}

// PrivateAdminAPI is the collection of Ethereum full node-related APIs
// exposed over the private admin endpoint.
type PrivateAdminAPI struct {
Expand Down
12 changes: 7 additions & 5 deletions eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@
package ethconfig

import (
"github.com/ethereum/go-ethereum/consensus/consortium"
"github.com/ethereum/go-ethereum/internal/ethapi"
"math/big"
"os"
"os/user"
"path/filepath"
"runtime"
"time"

"github.com/ethereum/go-ethereum/consensus/consortium"
"github.com/ethereum/go-ethereum/internal/ethapi"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/clique"
Expand Down Expand Up @@ -85,9 +86,10 @@ var Defaults = Config{
TrieTimeout: 60 * time.Minute,
SnapshotCache: 102,
Miner: miner.Config{
GasCeil: 8000000,
GasPrice: big.NewInt(params.GWei),
Recommit: 3 * time.Second,
GasCeil: 8000000,
GasPrice: big.NewInt(params.GWei),
Recommit: 3 * time.Second,
BlockProduceLeftOver: 200 * time.Millisecond,
},
TxPool: core.DefaultTxPoolConfig,
RPCGasCap: 50000000,
Expand Down
25 changes: 15 additions & 10 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,17 @@ type Backend interface {

// Config is the configuration parameters of mining.
type Config struct {
Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards (default = first account)
Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages (only useful in ethash).
NotifyFull bool `toml:",omitempty"` // Notify with pending block headers instead of work packages
ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner
GasFloor uint64 // Target gas floor for mined blocks.
GasCeil uint64 // Target gas ceiling for mined blocks.
GasReserve uint64 // Reserved gas for system transactions
GasPrice *big.Int // Minimum gas price for mining a transaction
Recommit time.Duration // The time interval for miner to re-create mining work.
Noverify bool // Disable remote mining solution verification(only useful in ethash).
Etherbase common.Address `toml:",omitempty"` // Public address for block mining rewards (default = first account)
Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages (only useful in ethash).
NotifyFull bool `toml:",omitempty"` // Notify with pending block headers instead of work packages
ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner
GasFloor uint64 // Target gas floor for mined blocks.
GasCeil uint64 // Target gas ceiling for mined blocks.
GasReserve uint64 // Reserved gas for system transactions
GasPrice *big.Int // Minimum gas price for mining a transaction
Recommit time.Duration // The time interval for miner to re-create mining work.
Noverify bool // Disable remote mining solution verification(only useful in ethash).
BlockProduceLeftOver time.Duration
}

// Miner creates blocks and searches for proof-of-work values.
Expand Down Expand Up @@ -222,6 +223,10 @@ func (miner *Miner) SetGasReserve(reserve uint64) {
miner.worker.setGasReserve(reserve)
}

func (miner *Miner) SetBlockProducerLeftover(interval time.Duration) {
miner.worker.setBlockProducerLeftover(interval)
}

// EnablePreseal turns on the preseal mining feature. It's enabled by default.
// Note this function shouldn't be exposed to API, it's unnecessary for users
// (miners) to actually know the underlying detail. It's only for outside project
Expand Down
26 changes: 26 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ func (w *worker) setRecommitInterval(interval time.Duration) {
w.resubmitIntervalCh <- interval
}

func (w *worker) setBlockProducerLeftover(interval time.Duration) {
w.mu.Lock()
defer w.mu.Unlock()
w.config.BlockProduceLeftOver = interval
}

// disablePreseal disables pre-sealing mining feature
func (w *worker) disablePreseal() {
atomic.StoreUint32(&w.noempty, 1)
Expand Down Expand Up @@ -828,8 +834,28 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin
}

var coalescedLogs []*types.Log
var timer *time.Timer

// This timer is only shipped after Buba hardfork
// When it is nearly the time an empty block is produced,
// we break the commit transactions process, allow the
// block with transactions to be produced and abort the
// empty block producer.
if w.chainConfig.IsBuba(w.current.header.Number) {
duration := time.Until(time.Unix(int64(w.current.header.Time), 0)) - w.config.BlockProduceLeftOver
timer = time.NewTimer(duration)
}

Loop:
for {
if timer != nil {
select {
case <-timer.C:
break Loop
trantienduchn marked this conversation as resolved.
Show resolved Hide resolved
default:
}
}

// In the following three cases, we will interrupt the execution of the transaction.
// (1) new head block event arrival, the interrupt signal is 1
// (2) worker start or restart, the interrupt signal is 1
Expand Down