@@ -21,6 +21,7 @@ import (
2121 "math/big"
2222
2323 "github.com/ethereum/go-ethereum/common"
24+ "github.com/ethereum/go-ethereum/common/math"
2425 "github.com/ethereum/go-ethereum/core/types"
2526 "github.com/ethereum/go-ethereum/params"
2627)
@@ -59,66 +60,55 @@ func VerifyEIP1559BaseFee(config *params.ChainConfig, header, parent *types.Head
5960}
6061
6162// 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 {
6364 height := new (big.Int ).Add (parent .Number , common .Big1 )
65+
6466 // If we are before EIP1559 activation, the baseFee is nil
6567 if ! config .IsEIP1559 (height ) {
66- return
68+ return nil
6769 }
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+
7471 // If we are at the block of EIP1559 activation then the BaseFee is set to the initial value
7572 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 )
7874 }
7975
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 )
9480
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
10885 }
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 )
120100 }
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 )
122112}
123113
124114// CalcEIP1559GasTarget returns the EIP1559GasTarget at the current height and header.GasLimit
0 commit comments