Skip to content

Commit ff32de1

Browse files
add header & block fields for Withdrawals
1 parent 6c556bd commit ff32de1

File tree

9 files changed

+356
-121
lines changed

9 files changed

+356
-121
lines changed

cmd/evm/internal/t8ntool/block.go

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,24 @@ import (
3838

3939
//go:generate go run github.com/fjl/gencodec -type header -field-override headerMarshaling -out gen_header.go
4040
type header struct {
41-
ParentHash common.Hash `json:"parentHash"`
42-
OmmerHash *common.Hash `json:"sha3Uncles"`
43-
Coinbase *common.Address `json:"miner"`
44-
Root common.Hash `json:"stateRoot" gencodec:"required"`
45-
TxHash *common.Hash `json:"transactionsRoot"`
46-
ReceiptHash *common.Hash `json:"receiptsRoot"`
47-
Bloom types.Bloom `json:"logsBloom"`
48-
Difficulty *big.Int `json:"difficulty"`
49-
Number *big.Int `json:"number" gencodec:"required"`
50-
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
51-
GasUsed uint64 `json:"gasUsed"`
52-
Time uint64 `json:"timestamp" gencodec:"required"`
53-
Extra []byte `json:"extraData"`
54-
MixDigest common.Hash `json:"mixHash"`
55-
Nonce *types.BlockNonce `json:"nonce"`
56-
BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
57-
ExcessDataGas *big.Int `json:"excessDataGas" rlp:"optional"`
41+
ParentHash common.Hash `json:"parentHash"`
42+
OmmerHash *common.Hash `json:"sha3Uncles"`
43+
Coinbase *common.Address `json:"miner"`
44+
Root common.Hash `json:"stateRoot" gencodec:"required"`
45+
TxHash *common.Hash `json:"transactionsRoot"`
46+
ReceiptHash *common.Hash `json:"receiptsRoot"`
47+
Bloom types.Bloom `json:"logsBloom"`
48+
Difficulty *big.Int `json:"difficulty"`
49+
Number *big.Int `json:"number" gencodec:"required"`
50+
GasLimit uint64 `json:"gasLimit" gencodec:"required"`
51+
GasUsed uint64 `json:"gasUsed"`
52+
Time uint64 `json:"timestamp" gencodec:"required"`
53+
Extra []byte `json:"extraData"`
54+
MixDigest common.Hash `json:"mixHash"`
55+
Nonce *types.BlockNonce `json:"nonce"`
56+
BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
57+
WithdrawalsHash *common.Hash `json:"withdrawalsRoog" rlp:"optional"`
58+
ExcessDataGas *big.Int `json:"excessDataGas" rlp:"optional"`
5859
}
5960

6061
type headerMarshaling struct {
@@ -68,10 +69,11 @@ type headerMarshaling struct {
6869
}
6970

7071
type bbInput struct {
71-
Header *header `json:"header,omitempty"`
72-
OmmersRlp []string `json:"ommers,omitempty"`
73-
TxRlp string `json:"txs,omitempty"`
74-
Clique *cliqueInput `json:"clique,omitempty"`
72+
Header *header `json:"header,omitempty"`
73+
OmmersRlp []string `json:"ommers,omitempty"`
74+
TxRlp string `json:"txs,omitempty"`
75+
Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"`
76+
Clique *cliqueInput `json:"clique,omitempty"`
7577

7678
Ethash bool `json:"-"`
7779
EthashDir string `json:"-"`
@@ -115,22 +117,23 @@ func (c *cliqueInput) UnmarshalJSON(input []byte) error {
115117
// ToBlock converts i into a *types.Block
116118
func (i *bbInput) ToBlock() *types.Block {
117119
header := &types.Header{
118-
ParentHash: i.Header.ParentHash,
119-
UncleHash: types.EmptyUncleHash,
120-
Coinbase: common.Address{},
121-
Root: i.Header.Root,
122-
TxHash: types.EmptyRootHash,
123-
ReceiptHash: types.EmptyRootHash,
124-
Bloom: i.Header.Bloom,
125-
Difficulty: common.Big0,
126-
Number: i.Header.Number,
127-
GasLimit: i.Header.GasLimit,
128-
GasUsed: i.Header.GasUsed,
129-
Time: i.Header.Time,
130-
Extra: i.Header.Extra,
131-
MixDigest: i.Header.MixDigest,
132-
BaseFee: i.Header.BaseFee,
133-
ExcessDataGas: i.Header.ExcessDataGas,
120+
ParentHash: i.Header.ParentHash,
121+
UncleHash: types.EmptyUncleHash,
122+
Coinbase: common.Address{},
123+
Root: i.Header.Root,
124+
TxHash: types.EmptyRootHash,
125+
ReceiptHash: types.EmptyRootHash,
126+
Bloom: i.Header.Bloom,
127+
Difficulty: common.Big0,
128+
Number: i.Header.Number,
129+
GasLimit: i.Header.GasLimit,
130+
GasUsed: i.Header.GasUsed,
131+
Time: i.Header.Time,
132+
Extra: i.Header.Extra,
133+
MixDigest: i.Header.MixDigest,
134+
BaseFee: i.Header.BaseFee,
135+
WithdrawalsHash: i.Header.WithdrawalsHash,
136+
ExcessDataGas: i.Header.ExcessDataGas,
134137
}
135138

136139
// Fill optional values.

cmd/evm/internal/t8ntool/gen_header.go

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

core/types/block.go

Lines changed: 79 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package types
2020
import (
2121
"bytes"
2222
"encoding/binary"
23+
"errors"
2324
"fmt"
2425
"io"
2526
"math/big"
@@ -88,6 +89,9 @@ type Header struct {
8889
// BaseFee was added by EIP-1559 and is ignored in legacy headers.
8990
BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"`
9091

92+
// WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers.
93+
WithdrawalsHash *common.Hash `json:"withdrawalsRoot" rlp:"optional"`
94+
9195
// ExcessDataGas was added by EIP-4844 and is ignored in legacy headers.
9296
ExcessDataGas *big.Int `json:"excessDataGas" rlp:"optional"`
9397

@@ -117,6 +121,10 @@ func (h *Header) SetExcessDataGas(v *big.Int) {
117121
if v != nil {
118122
h.ExcessDataGas.Set(v)
119123
}
124+
if h.WithdrawalsHash == nil {
125+
// leaving this nil would result in a buggy encoding
126+
h.WithdrawalsHash = &EmptyRootHash
127+
}
120128
}
121129

122130
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
@@ -184,6 +192,7 @@ type Block struct {
184192
header *Header
185193
uncles []*Header
186194
transactions Transactions
195+
withdrawals []*Withdrawal
187196

188197
// caches
189198
hash atomic.Value
@@ -271,9 +280,10 @@ func (txs *extBlockTxs) EncodeRLP(w io.Writer) error {
271280

272281
// "external" block encoding. used for eth protocol, etc.
273282
type extblock struct {
274-
Header *Header
275-
Txs *extBlockTxs
276-
Uncles []*Header
283+
Header *Header
284+
Txs *extBlockTxs
285+
Uncles []*Header
286+
Withdrawals []*Withdrawal `rlp:"optional"`
277287
}
278288

279289
// NewBlock creates a new block. The input data is copied,
@@ -315,6 +325,31 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
315325
return b
316326
}
317327

328+
// NewBlock2 creates a new block with withdrawals. The input data
329+
// is copied, changes to header and to the field values will not
330+
// affect the block.
331+
//
332+
// The values of TxHash, UncleHash, ReceiptHash and Bloom in header
333+
// are ignored and set to values derived from the given txs, uncles
334+
// and receipts.
335+
func NewBlock2(header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, withdrawals []*Withdrawal, hasher TrieHasher) *Block {
336+
b := NewBlock(header, txs, uncles, receipts, hasher)
337+
if withdrawals == nil {
338+
return b
339+
}
340+
341+
b.withdrawals = make([]*Withdrawal, len(withdrawals))
342+
copy(b.withdrawals, withdrawals)
343+
344+
if len(withdrawals) == 0 {
345+
b.header.WithdrawalsHash = &EmptyRootHash
346+
} else {
347+
h := DeriveSha(Withdrawals(withdrawals), hasher)
348+
b.header.WithdrawalsHash = &h
349+
}
350+
return b
351+
}
352+
318353
// NewBlockWithHeader creates a block with the given header data. The
319354
// header data is copied, changes to header and to the field values
320355
// will not affect the block.
@@ -342,6 +377,10 @@ func CopyHeader(h *Header) *Header {
342377
cpy.Extra = make([]byte, len(h.Extra))
343378
copy(cpy.Extra, h.Extra)
344379
}
380+
if h.WithdrawalsHash != nil {
381+
cpy.WithdrawalsHash = new(common.Hash)
382+
cpy.WithdrawalsHash.SetBytes(h.WithdrawalsHash.Bytes())
383+
}
345384
return &cpy
346385
}
347386

@@ -357,17 +396,24 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
357396
return fmt.Errorf("transactions in blocks must not contain wrap-data, tx %d is bad", i)
358397
}
359398
}
360-
b.header, b.uncles, b.transactions = eb.Header, eb.Uncles, []*Transaction(*eb.Txs)
399+
b.header, b.uncles, b.transactions, b.withdrawals = eb.Header, eb.Uncles, []*Transaction(*eb.Txs), eb.Withdrawals
361400
b.size.Store(rlp.ListSize(size))
362401
return nil
363402
}
364403

365404
// EncodeRLP serializes b into the Ethereum RLP block format.
366405
func (b *Block) EncodeRLP(w io.Writer) error {
406+
if b.header.ExcessDataGas != nil && b.header.WithdrawalsHash == nil {
407+
// This situation should not arise, but if it does (due to a bug) you'd silently produce an
408+
// encoding that would fail to decode. ref:
409+
// https://github.com/ethereum/go-ethereum/pull/26077
410+
return errors.New("nil WithdrawalsHash in header with non-nil ExcessDataGas")
411+
}
367412
return rlp.Encode(w, extblock{
368-
Header: b.header,
369-
Txs: (*extBlockTxs)(&b.transactions),
370-
Uncles: b.uncles,
413+
Header: b.header,
414+
Txs: (*extBlockTxs)(&b.transactions),
415+
Uncles: b.uncles,
416+
Withdrawals: b.withdrawals,
371417
})
372418
}
373419

@@ -410,6 +456,19 @@ func (b *Block) BaseFee() *big.Int {
410456
return new(big.Int).Set(b.header.BaseFee)
411457
}
412458

459+
func (b *Block) WithdrawalsHash() *common.Hash {
460+
if b.header.WithdrawalsHash == nil {
461+
return nil
462+
}
463+
var h common.Hash
464+
h.SetBytes(b.header.WithdrawalsHash.Bytes())
465+
return &h
466+
}
467+
468+
func (b *Block) Withdrawals() Withdrawals {
469+
return b.withdrawals
470+
}
471+
413472
func (b *Block) ExcessDataGas() *big.Int {
414473
if b.header.ExcessDataGas == nil {
415474
return nil
@@ -463,6 +522,7 @@ func (b *Block) WithSeal(header *Header) *Block {
463522
header: &cpy,
464523
transactions: b.transactions,
465524
uncles: b.uncles,
525+
withdrawals: b.withdrawals,
466526
}
467527
}
468528

@@ -480,6 +540,18 @@ func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
480540
return block
481541
}
482542

543+
// WithBody2 returns a new block with the given transaction, uncle, and
544+
// withdrawal contents.
545+
func (b *Block) WithBody2(transactions []*Transaction, uncles []*Header, withdrawals []*Withdrawal) *Block {
546+
block := b.WithBody(transactions, uncles)
547+
if withdrawals == nil {
548+
return block
549+
}
550+
block.withdrawals = make([]*Withdrawal, len(withdrawals))
551+
copy(block.withdrawals, withdrawals)
552+
return block
553+
}
554+
483555
// Hash returns the keccak256 hash of b's header.
484556
// The hash is computed on the first call and cached thereafter.
485557
func (b *Block) Hash() common.Hash {

0 commit comments

Comments
 (0)