diff --git a/consensus/misc/eip1559.go b/consensus/misc/eip1559.go index e0216243f057..4521b47b36e6 100644 --- a/consensus/misc/eip1559.go +++ b/consensus/misc/eip1559.go @@ -33,7 +33,7 @@ func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Heade // Verify that the gas limit remains within allowed bounds parentGasLimit := parent.GasLimit if !config.IsLondon(parent.Number) { - parentGasLimit = parent.GasLimit * params.ElasticityMultiplier + parentGasLimit = parent.GasLimit * config.ElasticityMultiplier() } if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil { return err @@ -58,7 +58,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { return new(big.Int).SetUint64(params.InitialBaseFee) } - parentGasTarget := parent.GasLimit / params.ElasticityMultiplier + parentGasTarget := parent.GasLimit / config.ElasticityMultiplier() // If the parent gasUsed is the same as the target, the baseFee remains unchanged. if parent.GasUsed == parentGasTarget { return new(big.Int).Set(parent.BaseFee) @@ -75,7 +75,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { num.SetUint64(parent.GasUsed - parentGasTarget) num.Mul(num, parent.BaseFee) num.Div(num, denom.SetUint64(parentGasTarget)) - num.Div(num, denom.SetUint64(params.BaseFeeChangeDenominator)) + num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator())) baseFeeDelta := math.BigMax(num, common.Big1) return num.Add(parent.BaseFee, baseFeeDelta) @@ -85,7 +85,7 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int { num.SetUint64(parentGasTarget - parent.GasUsed) num.Mul(num, parent.BaseFee) num.Div(num, denom.SetUint64(parentGasTarget)) - num.Div(num, denom.SetUint64(params.BaseFeeChangeDenominator)) + num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator())) baseFee := num.Sub(parent.BaseFee, num) return math.BigMax(baseFee, common.Big0) diff --git a/core/chain_makers.go b/core/chain_makers.go index 88a1c4e87024..2ed87e0a9e3a 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -174,7 +174,7 @@ func (b *BlockGen) AddUncle(h *types.Header) { if b.config.IsLondon(h.Number) { h.BaseFee = misc.CalcBaseFee(b.config, parent) if !b.config.IsLondon(parent.Number) { - parentGasLimit := parent.GasLimit * params.ElasticityMultiplier + parentGasLimit := parent.GasLimit * b.config.ElasticityMultiplier() h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) } } @@ -322,7 +322,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S if chain.Config().IsLondon(header.Number) { header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header()) if !chain.Config().IsLondon(parent.Number()) { - parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier + parentGasLimit := parent.GasLimit() * chain.Config().ElasticityMultiplier() header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) } } diff --git a/miner/worker.go b/miner/worker.go index 93fb6288bb45..f73417058ec1 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1006,7 +1006,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) { if w.chainConfig.IsLondon(header.Number) { header.BaseFee = misc.CalcBaseFee(w.chainConfig, parent.Header()) if !w.chainConfig.IsLondon(parent.Number()) { - parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier + parentGasLimit := parent.GasLimit() * w.chainConfig.ElasticityMultiplier() header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil) } } diff --git a/params/config.go b/params/config.go index 22b36b7d68e3..28037136130d 100644 --- a/params/config.go +++ b/params/config.go @@ -270,17 +270,17 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(EthashConfig), nil} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, nil, new(EthashConfig), nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, false, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(EthashConfig), nil} - NonActivatedConfig = &ChainConfig{big.NewInt(1), nil, nil, false, nil, common.Hash{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, nil, new(EthashConfig), nil} + NonActivatedConfig = &ChainConfig{big.NewInt(1), nil, nil, false, nil, common.Hash{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, nil, new(EthashConfig), nil} TestRules = TestChainConfig.Rules(new(big.Int), false) ) @@ -383,6 +383,9 @@ type ChainConfig struct { // even without having seen the TTD locally (safer long term). TerminalTotalDifficultyPassed bool `json:"terminalTotalDifficultyPassed,omitempty"` + // EIP-1559 parameters. Defaults to standard mainnet parameters if left unspecified. + EIP1559 *EIP1559Config `json:"eip1559,omitempty"` + // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` @@ -709,6 +712,34 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi return nil } +// EIP1559Config makes the EIP-1559 parameters configurable. +// Chains with non-standard block time may adjust these to maintain a similar base fee adjustment rate +// and maximum gas limit, while maintaining a safe block gas target. +type EIP1559Config struct { + // BaseFeeChangeDenominator bounds the amount the base fee can change between blocks. + BaseFeeChangeDenominator uint64 `json:"baseFeeChangeDenominator"` + // ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have. + ElasticityMultiplier uint64 `json:"elasticityMultiplier"` +} + +// BaseFeeChangeDenominator bounds the amount the base fee can change between blocks. +// This defaults to DefaultBaseFeeChangeDenominator if the EIP-1559 parameters are unspecified. +func (c *ChainConfig) BaseFeeChangeDenominator() uint64 { + if c.EIP1559 != nil { + return c.EIP1559.BaseFeeChangeDenominator + } + return DefaultBaseFeeChangeDenominator +} + +// ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have. +// This defaults to DefaultElasticityMultiplier if the EIP-1559 parameters are unspecified. +func (c *ChainConfig) ElasticityMultiplier() uint64 { + if c.EIP1559 != nil { + return c.EIP1559.ElasticityMultiplier + } + return DefaultElasticityMultiplier +} + // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to // block s2 because head is already past the fork. func isForkIncompatible(s1, s2, head *big.Int) bool { diff --git a/params/protocol_params.go b/params/protocol_params.go index 5f154597a7fa..b0037fd471c4 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -119,9 +119,9 @@ const ( // Introduced in Tangerine Whistle (Eip 150) CreateBySelfdestructGas uint64 = 25000 - BaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks. - ElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have. - InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks. + DefaultBaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks. + DefaultElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have. + InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks. MaxCodeSize = 24576 // Maximum bytecode to permit for a contract