Skip to content

Commit 9ce143a

Browse files
committed
Make excess_blobs Header field optional
In order to be backwards compatible with prior forks, the excess_blobs field must not be set until we're on an EIP-4844 compatible fork. This patch also fixes several bugs and now we're passing all tests.
1 parent ede1eaa commit 9ce143a

File tree

22 files changed

+271
-79
lines changed

22 files changed

+271
-79
lines changed

cmd/evm/internal/t8ntool/block.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type header struct {
5454
MixDigest common.Hash `json:"mixHash"`
5555
Nonce *types.BlockNonce `json:"nonce"`
5656
BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
57-
ExcessBlobs uint64 `json:"excessBlobs" rlp:"optional"`
57+
ExcessBlobs *uint64 `json:"excessBlobs" rlp:"optional"`
5858
}
5959

6060
type headerMarshaling struct {

cmd/evm/internal/t8ntool/gen_header.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

consensus/beacon/consensus.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,19 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa
262262
if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(common.Big1) != 0 {
263263
return consensus.ErrInvalidNumber
264264
}
265-
// Verify the header's EIP-1559 attributes.
266-
return misc.VerifyEip1559Header(chain.Config(), parent, header)
265+
if chain.Config().IsLondon(header.Number) {
266+
// Verify the header's EIP-1559 attributes.
267+
if err := misc.VerifyEip1559Header(chain.Config(), parent, header); err != nil {
268+
return err
269+
}
270+
}
271+
if chain.Config().IsSharding(header.Number) {
272+
// Verify the header's EIP-4844 attributes.
273+
if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil {
274+
return err
275+
}
276+
}
277+
return nil
267278
}
268279

