Skip to content

Commit 765f39a

Browse files
committed
revert back to using miner defined gas limit; calc baseFee using EIP1559_GAS_TARGET
1 parent 2e95968 commit 765f39a

File tree

19 files changed

+236
-452
lines changed

19 files changed

+236
-452
lines changed

cmd/geth/main.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,9 @@ var (
156156
utils.EIP1559CLIConfigure,
157157
utils.EIP1559ForkBlockNumber,
158158
utils.EIP1559InitialBaseFee,
159-
utils.EIP1559BaseFeeMaxChangeDenominator,
160-
utils.EIP1559SlackCoefficient,
161-
utils.EIP1559TargetGasUsed,
162-
utils.EIP1559DecayRange,
159+
utils.EIP1559EIP1559BaseFeeMaxChangeDenominator,
160+
utils.EIP1559EIP1559SlackCoefficient,
161+
utils.EIP1559MigrationBlockDuration,
163162
}
164163

165164
rpcFlags = []cli.Flag{

cmd/geth/retesteth.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,10 @@ func (api *RetestethAPI) mineBlock() error {
503503

504504
var gp1559 *core.GasPool
505505
var gasPool *core.GasPool
506+
// See core/gaspool.go for detials on how these gas limit values are calculated
507+
gasPool = core.NewLegacyGasPool(api.chainConfig, header.Number, new(big.Int).SetUint64(header.GasLimit))
506508
if api.chainConfig.IsEIP1559(header.Number) {
507-
gasPool = new(core.GasPool).AddGas(api.chainConfig.EIP1559.MaxGas - header.GasLimit)
508-
gp1559 = new(core.GasPool).AddGas(header.GasLimit)
509-
} else {
510-
gasPool = new(core.GasPool).AddGas(header.GasLimit)
509+
gp1559 = core.NewEIP1559GasPool(api.chainConfig, header.Number, new(big.Int).SetUint64(header.GasLimit))
511510
}
512511

513512
txCount := 0

cmd/geth/usage.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,9 @@ var AppHelpFlagGroups = []flagGroup{
267267
utils.EIP1559CLIConfigure,
268268
utils.EIP1559ForkBlockNumber,
269269
utils.EIP1559InitialBaseFee,
270-
utils.EIP1559BaseFeeMaxChangeDenominator,
271-
utils.EIP1559SlackCoefficient,
272-
utils.EIP1559TargetGasUsed,
273-
utils.EIP1559DecayRange,
270+
utils.EIP1559EIP1559BaseFeeMaxChangeDenominator,
271+
utils.EIP1559EIP1559SlackCoefficient,
272+
utils.EIP1559MigrationBlockDuration,
274273
},
275274
},
276275
{

cmd/utils/flags.go

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -742,25 +742,20 @@ var (
742742
Usage: "External configuration of EIP1559 ForkBlockNumber",
743743
Value: params.EIP1559ForkBlockNumber,
744744
}
745-
EIP1559BaseFeeMaxChangeDenominator = cli.Uint64Flag{
745+
EIP1559EIP1559BaseFeeMaxChangeDenominator = cli.Uint64Flag{
746746
Name: "eip1559.basefeemaxchangedenominator",
747-
Usage: "External configuration of EIP1559 BaseFeeMaxChangeDenominator",
748-
Value: params.BaseFeeMaxChangeDenominator,
747+
Usage: "External configuration of EIP1559 EIP1559BaseFeeMaxChangeDenominator",
748+
Value: params.EIP1559BaseFeeMaxChangeDenominator,
749749
}
750-
EIP1559TargetGasUsed = cli.Uint64Flag{
751-
Name: "eip1559.targetgasused",
752-
Usage: "External configuration of EIP1559 TargetGasUsed",
753-
Value: params.TargetGasUsed,
754-
}
755-
EIP1559SlackCoefficient = cli.Uint64Flag{
750+
EIP1559EIP1559SlackCoefficient = cli.Uint64Flag{
756751
Name: "eip1559.slackcoefficient",
757-
Usage: "External configuration of EIP1559 SlackCoefficient",
758-
Value: params.SlackCoefficient,
752+
Usage: "External configuration of EIP1559 EIP1559SlackCoefficient",
753+
Value: params.EIP1559SlackCoefficient,
759754
}
760-
EIP1559DecayRange = cli.Uint64Flag{
761-
Name: "eip1559.decayrange",
762-
Usage: "External configuration of EIP1559 DecayRange",
763-
Value: params.EIP1559DecayRange,
755+
EIP1559MigrationBlockDuration = cli.Uint64Flag{
756+
Name: "eip1559.migrationblockduration",
757+
Usage: "External configuration of the number of EIP1559 transition blocks",
758+
Value: params.EIP1559MigrationBlockDuration,
764759
}
765760
)
766761

@@ -1694,22 +1689,17 @@ func setEIP1559Params(ctx *cli.Context, config *eth.Config) {
16941689
if ctx.GlobalIsSet(EIP1559InitialBaseFee.Name) {
16951690
config.Genesis.Config.EIP1559.InitialBaseFee = ctx.GlobalUint64(EIP1559InitialBaseFee.Name)
16961691
}
1697-
if ctx.GlobalIsSet(EIP1559TargetGasUsed.Name) {
1698-
config.Genesis.Config.EIP1559.TargetGasUsed = ctx.GlobalUint64(EIP1559TargetGasUsed.Name)
1699-
}
1700-
if ctx.GlobalIsSet(EIP1559SlackCoefficient.Name) {
1701-
config.Genesis.Config.EIP1559.SlackCoefficient = ctx.GlobalUint64(EIP1559SlackCoefficient.Name)
1692+
if ctx.GlobalIsSet(EIP1559EIP1559SlackCoefficient.Name) {
1693+
config.Genesis.Config.EIP1559.EIP1559SlackCoefficient = ctx.GlobalUint64(EIP1559EIP1559SlackCoefficient.Name)
17021694
}
1703-
if ctx.GlobalIsSet(EIP1559BaseFeeMaxChangeDenominator.Name) {
1704-
config.Genesis.Config.EIP1559.BaseFeeMaxChangeDenominator = ctx.GlobalUint64(EIP1559BaseFeeMaxChangeDenominator.Name)
1695+
if ctx.GlobalIsSet(EIP1559EIP1559BaseFeeMaxChangeDenominator.Name) {
1696+
config.Genesis.Config.EIP1559.EIP1559BaseFeeMaxChangeDenominator = ctx.GlobalUint64(EIP1559EIP1559BaseFeeMaxChangeDenominator.Name)
17051697
}
1706-
if ctx.GlobalIsSet(EIP1559DecayRange.Name) {
1707-
config.Genesis.Config.EIP1559.DecayRange = ctx.GlobalUint64(EIP1559DecayRange.Name)
1698+
if ctx.GlobalIsSet(EIP1559MigrationBlockDuration.Name) {
1699+
config.Genesis.Config.EIP1559.MigrationBlockDuration = ctx.GlobalUint64(EIP1559MigrationBlockDuration.Name)
17081700
}
17091701
// Re-calculate the derived config params
1710-
config.Genesis.Config.EIP1559.ForkFinalizedBlockNumber = config.Genesis.Config.EIP1559.ForkBlockNumber + config.Genesis.Config.EIP1559.DecayRange
1711-
config.Genesis.Config.EIP1559.MaxGas = config.Genesis.Config.EIP1559.SlackCoefficient * config.Genesis.Config.EIP1559.TargetGasUsed
1712-
config.Genesis.Config.EIP1559.GasIncrementAmount = (config.Genesis.Config.EIP1559.MaxGas / 2) / config.Genesis.Config.EIP1559.DecayRange
1702+
config.Genesis.Config.EIP1559.ForkFinalizedBlockNumber = config.Genesis.Config.EIP1559.ForkBlockNumber + config.Genesis.Config.EIP1559.MigrationBlockDuration
17131703
config.Genesis.Config.EIP1559Block = new(big.Int).SetUint64(config.Genesis.Config.EIP1559.ForkBlockNumber)
17141704
config.Genesis.Config.EIP1559FinalizedBlock = new(big.Int).SetUint64(config.Genesis.Config.EIP1559.ForkFinalizedBlockNumber)
17151705

consensus/ethash/consensus.go

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -264,31 +264,26 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
264264
return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
265265
}
266266

267-
// If EIP1559 is not active we need to verify that the GasLimit field is valid according to the legacy rules
268-
if !chain.Config().IsEIP1559(header.Number) {
269-
// Verify that the gas limit is <= 2^63-1
270-
cap := uint64(0x7fffffffffffffff)
271-
if header.GasLimit > cap {
272-
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, cap)
273-
}
274-
// Verify that the gasUsed is <= gasLimit
275-
if header.GasUsed > header.GasLimit {
276-
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
277-
}
267+
// Verify that the "GasLimit" header field is valid
268+
// Verify that the gas limit is <= 2^63-1
269+
max := uint64(0x7fffffffffffffff)
270+
if header.GasLimit > max {
271+
return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, max)
272+
}
273+
// Verify that the gasUsed is <= gasLimit
274+
if header.GasUsed > header.GasLimit {
275+
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
276+
}
278277

279-
// Verify that the gas limit remains within allowed bounds
280-
diff := int64(parent.GasLimit) - int64(header.GasLimit)
281-
if diff < 0 {
282-
diff *= -1
283-
}
284-
limit := parent.GasLimit / params.GasLimitBoundDivisor
278+
// Verify that the gas limit remains within allowed bounds
279+
diff := int64(parent.GasLimit) - int64(header.GasLimit)
280+
if diff < 0 {
281+
diff *= -1
282+
}
283+
limit := parent.GasLimit / params.GasLimitBoundDivisor
285284

286-
if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
287-
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
288-
}
289-
// If EIP1559 is active, assert that the GasLimit field is valid according to the EIP1559 rules
290-
} else if err := misc.VerifyEIP1559GasLimit(chain.Config(), header); err != nil {
291-
return err
285+
if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit {
286+
return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit)
292287
}
293288

294289
// Verify that the block number is parent's +1

consensus/misc/basefee.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright 2017 The go-ethereum Authors
2+
// This file is part of the go-ethereum library.
3+
//
4+
// The go-ethereum library is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Lesser General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// The go-ethereum library is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Lesser General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Lesser General Public License
15+
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16+
17+
package misc
18+
19+
import (
20+
"errors"
21+
"fmt"
22+
"math/big"
23+
24+
"github.com/ethereum/go-ethereum/common"
25+
"github.com/ethereum/go-ethereum/core/types"
26+
"github.com/ethereum/go-ethereum/params"
27+
)
28+
29+
var (
30+
errInvalidBaseFee = errors.New("invalid BaseFee")
31+
errMissingParentBaseFee = errors.New("parent header is missing BaseFee")
32+
errMissingBaseFee = errors.New("current header is missing BaseFee")
33+
errHaveBaseFee = fmt.Errorf("BaseFee should not be set before block %d", params.EIP1559ForkBlockNumber)
34+
)
35+
36+
// VerifyEIP1559BaseFee verifies that the EIP1559 BaseFee field is valid for the current block height
37+
func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Header) error {
38+
if config.IsEIP1559(parent.Number) {
39+
if parent.BaseFee == nil {
40+
return errMissingParentBaseFee
41+
}
42+
}
43+
expectedBaseFee := CalcBaseFee(config, parent)
44+
if header.BaseFee == nil {
45+
if expectedBaseFee != nil {
46+
return errMissingBaseFee
47+
}
48+
return nil
49+
}
50+
if expectedBaseFee == nil {
51+
if header.BaseFee != nil {
52+
return errHaveBaseFee
53+
}
54+
return nil
55+
}
56+
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
57+
return errInvalidBaseFee
58+
}
59+
return nil
60+
}
61+
62+
// CalcBaseFee returns the baseFee for the current block provided the parent header and config parameters
63+
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
64+
height := new(big.Int).Add(parent.Number, common.Big1)
65+
// If we are before EIP1559 activation, the baseFee is nil
66+
if !config.IsEIP1559(height) {
67+
return nil
68+
}
69+
// If we are at the block of EIP1559 activation then the BaseFee is set to the initial value
70+
if config.EIP1559Block.Cmp(height) == 0 {
71+
return new(big.Int).SetUint64(config.EIP1559.InitialBaseFee)
72+
}
73+
74+
// Otherwise,
75+
// BASEFEE = PARENT_BASEFEE + PARENT_BASEFEE * delta // EIP1559_GAS_TARGET // BASEFEE_MAX_CHANGE_DENOMINATOR
76+
// Where delta = block.gas_used - EIP1559_GAS_TARGET
77+
parentGasTarget := CalcEIP1559GasTarget(config, parent.Number, new(big.Int).SetUint64(parent.GasLimit))
78+
delta := new(big.Int).Sub(new(big.Int).SetUint64(parent.GasUsed), parentGasTarget)
79+
mul := new(big.Int).Mul(parent.BaseFee, delta)
80+
div := new(big.Int).Div(mul, parentGasTarget)
81+
div2 := new(big.Int).Div(div, new(big.Int).SetUint64(config.EIP1559.EIP1559BaseFeeMaxChangeDenominator))
82+
83+
baseFee := new(big.Int).Add(parent.BaseFee, div2)
84+
85+
// A valid BASEFEE is one such that abs(BASEFEE - PARENT_BASEFEE) <= max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)
86+
diff := new(big.Int).Sub(baseFee, parent.BaseFee)
87+
neg := false
88+
if diff.Sign() < 0 {
89+
neg = true
90+
diff.Neg(diff)
91+
}
92+
max := new(big.Int).Div(parent.BaseFee, new(big.Int).SetUint64(config.EIP1559.EIP1559BaseFeeMaxChangeDenominator))
93+
if max.Cmp(common.Big1) < 0 {
94+
max = common.Big1
95+
}
96+
// If derived BaseFee is not valid, restrict it within the bounds
97+
if diff.Cmp(max) > 0 {
98+
if neg {
99+
max.Neg(max)
100+
}
101+
baseFee.Set(new(big.Int).Add(parent.BaseFee, max))
102+
}
103+
return baseFee
104+
}
105+
106+
// CalcEIP1559GasTarget returns the EIP1559GasTarget at the current height and header.GasLimit
107+
// This should only be called at or above the block height of EIP1559 activation and below finalization
108+
func CalcEIP1559GasTarget(chainConfig *params.ChainConfig, height, gasLimit *big.Int) *big.Int {
109+
// After EIP1559 finalization the entire header.GasLimit field instead represents the EIP1559GasTarget
110+
if chainConfig.IsEIP1559Finalized(height) {
111+
return gasLimit
112+
} else if chainConfig.IsEIP1559(height) {
113+
// During transition,
114+
// EIP1559GasTarget = (header.GasLimit/2) + (header.GasLimit/2) * (blockNumber-initBlockNumber) / migrationBlockDuration
115+
// migrationBlockDuration cannot be 0 or IsEIP1559Finalized would be true
116+
halfLim := new(big.Int).Div(gasLimit, big.NewInt(2))
117+
blockDiff := new(big.Int).Sub(height, chainConfig.EIP1559Block)
118+
migrationBlockDuration := new(big.Int).SetUint64(chainConfig.EIP1559.MigrationBlockDuration)
119+
return new(big.Int).Add(halfLim, new(big.Int).Div(new(big.Int).Mul(halfLim, blockDiff), migrationBlockDuration))
120+
}
121+
// Before EIP1559 activation the target is 0
122+
return big.NewInt(0)
123+
}

consensus/misc/forks.go

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,13 @@
1717
package misc
1818

1919
import (
20-
"errors"
2120
"fmt"
22-
"math/big"
2321

2422
"github.com/ethereum/go-ethereum/common"
2523
"github.com/ethereum/go-ethereum/core/types"
2624
"github.com/ethereum/go-ethereum/params"
2725
)
2826

29-
var (
30-
errInvalidInitialBaseFee = fmt.Errorf("initial BaseFee must equal %d", params.EIP1559InitialBaseFee)
31-
errInvalidBaseFee = errors.New("invalid BaseFee")
32-
errMissingParentBaseFee = errors.New("parent header is missing BaseFee")
33-
errMissingBaseFee = errors.New("current header is missing BaseFee")
34-
errHaveBaseFee = fmt.Errorf("BaseFee should not be set before block %d", params.EIP1559ForkBlockNumber)
35-
errInvalidEIP1559FinalizedGasLimit = fmt.Errorf("after EIP1559 finalization, GasLimit must equal %d", params.MaxGasEIP1559)
36-
)
37-
3827
// VerifyForkHashes verifies that blocks conforming to network hard-forks do have
3928
// the correct hashes, to avoid clients going off on different chains. This is an
4029
// optional feature.
@@ -52,73 +41,3 @@ func VerifyForkHashes(config *params.ChainConfig, header *types.Header, uncle bo
5241
// All ok, return
5342
return nil
5443
}
55-
56-
// VerifyEIP1559BaseFee verifies that the EIP1559 BaseFee field is valid for the current block height
57-
func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Header) error {
58-
// If we are at the EIP1559 fork block the BaseFee needs to be equal to params.EIP1559InitialBaseFee
59-
if config.EIP1559Block != nil && config.EIP1559Block.Cmp(header.Number) == 0 {
60-
if header.BaseFee == nil || header.BaseFee.Cmp(new(big.Int).SetUint64(config.EIP1559.InitialBaseFee)) != 0 {
61-
return errInvalidInitialBaseFee
62-
}
63-
return nil
64-
}
65-
// If we are past the EIP1559 activation block verify the header's BaseFee is valid by deriving
66-
// it from the parent header and validating that they are the same
67-
if config.IsEIP1559(header.Number) {
68-
if parent.BaseFee == nil {
69-
return errMissingParentBaseFee
70-
}
71-
if header.BaseFee == nil {
72-
return errMissingBaseFee
73-
}
74-
delta := new(big.Int).Sub(new(big.Int).SetUint64(parent.GasUsed), new(big.Int).SetUint64(config.EIP1559.TargetGasUsed))
75-
mul := new(big.Int).Mul(parent.BaseFee, delta)
76-
div := new(big.Int).Div(mul, new(big.Int).SetUint64(config.EIP1559.TargetGasUsed))
77-
div2 := new(big.Int).Div(div, new(big.Int).SetUint64(config.EIP1559.BaseFeeMaxChangeDenominator))
78-
expectedBaseFee := new(big.Int).Add(parent.BaseFee, div2)
79-
diff := new(big.Int).Sub(expectedBaseFee, parent.BaseFee)
80-
neg := false
81-
if diff.Sign() < 0 {
82-
neg = true
83-
diff.Neg(diff)
84-
}
85-
max := new(big.Int).Div(parent.BaseFee, new(big.Int).SetUint64(config.EIP1559.BaseFeeMaxChangeDenominator))
86-
if max.Cmp(common.Big1) < 0 {
87-
max = common.Big1
88-
}
89-
if diff.Cmp(max) > 0 {
90-
if neg {
91-
max.Neg(max)
92-
}
93-
expectedBaseFee.Set(new(big.Int).Add(parent.BaseFee, max))
94-
}
95-
if expectedBaseFee.Cmp(header.BaseFee) != 0 {
96-
return errInvalidBaseFee
97-
}
98-
return nil
99-
}
100-
// If we are before the EIP1559 activation block the current and parent BaseFees should be nil
101-
if header.BaseFee != nil || parent.BaseFee != nil {
102-
return errHaveBaseFee
103-
}
104-
return nil
105-
}
106-
107-
// VerifyEIP1559GasLimit verifies that the header.GasLimit field is valid for the current block height
108-
// Only call this after activation has been confirmed (config.IsEIP1559(header.Number) == true)
109-
func VerifyEIP1559GasLimit(config *params.ChainConfig, header *types.Header) error {
110-
// If EIP1559 has been finalized then header.GasLimit should be equal to the MaxGasEIP1559 (entire limit is in EIP1559 pool)
111-
if config.IsEIP1559Finalized(header.Number) {
112-
if header.GasLimit != config.EIP1559.MaxGas {
113-
return errInvalidEIP1559FinalizedGasLimit
114-
}
115-
return nil
116-
}
117-
// Else if we are between activation and finalization, header.GasLimit must be valid based on the decay function
118-
numOfIncrements := new(big.Int).Sub(header.Number, config.EIP1559Block).Uint64()
119-
expectedGasLimit := (config.EIP1559.MaxGas / 2) + (numOfIncrements * config.EIP1559.GasIncrementAmount)
120-
if header.GasLimit != expectedGasLimit {
121-
return fmt.Errorf("invalid GasLimit: have %d, need %d", header.GasLimit, expectedGasLimit)
122-
}
123-
return nil
124-
}

0 commit comments

Comments
 (0)