@@ -20,6 +20,7 @@ package types
2020import  (
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. 
273282type  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. 
366405func  (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+ 
413472func  (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. 
485557func  (b  * Block ) Hash () common.Hash  {
0 commit comments