Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

go_test_short:
env:
FLAKY_REGEX: "ava-labs/libevm/(triedb/pathdb|eth|eth/tracers/js|eth/tracers/logger|accounts/abi/bind|accounts/keystore|eth/downloader|miner|ethclient|ethclient/gethclient|eth/catalyst)$"
FLAKY_REGEX: "ava-labs/libevm/(triedb/pathdb|eth|eth/tracers/js|eth/tracers/logger|eth/tracers/internal/tracetest|accounts/abi/bind|accounts/keystore|eth/downloader|miner|ethclient|ethclient/gethclient|eth/catalyst)$"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -43,6 +43,8 @@ jobs:
defaults:
run:
working-directory: ./libevm/tooling
env:
TARGET_BRANCH: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref }}
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -51,7 +53,8 @@ jobs:
uses: actions/setup-go@v5
with:
go-version-file: "./libevm/tooling/go.mod"
- run: go test ./...
- run: git branch main origin/main
- run: go test -v ./... --target_branch="${{ env.TARGET_BRANCH }}"

go_generate:
env:
Expand Down
102 changes: 66 additions & 36 deletions .github/workflows/rename-module.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@ name: Rename Go module
on:
workflow_dispatch:
inputs:
source_commit:
description: "Upstream commit on which to base module renaming"
source:
description: "Reference or commit on which to base module renaming"
required: true
type: string
default: "2bd6bd01d2e8561dd7fc21b631f4a34ac16627a1"
default: "main"
branch:
description: "Branch to which a commit of the changes is pushed; leave blank for auto-naming. If non-existent, the branch is created."
type: string
default: ""

jobs:
rename-module:
Expand All @@ -17,71 +21,97 @@ jobs:
with:
fetch-depth: 0 # everything

- run: git fetch --tags https://github.com/ethereum/go-ethereum.git

- run: git checkout ${{ inputs.source }}

- name: References pointing to source
# NOTE: This step assumes that the source has been checked out, which
# might not hold if reordered.
run: |
git branch --points-at HEAD;
git tag --points-at HEAD;

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: "go.mod"

- name: Detect Go module
id: go
run: |
echo "MODULE=$(go list -m)" >> "$GITHUB_OUTPUT";
echo "MODULE_SUFFIX=$(go list -m | cut -b 12-)" >> "$GITHUB_OUTPUT"; # Strip github.com/

- name: Validate Go module
if: ${{ steps.go.outputs.MODULE != 'github.com/ava-labs/libevm' && steps.go.outputs.MODULE != 'github.com/ethereum/go-ethereum' }}
run: echo "Unexpected Go module ${{ steps.go.outputs.MODULE }}" && exit 1;

- name: Set variables
id: vars
# Including hashes of both the source commit and the workflow file makes
# this idempotent.
env:
WORKFLOW_HASH: ${{ hashFiles('.github/workflows/rename-module.yml') }}
# `cond && ifTrue || ifFalse` is effectively a ternary operator, based on short-circuiting Boolean logic (assumes `ifTrue` is truthy)
RENAME_TO: ${{ steps.go.outputs.MODULE_SUFFIX == 'ava-labs/libevm' && 'ethereum/go-ethereum' || 'ava-labs/libevm' }}
run: |
echo "RENAME_FROM=${{ steps.go.outputs.MODULE_SUFFIX}}" >> "$GITHUB_OUTPUT";
echo "RENAME_TO=${RENAME_TO}" >> "$GITHUB_OUTPUT";
echo "WORKFLOW_HASH=${WORKFLOW_HASH}" >> "$GITHUB_OUTPUT";
echo "DEST_BRANCH=auto-rename-module_source-${{ inputs.source_commit }}_workflow-${WORKFLOW_HASH}-${{ github.ref_name }}" \
echo "SOURCE_COMMIT=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT";
echo "AUTO_BRANCH_NAME=auto/rename-module/to=${RENAME_TO}/src=$(git rev-parse HEAD)/workflow_sha=${{ github.workflow_sha }}/run=${{ github.run_id }}" \
>> "$GITHUB_OUTPUT";

- name: Fetch tags from ethereum/go-ethereum
run: git fetch --tags https://github.com/ethereum/go-ethereum.git

- name: Tags pointing to source commit
run: git tag --points-at ${{ inputs.source_commit }}

- name: Check out source commit
run: git checkout ${{ inputs.source_commit }}

