@@ -20,6 +20,7 @@ package types
20
20
import (
21
21
"bytes"
22
22
"encoding/binary"
23
+ "errors"
23
24
"fmt"
24
25
"io"
25
26
"math/big"
@@ -88,6 +89,9 @@ type Header struct {
88
89
// BaseFee was added by EIP-1559 and is ignored in legacy headers.
89
90
BaseFee * big.Int `json:"baseFeePerGas" rlp:"optional"`
90
91
92
+ // WithdrawalsHash was added by EIP-4895 and is ignored in legacy headers.
93
+ WithdrawalsHash * common.Hash `json:"withdrawalsRoot" rlp:"optional"`
94
+
91
95
// ExcessDataGas was added by EIP-4844 and is ignored in legacy headers.
92
96
ExcessDataGas * big.Int `json:"excessDataGas" rlp:"optional"`
93
97
@@ -117,6 +121,10 @@ func (h *Header) SetExcessDataGas(v *big.Int) {
117
121
if v != nil {
118
122
h .ExcessDataGas .Set (v )
119
123
}
124
+ if h .WithdrawalsHash == nil {
125
+ // leaving this nil would result in a buggy encoding
126
+ h .WithdrawalsHash = & EmptyRootHash
127
+ }
120
128
}
121
129
122
130
// Hash returns the block hash of the header, which is simply the keccak256 hash of its
@@ -184,6 +192,7 @@ type Block struct {
184
192
header * Header
185
193
uncles []* Header
186
194
transactions Transactions
195
+ withdrawals []* Withdrawal
187
196
188
197
// caches
189
198
hash atomic.Value
@@ -271,9 +280,10 @@ func (txs *extBlockTxs) EncodeRLP(w io.Writer) error {
271
280
272
281
// "external" block encoding. used for eth protocol, etc.
273
282
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"`
277
287
}
278
288
279
289
// NewBlock creates a new block. The input data is copied,
@@ -315,6 +325,31 @@ func NewBlock(header *Header, txs []*Transaction, uncles []*Header, receipts []*
315
325
return b
316
326
}
317
327
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
+
318
353
// NewBlockWithHeader creates a block with the given header data. The
319
354
// header data is copied, changes to header and to the field values
320
355
// will not affect the block.
@@ -342,6 +377,10 @@ func CopyHeader(h *Header) *Header {
342
377
cpy .Extra = make ([]byte , len (h .Extra ))
343
378
copy (cpy .Extra , h .Extra )
344
379
}
380
+ if h .WithdrawalsHash != nil {
381
+ cpy .WithdrawalsHash = new (common.Hash )
382
+ cpy .WithdrawalsHash .SetBytes (h .WithdrawalsHash .Bytes ())
383
+ }
345
384
return & cpy
346
385
}
347
386
@@ -357,17 +396,24 @@ func (b *Block) DecodeRLP(s *rlp.Stream) error {
357
396
return fmt .Errorf ("transactions in blocks must not contain wrap-data, tx %d is bad" , i )
358
397
}
359
398
}
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
361
400
b .size .Store (rlp .ListSize (size ))
362
401
return nil
363
402
}
364
403
365
404
// EncodeRLP serializes b into the Ethereum RLP block format.
366
405
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
+ }
367
412
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 ,
371
417
})
372
418
}
373
419
@@ -410,6 +456,19 @@ func (b *Block) BaseFee() *big.Int {
410
456
return new (big.Int ).Set (b .header .BaseFee )
411
457
}
412
458
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
+
413
472
func (b * Block ) ExcessDataGas () * big.Int {
414
473
if b .header .ExcessDataGas == nil {
415
474
return nil
@@ -463,6 +522,7 @@ func (b *Block) WithSeal(header *Header) *Block {
463
522
header : & cpy ,
464
523
transactions : b .transactions ,
465
524
uncles : b .uncles ,
525
+ withdrawals : b .withdrawals ,
466
526
}
467
527
}
468
528
@@ -480,6 +540,18 @@ func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
480
540
return block
481
541
}
482
542
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
+
483
555
// Hash returns the keccak256 hash of b's header.
484
556
// The hash is computed on the first call and cached thereafter.
485
557
func (b * Block ) Hash () common.Hash {
0 commit comments