Skip to content
Draft
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
11 changes: 11 additions & 0 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/ava-labs/libevm/core/state"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/core/vm"
"github.com/ava-labs/libevm/libevm"
"github.com/ava-labs/libevm/libevm/stateconf"
"github.com/holiman/uint256"
)
Expand All @@ -56,6 +57,16 @@ func RegisterExtras() {
vm.RegisterHooks(hooks{})
}

// WithTempRegisteredExtras runs `fn` with temporary registration otherwise
// equivalent to a call to [RegisterExtras], but limited to the life of `fn`.
//
// This function is not intended for direct use. Use
// `evm.WithTempRegisteredLibEVMExtras()` instead as it calls this along with
// all other temporary-registration functions.
func WithTempRegisteredExtras(lock libevm.ExtrasLock, fn func() error) error {
return vm.WithTempRegisteredHooks(lock, hooks{}, fn)
}

type hooks struct{}

// OverrideNewEVMArgs is a hook that is called in [vm.NewEVM].
Expand Down
11 changes: 11 additions & 0 deletions core/extstate/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/core/state"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/libevm"
"github.com/ava-labs/libevm/libevm/stateconf"
"github.com/holiman/uint256"

Expand All @@ -28,6 +29,16 @@ func RegisterExtras() {
state.RegisterExtras(normalizeStateKeysHook{})
}

// WithTempRegisteredExtras runs `fn` with temporary registration otherwise
// equivalent to a call to [RegisterExtras], but limited to the life of `fn`.
//
// This function is not intended for direct use. Use
// `evm.WithTempRegisteredLibEVMExtras()` instead as it calls this along with
// all other temporary-registration functions.
func WithTempRegisteredExtras(lock libevm.ExtrasLock, fn func() error) error {
return state.WithTempRegisteredExtras(lock, normalizeStateKeysHook{}, fn)
}

type normalizeStateKeysHook struct{}

// TransformStateKey transforms all keys with [normalizeStateKey].
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/VictoriaMetrics/fastcache v1.12.1
github.com/ava-labs/avalanchego v1.13.6-0.20251003124629-84e9aebcfbc0
github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12
github.com/ava-labs/libevm v1.13.15-0.20251002164226-35926db4d661
github.com/ava-labs/libevm v1.13.15-0.20251007153555-3ee649c91723
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
github.com/deckarep/golang-set/v2 v2.1.0
github.com/fjl/gencodec v0.1.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12 h1:aMcrLbpJ/dyu2kZDf/Di/4JIW
github.com/ava-labs/firewood-go-ethhash/ffi v0.0.12/go.mod h1:cq89ua3iiZ5wPBALTEQS5eG8DIZcs7ov6OiL4YR1BVY=
github.com/ava-labs/libevm v1.13.15-0.20251002164226-35926db4d661 h1:lt4yQE1HMvxWrdD5RFj+h9kWUsZK2rmNohvkeQsbG9M=
github.com/ava-labs/libevm v1.13.15-0.20251002164226-35926db4d661/go.mod h1:ivRC/KojP8sai7j8WnpXIReQpcRklL2bIzoysnjpARQ=
github.com/ava-labs/libevm v1.13.15-0.20251007153555-3ee649c91723 h1:VCPjG+9LOu1M74Eeuhhe536TzIXJEueHT83rgkkDfAY=
github.com/ava-labs/libevm v1.13.15-0.20251007153555-3ee649c91723/go.mod h1:ivRC/KojP8sai7j8WnpXIReQpcRklL2bIzoysnjpARQ=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
Expand Down
8 changes: 7 additions & 1 deletion params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/utils"
"github.com/ava-labs/libevm/libevm"
ethparams "github.com/ava-labs/libevm/params"
)

Expand All @@ -46,7 +47,12 @@ var (
)

func init() {
WithTempRegisteredExtras(initialiseChainConfigs)
libevm.WithTemporaryExtrasLock(func(l libevm.ExtrasLock) error {
return WithTempRegisteredExtras(l, func() error {
initialiseChainConfigs()
return nil
})
})
}

