mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 13:46:43 +00:00
consensus/misc/eip4844: port to config2
This commit is contained in:
parent
cab21e0b0a
commit
9268b84142
2 changed files with 56 additions and 83 deletions
|
|
@ -20,9 +20,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/params/forks"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -32,7 +34,7 @@ var (
|
||||||
// VerifyEIP4844Header verifies the presence of the excessBlobGas field and that
|
// VerifyEIP4844Header verifies the presence of the excessBlobGas field and that
|
||||||
// if the current block contains no transactions, the excessBlobGas is updated
|
// if the current block contains no transactions, the excessBlobGas is updated
|
||||||
// accordingly.
|
// accordingly.
|
||||||
func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Header) error {
|
func VerifyEIP4844Header(config *params.Config2, parent, header *types.Header) error {
|
||||||
if header.Number.Uint64() != parent.Number.Uint64()+1 {
|
if header.Number.Uint64() != parent.Number.Uint64()+1 {
|
||||||
panic("bad header pair")
|
panic("bad header pair")
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +63,7 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade
|
||||||
|
|
||||||
// CalcExcessBlobGas calculates the excess blob gas after applying the set of
|
// CalcExcessBlobGas calculates the excess blob gas after applying the set of
|
||||||
// blobs on top of the excess blob gas.
|
// blobs on top of the excess blob gas.
|
||||||
func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTimestamp uint64) uint64 {
|
func CalcExcessBlobGas(config *params.Config2, parent *types.Header, headTimestamp uint64) uint64 {
|
||||||
var (
|
var (
|
||||||
parentExcessBlobGas uint64
|
parentExcessBlobGas uint64
|
||||||
parentBlobGasUsed uint64
|
parentBlobGasUsed uint64
|
||||||
|
|
@ -78,7 +80,7 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTim
|
||||||
if excessBlobGas < targetGas {
|
if excessBlobGas < targetGas {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
if !config.IsOsaka(config.LondonBlock, headTimestamp) {
|
if !config.Active(forks.Osaka, parent.Number.Uint64()+1, headTimestamp) {
|
||||||
// Pre-Osaka, we use the formula defined by EIP-4844.
|
// Pre-Osaka, we use the formula defined by EIP-4844.
|
||||||
return excessBlobGas - targetGas
|
return excessBlobGas - targetGas
|
||||||
}
|
}
|
||||||
|
|
@ -98,94 +100,53 @@ func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTim
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalcBlobFee calculates the blobfee from the header's excess blob gas field.
|
// CalcBlobFee calculates the blobfee from the header's excess blob gas field.
|
||||||
func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int {
|
func CalcBlobFee(config *params.Config2, header *types.Header) *big.Int {
|
||||||
blobConfig := latestBlobConfig(config, header.Time)
|
schedule := params.Get[params.BlobSchedule](config)
|
||||||
if blobConfig == nil {
|
if schedule == nil {
|
||||||
panic("calculating blob fee on unsupported fork")
|
return new(big.Int)
|
||||||
}
|
}
|
||||||
return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(*header.ExcessBlobGas), new(big.Int).SetUint64(blobConfig.UpdateFraction))
|
f := config.LatestFork(header.Time)
|
||||||
|
frac := schedule[f].UpdateFraction
|
||||||
|
return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(*header.ExcessBlobGas), new(big.Int).SetUint64(frac))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp.
|
// MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp.
|
||||||
func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
|
func MaxBlobsPerBlock(cfg *params.Config2, time uint64) int {
|
||||||
blobConfig := latestBlobConfig(cfg, time)
|
return scheduleAtTime(cfg, time).Max
|
||||||
if blobConfig == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return blobConfig.Max
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func latestBlobConfig(cfg *params.ChainConfig, time uint64) *params.BlobConfig {
|
// MaxBlobsPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp.
|
||||||
if cfg.BlobScheduleConfig == nil {
|
func MaxBlobGasPerBlock(cfg *params.Config2, time uint64) uint64 {
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
london = cfg.LondonBlock
|
|
||||||
s = cfg.BlobScheduleConfig
|
|
||||||
)
|
|
||||||
switch {
|
|
||||||
case cfg.IsBPO5(london, time) && s.BPO5 != nil:
|
|
||||||
return s.BPO5
|
|
||||||
case cfg.IsBPO4(london, time) && s.BPO4 != nil:
|
|
||||||
return s.BPO4
|
|
||||||
case cfg.IsBPO3(london, time) && s.BPO3 != nil:
|
|
||||||
return s.BPO3
|
|
||||||
case cfg.IsBPO2(london, time) && s.BPO2 != nil:
|
|
||||||
return s.BPO2
|
|
||||||
case cfg.IsBPO1(london, time) && s.BPO1 != nil:
|
|
||||||
return s.BPO1
|
|
||||||
case cfg.IsOsaka(london, time) && s.Osaka != nil:
|
|
||||||
return s.Osaka
|
|
||||||
case cfg.IsPrague(london, time) && s.Prague != nil:
|
|
||||||
return s.Prague
|
|
||||||
case cfg.IsCancun(london, time) && s.Cancun != nil:
|
|
||||||
return s.Cancun
|
|
||||||
default:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MaxBlobGasPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp.
|
|
||||||
func MaxBlobGasPerBlock(cfg *params.ChainConfig, time uint64) uint64 {
|
|
||||||
return uint64(MaxBlobsPerBlock(cfg, time)) * params.BlobTxBlobGasPerBlob
|
return uint64(MaxBlobsPerBlock(cfg, time)) * params.BlobTxBlobGasPerBlob
|
||||||
}
|
}
|
||||||
|
|
||||||
// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the
|
// LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the
|
||||||
// configuration, regardless of the currently active fork.
|
// configuration, regardless of the currently active fork.
|
||||||
func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int {
|
func LatestMaxBlobsPerBlock(cfg *params.Config2) int {
|
||||||
s := cfg.BlobScheduleConfig
|
schedule := params.Get[params.BlobSchedule](cfg)
|
||||||
if s == nil {
|
if schedule == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
switch {
|
for _, f := range slices.Backward(forks.CanonOrder) {
|
||||||
case s.BPO5 != nil:
|
if f.HasBlobs() && cfg.Scheduled(f) {
|
||||||
return s.BPO5.Max
|
return schedule[f].Max
|
||||||
case s.BPO4 != nil:
|
|
||||||
return s.BPO4.Max
|
|
||||||
case s.BPO3 != nil:
|
|
||||||
return s.BPO3.Max
|
|
||||||
case s.BPO2 != nil:
|
|
||||||
return s.BPO2.Max
|
|
||||||
case s.BPO1 != nil:
|
|
||||||
return s.BPO1.Max
|
|
||||||
case s.Osaka != nil:
|
|
||||||
return s.Osaka.Max
|
|
||||||
case s.Prague != nil:
|
|
||||||
return s.Prague.Max
|
|
||||||
case s.Cancun != nil:
|
|
||||||
return s.Cancun.Max
|
|
||||||
default:
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// targetBlobsPerBlock returns the target number of blobs in a block at the given timestamp.
|
// targetBlobsPerBlock returns the target number of blobs in a block at the given timestamp.
|
||||||
func targetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int {
|
func targetBlobsPerBlock(cfg *params.Config2, time uint64) int {
|
||||||
blobConfig := latestBlobConfig(cfg, time)
|
return scheduleAtTime(cfg, time).Target
|
||||||
if blobConfig == nil {
|
}
|
||||||
return 0
|
|
||||||
|
func scheduleAtTime(cfg *params.Config2, time uint64) params.BlobConfig {
|
||||||
|
schedule := params.Get[params.BlobSchedule](cfg)
|
||||||
|
if schedule == nil {
|
||||||
|
return params.BlobConfig{}
|
||||||
}
|
}
|
||||||
return blobConfig.Target
|
f := cfg.LatestFork(time)
|
||||||
|
return schedule[f]
|
||||||
}
|
}
|
||||||
|
|
||||||
// fakeExponential approximates factor * e ** (numerator / denominator) using
|
// fakeExponential approximates factor * e ** (numerator / denominator) using
|
||||||
|
|
@ -206,7 +167,7 @@ func fakeExponential(factor, numerator, denominator *big.Int) *big.Int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// calcBlobPrice calculates the blob price for a block.
|
// calcBlobPrice calculates the blob price for a block.
|
||||||
func calcBlobPrice(config *params.ChainConfig, header *types.Header) *big.Int {
|
func calcBlobPrice(config *params.Config2, header *types.Header) *big.Int {
|
||||||
blobBaseFee := CalcBlobFee(config, header)
|
blobBaseFee := CalcBlobFee(config, header)
|
||||||
return new(big.Int).Mul(blobBaseFee, big.NewInt(params.BlobTxBlobGasPerBlob))
|
return new(big.Int).Mul(blobBaseFee, big.NewInt(params.BlobTxBlobGasPerBlob))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,15 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/params/forks"
|
||||||
|
"github.com/ethereum/go-ethereum/params/presets"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCalcExcessBlobGas(t *testing.T) {
|
func TestCalcExcessBlobGas(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
config = params.MainnetChainConfig
|
config = presets.Mainnet
|
||||||
targetBlobs = targetBlobsPerBlock(config, *config.CancunTime)
|
cancunTime, _ = config.Activation(forks.Cancun)
|
||||||
|
targetBlobs = targetBlobsPerBlock(config, cancunTime)
|
||||||
targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
||||||
)
|
)
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
|
|
@ -58,10 +61,11 @@ func TestCalcExcessBlobGas(t *testing.T) {
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
blobGasUsed := uint64(tt.blobs) * params.BlobTxBlobGasPerBlob
|
blobGasUsed := uint64(tt.blobs) * params.BlobTxBlobGasPerBlob
|
||||||
header := &types.Header{
|
header := &types.Header{
|
||||||
|
Number: big.NewInt(1),
|
||||||
ExcessBlobGas: &tt.excess,
|
ExcessBlobGas: &tt.excess,
|
||||||
BlobGasUsed: &blobGasUsed,
|
BlobGasUsed: &blobGasUsed,
|
||||||
}
|
}
|
||||||
result := CalcExcessBlobGas(config, header, *config.CancunTime)
|
result := CalcExcessBlobGas(config, header, cancunTime)
|
||||||
if result != tt.want {
|
if result != tt.want {
|
||||||
t.Errorf("test %d: excess blob gas mismatch: have %v, want %v", i, result, tt.want)
|
t.Errorf("test %d: excess blob gas mismatch: have %v, want %v", i, result, tt.want)
|
||||||
}
|
}
|
||||||
|
|
@ -69,8 +73,6 @@ func TestCalcExcessBlobGas(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCalcBlobFee(t *testing.T) {
|
func TestCalcBlobFee(t *testing.T) {
|
||||||
zero := uint64(0)
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
excessBlobGas uint64
|
excessBlobGas uint64
|
||||||
blobfee int64
|
blobfee int64
|
||||||
|
|
@ -81,7 +83,15 @@ func TestCalcBlobFee(t *testing.T) {
|
||||||
{10 * 1024 * 1024, 23},
|
{10 * 1024 * 1024, 23},
|
||||||
}
|
}
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
config := ¶ms.ChainConfig{LondonBlock: big.NewInt(0), CancunTime: &zero, BlobScheduleConfig: params.DefaultBlobSchedule}
|
config := params.NewConfig2(
|
||||||
|
params.Activations{
|
||||||
|
forks.London: 0,
|
||||||
|
forks.Cancun: 0,
|
||||||
|
},
|
||||||
|
params.BlobSchedule{
|
||||||
|
forks.Cancun: *params.DefaultCancunBlobConfig,
|
||||||
|
},
|
||||||
|
)
|
||||||
header := &types.Header{ExcessBlobGas: &tt.excessBlobGas}
|
header := &types.Header{ExcessBlobGas: &tt.excessBlobGas}
|
||||||
have := CalcBlobFee(config, header)
|
have := CalcBlobFee(config, header)
|
||||||
if have.Int64() != tt.blobfee {
|
if have.Int64() != tt.blobfee {
|
||||||
|
|
@ -130,13 +140,15 @@ func TestFakeExponential(t *testing.T) {
|
||||||
|
|
||||||
func TestCalcExcessBlobGasEIP7918(t *testing.T) {
|
func TestCalcExcessBlobGasEIP7918(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
cfg = params.MergedTestChainConfig
|
cfg = presets.MergedTestChainConfig
|
||||||
targetBlobs = targetBlobsPerBlock(cfg, *cfg.CancunTime)
|
cancunTime, _ = cfg.Activation(forks.Cancun)
|
||||||
|
targetBlobs = targetBlobsPerBlock(cfg, cancunTime)
|
||||||
blobGasTarget = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
blobGasTarget = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob
|
||||||
)
|
)
|
||||||
makeHeader := func(parentExcess, parentBaseFee uint64, blobsUsed int) *types.Header {
|
makeHeader := func(parentExcess, parentBaseFee uint64, blobsUsed int) *types.Header {
|
||||||
blobGasUsed := uint64(blobsUsed) * params.BlobTxBlobGasPerBlob
|
blobGasUsed := uint64(blobsUsed) * params.BlobTxBlobGasPerBlob
|
||||||
return &types.Header{
|
return &types.Header{
|
||||||
|
Number: big.NewInt(1),
|
||||||
BaseFee: big.NewInt(int64(parentBaseFee)),
|
BaseFee: big.NewInt(int64(parentBaseFee)),
|
||||||
ExcessBlobGas: &parentExcess,
|
ExcessBlobGas: &parentExcess,
|
||||||
BlobGasUsed: &blobGasUsed,
|
BlobGasUsed: &blobGasUsed,
|
||||||
|
|
@ -160,7 +172,7 @@ func TestCalcExcessBlobGasEIP7918(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
got := CalcExcessBlobGas(cfg, tc.header, *cfg.CancunTime)
|
got := CalcExcessBlobGas(cfg, tc.header, cancunTime)
|
||||||
if got != tc.wantExcessGas {
|
if got != tc.wantExcessGas {
|
||||||
t.Fatalf("%s: excess-blob-gas mismatch – have %d, want %d",
|
t.Fatalf("%s: excess-blob-gas mismatch – have %d, want %d",
|
||||||
tc.name, got, tc.wantExcessGas)
|
tc.name, got, tc.wantExcessGas)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue