## Why this should be merged
There are 3 places at which we perform the same, sensitive logic to
access registered payloads and as we modify more types this is likely to
expand. (e.g. `types.Header`).
## How this works
Introduces `pseudo.Accessor` to abstract the reusable code.
## How this was tested
Existing unit tests. Note that the `types.StateAccount` tests needed a
minor refactor to provide the assertions with access to the
`ExtraPayloads[T]` without introducing generic types anywhere.
## Why this should be merged
Consolidates duplicated logic. Similar rationale to #84.
## How this works
New `register.AtMostOnce[T]` type is responsible for limiting calls to
`Register()`.
## How this was tested
Existing unit tests of `params`. Note that the equivalent functionality
in `types` wasn't tested but now is.
## Why this should be merged
I messed up the format of `rc` version tags, resulting in `rc.1` being
considered a later version that `rc.2`.
## How this works
The [release tagging](https://github.com/ava-labs/libevm/discussions/37)
pattern that includes a combination of `geth` and `libevm` semver
triplets (e.g. `1.13.14-0.1.0`) doesn't work well with extra identifiers
like `rc` because more pre-release identifiers (those after `-`) take
higher precedence if all those before them match. We therefore have to
use a `release` suffix (`"release" > "rc"` in ASCII).
This all became too much to expect to be done manually so I chucked it
in code instead.
## How this was tested
Unit test demonstrates expectation of version ordering.
## Why this should be merged
Provides access to extra payloads registered on `types.SlimAccount`, not
just on regular `types.StateAccount`. This is a breaking syntax change
to have the method reflect the behaviour.
## How this works
Modify existing method to accept the `ExtraPayloadCarrier` interface
instead of `*StateAccount`. The interface is implemented by both
`*StateAccount` and `*SlimAccount`.
## How this was tested
Covered by existing testing.
## Why this should be merged
Allows for a drop-in replacement of `snapshot.Tree` (i.e. one that uses
block hashes instead of state roots). This is intended as a temporary
solution while we investigate having the state root affected by the
block hash to remove path ambiguity.
## How this works
Introduction of:
1. `state.SnapshotTree` interface to match methods required on
`snapshot.Tree` as used by `state.StateDB`; and
2. `stateconf` package for variadic options plumbed by
`StateDB.Commit()` through to `SnapshotTree.Update()`.
Although variadic (to maintain function call-signature compatibility)
only the `stateconf.WithUpdatePayload(any)` is expected to be used.
Recipients of the options can access the payload with
`stateconf.ExtractUpdatePayload()`.
## How this was tested
Unit test demonstrating propagation of `stateconf.UpdateOption` payload.
## Why this should be merged
Performs trie prefetching concurrently, required for equivalent
performance with `coreth` / `subnet-evm` implementations.
## How this works
`StateDB.StartPrefetcher()` accepts variadic options (for backwards
compatibility of function signatures). An option to specify a
`WorkerPool` is provided which, if present, is used to call
`Trie.Get{Account,Storage}()`; the pool is responsible for concurrency
but does not need to be able to wait on the work as that is handled by
this change.
## How this was tested
Unit test demonstrating hand-off of work to a `WorkerPool` as well as
API-guaranteed ordering of events.
## Why this should be merged
Simplifies the creation and application of variadic options; this is
also applicable to many of my other WIP branches (e.g. `snapshot`).
## How this works
See `libevm/options/options.go`, which is very simple.
## How this was tested
Existing tests of `vm.PrecompileEnvironment.Call()`, which itself uses
refactored options.
## Why this should be merged
Allow `ava-labs/coreth` to use arbitrary `triedb` database
implementations.
## How this works
Introduces `HashBackend` and `PathBackend` interfaces that
`triedb.Database` type-asserts to instead of `hashdb.Database` and
`pathdb.Backend` respectively. Other interfaces are introduced to avoid
having to modify `{hash,path}db.Database.Reader()` return values.
The explicit `DBOverride` field means that we don't have to modify any
of the `triedb` constructor beyond adding a single line immediately
before the return. This leaves all modifications of original files
entirely mechanistic. This is, however, at the expense of compile-time
guarantees of the overriding database being either a `HashBackend` or a
`PathBackend`.
## How this was tested
Unit test demonstrating override + plumbing.
---------
Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
## Why this should be merged
Cleans up loose ends after renaming the Go module. Also adds an
introduction to the README to explain the purpose of libevm.
## How this works
The changed hash in the workflow is just a fix (although a no-op). The
spaces after the copyright headers are to stop them from [showing up in
documentation](https://pkg.go.dev/github.com/ava-labs/libevm@v1.13.14-0.1.0-rc.1/params).
## How this was tested
n/a
## Why this should be merged
These workflows are required by branch protection for release branches,
but aren't run automatically so release PRs can't currently be merged.
## How this works
Extends the `branches` filters of necessary workflows.
## How this was tested
n/a
## Why this should be merged
Fixes tracing when a stateful precompile calls another contract that
itself accesses storage.
## How this works
The pre-state tracer from `eth/tracers/native` doesn't implement
`CaptureEnter()` (entry of a new context), instead relying on
`CaptureState()` (per-opcode tracing) to detect that a new contract has
been entered. In doing so, it [maintains an
invariant](cb7eb89341/eth/tracers/native/prestate.go (L160))
that is expected when `CaptureState(vm.SLOAD, ...)` is called—breaking
the invariant results in a panic due to a nil map.
The fix involves (a) maintaining the invariant as part of
`CaptureEnter()` (previously a no-op); and (b) calling said method
inside `vm.PrecompileEnvironment.Call()`. The latter has the added
benefit of properly handling all tracing involving an outbound call from
precompiles.
## How this was tested
New integration test demonstrates that the tracer can log the retrieved
storage value.
---------
Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
## Why this should be merged
Fixes invariant broken by introduction of `types.StateAccountExtra`.
## How this works
`state.stateObject.empty()` now also requires that the underlying
account's `Extra` field carries the zero value if a type is registered,
or is itself nil.
## How this was tested
New unit test.
---------
Co-authored-by: Darioush Jalali <darioush.jalali@avalabs.org>
Linter:
- Block imports of `ethereum/go-ethereum` upstream module
- Disable `goimports` checks on upstream code
Go:
- Update flaky-test regex
- Run flaky and non-flaky tests in different steps as this makes it easier to spot incorrect regex
Upstream delta:
- Use env var in workflow instead of `libevm-base` tag -> base changes atomically with the update commit
## Why this should be merged
Signs commits for auto-renaming the Go module, originally introduced in
#51 with unsigned commits that can't be merged to `main`.
## How this works
Changes the commit action to use
[`ghcommit`](https://github.com/planetscale/ghcommit), which was made
specifically to allow for keyless signing (GitHub signs the commit). The
workflow no longer opens a PR to the `renamed-go-module` branch as it's
redundant and the generated branch can be used directly.
The commit message includes the `workflow_dispatch` trigger branch as
well as a hash of the workflow file for a complete audit trail.
I removed the commented-out PR trigger as it's unnecessary. In
development we can now just trigger the workflow on the dev branch.
## How this was tested
Inspecting [the
commit](572b8ab74e)
generated by a [workflow
run](https://github.com/ava-labs/libevm/actions/runs/11357025696/job/31589219847).
It is identical in modifications to the one reviewed in #59.
## Why this should be merged
#51 had a bug when checking whether or not to open a PR. I was
originally blocking everything if _not_ on main instead of doing
something if on it. The [manually dispatched run therefore didn't open a
PR as
expected](https://github.com/ava-labs/libevm/actions/runs/11299366394/job/31430160561).
## How this works
Change `!=` to `==`
## How this was tested
n/a
Signed-off-by: Arran Schlosberg <519948+ARR4N@users.noreply.github.com>
## Why this should be merged
Automate renaming of the Go module from
`github.com/ethereum/go-ethereum` to `github.com/ava-labs/libevm`.
## How this works
Before starting this PR, I branched the `renamed-go-module` branch off
`master` (the upstream geth branch; our default is called `main`). It
has been protected to require PRs, which are automatically generated by
the workflow introduced in this PR.
The new workflow is designed to be manually dispatched with an input
string of the commit hash to use as a source for renaming. On dispatch,
it:
1. Checks out the source commit;
2. Renames the module;
3. Makes all necessary internal changes (e.g. import renaming);
4. Runs [smoke
tests](https://en.wikipedia.org/wiki/Smoke_testing_(software));
5. Commits the changes to a new branch; and
6. Opens a PR to merge the new branch into `renamed-go-module`.
### Intended usage
When performing an upstream sync to pull in new geth code, this workflow
will first be run against the geth commit we intend to merge. After the
generated PR is merged, the `renamed-go-module` branch will be the one
incorporated into `main`.
Note that the `renamed-go-module` branch requires _two_ reviewers to
approve. The user who dispatches the workflow SHOULD be one, with any
other valid reviewer as the other. This is because a single-reviewer
workflow would allow any user to update the `renamed-go-module` branch
because the PR author is `github-actions`.
## How this was tested
Inspection of the generated PR #57 as well as the [workflow run that
generated
it](https://github.com/ava-labs/libevm/actions/runs/11298471240/job/31427495426).
Pushing this commit to the `libevm` branch fails (by design) because of branch protection requiring a PR. I want to test what happens if, once the PR is approved and all status checks pass, I _locally_ `git merge --ff-only` on the `libevm` branch before pushing to GitHub. Will it recognise and honour the PR?
Without this, the GitHub PR merge uses `--no-ff`, which isn't always desirable.
* feat: `state.{Get,Set}Extra[SA any](*StateDB,types.ExtraPayloads,...)`
* test: `GetExtra()` at each point in `CreateAccount()` + `SetExtra()` lifecycle
* test: reverting extras to snapshot
* test: `GetExtra()` after `StateDB.Copy()` and writes to original
* fix: `vm.WithUNSAFECallerAddressProxying` under `DELEGATECALL`
* test: `vm.WithUNSAFECallerAddressProxying()` effect on outgoing caller addr
* chore: mark `eth/tracers/js` test flaky
* feat: `vm.PrecompileEnvironment.IncomingCallType()`
* chore: minor documentation edit
* doc: `PrecompileEnvironment` example for determining actual caller
* chore: placate the linter
* refactor: abstract `testonly` package
* test: `StateAccount.Extra` via `trie.StateTrie.{Update,Get}Account()`
* chore: `types.TestOnlyClearRegisteredExtras()` at beginning of tests
This is a purely defensive approach in case future tests forget to clean up.
* chore: placate the linter
Some of the changes in the full commit history were merged into `libevm` as part of #43 in `336a289` and then merged back into this branch as `5b15698`. Cherry-picking commits was not possible as some touched both halves of the changes; the squash-merges will, however, make this convoluted history irrelevant.
* feat: `types.StateAccount` pseudo-generic payload
* feat: registration of `StateAccount` payload type
* chore: mark `eth/tracers/logger` flaky
* chore: copyright header + `gci`
* test: lock default `types.SlimAccount` RLP encoding
* feat: `vm.SlimAccount.Extra` from `StateAccount` equiv
* chore: placate the linter
* test: `pseudo.Type.EncodeRLP()`
* test: `pseudo.Type.DecodeRLP()`
* fix: `pseudo.Type.DecodeRLP()` with non-pointer type
* feat: `pseudo.Type.IsZero()` and `Type.Equal(*Type)`
* feat: `types.StateAccountExtra.DecodeRLP()`
* fix: remove unnecessary `StateAccountExtra.clone()`
* refactor: readability
* feat: `pseudo.Type.Format()` implements `fmt.Formatter`
All commits except the last two constitute PRs #43 and #44. The last two reverted files such that only changes to the `pseudo` and `ethtest` packages remain; once this is merged into the `libevm` branch then `libevm` will be merged into the branch for #44 too. Cherry-picking commits was not possible as some touched both halves of the changes; the squash-merges will, however, make this convoluted history irrelevant.
* feat: `types.StateAccount` pseudo-generic payload
* feat: registration of `StateAccount` payload type
* chore: mark `eth/tracers/logger` flaky
* chore: copyright header + `gci`
* test: lock default `types.SlimAccount` RLP encoding
* feat: `vm.SlimAccount.Extra` from `StateAccount` equiv
* chore: placate the linter
* test: `pseudo.Type.EncodeRLP()`
* test: `pseudo.Type.DecodeRLP()`
* fix: `pseudo.Type.DecodeRLP()` with non-pointer type
* feat: `pseudo.Type.IsZero()` and `Type.Equal(*Type)`
* feat: `types.StateAccountExtra.DecodeRLP()`
* chore: revert non-pseudo-package modifications
* chore: delete non-pseudo-package additions
* feat: override `vm.NewEVM()` args
* test: `vm.Hooks.OverrideNewEVMArgs`
* refactor: use `NewEVMArgs struct` in hook
* chore: `gci`
* fix: clear `vm.Hooks` at end of test
* refactor!: `RulesHooks.CanCreateContract()` via `defer`
`TestCanCreateContract` is unchanged and merely moved to the appropriate file.
* feat!: `RulesHooks.CanCreateContract()` accepts and returns gas
* chore: move `TestCanCreateContract` to original file
Simplifies code review
* chore: pacify linter
* refactor!: revert to non-deferred call (not at start)
* chore: workflow to print diffs vs `libevm-base` tag
* fix: job name
* fix: use `${{ github.ref_name }}` instead of `HEAD`
* fix: use `github.sha` instead of `github.ref_name`
* fix: `fetch-tags: true`
* chore: fml
* fix: `fetch-depth: 0` for more than just 1 commit
* fix: check out branch before performing diff
* chore: `set -x` to aid debugging
* fix: add `--` suffix to `git checkout`
* fix: use `github.ref_name` instead of `github.sha`
* refactor: move all actions inside workflow
* fix: use `github.ref` for full name
* fix: only use explicit diff for `libevm`
* chore: `git diff --color=always`
* feat: color-blindness a11y
* chore: `golangci-lint` CI workflow
* fix: make `golangci-lint` happy
* chore: bump `actions/{checkout,setup-go}` versions
* chore: overhaul `.golanci.yml` config
* fix: all linter issues
* chore: exclude non-libevm linters + change deprecated option
* fix: add overflow check in example
* fix: try again; different local version?
* chore: this is trying my patience
* chore: enable `gci` and fix ordering
* chore: mark `ethclient/gethclient` test as flaky
* chore: mark `eth/catalyst` test as flaky
* fix: run flaky upstream tests sequentially
* chore: run flaky tests first to fail early
There are fewer of them so they'll fail quickly and allow the CI run to just be restarted.
* refactor: extra types `C` + `R` are never plumbed as `*C` / `*R`
* refactor: force use of `pseudo.Constructor.Zero()` instead of `NilPointer()`
* feat: `pseudo.PointerTo()`
* feat: `params.ExtraPayloadGetter[C,R].PointerFromChainConfig(...) *C` and `Rules => *R` equiv
* test: shallow copy of `ChainConfig`/`Rules` includes extras
* feat: `params.ChainConfig` extra payload can use root JSON
* refactor: simplify `ChainConfig.UnmarshalJSON()` branches
* fix: change redundant `assert` to `require` for simplicity
* feat: pseudo-generic extra payloads in `params.ChainConfig` and `params.Rules`
* feat: `params.ExtraPayloadGetter` for end-user type safety
* refactor: payloads only available through `params.ExtraPayloadGetter`
* chore: make `libevm/examples/extraparams` a `params` testable example
* doc: `libevm/pseudo` package comments and improved readability
* doc: `params.*Extra*` comments and improved readability
* doc: `params.ExtraPayloadGetter` comments and improved readability
* doc: `params/config.libevm_test.go` comments and improved readability
* refactor: simplify `params.ChainConfig.UnmarshalJSON()`
* refactor: abstract new/nil-pointer creation into `pseudo.Constructor`s
* feat: precompile override via `params.Extras` hooks
* doc: flesh out `PrecompileOverride()` in example
* doc: complete commentary and improve readability
* refactor: `ChainConfig.Hooks()` + `Rules` equivalent
* chore: rename precompiles test file in keeping with geth equivalent
* feat: stateful precompiles + allowlist hooks
The allowlist hooks are included in this commit because they allow for the same functionality as stateful precompiles in `ava-labs/coreth` and `ava-labs/subnet-evm`.
* fix: `StateTransition.canExecuteTransaction()` used `msg.From` instead of `To`
* test: `params.RulesHooks.CanCreateContract` integration
* test: `params.RulesHooks.CanExecuteTransaction` integration
* test: `vm.NewStatefulPrecompile()` integration
* refactor: simplify test of `CanCreateContract`
* refactor: abstract generation of random `Address`/`Hash` values
* doc: full documentation + readability refactoring/renaming
* fix: remove circular dependency in tests