-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core/types): Header
Copy hook
#106
base: darioush/libevm-phase-2.5
Are you sure you want to change the base?
feat(core/types): Header
Copy hook
#106
Conversation
Header
Copy hook
core/types/block.go
Outdated
func CopyHeader(h *Header) *Header { | ||
// CopyEthHeader creates a deep copy of an Ethereum block header. | ||
// Use [CopyHeader] instead if your header has any registered extra. | ||
func CopyEthHeader(h *Header) *Header { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This introduces a breaking change, which we should only do as an absolute last resort because it can have flow-on effects that require changes elsewhere now or in the future. This was a primary source of difficulty when performing upgrades under the old forking approach as I explained in the proposal for this project:
A core tenet of [the
libevm
] approach is thatgeth
MUST be considered to be a “user” oflibevm
. As they update their own code, they assume that the rest of it is intact—this may be a tautology, but an important one nonetheless.
It also places the entire burden of copying on the libevm importer when all that's needed is for them to copy the registered extra.
What if the hook was PostCopy(dst, src *Header)
, called at the end of this function, and the NOOPHeaderHooks
implementation was empty?
func CopyHeader(h *Header) *Header {
// ...
h.hooks().PostCopy(cpy, h)
return cpy
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's PostCopy(dst)
in the end, given the source is already accessible by the header hooks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is it already accessible? Can you share an example snippet, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never mind, I had too many dead brain cells when writing this.
PostCopy doesn't (at least for now) need to do anything with the source header, since it's meant to only copy the extra payload (aka HeaderExtra). For example in coreth:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair. We can always add it later as we don't make any interface-stability guarantees.
5b49266
to
9236b52
Compare
Why not merge into |
I needed the fixes of
Not at all, I would rather not 😉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with minor suggestions that don't require re-review
accessor pseudo.Accessor[*Header, *stubHeaderHooks] | ||
copied *stubHeaderHooks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
accessor pseudo.Accessor[*Header, *stubHeaderHooks] | |
copied *stubHeaderHooks | |
accessor pseudo.Accessor[*Header, *stubHeaderHooks] // from [RegisterExtras] | |
toCopy *stubHeaderHooks |
copied
implies that it's the "got" / "actual" of the test whereas toCopy
implies that it's an action for the test double.
hdr := new(Header) | ||
stub := &stubHeaderHooks{ | ||
accessor: extras.Header, | ||
copied: &stubHeaderHooks{ | ||
suffix: []byte("copied"), | ||
}, | ||
} | ||
extras.Header.Set(hdr, stub) | ||
cpy := CopyHeader(hdr) | ||
|
||
copiedStub := extras.Header.Get(cpy) | ||
|
||
assert.Equal(t, stub.copied, copiedStub) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hdr := new(Header) | |
stub := &stubHeaderHooks{ | |
accessor: extras.Header, | |
copied: &stubHeaderHooks{ | |
suffix: []byte("copied"), | |
}, | |
} | |
extras.Header.Set(hdr, stub) | |
cpy := CopyHeader(hdr) | |
copiedStub := extras.Header.Get(cpy) | |
assert.Equal(t, stub.copied, copiedStub) | |
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) |
My suggested changes aren't as broad as the GH diff suggests:
- Changed
copied
totoCopy
, in keeping with my earlier suggestion; - Spacing change to logically group operations as setup then assertion; and
- Usage of "got" variable to signal that it's the value under test.
Was it only the change to the |
Why this should be merged
Introduce header copy hooks to get rid of core/types.CopyHeader in coreth and subnet-evm
How this works
Header copy hooks 🎉
How this was tested
Header
libevm PostCopy hook coreth#759