Skip to content

Commit

Permalink
Change EIP 1559 Denominator with Canyon (bnb-chain#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
trianglesphere authored Oct 24, 2023
1 parent 5023660 commit 29cd9a3
Show file tree
Hide file tree
Showing 14 changed files with 75 additions and 22 deletions.
2 changes: 1 addition & 1 deletion cmd/evm/internal/t8ntool/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error {
BaseFee: env.ParentBaseFee,
GasUsed: env.ParentGasUsed,
GasLimit: env.ParentGasLimit,
})
}, env.Timestamp)
return nil
}

Expand Down
9 changes: 5 additions & 4 deletions consensus/misc/eip1559/eip1559.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
return errors.New("header is missing baseFee")
}
// Verify the baseFee is correct based on the parent header.
expectedBaseFee := CalcBaseFee(config, parent)
expectedBaseFee := CalcBaseFee(config, parent, header.Time)
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d",
header.BaseFee, expectedBaseFee, parent.BaseFee, parent.GasUsed)
Expand All @@ -56,7 +56,8 @@ func VerifyEIP1559Header(config *params.ChainConfig, parent, header *types.Heade
}

// CalcBaseFee calculates the basefee of the header.
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
// The time belongs to the new block to check if Canyon is activted or not
func CalcBaseFee(config *params.ChainConfig, parent *types.Header, time uint64) *big.Int {
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
if !config.IsLondon(parent.Number) {
return new(big.Int).SetUint64(params.InitialBaseFee)
Expand All @@ -79,7 +80,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(config.BaseFeeChangeDenominator()))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator(time)))
baseFeeDelta := math.BigMax(num, common.Big1)

return num.Add(parent.BaseFee, baseFeeDelta)
Expand All @@ -89,7 +90,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(config.BaseFeeChangeDenominator()))
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator(time)))
baseFee := num.Sub(parent.BaseFee, num)

return math.BigMax(baseFee, common.Big0)
Expand Down
48 changes: 47 additions & 1 deletion consensus/misc/eip1559/eip1559_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ func config() *params.ChainConfig {
return config
}

func opConfig() *params.ChainConfig {
config := copyConfig(params.TestChainConfig)
config.LondonBlock = big.NewInt(5)
ct := uint64(10)
config.CanyonTime = &ct
config.Optimism = &params.OptimismConfig{
EIP1559Elasticity: 6,
EIP1559Denominator: 50,
EIP1559DenominatorPostCanyon: 250,
}
return config
}

// TestBlockGasLimits tests the gasLimit checks for blocks both across
// the EIP-1559 boundary and post-1559 blocks
func TestBlockGasLimits(t *testing.T) {
Expand Down Expand Up @@ -124,7 +137,40 @@ func TestCalcBaseFee(t *testing.T) {
GasUsed: test.parentGasUsed,
BaseFee: big.NewInt(test.parentBaseFee),
}
if have, want := CalcBaseFee(config(), parent), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
if have, want := CalcBaseFee(config(), parent, 0), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
t.Errorf("test %d: have %d want %d, ", i, have, want)
}
}
}