269280
// verifyHeaders is similar to verifyHeader, but verifies a batch of headers
@@ -332,8 +343,10 @@ func (beacon *Beacon) Finalize(chain consensus.ChainHeaderReader, header *types.
332343
// The block reward is no longer handled here. It's done by the
333344
// external consensus engine.
334345
header.Root = state.IntermediateRoot(true)
335-
if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil {
336-
header.ExcessBlobs = misc.CalcExcessBlobTransactions(parent, uint64(misc.CountBlobs(txs)))
346+
if chain.Config().IsSharding(header.Number) {
347+
if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil {
348+
header.SetExcessBlobs(misc.CalcExcessBlobTransactions(parent, uint64(misc.CountBlobs(txs))))
349+
}
337350
}
338351
}
339352

consensus/clique/clique.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,14 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
345345
// Verify the header's EIP-1559 attributes.
346346
return err
347347
}
348+
if !chain.Config().IsSharding(header.Number) {
349+
if header.ExcessBlobs != nil {
350+
return fmt.Errorf("invalid excessBlobs before fork: have %d, want <nil>", *header.ExcessBlobs)
351+
}
352+
} else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil {
353+
// Verify the header's EIP-4844 attributes.
354+
return err
355+
}
348356
// Retrieve the snapshot needed to verify this header and cache it
349357
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
350358
if err != nil {
@@ -568,8 +576,10 @@ func (c *Clique) Finalize(chain consensus.ChainHeaderReader, header *types.Heade
568576
// No block rewards in PoA, so the state remains as is and uncles are dropped
569577
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
570578
header.UncleHash = types.CalcUncleHash(nil)
571-
if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil {
572-
header.ExcessBlobs = misc.CalcExcessBlobTransactions(parent, uint64(misc.CountBlobs(txs)))
579+
if chain.Config().IsSharding(header.Number) {
580+
if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil {
581+
header.SetExcessBlobs(misc.CalcExcessBlobTransactions(parent, uint64(misc.CountBlobs(txs))))
582+
}
573583
}
574584
}
575585

@@ -746,7 +756,9 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
746756
if header.BaseFee != nil {
747757
enc = append(enc, header.BaseFee)
748758
}
749-
enc = append(enc, header.ExcessBlobs)
759+
if header.ExcessBlobs != nil {
760+
enc = append(enc, header.ExcessBlobs)
761+
}
750762
if err := rlp.Encode(w, enc); err != nil {
751763
panic("can't encode: " + err.Error())
752764
}

consensus/ethash/consensus.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,14 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
306306
// Verify the header's EIP-1559 attributes.
307307
return err
308308
}
309+
if !chain.Config().IsSharding(header.Number) {
310+
if header.ExcessBlobs != nil {
311+
return fmt.Errorf("invalid excessBlobs before fork: have %d, expected 'nil'", *header.ExcessBlobs)
312+
}
313+
} else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil {
314+
// Verify the header's EIP-4844 attributes.
315+
return err
316+
}
309317
// Verify that the block number is parent's +1
310318
if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 {
311319
return consensus.ErrInvalidNumber
@@ -601,8 +609,10 @@ func (ethash *Ethash) Finalize(chain consensus.ChainHeaderReader, header *types.
601609
// Accumulate any block and uncle rewards and commit the final state root
602610
accumulateRewards(chain.Config(), state, header, uncles)
603611
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
604-
if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil {
605-
header.ExcessBlobs = misc.CalcExcessBlobTransactions(parent, uint64(misc.CountBlobs(txs)))
612+
if chain.Config().IsSharding(header.Number) {
613+
if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil {
614+
header.SetExcessBlobs(misc.CalcExcessBlobTransactions(parent, uint64(misc.CountBlobs(txs))))
615+
}
606616
}
607617
}
608618

@@ -638,7 +648,9 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash common.Hash) {
638648
if header.BaseFee != nil {
639649
enc = append(enc, header.BaseFee)
640650
}
641-
enc = append(enc, header.ExcessBlobs)
651+
if header.ExcessBlobs != nil {
652+
enc = append(enc, header.ExcessBlobs)
653+
}
642654
rlp.Encode(hasher, enc)
643655
hasher.Sum(hash[:0])
644656
return hash

consensus/misc/eip4844.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package misc
1818

1919
import (
20+
"fmt"
2021
"math"
2122

2223
"github.com/ethereum/go-ethereum/core/types"
@@ -25,7 +26,11 @@ import (
2526

2627
// CalcExcessBlobTransactions calculates the number of blobs above the target
2728
func CalcExcessBlobTransactions(parent *types.Header, blobs uint64) uint64 {
28-
adjusted := parent.ExcessBlobs + blobs
29+
var excessBlobs uint64
30+
if parent.ExcessBlobs != nil {
31+
excessBlobs = *parent.ExcessBlobs
32+
}
33+
adjusted := excessBlobs + blobs
2934
if adjusted < params.TargetBlobsPerBlock {
3035
return 0
3136
}
@@ -40,10 +45,19 @@ func FakeExponential(num uint64, denom uint64) uint64 {
4045
(uint64(math.Pow(float64(fractional), 2))*cofactor)/denom)/(denom*3)
4146
}
4247

48+
// CountBlobs returns the number of blob transactions in txs
4349
func CountBlobs(txs []*types.Transaction) int {
4450
var count int
4551
for _, tx := range txs {
4652
count += len(tx.DataHashes())
4753
}
4854
return count
4955
}
56+
57+
// VerifyEip4844Header verifies that the header is not malformed
58+
func VerifyEip4844Header(config *params.ChainConfig, parent, header *types.Header) error {
59+
if header.ExcessBlobs == nil {
60+
return fmt.Errorf("header is missing excessBlobs")
61+
}
62+
return nil
63+
}

core/beacon/gen_ed.go

Lines changed: 6 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/beacon/types.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@ type ExecutableDataV1 struct {
6565
Timestamp uint64 `json:"timestamp" gencodec:"required"`
6666
ExtraData []byte `json:"extraData" gencodec:"required"`
6767
BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"`
68-
ExcessBlobs uint64 `json:"excessBlobs" gencodec:"required"`
6968
BlockHash common.Hash `json:"blockHash" gencodec:"required"`
7069
Transactions [][]byte `json:"transactions" gencodec:"required"`
70+
71+
// New in EIP-4844
72+
ExcessBlobs *uint64 `json:"excessBlobs" gencodec:"optional"`
7173
}
7274

7375
// JSON type overrides for executableData.
@@ -77,7 +79,7 @@ type executableDataMarshaling struct {
7779
GasUsed hexutil.Uint64
7880
Timestamp hexutil.Uint64
7981
BaseFeePerGas *hexutil.Big
80-
ExcessBlobs hexutil.Uint64
82+
ExcessBlobs *hexutil.Uint64
8183
ExtraData hexutil.Bytes
8284
LogsBloom hexutil.Bytes
8385
Transactions []hexutil.Bytes

core/blockchain_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3913,6 +3913,7 @@ func TestDataBlobTxs(t *testing.T) {
39133913

39143914
blocks, _ := GenerateChain(gspec.Config, genesis, engine, db, 1, func(i int, b *BlockGen) {
39153915
b.SetCoinbase(common.Address{1})
3916+
b.SetExcessBlobs(0)
39163917
msg := types.BlobTxMessage{
39173918
Nonce: 0,
39183919
Gas: 500000,
@@ -3950,4 +3951,3 @@ func TestDataBlobTxs(t *testing.T) {
39503951
t.Fatalf("incorrect data hash written to state (want: %s, got: %s)", two, actual)
39513952
}
39523953
}
3953-

core/chain_makers.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ func (b *BlockGen) SetDifficulty(diff *big.Int) {
7878
b.header.Difficulty = diff
7979
}
8080

81+
// SetExcessBlobs sets the excess_blobs field of the generated block.
82+
func (b *BlockGen) SetExcessBlobs(excessBlobs uint64) {
83+
b.header.SetExcessBlobs(excessBlobs)
84+
}
85+
8186
// AddTx adds a transaction to the generated block. If no coinbase has
8287
// been set, the block's coinbase is set to the zero address.
8388
//
@@ -135,6 +140,15 @@ func (b *BlockGen) BaseFee() *big.Int {
135140
return new(big.Int).Set(b.header.BaseFee)
136141
}
137142

143+
// ExcessBlobs returns the EIP-4844 excess blobs of the block being generated.
144+
func (b *BlockGen) ExcessBlobs() *uint64 {
145+
v := new(uint64)
146+
if b.header.ExcessBlobs != nil {
147+
*v = *b.header.ExcessBlobs
148+
}
149+
return v
150+
}
151+
138152
// AddUncheckedReceipt forcefully adds a receipts to the block without a
139153
// backing transaction.
140154
//

0 commit comments

Comments
 (0)