- name: Globally update module name
- name: Globally rename module from ${{ steps.vars.outputs.RENAME_FROM }} to ${{ steps.vars.outputs.RENAME_TO }}
run: |
go mod edit -module github.com/ava-labs/libevm;
go mod edit -module github.com/${{ steps.vars.outputs.RENAME_TO }};
find . \
-iname '*.go' \
-o -iname '*.txt' \
-o -iname '*.go.tpl' \
-o -iname '*.proto' | xargs \
sed -i -E 's|(["`]github\.com/)ethereum/go-ethereum|\1ava-labs/libevm|g';
-o -iname '*.proto' \
-not -wholename '*/libevm/tooling/*' | xargs \
sed -i -E 's|(["`]github\.com/)${{ steps.vars.outputs.RENAME_FROM }}|\1${{ steps.vars.outputs.RENAME_TO }}|g';

- name: Remnant references
run: |
find . -type f | \
xargs grep -In github.com/ethereum/go-ethereum | \
grep -v "https://github.com/ethereum/go-ethereum"

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: "go.mod"
xargs grep -In github.com/${{ steps.vars.outputs.RENAME_FROM }} | \
grep -v "https://github.com/${{ steps.vars.outputs.RENAME_FROM }}"

- name: Smoke tests
# `go list` shows us the module name and grep will non-zero exit on mismatch
# `go list -m` shows us the module name and grep will non-zero exit on mismatch
# `go build` is a rudimentary but broad test of correctness
# The explicitly tested packages are edge cases:
# - bind generates tests and a go.mod on the fly
# - rlpgen has testdata with imports that need updating
run: |
go list . | grep ava-labs/libevm;
go list -m | grep github.com/${{ steps.vars.outputs.RENAME_TO }};
go build ./...;
go test ./accounts/abi/bind ./rlp/rlpgen

- name: Create new branch
- name: Set branch name
id: branch
env:
BRANCH: ${{ steps.vars.outputs.DEST_BRANCH }}
BRANCH: ${{ inputs.branch || steps.vars.outputs.AUTO_BRANCH_NAME }}
run: echo "NAME=${BRANCH}" >> "$GITHUB_OUTPUT";

- name: Check out branch (create if non-existent)
env:
BRANCH: ${{ steps.branch.outputs.NAME }}
run: |
git checkout -b "${BRANCH}";
git push origin "${BRANCH}";
git checkout "${BRANCH}" 2>/dev/null || \
(git checkout -b "${BRANCH}" && git push origin "${BRANCH}");

- name: Commit to new branch
- name: Commit to branch
uses: planetscale/ghcommit-action@d4176bfacef926cc2db351eab20398dfc2f593b5 # v0.2.0
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
with:
# WARNING: mirror any change to the commit_message value below in libevm-delta.yml
commit_message: "[AUTO] rename Go module + update internal import paths\n\nWorkflow: ${{ steps.vars.outputs.WORKFLOW_HASH }} on branch ${{ github.ref_name }}"
commit_message: |
[AUTO] rename Go module to ${{ steps.vars.outputs.RENAME_TO }}

Source: ${{ steps.vars.outputs.SOURCE_COMMIT }} (${{ inputs.source }})
Workflow: ${{ github.workflow_sha }} (${{ github.workflow_ref }})
Run ID: ${{ github.run_id }}
repo: ${{ github.repository }}
branch: ${{ steps.vars.outputs.DEST_BRANCH }}
branch: ${{ steps.branch.outputs.NAME }}
16 changes: 15 additions & 1 deletion core/state_transition.libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,24 @@

package core

import (
"github.com/ava-labs/libevm/log"
)

// canExecuteTransaction is a convenience wrapper for calling the
// [params.RulesHooks.CanExecuteTransaction] hook.
func (st *StateTransition) canExecuteTransaction() error {
bCtx := st.evm.Context
rules := st.evm.ChainConfig().Rules(bCtx.BlockNumber, bCtx.Random != nil, bCtx.Time)
return rules.Hooks().CanExecuteTransaction(st.msg.From, st.msg.To, st.state)
if err := rules.Hooks().CanExecuteTransaction(st.msg.From, st.msg.To, st.state); err != nil {
log.Debug(
"Transaction execution blocked by libevm hook",
"from", st.msg.From,
"to", st.msg.To,
"hooks", log.TypeOf(rules.Hooks()),
"reason", err,
)
return err
}
return nil
}
7 changes: 7 additions & 0 deletions core/types/rlp_payload.libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/ava-labs/libevm/libevm/pseudo"
"github.com/ava-labs/libevm/libevm/register"
"github.com/ava-labs/libevm/libevm/testonly"
"github.com/ava-labs/libevm/log"
"github.com/ava-labs/libevm/rlp"
)