var (
Expand Down
21 changes: 14 additions & 7 deletions params/config_libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math/big"

"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/libevm"

"github.com/ava-labs/coreth/params/extras"
"github.com/ava-labs/coreth/precompile/modules"
Expand Down Expand Up @@ -34,16 +35,22 @@ func RegisterExtras() {
}

// WithTempRegisteredExtras runs `fn` with temporary registration otherwise
// equivalent to a call to [RegisterExtras], but limited to the life of `fn`. It
// is not threadsafe.
func WithTempRegisteredExtras(fn func()) {
// equivalent to a call to [RegisterExtras], but limited to the life of `fn`.
//
// This function is not intended for direct use. Use
// `evm.WithTempRegisteredLibEVMExtras()` instead as it calls this along with
// all other temporary-registration functions.
func WithTempRegisteredExtras(lock libevm.ExtrasLock, fn func() error) error {
old := payloads
defer func() { payloads = old }()

ethparams.WithTempRegisteredExtras(extrasToRegister(), func(extras ethparams.ExtraPayloads[*extras.ChainConfig, RulesExtra]) {
payloads = extras
fn()
})
return ethparams.WithTempRegisteredExtras(
lock, extrasToRegister(),
func(extras ethparams.ExtraPayloads[*extras.ChainConfig, RulesExtra]) error {
payloads = extras
return fn()
},
)
}

var payloads ethparams.ExtraPayloads[*extras.ChainConfig, RulesExtra]
Expand Down
43 changes: 43 additions & 0 deletions plugin/evm/customtypes/aliases_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package customtypes

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

// TODO(arr4n) These tests were originally part of the `coreth/core/types`
// package so assume the presence of identifiers. Aliases reduce PR noise during
// the refactoring.

type (
AccessListTx = types.AccessListTx
Block = types.Block
BlockNonce = types.BlockNonce
Bloom = types.Bloom
Body = types.Body
DynamicFeeTx = types.DynamicFeeTx
Header = types.Header
LegacyTx = types.LegacyTx
Log = types.Log
Receipt = types.Receipt
ReceiptForStorage = types.ReceiptForStorage
Receipts = types.Receipts
Transaction = types.Transaction
Transactions = types.Transactions
Withdrawal = types.Withdrawal
Withdrawals = types.Withdrawals
)

var (
// Function aliases in production code MUST be `func` declarations, not
// variables; this is only acceptable in tests.
CopyHeader = types.CopyHeader
MustSignNewTx = types.MustSignNewTx
NewBlock = types.NewBlock
NewLondonSigner = types.NewLondonSigner
NewTransaction = types.NewTransaction
)

const ReceiptStatusSuccessful = types.ReceiptStatusSuccessful
5 changes: 0 additions & 5 deletions plugin/evm/customtypes/block_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ import (

"github.com/ava-labs/coreth/utils"
"github.com/ava-labs/coreth/utils/utilstest"

// TODO(arr4n) These tests were originally part of the `coreth/core/types`
// package so assume the presence of identifiers. A dot-import reduces PR
// noise during the refactoring.
. "github.com/ava-labs/libevm/core/types"
)

func TestCopyHeader(t *testing.T) {
Expand Down
5 changes: 0 additions & 5 deletions plugin/evm/customtypes/header_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ import (
"github.com/stretchr/testify/require"

"github.com/ava-labs/coreth/utils/utilstest"

// TODO(arr4n) These tests were originally part of the `coreth/core/types`
// package so assume the presence of identifiers. A dot-import reduces PR
// noise during the refactoring.
. "github.com/ava-labs/libevm/core/types"
)

func TestHeaderRLP(t *testing.T) {
Expand Down
31 changes: 28 additions & 3 deletions plugin/evm/customtypes/libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@
package customtypes

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

ethtypes "github.com/ava-labs/libevm/core/types"
)

var extras ethtypes.ExtraPayloads[*HeaderExtra, *BlockBodyExtra, isMultiCoin]

func setExtras(e ethtypes.ExtraPayloads[*HeaderExtra, *BlockBodyExtra, isMultiCoin]) {
extras = e
IsMultiCoinPayloads = e.StateAccount
}

// Register registers the types with libevm. It MUST NOT be called more than
// once and therefore is only allowed to be used in tests and `package main`, to
// avoid polluting other packages that transitively depend on this one but don't
Expand All @@ -17,10 +24,28 @@ var extras ethtypes.ExtraPayloads[*HeaderExtra, *BlockBodyExtra, isMultiCoin]
// Without a call to Register, none of the functionality of this package will
// work, and most will simply panic.
func Register() {
extras = ethtypes.RegisterExtras[
setExtras(ethtypes.RegisterExtras[
HeaderExtra, *HeaderExtra,
BlockBodyExtra, *BlockBodyExtra,
isMultiCoin,
]()
IsMultiCoinPayloads = extras.StateAccount
]())
}

// WithTempRegisteredExtras runs `fn` with temporary registration otherwise
// equivalent to a call to [RegisterExtras], but limited to the life of `fn`.
//
// This function is not intended for direct use. Use
// `evm.WithTempRegisteredLibEVMExtras()` instead as it calls this along with
// all other temporary-registration functions.
func WithTempRegisteredExtras(lock libevm.ExtrasLock, fn func() error) error {
old := extras
defer setExtras(old)

return ethtypes.WithTempRegisteredExtras[HeaderExtra, BlockBodyExtra, isMultiCoin](
lock,
func(e ethtypes.ExtraPayloads[*HeaderExtra, *BlockBodyExtra, isMultiCoin]) error {
setExtras(e)
return fn()
},
)
}
5 changes: 0 additions & 5 deletions plugin/evm/customtypes/rlp_fuzzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ import (

"github.com/ava-labs/libevm/rlp"
"github.com/holiman/uint256"

// TODO(arr4n) These tests were originally part of the `coreth/core/types`
// package so assume the presence of identifiers. A dot-import reduces PR
// noise during the refactoring.
. "github.com/ava-labs/libevm/core/types"
)

func decodeEncode(input []byte, val interface{}) error {
Expand Down
5 changes: 0 additions & 5 deletions plugin/evm/customtypes/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ import (
"github.com/ava-labs/libevm/common"
"github.com/ava-labs/libevm/crypto"
"github.com/ava-labs/libevm/rlp"

// TODO(arr4n) These tests were originally part of the `coreth/core/types`
// package so assume the presence of identifiers. A dot-import reduces PR
// noise during the refactoring.
. "github.com/ava-labs/libevm/core/types"
)

func TestMain(m *testing.M) {
Expand Down
15 changes: 15 additions & 0 deletions plugin/evm/libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package evm

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

"github.com/ava-labs/coreth/core"
"github.com/ava-labs/coreth/core/extstate"
"github.com/ava-labs/coreth/params"
Expand All @@ -24,3 +26,16 @@ func RegisterAllLibEVMExtras() {
extstate.RegisterExtras()
params.RegisterExtras()
}

// WithTempRegisteredLibEVMExtras runs `fn` with temporary registration
// otherwise equivalent to a call to [RegisterAllLibEVMExtras], but limited to
// the life of `fn`.
func WithTempRegisteredLibEVMExtras(lock libevm.ExtrasLock, fn func() error) error {
return core.WithTempRegisteredExtras(lock, func() error {
return customtypes.WithTempRegisteredExtras(lock, func() error {
return extstate.WithTempRegisteredExtras(lock, func() error {
return params.WithTempRegisteredExtras(lock, fn)
})
})
})
}
87 changes: 87 additions & 0 deletions plugin/evm/libevm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

// These tests are run in a different package because the primary `evm` tests
// leak goroutines that result in race conditions with the temporary
// registration of extras, which is intended to be done separately.
package evm_test

import (
"testing"

"github.com/ava-labs/libevm/core/state"
"github.com/ava-labs/libevm/core/types"
"github.com/ava-labs/libevm/core/vm"
"github.com/ava-labs/libevm/libevm"
"github.com/ava-labs/libevm/params"
"github.com/stretchr/testify/require"

"github.com/ava-labs/coreth/plugin/evm"
"github.com/ava-labs/coreth/plugin/evm/customtypes"

cparams "github.com/ava-labs/coreth/params"
)

func TestWithTempRegisteredLibEVMExtras(t *testing.T) {
params.TestOnlyClearRegisteredExtras()
state.TestOnlyClearRegisteredExtras()
types.TestOnlyClearRegisteredExtras()
vm.TestOnlyClearRegisteredHooks()

var reRegistered bool
t.Cleanup(func() {
if !reRegistered {
evm.RegisterAllLibEVMExtras()
}
})

payloadTests := map[string]func(t *testing.T){
"customtypes": func(t *testing.T) {
t.Helper()
require.False(t, customtypes.IsMultiCoin(&types.StateAccount{}))
},
"params": func(t *testing.T) {
t.Helper()
require.False(t, cparams.GetRulesExtra(params.Rules{}).IsEtna)
},
}

t.Run("with_temp_registration", func(t *testing.T) {
err := libevm.WithTemporaryExtrasLock(func(lock libevm.ExtrasLock) error {
return evm.WithTempRegisteredLibEVMExtras(lock, func() error { //nolint:whitespace // Avoid visual crowding due to nested calls

t.Run("payloads", func(t *testing.T) {
for pkg, fn := range payloadTests {
t.Run(pkg, fn)
}
})
return nil
})
})
require.NoError(t, err)
})

// These are deliberately placed after the tests of temporary registration,
// to demonstrate that (a) they are indeed temporary, and (b) they would
// otherwise panic.
t.Run("without_registration", func(t *testing.T) {
t.Run("payloads", func(t *testing.T) {
for pkg, fn := range payloadTests {
t.Run(pkg, func(t *testing.T) {
require.Panics(t, func() { fn(t) })
})
}
})
})

evm.RegisterAllLibEVMExtras()
reRegistered = true

t.Run("with_permanent_registration", func(t *testing.T) {
t.Run("payloads", func(t *testing.T) {
for pkg, fn := range payloadTests {
t.Run(pkg, fn)
}
})
})
}
Loading
Loading