Skip to content

Commit

Permalink
GasLimit adjustment logic updated and network specific gas ceil is used
Browse files Browse the repository at this point in the history
Previously the gas adjustment was being done using arbitrary code which I
couldn't track from Geth. And the variables were being used in a wrong way.

PROBLEM: To be specific, genesis gas limit was set to the min gas limit and
Parent gas limit was given as an input to the CalcGasLimit function. This meant
that the gas limit would never adjust and it will always stay the same as the
genesis gas limit set in the genesis block.

SOLUTION: Gas limit should adjust based on the usage, and by default a spike in
the gas limit shouldn't be allowed This Commit does exactly that.

CalcGasLimit takes parent gas limit and the desired gas limit and returns the
gas limit after adjustment, either adding/subtracting a fixed proportion of the parent gas
limit to the parent gas limit.

If the percentage of gas used is less than 80 percent adjust downwards to
default GasFloor and otherwise adjust upwards to the GasCeil

Since this is not consensus, a Node operator can change this default behavior
if he chooses to do so, he can increase or decrease within the allowable range.
  • Loading branch information
gameofpointers committed Jul 3, 2023
1 parent c6ead67 commit af53114
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 50 deletions.
25 changes: 24 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,6 @@ var (
Usage: "Enable colorized logging",
}


LogToStdOutFlag = cli.BoolFlag{
Name: "logtostdout",
Usage: "Write log messages to stdout",
Expand Down Expand Up @@ -932,6 +931,27 @@ func setSubUrls(ctx *cli.Context, cfg *ethconfig.Config) {
}
}

// setGasLimitCeil sets the gas limit ceils based on the network that is
// running
func setGasLimitCeil(ctx *cli.Context, cfg *ethconfig.Config) {
switch {
case ctx.GlobalBool(ColosseumFlag.Name):
cfg.Miner.GasCeil = params.ColosseumGasCeil
case ctx.GlobalBool(GardenFlag.Name):
cfg.Miner.GasCeil = params.GardenGasCeil
case ctx.GlobalBool(OrchardFlag.Name):
cfg.Miner.GasCeil = params.OrchardGasCeil
case ctx.GlobalBool(GalenaFlag.Name):
cfg.Miner.GasCeil = params.GalenaGasCeil
case ctx.GlobalBool(LocalFlag.Name):
cfg.Miner.GasCeil = params.LocalGasCeil
case ctx.GlobalBool(DeveloperFlag.Name):
cfg.Miner.GasCeil = params.LocalGasCeil
default:
cfg.Miner.GasCeil = params.ColosseumGasCeil
}
}

// makeSubUrls returns the subordinate chain urls
func makeSubUrls(ctx *cli.Context) []string {
return strings.Split(ctx.GlobalString(SubUrls.Name), ",")
Expand Down Expand Up @@ -1352,6 +1372,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// set the subordinate chain websocket urls
setSubUrls(ctx, cfg)

// set the gas limit ceil
setGasLimitCeil(ctx, cfg)

// set the slices that the node is running
setSlicesRunning(ctx, cfg)

Expand Down
18 changes: 9 additions & 9 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ func DefaultColosseumGenesisBlock() *Genesis {
return &Genesis{
Config: params.ColosseumChainConfig,
Nonce: 66,
ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
GasLimit: 50000000,
ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"),
GasLimit: 5000000,
Difficulty: big.NewInt(1000),
}
}
Expand All @@ -330,8 +330,8 @@ func DefaultGardenGenesisBlock() *Genesis {
return &Genesis{
Config: params.GardenChainConfig,
Nonce: 0,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
GasLimit: 17000000,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353539"),
GasLimit: 5000000,
Difficulty: big.NewInt(1000),
}
}
Expand All @@ -341,8 +341,8 @@ func DefaultOrchardGenesisBlock() *Genesis {
return &Genesis{
Config: params.OrchardChainConfig,
Nonce: 0,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
GasLimit: 50000000,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353536"),
GasLimit: 5000000,
Difficulty: big.NewInt(1000),
}
}
Expand All @@ -352,8 +352,8 @@ func DefaultGalenaGenesisBlock() *Genesis {
return &Genesis{
Config: params.GalenaChainConfig,
Nonce: 0,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
GasLimit: 160000000,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353537"),
GasLimit: 5000000,
Difficulty: big.NewInt(1000),
}
}
Expand All @@ -364,7 +364,7 @@ func DefaultLocalGenesisBlock() *Genesis {
Config: params.LocalChainConfig,
Nonce: 0,
ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
GasLimit: 160000000,
GasLimit: 5000000,
Difficulty: big.NewInt(1000),
}
}
Expand Down
43 changes: 22 additions & 21 deletions core/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,13 @@ type environment struct {
gasPool *GasPool // available gas used to pack transactions
coinbase common.Address

header *types.Header
txs []*types.Transaction
etxs []*types.Transaction
subManifest types.BlockManifest
receipts []*types.Receipt
uncleMu sync.RWMutex
uncles map[common.Hash]*types.Header
externalGasUsed uint64
externalBlockLength int
header *types.Header
txs []*types.Transaction
etxs []*types.Transaction
subManifest types.BlockManifest
receipts []*types.Receipt
uncleMu sync.RWMutex
uncles map[common.Hash]*types.Header
}

