all: set gas limit dynamically (#1945)

This commit is contained in:
Daniel Liu 2026-01-21 13:19:20 +08:00 committed by GitHub
parent c27d49c03e
commit 1f3faa5184
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 44 additions and 25 deletions

View file

@ -65,6 +65,7 @@ type constant struct {
eip1559Block *big.Int eip1559Block *big.Int
cancunBlock *big.Int cancunBlock *big.Int
pragueBlock *big.Int pragueBlock *big.Int
dynamicGasLimitBlock *big.Int
trc21IssuerSMC Address trc21IssuerSMC Address
xdcxListingSMC Address xdcxListingSMC Address
@ -100,6 +101,7 @@ var (
Eip1559Block = MainnetConstant.eip1559Block Eip1559Block = MainnetConstant.eip1559Block
CancunBlock = MainnetConstant.cancunBlock CancunBlock = MainnetConstant.cancunBlock
PragueBlock = MainnetConstant.pragueBlock PragueBlock = MainnetConstant.pragueBlock
DynamicGasLimitBlock = MainnetConstant.dynamicGasLimitBlock
TIPUpgradeReward = MainnetConstant.tipUpgradeReward TIPUpgradeReward = MainnetConstant.tipUpgradeReward
TipUpgradePenalty = MainnetConstant.tipUpgradePenalty TipUpgradePenalty = MainnetConstant.tipUpgradePenalty
TIPEpochHalving = MainnetConstant.tipEpochHalving TIPEpochHalving = MainnetConstant.tipEpochHalving
@ -163,6 +165,7 @@ func CopyConstants(chainID uint64) {
Eip1559Block = c.eip1559Block Eip1559Block = c.eip1559Block
CancunBlock = c.cancunBlock CancunBlock = c.cancunBlock
PragueBlock = c.pragueBlock PragueBlock = c.pragueBlock
DynamicGasLimitBlock = c.dynamicGasLimitBlock
TIPUpgradeReward = c.tipUpgradeReward TIPUpgradeReward = c.tipUpgradeReward
TipUpgradePenalty = c.tipUpgradePenalty TipUpgradePenalty = c.tipUpgradePenalty
TIPEpochHalving = c.tipEpochHalving TIPEpochHalving = c.tipEpochHalving

View file

@ -30,6 +30,7 @@ var DevnetConstant = constant{
eip1559Block: big.NewInt(32400), eip1559Block: big.NewInt(32400),
cancunBlock: big.NewInt(43200), cancunBlock: big.NewInt(43200),
pragueBlock: big.NewInt(math.MaxInt64), pragueBlock: big.NewInt(math.MaxInt64),
dynamicGasLimitBlock: big.NewInt(math.MaxInt64),
tipUpgradeReward: big.NewInt(math.MaxInt64), tipUpgradeReward: big.NewInt(math.MaxInt64),
tipUpgradePenalty: big.NewInt(math.MaxInt64), tipUpgradePenalty: big.NewInt(math.MaxInt64),
tipEpochHalving: big.NewInt(math.MaxInt64), tipEpochHalving: big.NewInt(math.MaxInt64),

View file

@ -30,6 +30,7 @@ var localConstant = constant{
eip1559Block: big.NewInt(0), eip1559Block: big.NewInt(0),
cancunBlock: big.NewInt(0), cancunBlock: big.NewInt(0),
pragueBlock: big.NewInt(math.MaxInt64), pragueBlock: big.NewInt(math.MaxInt64),
dynamicGasLimitBlock: big.NewInt(0),
tipUpgradeReward: big.NewInt(math.MaxInt64), tipUpgradeReward: big.NewInt(math.MaxInt64),
tipUpgradePenalty: big.NewInt(math.MaxInt64), tipUpgradePenalty: big.NewInt(math.MaxInt64),
tipEpochHalving: big.NewInt(math.MaxInt64), tipEpochHalving: big.NewInt(math.MaxInt64),

View file

@ -30,6 +30,7 @@ var MainnetConstant = constant{
eip1559Block: big.NewInt(math.MaxInt64), eip1559Block: big.NewInt(math.MaxInt64),
cancunBlock: big.NewInt(math.MaxInt64), cancunBlock: big.NewInt(math.MaxInt64),
pragueBlock: big.NewInt(math.MaxInt64), pragueBlock: big.NewInt(math.MaxInt64),
dynamicGasLimitBlock: big.NewInt(math.MaxInt64),
tipUpgradeReward: big.NewInt(math.MaxInt64), tipUpgradeReward: big.NewInt(math.MaxInt64),
tipUpgradePenalty: big.NewInt(math.MaxInt64), tipUpgradePenalty: big.NewInt(math.MaxInt64),
tipEpochHalving: big.NewInt(math.MaxInt64), tipEpochHalving: big.NewInt(math.MaxInt64),

View file

@ -30,6 +30,7 @@ var TestnetConstant = constant{
eip1559Block: big.NewInt(71550000), // Target 14th Feb 2025 eip1559Block: big.NewInt(71550000), // Target 14th Feb 2025
cancunBlock: big.NewInt(71551800), cancunBlock: big.NewInt(71551800),
pragueBlock: big.NewInt(math.MaxInt64), pragueBlock: big.NewInt(math.MaxInt64),
dynamicGasLimitBlock: big.NewInt(math.MaxInt64),
tipUpgradeReward: big.NewInt(math.MaxInt64), tipUpgradeReward: big.NewInt(math.MaxInt64),
tipUpgradePenalty: big.NewInt(math.MaxInt64), tipUpgradePenalty: big.NewInt(math.MaxInt64),
tipEpochHalving: big.NewInt(math.MaxInt64), tipEpochHalving: big.NewInt(math.MaxInt64),

View file

@ -110,7 +110,7 @@ func init() {
func genTxRing(naccounts int) func(int, *BlockGen) { func genTxRing(naccounts int) func(int, *BlockGen) {
from := 0 from := 0
return func(i int, gen *BlockGen) { return func(i int, gen *BlockGen) {
gas := CalcGasLimit(gen.PrevBlock(i - 1)) gas := CalcGasLimit(gen.PrevBlock(i-1).GasLimit(), params.TargetGasLimit)
for { for {
gas -= params.TxGas gas -= params.TxGas
if gas < params.TxGas { if gas < params.TxGas {

View file

@ -173,29 +173,22 @@ func (v *BlockValidator) ValidateLendingOrder(statedb *state.StateDB, lendingSta
return nil return nil
} }
// CalcGasLimit computes the gas limit of the next block after parent. // CalcGasLimit computes the gas limit of the next block after parent. It aims
// This is miner strategy, not consensus protocol. // to keep the baseline gas close to the provided target, and increase it towards
func CalcGasLimit(parent *types.Block) uint64 { // the target if the baseline gas is lower.
// contrib = (parentGasUsed * 3 / 2) / 1024 func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 {
contrib := (parent.GasUsed() + parent.GasUsed()/2) / params.GasLimitBoundDivisor delta := parentGasLimit/params.GasLimitBoundDivisor - 1
if desiredLimit < params.MinGasLimit {
// decay = parentGasLimit / 1024 -1 desiredLimit = params.MinGasLimit
decay := parent.GasLimit()/params.GasLimitBoundDivisor - 1
/*
strategy: gasLimit of block-to-mine is set based on parent's
gasUsed value. if parentGasUsed > parentGasLimit * (2/3) then we
increase it, otherwise lower it (or leave it unchanged if it's right
at that usage) the amount increased/decreased depends on how far away
from parentGasLimit * (2/3) parentGasUsed is.
*/
limit := max(parent.GasLimit()-decay+contrib, params.MinGasLimit)
// however, if we're now below the target (TargetGasLimit) we increase the
// limit as much as we can (parentGasLimit / 1024 -1)
if limit < params.TargetGasLimit {
limit = min(parent.GasLimit() + decay, params.TargetGasLimit)
} }
return limit // If we're outside our allowed gas range, we try to hone towards them
if parentGasLimit < desiredLimit {
return min(parentGasLimit+delta, desiredLimit)
}
if parentGasLimit > desiredLimit {
return max(parentGasLimit-delta, desiredLimit)
}
return parentGasLimit
} }
func ExtractTradingTransactions(transactions types.Transactions) ([]tradingstate.TxMatchBatch, error) { func ExtractTradingTransactions(transactions types.Transactions) ([]tradingstate.TxMatchBatch, error) {

View file

@ -293,7 +293,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
Difficulty: parent.Difficulty(), Difficulty: parent.Difficulty(),
UncleHash: parent.UncleHash(), UncleHash: parent.UncleHash(),
}), }),
GasLimit: CalcGasLimit(parent), GasLimit: CalcGasLimit(parent.GasLimit(), params.TargetGasLimit),
Number: new(big.Int).Add(parent.Number(), common.Big1), Number: new(big.Int).Add(parent.Number(), common.Big1),
Time: time, Time: time,
} }

View file

@ -736,10 +736,14 @@ func (w *worker) commitNewWork() {
header := &types.Header{ header := &types.Header{
ParentHash: parent.Hash(), ParentHash: parent.Hash(),
Number: num.Add(num, common.Big1), Number: num.Add(num, common.Big1),
GasLimit: params.TargetGasLimit,
Extra: w.extra, Extra: w.extra,
Time: uint64(tstamp), Time: uint64(tstamp),
} }
if w.config.IsDynamicGasLimitBlock(header.Number) {
header.GasLimit = core.CalcGasLimit(parent.GasLimit(), params.TargetGasLimit)
} else {
header.GasLimit = params.TargetGasLimit
}
// Set baseFee if we are on an EIP-1559 chain // Set baseFee if we are on an EIP-1559 chain
header.BaseFee = eip1559.CalcBaseFee(w.config, header) header.BaseFee = eip1559.CalcBaseFee(w.config, header)

View file

@ -495,6 +495,8 @@ type ChainConfig struct {
CancunBlock *big.Int `json:"cancunBlock,omitempty"` CancunBlock *big.Int `json:"cancunBlock,omitempty"`
PragueBlock *big.Int `json:"pragueBlock,omitempty"` PragueBlock *big.Int `json:"pragueBlock,omitempty"`
DynamicGasLimitBlock *big.Int `json:"dynamicGasLimitBlock,omitempty"` // Dynamic gas limit adjustment algorithm activation block (nil = no fork)
// Various consensus engines // Various consensus engines
Ethash *EthashConfig `json:"ethash,omitempty"` Ethash *EthashConfig `json:"ethash,omitempty"`
Clique *CliqueConfig `json:"clique,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"`
@ -860,6 +862,9 @@ func (c *ChainConfig) String() string {
if c.PragueBlock != nil { if c.PragueBlock != nil {
result += fmt.Sprintf(", PragueBlock: %v", c.PragueBlock) result += fmt.Sprintf(", PragueBlock: %v", c.PragueBlock)
} }
if c.DynamicGasLimitBlock != nil {
result += fmt.Sprintf(", DynamicGasLimitBlock: %v", c.DynamicGasLimitBlock)
}
if c.XDPoS != nil { if c.XDPoS != nil {
result += fmt.Sprintf(", %s", c.XDPoS.String()) result += fmt.Sprintf(", %s", c.XDPoS.String())
} }
@ -907,6 +912,10 @@ func (c *ChainConfig) Description() string {
if c.PragueBlock != nil { if c.PragueBlock != nil {
pragueBlock = c.PragueBlock pragueBlock = c.PragueBlock
} }
dynamicGasLimitBlock := common.DynamicGasLimitBlock
if c.DynamicGasLimitBlock != nil {
dynamicGasLimitBlock = c.DynamicGasLimitBlock
}
var banner = "Chain configuration:\n" var banner = "Chain configuration:\n"
banner += fmt.Sprintf(" - ChainID: %-8v\n", c.ChainID) banner += fmt.Sprintf(" - ChainID: %-8v\n", c.ChainID)
@ -939,6 +948,7 @@ func (c *ChainConfig) Description() string {
banner += fmt.Sprintf(" - Eip1559: %-8v\n", eip1559Block) banner += fmt.Sprintf(" - Eip1559: %-8v\n", eip1559Block)
banner += fmt.Sprintf(" - Cancun: %-8v\n", cancunBlock) banner += fmt.Sprintf(" - Cancun: %-8v\n", cancunBlock)
banner += fmt.Sprintf(" - Prague: %-8v\n", pragueBlock) banner += fmt.Sprintf(" - Prague: %-8v\n", pragueBlock)
banner += fmt.Sprintf(" - DynamicGasLimitBlock: %-8v\n", dynamicGasLimitBlock)
banner += fmt.Sprintf(" - TIPUpgradeReward: %-8v\n", common.TIPUpgradeReward) banner += fmt.Sprintf(" - TIPUpgradeReward: %-8v\n", common.TIPUpgradeReward)
banner += fmt.Sprintf(" - TipUpgradePenalty: %-8v\n", common.TipUpgradePenalty) banner += fmt.Sprintf(" - TipUpgradePenalty: %-8v\n", common.TipUpgradePenalty)
banner += fmt.Sprintf(" - TIPEpochHalving: %-8v\n", common.TIPEpochHalving) banner += fmt.Sprintf(" - TIPEpochHalving: %-8v\n", common.TIPEpochHalving)
@ -1024,6 +1034,11 @@ func (c *ChainConfig) IsPrague(num *big.Int) bool {
return isForked(common.PragueBlock, num) || isForked(c.PragueBlock, num) return isForked(common.PragueBlock, num) || isForked(c.PragueBlock, num)
} }
// IsDynamicGasLimitBlock returns whether num is either equal to the DynamicGasLimitBlock fork block or greater.
func (c *ChainConfig) IsDynamicGasLimitBlock(num *big.Int) bool {
return isForked(common.DynamicGasLimitBlock, num) || isForked(c.DynamicGasLimitBlock, num)
}
func (c *ChainConfig) IsTIP2019(num *big.Int) bool { func (c *ChainConfig) IsTIP2019(num *big.Int) bool {
return isForked(common.TIP2019Block, num) return isForked(common.TIP2019Block, num)
} }