Commit graph

14 commits

Author SHA1 Message Date
Arran Schlosberg
02110d3f34
chore: logging (#151)
## Why this should be merged

Adds logging of `libevm` modification of default behaviour.

## How this works

1. Introduces `log.Lazy` functions to allow expensive logging operations
to be computed i.f.f. required by the logging level.
2. Adds `Info` logging for registration of types and `Debug` logging for
all else.
3. Only paths that change behaviour in a potentially unpredictable
manner are logged; of note, RLP / JSON encoding is _not_ considered
unpredictable given that registered extras are logged.
4. The minimal viable package, `set`, was necessary because we don't
want to depend on `avalanchego` and the `hashicorp/go-set` latest
version requires a later version of Go. #153 tracks a swap to the latter
when possible.

The `eth/tracers/internal/tracetest` test flaked at least twice
(unrelated to these changes) so I've marked it as such since it's not
worth a separate PR.

## How this was tested

New unit test on `log.Lazy` + `set` methods. Existing CI for the rest as
it's a refactor.
2025-02-24 16:53:21 +00:00
Arran Schlosberg
44f23c8869
refactor: PrecompileEnvironment.{,Use,Refund}Gas() in lieu of args (#73)
## Why this should be merged

Aligns precompiled contracts with the pattern used in
`vm.EVMInterpreter` for regular contracts and simplifies gas accounting
by using existing mechanisms. The most notable simplification occurs
when there are multiple error paths that return early and have to
account for consumed gas (any local solution would likely just mirror
this one).

This forms part of a broader, long-term direction of feature parity
between precompiled and bytecode contracts, exposed via
`vm.PrecompileEnvironment`.

The `vm.Contract.Value()` method is also exposed as a natural
accompaniment to this change.

## How this works

The original signature for `vm.PrecompiledStatefulContract` received the
amount of gas available and then returned the amount remaining; this has
been removed in lieu of exposing the existing `vm.Contract.UseGas()`
method via the `vm.PrecompileEnvironment`. A new `legacy` package wraps
the old signature and converts it to a new one so `ava-labs/coreth`
doesn't need to be refactored.

```go
func oldPrecompile(env vm.PrecompileEnvironment, input []byte, gas uint64) ([]byte, uint64, error) {
  // ...
  if err != nil {
    return nil, gas - gasCost, err // pattern susceptible to bugs; should it be `nil, gas, err` ?
  }
  // ...
  return output, gas - gasCost, nil  
}

func newPrecompile(env vm.PrecompileEnvironment, input []byte) ([]byte, error) {
  // The original `gas` argument is still available as `env.Gas()`
  // ...
  if !env.UseGas(gasCost) { // an explicit point at which gas is consumed
    return nil, vm.ErrOutOfGas
  }
  // ...
  if err != nil {
    return nil, err
  }
  // ...
  return output, nil
}
```

## How this was tested

Existing unit test modified to use the `legacy` adaptor.

---------

Signed-off-by: Arran Schlosberg <519948+ARR4N@users.noreply.github.com>
Co-authored-by: Quentin McGaw <quentin.mcgaw@gmail.com>
2024-12-18 13:54:51 +00:00
Arran Schlosberg
12b8aa5c2e
fix: pre-state tracer logging storage after call from precompile (#64)
## 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>
2024-10-29 17:26:29 +11:00
Arran Schlosberg
4410f807c2
Merge branch 'auto-rename-module_source-2bd6bd01d2e8561dd7fc21b631f4a34ac16627a1_workflow-c1fc594f020d23958b641a4e5a856b6e52c49d3bece94b95594864db16c1b0fc-main' into arr4n/rename-module 2024-10-17 13:07:28 +11:00
Arran Schlosberg
51cd795878
fix: vm.WithUNSAFECallerAddressProxying under DELEGATECALL (#50)
* 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
2024-10-07 12:46:14 +01:00
Arran Schlosberg
210f8ab8e1
feat: vm.PrecompiledStatefulContract can make CALLs (#40)
* feat: `vm.PrecompiledStatefulContract` can make `CALL`s

* fix: caller propagation

* feat: precompile can override default caller in `Call()`

* refactor: `WithUNSAFEForceDelegate()` replaces `WithCaller()`

* refactor: `WithUNSAFECallerAddressProxying()` instead of `ForceDelegate`

This matches the pattern used by `ava-labs/coreth` `NativeAssetCall`.

* refactor: `type callType` replaces `rwInheritance` + `delegation` types

* refactor: abstract return-data-proxy contract bytecode

* doc: fix comments from `46346f51`

* fix: `PrecompileEnvironment.Addresses()` for all call types

* chore: readability, linting & mark upstream test flaky

* test: `PrecompileEnvironment.Call()`

* refactor: improved {read,maintain}ability

* doc: fix `evmCallArgs` example

* test: `PrecompileEnvironment.Call()` input data

* fix: write protection for non-zero call value
2024-09-30 17:26:50 +01:00
Arran Schlosberg
53ef0712af
feat: override EVM.Reset() args (#36) 2024-09-25 15:03:36 +01:00
Arran Schlosberg
dc619990f5
doc: licensing of libevm additions and modifications (#34)
* doc: licensing of libevm extensions and modifications

* chore: add license headers via linter

* chore: `golangci-lint run --fix`

* chore: `golangci-lint run --fix`

* chore: fix `libevm/libevm.go` header

* chore: `s/extensions/additions/`

* chore: add missing headers
2024-09-19 21:38:26 +00:00
Arran Schlosberg
81e109afcc
feat: PrecompileEnvironment.ChainConfig() (#32) 2024-09-18 12:29:56 -04:00
Arran Schlosberg
ab357e0279
feat: vm.PrecompileEnvironment access to block info (#27) 2024-09-17 13:08:42 -04:00
Arran Schlosberg
c5da3ca99e
refactor!: gas consumption for stateful precompiles (#26)
* refactor!: gas consumption for stateful precompiles

* chore: remove receiver & arg names on `statefulPrecompile.RequiredGas()`

* doc: `vm.statefulPrecompile`
2024-09-17 12:58:59 -04:00
Arran Schlosberg
58f38836c0
feat: read-only stateful precompiles (#20)
* feat: read-only argument to stateful precompiles

* refactor: group `PrecompiledStatefulRun()` args except input

* test: read-only status of all `EVM.*Call*()` methods

* feat: `PrecompileEnvironment.ReadOnlyStateDB()`

* doc: warning about allowing recursive calling

* test: precompile call from within read-only env

* refactor: introduce `{inherit,force}ReadOnly` consts

* fix: `nolint` verbose if statement
2024-09-14 10:45:18 +01:00
Arran Schlosberg
04543ea837
chore: golangci-lint CI workflow (#16)
* 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
2024-09-12 20:31:04 +01:00
Arran Schlosberg
5429fd87c8
chore: squash arr4n/libevm into libevm (#7)
* 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
2024-09-10 19:20:32 +01:00