Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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 docs/cli/default_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ devfakeauthor = false
base-fee-change-denominator = 0
prefetch = false
prefetch-gaslimit-percent = 100
disable-pending-block = false

[jsonrpc]
ipcdisable = false
Expand Down
15 changes: 8 additions & 7 deletions docs/cli/example_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,14 @@ bp-rpc-endpoints = [ ] # Comma separated rpc endpoints of all block producers
lifetime = "3h0m0s" # Maximum amount of time non-executable transaction are queued

[miner]
mine = false # Enable mining
etherbase = "" # Public address for block mining rewards
extradata = "" # Block extra data set by the miner (default = client version)
gaslimit = 50000000 # Target gas ceiling for mined blocks (used when dynamic gas limit is disabled)
gasprice = "25000000000" # Minimum gas price for mining a transaction. Regardless the value set, it will be enforced to 25000000000 for all networks
recommit = "2m5s" # The time interval for miner to re-create mining work
commitinterrupt = true # Interrupt the current mining work when time is exceeded and create partial blocks
mine = false # Enable mining
etherbase = "" # Public address for block mining rewards
extradata = "" # Block extra data set by the miner (default = client version)
gaslimit = 50000000 # Target gas ceiling for mined blocks (used when dynamic gas limit is disabled)
gasprice = "25000000000" # Minimum gas price for mining a transaction. Regardless the value set, it will be enforced to 25000000000 for all networks
recommit = "2m5s" # The time interval for miner to re-create mining work
commitinterrupt = true # Interrupt the current mining work when time is exceeded and create partial blocks
disable-pending-block = false # Disable the pending block creation loop. When set, RPC queries for 'pending' block will return nil
Comment thread
manav2401 marked this conversation as resolved.
Outdated
# Dynamic gas limit configuration
enableDynamicGasLimit = false # Enable dynamic gas limit adjustment based on base fee
gasLimitMin = 50000000 # Minimum gas limit when dynamic gas limit is enabled
Expand Down
2 changes: 2 additions & 0 deletions docs/cli/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ The ```bor server``` command runs the Bor client.

- ```miner.blocktime```: The block time defined by the miner. Needs to be larger or equal to the consensus block time. If not set (default = 0), the miner will use the consensus block time. (default: 0s)

- ```miner.disable-pending-block```: Disable the pending block creation loop. When set, RPC queries for 'pending' block will return nil on non block producer nodes (default: false)

- ```miner.enableDynamicGasLimit```: Enable dynamic gas limit adjustment based on base fee (default: false)

- ```miner.enableDynamicTargetGas```: Enable dynamic EIP-1559 target gas percentage adjustment based on base fee (post-Lisovo, mutually exclusive with enableDynamicGasLimit) (default: false)
Expand Down
8 changes: 7 additions & 1 deletion internal/cli/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,11 @@ type SealerConfig struct {

// PrefetchGasLimitPercent is the gas limit percentage for prefetching (e.g., 100 = 100%, 110 = 110%)
PrefetchGasLimitPercent uint64 `hcl:"prefetch-gaslimit-percent,optional" toml:"prefetch-gaslimit-percent,optional"`

// DisablePendingBlock disables the pending block creation loop which primarily builds a 'pending'
// block to serve rpc queries. If enabled, all 'pending' block queries will return nil. This won't
// apply for block producer nodes.
Comment thread
manav2401 marked this conversation as resolved.
Outdated
DisablePendingBlock bool `hcl:"disable-pending-block,optional" toml:"disable-pending-block,optional"`
}

