@@ -21,6 +21,7 @@ import (
21
21
"math/big"
22
22
23
23
"github.com/ethereum/go-ethereum/common"
24
+ "github.com/ethereum/go-ethereum/common/math"
24
25
"github.com/ethereum/go-ethereum/core/types"
25
26
"github.com/ethereum/go-ethereum/params"
26
27
)
@@ -59,66 +60,55 @@ func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Head
59
60
}
60
61
61
62
// CalcBaseFee returns the baseFee for the current block provided the parent header and config parameters
62
- func CalcBaseFee (config * params.ChainConfig , parent * types.Header ) ( baseFee * big.Int ) {
63
+ func CalcBaseFee (config * params.ChainConfig , parent * types.Header ) * big.Int {
63
64
height := new (big.Int ).Add (parent .Number , common .Big1 )
65
+
64
66
// If we are before EIP1559 activation, the baseFee is nil
65
67
if ! config .IsEIP1559 (height ) {
66
- return
68
+ return nil
67
69
}
68
- // never let baseFee drop below 0
69
- defer func () {
70
- if baseFee .Cmp (common .Big0 ) < 0 {
71
- baseFee .Set (common .Big0 )
72
- }
73
- }()
70
+
74
71
// If we are at the block of EIP1559 activation then the BaseFee is set to the initial value
75
72
if config .EIP1559Block .Cmp (height ) == 0 {
76
- baseFee = new (big.Int ).SetUint64 (config .EIP1559 .InitialBaseFee )
77
- return
73
+ return new (big.Int ).SetUint64 (config .EIP1559 .InitialBaseFee )
78
74
}
79
75
80
- // Otherwise,
81
- // BASEFEE = PARENT_BASEFEE + PARENT_BASEFEE * delta // PARENT_EIP1559_GAS_TARGET // BASEFEE_MAX_CHANGE_DENOMINATOR
82
- // Where delta = PARENT_GAS_USED - PARENT_EIP1559_GAS_TARGET (possibly negative)
83
- parentGasTarget := CalcEIP1559GasTarget (config , parent .Number , new (big.Int ).SetUint64 (parent .GasLimit ))
84
- delta := new (big.Int ).Sub (new (big.Int ).SetUint64 (parent .GasUsed ), parentGasTarget )
85
- // If PARENT_GAS_USAGE == TARGET_GAS_USAGE; BASEFEE = PARENT_BASEFEE - 1
86
- if delta .Cmp (common .Big0 ) == 0 {
87
- baseFee = new (big.Int ).Sub (parent .BaseFee , common .Big1 )
88
- return
89
- }
90
- mul := new (big.Int ).Mul (parent .BaseFee , delta )
91
- div := new (big.Int ).Div (mul , parentGasTarget )
92
- div2 := new (big.Int ).Div (div , new (big.Int ).SetUint64 (config .EIP1559 .EIP1559BaseFeeMaxChangeDenominator ))
93
- baseFee = new (big.Int ).Add (parent .BaseFee , div2 )
76
+ parentBaseFee := parent .BaseFee
77
+ parentBlockGasUsed := new (big.Int ).SetUint64 (parent .GasUsed )
78
+ targetGasUsed := new (big.Int ).SetUint64 (parent .GasLimit )
79
+ baseFeeMaxChangeDenominator := new (big.Int ).SetUint64 (config .EIP1559 .EIP1559BaseFeeMaxChangeDenominator )
94
80
95
- // A valid BASEFEE is one such that
96
- // abs(BASEFEE - PARENT_BASEFEE) <= max(1, PARENT_BASEFEE // BASEFEE_MAX_CHANGE_DENOMINATOR)
97
- // abs(BASEFEE - PARENT_BASEFEE) >= 1
98
- diff := new (big.Int ).Sub (baseFee , parent .BaseFee )
99
- neg := false
100
- if diff .Sign () < 0 {
101
- neg = true
102
- diff .Neg (diff )
103
- }
104
- min := common .Big1
105
- max := new (big.Int ).Div (parent .BaseFee , new (big.Int ).SetUint64 (config .EIP1559 .EIP1559BaseFeeMaxChangeDenominator ))
106
- if max .Cmp (common .Big1 ) < 0 {
107
- max = common .Big1
81
+ cmp := parentBlockGasUsed .Cmp (targetGasUsed )
82
+
83
+ if cmp == 0 {
84
+ return targetGasUsed
108
85
}
109
- // If BASEFEE is not valid, restrict it within the bounds
110
- if diff .Cmp (max ) > 0 {
111
- if neg {
112
- max .Neg (max )
113
- }
114
- baseFee .Set (new (big.Int ).Add (parent .BaseFee , max ))
115
- } else if diff .Cmp (min ) < 0 {
116
- if neg {
117
- min .Neg (min )
118
- }
119
- baseFee .Set (new (big.Int ).Add (parent .BaseFee , min ))
86
+
87
+ if cmp > 0 {
88
+ gasDelta := new (big.Int ).Sub (parentBlockGasUsed , targetGasUsed )
89
+ feeDelta := math .BigMax (
90
+ new (big.Int ).Div (
91
+ new (big.Int ).Div (
92
+ new (big.Int ).Mul (parentBaseFee , gasDelta ),
93
+ targetGasUsed ,
94
+ ),
95
+ baseFeeMaxChangeDenominator ,
96
+ ),
97
+ common .Big1 ,
98
+ )
99
+ return new (big.Int ).Add (parentBaseFee , feeDelta )
120
100
}
121
- return baseFee
101
+
102
+ gasDelta := new (big.Int ).Sub (targetGasUsed , parentBlockGasUsed )
103
+ feeDelta := new (big.Int ).Div (
104
+ new (big.Int ).Div (
105
+ new (big.Int ).Mul (parentBaseFee , gasDelta ),
106
+ targetGasUsed ,
107
+ ),
108
+ baseFeeMaxChangeDenominator ,
109
+ )
110
+
111
+ return new (big.Int ).Sub (parentBaseFee , feeDelta )
122
112
}
123
113
124
114
// CalcEIP1559GasTarget returns the EIP1559GasTarget at the current height and header.GasLimit
0 commit comments