// TestCalcBaseFeeOptimism assumes all blocks are 1559-blocks but tests the Canyon activation
func TestCalcBaseFeeOptimism(t *testing.T) {
tests := []struct {
parentBaseFee int64
parentGasLimit uint64
parentGasUsed uint64
expectedBaseFee int64
postCanyon bool
}{
{params.InitialBaseFee, 30_000_000, 5_000_000, params.InitialBaseFee, false}, // usage == target
{params.InitialBaseFee, 30_000_000, 4_000_000, 996000000, false}, // usage below target
{params.InitialBaseFee, 30_000_000, 10_000_000, 1020000000, false}, // usage above target
{params.InitialBaseFee, 30_000_000, 5_000_000, params.InitialBaseFee, true}, // usage == target
{params.InitialBaseFee, 30_000_000, 4_000_000, 999200000, true}, // usage below target
{params.InitialBaseFee, 30_000_000, 10_000_000, 1004000000, true}, // usage above target
}
for i, test := range tests {
parent := &types.Header{
Number: common.Big32,
GasLimit: test.parentGasLimit,
GasUsed: test.parentGasUsed,
BaseFee: big.NewInt(test.parentBaseFee),
Time: 6,
}
if test.postCanyon {
parent.Time = 8
}
if have, want := CalcBaseFee(opConfig(), parent, parent.Time+2), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
t.Errorf("test %d: have %d want %d, ", i, have, want)
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func (b *BlockGen) AddUncle(h *types.Header) {
// The gas limit and price should be derived from the parent
h.GasLimit = parent.GasLimit
if b.config.IsLondon(h.Number) {
h.BaseFee = eip1559.CalcBaseFee(b.config, parent)
h.BaseFee = eip1559.CalcBaseFee(b.config, parent, h.Time)
if !b.config.IsLondon(parent.Number) {
parentGasLimit := parent.GasLimit * b.config.ElasticityMultiplier()
h.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
Expand Down Expand Up @@ -391,7 +391,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
Time: time,
}
if chain.Config().IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(chain.Config(), parent.Header())
header.BaseFee = eip1559.CalcBaseFee(chain.Config(), parent.Header(), header.Time)
if !chain.Config().IsLondon(parent.Number()) {
parentGasLimit := parent.GasLimit() * chain.Config().ElasticityMultiplier()
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
Expand Down
2 changes: 1 addition & 1 deletion core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr
UncleHash: types.EmptyUncleHash,
}
if config.IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(config, parent.Header())
header.BaseFee = eip1559.CalcBaseFee(config, parent.Header(), header.Time)
}
if config.IsShanghai(header.Number, header.Time) {
header.WithdrawalsHash = &types.EmptyWithdrawalsHash
Expand Down
4 changes: 2 additions & 2 deletions core/txpool/blobpool/blobpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ func (p *BlobPool) Init(gasTip *big.Int, head *types.Header, reserve txpool.Addr
p.recheck(addr, nil)
}
var (
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head))
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head, p.head.Time+1))
blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice))
)
if p.head.ExcessBlobGas != nil {
Expand Down Expand Up @@ -782,7 +782,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) {
}
// Reset the price heap for the new set of basefee/blobfee pairs
var (
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead))
basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), newHead, newHead.Time+1))
blobfee = uint256.MustFromBig(big.NewInt(params.BlobTxMinBlobGasprice))
)
if newHead.ExcessBlobGas != nil {
Expand Down
2 changes: 1 addition & 1 deletion core/txpool/blobpool/blobpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header {
GasLimit: gasLimit,
GasUsed: 0,
BaseFee: mid,
}).Cmp(bc.basefee.ToBig()) > 0 {
}, blockTime).Cmp(bc.basefee.ToBig()) > 0 {
hi = mid
} else {
lo = mid
Expand Down
2 changes: 1 addition & 1 deletion core/txpool/legacypool/legacypool.go
Original file line number Diff line number Diff line change
Expand Up @@ -1317,7 +1317,7 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest,
pool.demoteUnexecutables()
if reset.newHead != nil {
if pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) {
pendingBaseFee := eip1559.CalcBaseFee(pool.chainconfig, reset.newHead)
pendingBaseFee := eip1559.CalcBaseFee(pool.chainconfig, reset.newHead, reset.newHead.Time+1)
pool.priced.SetBaseFee(pendingBaseFee)
} else {
pool.priced.Reheap()
Expand Down
2 changes: 1 addition & 1 deletion eth/gasprice/feehistory.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) {
bf.results.baseFee = new(big.Int)
}
if chainconfig.IsLondon(big.NewInt(int64(bf.blockNumber + 1))) {
bf.results.nextBaseFee = eip1559.CalcBaseFee(chainconfig, bf.header)
bf.results.nextBaseFee = eip1559.CalcBaseFee(chainconfig, bf.header, bf.header.Time+1)
} else {
bf.results.nextBaseFee = new(big.Int)
}
Expand Down
2 changes: 1 addition & 1 deletion graphql/graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ func (b *Block) NextBaseFeePerGas(ctx context.Context) (*hexutil.Big, error) {
return nil, nil
}
}
nextBaseFee := eip1559.CalcBaseFee(chaincfg, header)
nextBaseFee := eip1559.CalcBaseFee(chaincfg, header, header.Time+1)
return (*hexutil.Big)(nextBaseFee), nil
}

Expand Down
2 changes: 1 addition & 1 deletion internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1690,7 +1690,7 @@ func NewRPCPendingTransaction(tx *types.Transaction, current *types.Header, conf
blockTime = uint64(0)
)
if current != nil {
baseFee = eip1559.CalcBaseFee(config, current)
baseFee = eip1559.CalcBaseFee(config, current, current.Time+1)
blockNumber = current.Number.Uint64()
blockTime = current.Time
}
Expand Down
2 changes: 1 addition & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ func (w *worker) prepareWork(genParams *generateParams) (*environment, error) {
}
// Set baseFee and GasLimit if we are on an EIP-1559 chain
if w.chainConfig.IsLondon(header.Number) {
header.BaseFee = eip1559.CalcBaseFee(w.chainConfig, parent)
header.BaseFee = eip1559.CalcBaseFee(w.chainConfig, parent, header.Time)
if !w.chainConfig.IsLondon(parent.Number) {
parentGasLimit := parent.GasLimit * w.chainConfig.ElasticityMultiplier()
header.GasLimit = core.CalcGasLimit(parentGasLimit, w.config.GasCeil)
Expand Down
11 changes: 8 additions & 3 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,9 @@ func (c *CliqueConfig) String() string {

// OptimismConfig is the optimism config.
type OptimismConfig struct {
EIP1559Elasticity uint64 `json:"eip1559Elasticity"`
EIP1559Denominator uint64 `json:"eip1559Denominator"`
EIP1559Elasticity uint64 `json:"eip1559Elasticity"`
EIP1559Denominator uint64 `json:"eip1559Denominator"`
EIP1559DenominatorPostCanyon uint64 `json:"eip1559DenominatorPostCanyon"`
}

// String implements the stringer interface, returning the optimism fee config details.
Expand Down Expand Up @@ -802,8 +803,12 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int,
}

// BaseFeeChangeDenominator bounds the amount the base fee can change between blocks.
func (c *ChainConfig) BaseFeeChangeDenominator() uint64 {
// The time parameters is the timestamp of the block to determine if Canyon is active or not
func (c *ChainConfig) BaseFeeChangeDenominator(time uint64) uint64 {
if c.Optimism != nil {
if c.IsCanyon(time) {
return c.Optimism.EIP1559DenominatorPostCanyon
}
return c.Optimism.EIP1559Denominator
}
return DefaultBaseFeeChangeDenominator
Expand Down
5 changes: 3 additions & 2 deletions params/superchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ func LoadOPStackChainConfig(chainID uint64) (*ChainConfig, error) {
Ethash: nil,
Clique: nil,
Optimism: &OptimismConfig{
EIP1559Elasticity: 6,
EIP1559Denominator: 50,
EIP1559Elasticity: 6,
EIP1559Denominator: 50,
EIP1559DenominatorPostCanyon: 250,
},
}

Expand Down

0 comments on commit 29cd9a3

Please sign in to comment.