Skip to content
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

Open
wants to merge 5 commits into
base: darioush/libevm-phase-2.5
Choose a base branch
from

Conversation

qdm12
Copy link
Collaborator

@qdm12 qdm12 commented Jan 21, 2025

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

@qdm12 qdm12 changed the title feat(core/types): header copy hooks feat(core/types): Header Copy hook Jan 21, 2025
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 {
Copy link
Collaborator

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 that geth MUST be considered to be a “user” of libevm. 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
}

Copy link
Collaborator Author

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.

Copy link
Collaborator

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?

Copy link
Collaborator Author

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:

https://github.com/ava-labs/coreth/pull/759/files#diff-c238f33a661d072dc51dd5a20ab81dbd341f59478b5c26d25db686822b492521R85

Copy link
Collaborator

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.

@qdm12 qdm12 force-pushed the qdm12/core/types/header-copy-hooks branch from 5b49266 to 9236b52 Compare January 31, 2025 18:51
@qdm12 qdm12 marked this pull request as ready for review February 3, 2025 11:54
@qdm12 qdm12 requested a review from ARR4N February 3, 2025 11:54
@ARR4N
Copy link
Collaborator

ARR4N commented Feb 3, 2025

Why not merge into main? Is there a reason to batch PRs for a later re-review and merge?

@qdm12
Copy link
Collaborator Author

qdm12 commented Feb 3, 2025

Why not merge into main?

I needed the fixes of darioush/libevm-phase-2.5 to make it work in coreth. How are we planning to handle the few fix commits in darioush/libevm-phase-2.5 in the end?

Is there a reason to batch PRs for a later re-review and merge?

Not at all, I would rather not 😉

Copy link
Collaborator

@ARR4N ARR4N left a 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

Comment on lines +40 to +41
accessor pseudo.Accessor[*Header, *stubHeaderHooks]
copied *stubHeaderHooks
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.

Comment on lines +146 to +158
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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:

  1. Changed copied to toCopy, in keeping with my earlier suggestion;
  2. Spacing change to logically group operations as setup then assertion; and
  3. Usage of "got" variable to signal that it's the value under test.

@ARR4N
Copy link
Collaborator

ARR4N commented Feb 3, 2025

Why not merge into main?

I needed the fixes of darioush/libevm-phase-2.5 to make it work in coreth. How are we planning to handle the few fix commits in darioush/libevm-phase-2.5 in the end?

Is there a reason to batch PRs for a later re-review and merge?

Not at all, I would rather not 😉

Was it only the change to the legacy package that's absolutely required? If so, can you please open another PR and take a closer look re avoiding gas refunds I mentioned on DM?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants