diff --git a/core/types/block.go b/core/types/block.go index 692cf01c076b..336275917db0 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -309,6 +309,7 @@ func CopyHeader(h *Header) *Header { cpy.ParentBeaconRoot = new(common.Hash) *cpy.ParentBeaconRoot = *h.ParentBeaconRoot } + h.hooks().PostCopy(&cpy) return &cpy } diff --git a/core/types/block.libevm.go b/core/types/block.libevm.go index ca1e6d7e57d9..9258eefac799 100644 --- a/core/types/block.libevm.go +++ b/core/types/block.libevm.go @@ -32,6 +32,7 @@ type HeaderHooks interface { UnmarshalJSON(*Header, []byte) error //nolint:govet EncodeRLP(*Header, io.Writer) error DecodeRLP(*Header, *rlp.Stream) error + PostCopy(dst *Header) } // hooks returns the Header's registered HeaderHooks, if any, otherwise a @@ -108,3 +109,5 @@ func (*NOOPHeaderHooks) DecodeRLP(h *Header, s *rlp.Stream) error { type withoutMethods Header return s.Decode((*withoutMethods)(h)) } + +func (n *NOOPHeaderHooks) PostCopy(dst *Header) {} diff --git a/core/types/block.libevm_test.go b/core/types/block.libevm_test.go index 7f5cfd83c540..e89926767323 100644 --- a/core/types/block.libevm_test.go +++ b/core/types/block.libevm_test.go @@ -29,6 +29,7 @@ import ( . "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/crypto" "github.com/ava-labs/libevm/libevm/ethtest" + "github.com/ava-labs/libevm/libevm/pseudo" "github.com/ava-labs/libevm/rlp" ) @@ -36,6 +37,8 @@ type stubHeaderHooks struct { suffix []byte gotRawJSONToUnmarshal, gotRawRLPToDecode []byte setHeaderToOnUnmarshalOrDecode Header + accessor pseudo.Accessor[*Header, *stubHeaderHooks] + toCopy *stubHeaderHooks errMarshal, errUnmarshal, errEncode, errDecode error } @@ -75,6 +78,10 @@ func (hh *stubHeaderHooks) DecodeRLP(h *Header, s *rlp.Stream) error { return hh.errDecode } +func (hh *stubHeaderHooks) PostCopy(dst *Header) { + hh.accessor.Set(dst, hh.toCopy) +} + func TestHeaderHooks(t *testing.T) { TestOnlyClearRegisteredExtras() defer TestOnlyClearRegisteredExtras() @@ -135,6 +142,20 @@ func TestHeaderHooks(t *testing.T) { assert.Equalf(t, &stub.setHeaderToOnUnmarshalOrDecode, hdr, "%T after RLP decoding with hook", hdr) }) + t.Run("PostCopy", func(t *testing.T) { + hdr := new(Header) + stub := &stubHeaderHooks{ + accessor: extras.Header, + toCopy: &stubHeaderHooks{ + suffix: []byte("copied"), + }, + } + extras.Header.Set(hdr, stub) + + got := extras.Header.Get(CopyHeader(hdr)) + assert.Equal(t, stub.toCopy, got) + }) + t.Run("error_propagation", func(t *testing.T) { errMarshal := errors.New("whoops") errUnmarshal := errors.New("is it broken?")