Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change EIP 1559 Denominator with Canyon #165

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1696,7 +1696,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