// copy creates a deep copy of environment.
Expand Down Expand Up @@ -244,6 +242,8 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, db ethdb.Databas
resubmitIntervalCh: make(chan time.Duration),
resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize),
}
// Set the GasFloor of the worker to the minGasLimit
worker.config.GasFloor = params.MinGasLimit

phBodyCache, _ := lru.New(pendingBlockBodyLimit)
worker.pendingBlockBody = phBodyCache
Expand Down Expand Up @@ -531,14 +531,13 @@ func (w *worker) makeEnv(parent *types.Block, header *types.Header, coinbase com

// Note the passed coinbase may be different with header.Coinbase.
env := &environment{
signer: types.MakeSigner(w.chainConfig, header.Number()),
state: state,
coinbase: coinbase,
ancestors: mapset.NewSet(),
family: mapset.NewSet(),
header: header,
uncles: make(map[common.Hash]*types.Header),
externalGasUsed: uint64(0),
signer: types.MakeSigner(w.chainConfig, header.Number()),
state: state,
coinbase: coinbase,
ancestors: mapset.NewSet(),
family: mapset.NewSet(),
header: header,
uncles: make(map[common.Hash]*types.Header),
}
// when 08 is processed ancestors contain 07 (quick block)
for _, ancestor := range w.hc.GetBlocksFromHash(parent.Hash(), 7) {
Expand Down Expand Up @@ -841,10 +840,12 @@ func (w *worker) fillTransactions(interrupt *int32, env *environment, block *typ
// into the given sealing block. The transaction selection and ordering strategy can
// be customized with the plugin in the future.
func (w *worker) adjustGasLimit(interrupt *int32, env *environment, parent *types.Block) {

gasUsed := (parent.GasUsed() + env.externalGasUsed) / uint64(env.externalBlockLength+1)

env.header.SetGasLimit(CalcGasLimit(parent.GasLimit(), gasUsed))
percentGasUsed := parent.GasUsed() * 100 / parent.GasLimit()
if percentGasUsed > params.PercentGasUsedThreshold {
env.header.SetGasLimit(CalcGasLimit(parent.GasLimit(), w.config.GasCeil))
} else {
env.header.SetGasLimit(CalcGasLimit(parent.GasLimit(), w.config.GasFloor))
}
}

func (w *worker) FinalizeAssemble(chain consensus.ChainHeaderReader, header *types.Header, parent *types.Block, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, etxs []*types.Transaction, subManifest types.BlockManifest, receipts []*types.Receipt) (*types.Block, error) {
Expand Down
2 changes: 1 addition & 1 deletion eth/ethconfig/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var Defaults = Config{
TrieTimeout: 60 * time.Minute,
SnapshotCache: 102,
Miner: core.Config{
GasCeil: 8000000,
GasCeil: 18000000,
GasPrice: big.NewInt(params.GWei),
Recommit: 3 * time.Second,
},
Expand Down
10 changes: 5 additions & 5 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ import (

// Genesis hashes to enforce below configs on.
var (
ColosseumGenesisHash = common.HexToHash("0xff5907242c1dd76d1965e811bb65080788ead1f83863743d07302861ad8645c5")
GardenGenesisHash = common.HexToHash("0xc4bba72ab2bc665b30fff8a2d4a40867b501f861d55ffa84559dd1cf896833c7")
OrchardGenesisHash = common.HexToHash("0xfae78a649e29c4c3fffe9b2a7475e164ac25ccb324063504e8e6d0818d95806f")
LocalGenesisHash = common.HexToHash("0xa39b3d005d2541da2509e032289236a625d0d413cc14824ef31b0beef0c6bb85")
GalenaGenesisHash = common.HexToHash("0xa39b3d005d2541da2509e032289236a625d0d413cc14824ef31b0beef0c6bb85")
ColosseumGenesisHash = common.HexToHash("0x937e935af7be23cee3a138dcc0e1a0ba1ccf2c9d085d144d4fb2e6fbd54fdd67")
GardenGenesisHash = common.HexToHash("0x8975f8760d317524559986d595058d4d66c05d62e0eda1d740cdee56a25788a5")
OrchardGenesisHash = common.HexToHash("0x17cf57642df199efff2d6bbf34d99a842d0545980df30e40707ed54663b42baa")
LocalGenesisHash = common.HexToHash("0x9e7149a4f5ff07675e0e7881f004cd0dc1f5a28bb9ba8c4de86794ba6fe80b60")
GalenaGenesisHash = common.HexToHash("0xe0a395a3fcd7ecbb28dd66eeceab2fb40db01a2bfbf9e5fbc5b93269104df19a")
)

var (
Expand Down
32 changes: 19 additions & 13 deletions params/protocol_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ package params
import "math/big"

const (
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
MinGasLimit uint64 = 17000000 // Minimum the gas limit may ever be.
GenesisGasLimit uint64 = 471238800 // Gas limit of the Genesis block.
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
PercentGasUsedThreshold uint64 = 95 // Percent Gas used threshold at which the gas limit adjusts
MinGasLimit uint64 = 5000000 // Minimum the gas limit may ever be.
GenesisGasLimit uint64 = 5000000 // Gas limit of the Genesis block.

MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction.
Expand Down Expand Up @@ -129,14 +130,19 @@ const (
)

var (
DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations.
ZoneMinDifficulty = big.NewInt(1000) // The minimum difficulty in a zone. Prime & regions should be multiples of this value
MinimumDifficulty = ZoneMinDifficulty // The minimum that the difficulty may ever be.
GenesisDifficulty = ZoneMinDifficulty // Difficulty of the Genesis block.
DurationLimit = big.NewInt(10) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
GardenDurationLimit = big.NewInt(3) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
OrchardDurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
GalenaDurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
LocalDurationLimit = big.NewInt(2) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
TimeFactor = big.NewInt(7)
ColosseumGasCeil uint64 = 50000000
GardenGasCeil uint64 = 17000000
OrchardGasCeil uint64 = 50000000
GalenaGasCeil uint64 = 160000000
LocalGasCeil uint64 = 20000000
DifficultyBoundDivisor = big.NewInt(2048) // The bound divisor of the difficulty, used in the update calculations.
ZoneMinDifficulty = big.NewInt(1000) // The minimum difficulty in a zone. Prime & regions should be multiples of this value
MinimumDifficulty = ZoneMinDifficulty // The minimum that the difficulty may ever be.
GenesisDifficulty = ZoneMinDifficulty // Difficulty of the Genesis block.
DurationLimit = big.NewInt(10) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
GardenDurationLimit = big.NewInt(3) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
OrchardDurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
GalenaDurationLimit = big.NewInt(12) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
LocalDurationLimit = big.NewInt(2) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not.
TimeFactor = big.NewInt(7)
)

0 comments on commit af53114

Please sign in to comment.