type JsonRPCConfig struct {
Expand Down Expand Up @@ -866,7 +871,6 @@ func DefaultConfig() *Config {
StateScheme: "path",
Snapshot: true,
BorLogs: false,

TxPool: &TxPoolConfig{
Locals: []string{},
NoLocals: false,
Expand Down Expand Up @@ -906,6 +910,7 @@ func DefaultConfig() *Config {
PrefetchGasLimitPercent: 100,
TargetGasPercentage: 0, // Initialize to 0, will be set from CLI or remain 0 (meaning use default)
BaseFeeChangeDenominator: 0, // Initialize to 0, will be set from CLI or remain 0 (meaning use default)
DisablePendingBlock: false,
},
Gpo: &GpoConfig{
Blocks: 20,
Expand Down Expand Up @@ -1277,6 +1282,7 @@ func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*
n.Miner.BlockTime = c.Sealer.BlockTime
n.Miner.EnablePrefetch = c.Sealer.EnablePrefetch
n.Miner.PrefetchGasLimitPercent = c.Sealer.PrefetchGasLimitPercent
n.Miner.DisablePendingBlock = c.Sealer.DisablePendingBlock

// Validate prefetch gas limit percentage
if c.Sealer.EnablePrefetch && c.Sealer.PrefetchGasLimitPercent > 150 {
Expand Down
7 changes: 7 additions & 0 deletions internal/cli/server/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,13 @@ func (c *Command) Flags(config *Config) *flagset.Flagset {
Default: c.cliConfig.Sealer.TargetGasMaxPercentage,
Group: "Sealer",
})
f.BoolFlag(&flagset.BoolFlag{
Name: "miner.disable-pending-block",
Usage: "Disable the pending block creation loop. When set, RPC queries for 'pending' block will return nil on non block producer nodes",
Value: &c.cliConfig.Sealer.DisablePendingBlock,
Default: c.cliConfig.Sealer.DisablePendingBlock,
Group: "Sealer",
Comment thread
manav2401 marked this conversation as resolved.
})

// ethstats
f.StringFlag(&flagset.StringFlag{
Expand Down
4 changes: 4 additions & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ type Config struct {
PendingFeeRecipient common.Address `toml:"-"` // Address for pending block rewards.
EnablePrefetch bool // Enable transaction prefetching from pool during block building
PrefetchGasLimitPercent uint64 // Gas limit percentage for prefetching (e.g., 100 = 100%, 110 = 110%)

DisablePendingBlock bool // Disable the pending block creation loop on non block producer nodes
}

// DefaultConfig contains default settings for miner.
Expand All @@ -89,6 +91,8 @@ var DefaultConfig = Config{
Recommit: 2 * time.Second,
EnablePrefetch: true,
PrefetchGasLimitPercent: 100, // 100% of header gas limit

DisablePendingBlock: false,
}

// Miner is the main object which takes care of submitting new work to consensus
Expand Down
9 changes: 8 additions & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,13 @@ func (w *worker) mainLoop() {
for {
select {
case req := <-w.newWorkCh:
// When DisablePendingBlock is set and the worker is not actively producing
// blocks (non-validator), skip commitWork entirely — its only purpose in
// that case is to maintain the pending block snapshot for RPC.
if w.config.DisablePendingBlock && !w.IsRunning() {
Comment thread
manav2401 marked this conversation as resolved.
Comment thread
manav2401 marked this conversation as resolved.
continue
Comment thread
manav2401 marked this conversation as resolved.
}

if w.chainConfig.ChainID.Cmp(params.BorMainnetChainConfig.ChainID) == 0 || w.chainConfig.ChainID.Cmp(params.MumbaiChainConfig.ChainID) == 0 || w.chainConfig.ChainID.Cmp(params.AmoyChainConfig.ChainID) == 0 {
if w.eth.PeerCount() > 0 || devFakeAuthor {
//nolint:contextcheck
Expand All @@ -852,7 +859,7 @@ func (w *worker) mainLoop() {
// already included in the current sealing block. These transactions will
// be automatically eliminated.
// nolint : nestif
if !w.IsRunning() && w.current != nil {
if !w.IsRunning() && !w.config.DisablePendingBlock && w.current != nil {
Comment thread
manav2401 marked this conversation as resolved.
// If block is already full, abort
if gp := w.current.gasPool; gp != nil && gp.Gas() < params.TxGas {
continue
Comment thread
manav2401 marked this conversation as resolved.
Expand Down
40 changes: 40 additions & 0 deletions miner/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2967,3 +2967,43 @@ func TestDelayFlagOffByOne(t *testing.T) {
require.True(t, buggyDelayFlag(), "bug: last tx skipped, DAG hint incorrectly embedded")
require.False(t, fixedDelayFlag(), "fix: last tx detected, DAG hint suppressed")
}

// TestDisablePendingBlock validates if setting `DisablePendingBlock` affects the
// creation of pending block or not.
func TestDisablePendingBlock(t *testing.T) {
t.Parallel()

t.Run("pending block is nil when flag is enabled", func(t *testing.T) {
config := DefaultTestConfig()
config.DisablePendingBlock = true

w, _, cleanup := newTestWorker(t, config, ethashChainConfig, ethash.NewFaker(), rawdb.NewMemoryDatabase(), false, 0)
defer cleanup()

// Trigger the pending block build (non-validator path: worker is not started/running).
w.startCh <- struct{}{}
time.Sleep(500 * time.Millisecond)

Comment thread
manav2401 marked this conversation as resolved.
block, receipts, stateDB := w.pending()
require.Nil(t, block, "pending block should be nil when DisablePendingBlock is true")
require.Nil(t, receipts, "pending receipts should be nil when DisablePendingBlock is true")
require.Nil(t, stateDB, "pending state should be nil when DisablePendingBlock is true")
Comment thread
manav2401 marked this conversation as resolved.
Outdated
})

t.Run("pending block is created when flag is disabled", func(t *testing.T) {
config := DefaultTestConfig()
config.DisablePendingBlock = false

w, _, cleanup := newTestWorker(t, config, ethashChainConfig, ethash.NewFaker(), rawdb.NewMemoryDatabase(), false, 0)
defer cleanup()

// Trigger the pending block build (non-validator path: worker is not started/running).
w.startCh <- struct{}{}
time.Sleep(500 * time.Millisecond)

block, receipts, stateDB := w.pending()
require.NotNil(t, block, "pending block should not be nil when DisablePendingBlock is false")
require.NotNil(t, receipts, "pending receipts should not be nil when DisablePendingBlock is false")
require.NotNil(t, stateDB, "pending state should not be nil when DisablePendingBlock is false")
})
}
Loading