@@ -85,6 +85,9 @@ type Header struct {
8585
8686 // BaseFee was added by EIP-1559 and is ignored in legacy headers.
8787 BaseFee * big.Int `json:"baseFeePerGas" rlp:"optional"`
88+
89+ // caches
90+ externalHash atomic.Value `rlp:"-"`
8891}
8992
9093// field type overrides for gencodec
@@ -101,10 +104,21 @@ type headerMarshaling struct {
101104
102105// Hash returns the block hash of the header, which is simply the keccak256 hash of its
103106// RLP encoding.
107+ // Also hash of the header could be overridden with external value.
104108func (h * Header ) Hash () common.Hash {
109+ external := h .externalHash .Load ()
110+ if external != nil {
111+ return external .(common.Hash )
112+ }
113+
105114 return rlpHash (h )
106115}
107116
117+ // SetExternalHash overrides hash with external value.
118+ func (h * Header ) SetExternalHash (hash common.Hash ) {
119+ h .externalHash .Store (hash )
120+ }
121+
108122var headerSize = common .StorageSize (reflect .TypeOf (Header {}).Size ())
109123
110124// Size returns the approximate memory used by all internal contents. It is used
@@ -162,7 +176,6 @@ type Block struct {
162176 transactions Transactions
163177
164178 // caches
165- hash atomic.Value
166179 size atomic.Value
167180
168181 // Td is used by package core to store the total difficulty
@@ -245,6 +258,13 @@ func CopyHeader(h *Header) *Header {
245258 cpy .Extra = make ([]byte , len (h .Extra ))
246259 copy (cpy .Extra , h .Extra )
247260 }
261+
262+ external := h .externalHash .Load ()
263+ if external != nil {
264+ hash := external .(common.Hash )
265+ cpy .SetExternalHash (hash )
266+ }
267+
248268 return & cpy
249269}
250270
@@ -371,31 +391,9 @@ func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block {
371391 return block
372392}
373393
374- // WithHash returns a new block with the custom hash.
375- func (b * Block ) WithHash (h common.Hash ) * Block {
376- block := & Block {
377- header : CopyHeader (b .header ),
378- transactions : make ([]* Transaction , len (b .transactions )),
379- uncles : make ([]* Header , len (b .uncles )),
380- }
381- copy (block .transactions , b .transactions )
382- for i , uncle := range b .uncles {
383- block .uncles [i ] = CopyHeader (uncle )
384- }
385-
386- block .hash .Store (h )
387- return block
388- }
389-
390394// Hash returns the keccak256 hash of b's header.
391- // The hash is computed on the first call and cached thereafter.
392395func (b * Block ) Hash () common.Hash {
393- if hash := b .hash .Load (); hash != nil {
394- return hash .(common.Hash )
395- }
396- v := b .header .Hash ()
397- b .hash .Store (v )
398- return v
396+ return b .header .Hash ()
399397}
400398
401399type Blocks []* Block
0 commit comments