Expand Down Expand Up @@ -84,6 +85,12 @@ func RegisterExtras[
newStateAccount: pseudo.NewConstructor[SA]().Zero,
hooks: extra,
})
log.Info(
"Registered core/types extras",
"Header", log.TypeOf(pseudo.Zero[HPtr]().Value.Get()),
"Block/Body", log.TypeOf(pseudo.Zero[BPtr]().Value.Get()),
"StateAccount", log.TypeOf(pseudo.Zero[SA]().Value.Get()),
)
return extra
}

Expand Down
5 changes: 1 addition & 4 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,7 @@ func init() {
}

// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) (active []common.Address) {
defer func() {
active = rules.Hooks().ActivePrecompiles(append([]common.Address{}, active...))
}()
func activePrecompiles(rules params.Rules) []common.Address {
switch {
case rules.IsCancun:
return PrecompiledAddressesCancun
Expand Down
29 changes: 29 additions & 0 deletions core/vm/contracts.libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,42 @@ import (
"math/big"

"github.com/holiman/uint256"
"golang.org/x/exp/slog"

"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/libevm"
"github.com/ava-labs/libevm/libevm/set"
"github.com/ava-labs/libevm/log"
"github.com/ava-labs/libevm/params"
)

// ActivePrecompiles returns the precompiles enabled with the current configuration.
func ActivePrecompiles(rules params.Rules) []common.Address {
orig := activePrecompiles(rules) // original, upstream implementation
active := rules.Hooks().ActivePrecompiles(append([]common.Address{}, orig...))

// As all set computation is done lazily and only when debugging, there is
// some duplication in favour of simplified code.
log.Debug(
"Overriding active precompiles",
"added", log.Lazy(func() slog.Value {
diff := set.From(active...).Sub(set.From(orig...))
return slog.AnyValue(diff.Slice())
}),
"removed", log.Lazy(func() slog.Value {
diff := set.From(orig...).Sub(set.From(active...))
return slog.AnyValue(diff.Slice())
}),
"unchanged", log.Lazy(func() slog.Value {
both := set.From(active...).Intersect(set.From(orig...))
return slog.AnyValue(both.Slice())
}),
)

return active
}

// evmCallArgs mirrors the parameters of the [EVM] methods Call(), CallCode(),
// DelegateCall() and StaticCall(). Its fields are identical to those of the
// parameters, prepended with the receiver name and call type. As
Expand Down
6 changes: 3 additions & 3 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/crypto"
"github.com/ava-labs/libevm/libevm"
"github.com/ava-labs/libevm/log"
"github.com/ava-labs/libevm/params"
"github.com/holiman/uint256"
)
Expand All @@ -40,6 +40,7 @@ type (

func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) {
if p, override := evm.chainRules.Hooks().PrecompileOverride(addr); override {
log.Debug("Overriding precompile", "address", addr, "implementation", log.TypeOf(p))
return p, p != nil
}
var precompiles map[common.Address]PrecompiledContract
Expand Down Expand Up @@ -459,8 +460,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// This check MUST be placed after the caller's nonce is incremented but
// before all other state-modifying behaviour, even if changes may be
// reverted to the snapshot.
addrs := &libevm.AddressContext{Origin: evm.Origin, Caller: caller.Address(), Self: address}
gas, err := evm.chainRules.Hooks().CanCreateContract(addrs, gas, evm.StateDB)
gas, err := evm.canCreateContract(caller, address, gas)
if err != nil {
return nil, common.Address{}, gas, err
}
Expand Down
45 changes: 45 additions & 0 deletions core/vm/evm.libevm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2025 the libevm authors.
//
// The libevm additions to go-ethereum are free software: you can redistribute
// them and/or modify them under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The libevm additions are distributed in the hope that they will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see
// <http://www.gnu.org/licenses/>.

package vm

import (
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/libevm"
"github.com/ava-labs/libevm/log"
)

// canCreateContract is a convenience wrapper for calling the
// [params.RulesHooks.CanCreateContract] hook.
func (evm *EVM) canCreateContract(caller ContractRef, contractToCreate common.Address, gas uint64) (remainingGas uint64, _ error) {
addrs := &libevm.AddressContext{Origin: evm.Origin, Caller: caller.Address(), Self: contractToCreate}
gas, err := evm.chainRules.Hooks().CanCreateContract(addrs, gas, evm.StateDB)

// NOTE that this block only performs logging and that all paths propagate
// `(gas, err)` unmodified.
if err != nil {
log.Debug(
"Contract creation blocked by libevm hook",
"origin", addrs.Origin,
"caller", addrs.Caller,
"contract", addrs.Self,
"hooks", log.TypeOf(evm.chainRules.Hooks()),
"reason", err,
)
}

return gas, err
}
Loading
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.