diff --git a/core/evm.go b/core/evm.go index b7d48afd76..3c6a6cf21b 100644 --- a/core/evm.go +++ b/core/evm.go @@ -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" ) @@ -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]. diff --git a/core/extstate/statedb.go b/core/extstate/statedb.go index ab0393a9ee..a5301d43fe 100644 --- a/core/extstate/statedb.go +++ b/core/extstate/statedb.go @@ -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" @@ -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]. diff --git a/go.mod b/go.mod index 9fb08caed6..7c506a91db 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/VictoriaMetrics/fastcache v1.12.1 github.com/ava-labs/avalanchego v1.13.6-0.20251007213349-63cc1a166a56 github.com/ava-labs/firewood-go-ethhash/ffi v0.0.13 - github.com/ava-labs/libevm v1.13.15-0.20251002164226-35926db4d661 + github.com/ava-labs/libevm v1.13.15-0.20251016142715-1bccf4f2ddb2 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 @@ -44,11 +44,11 @@ require ( go.uber.org/goleak v1.3.0 go.uber.org/mock v0.5.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.42.0 + golang.org/x/crypto v0.43.0 golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e golang.org/x/sync v0.17.0 golang.org/x/time v0.12.0 - golang.org/x/tools v0.37.0 + golang.org/x/tools v0.38.0 google.golang.org/protobuf v1.36.8 gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) @@ -163,12 +163,12 @@ require ( go.opentelemetry.io/otel/trace v1.37.0 // indirect go.opentelemetry.io/proto/otlp v1.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.44.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.46.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/term v0.35.0 // indirect - golang.org/x/text v0.29.0 // indirect + golang.org/x/sys v0.37.0 // indirect + golang.org/x/term v0.36.0 // indirect + golang.org/x/text v0.30.0 // indirect gonum.org/v1/gonum v0.16.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect diff --git a/go.sum b/go.sum index eb74837482..11bad72878 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/ava-labs/avalanchego v1.13.6-0.20251007213349-63cc1a166a56 h1:Q4lnXtj github.com/ava-labs/avalanchego v1.13.6-0.20251007213349-63cc1a166a56/go.mod h1:EL0MGbL2liE9jp4QtCHR2thkNl8hCkD26DJ+7cmcaqs= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.13 h1:obPwnVCkF5+B2f8WbTepHj0ZgiW21vKUgFCtATuAYNY= github.com/ava-labs/firewood-go-ethhash/ffi v0.0.13/go.mod h1:gsGr1ICjokI9CyPaaRHMqDoDCaT1VguC/IyOTx6rJ14= -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.20251016142715-1bccf4f2ddb2 h1:hQ15IJxY7WOKqeJqCXawsiXh0NZTzmoQOemkWHz7rr4= +github.com/ava-labs/libevm v1.13.15-0.20251016142715-1bccf4f2ddb2/go.mod h1:DqSotSn4Dx/UJV+d3svfW8raR+cH7+Ohl9BpsQ5HlGU= 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= @@ -578,8 +578,8 @@ golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= -golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= +golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= +golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e h1:4qufH0hlUYs6AO6XmZC3GqfDPGSXHVXUFR6OND+iJX4= golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= @@ -592,8 +592,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -618,8 +618,8 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= @@ -671,12 +671,12 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= -golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= +golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= +golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -684,8 +684,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= +golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= @@ -704,8 +704,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/params/config.go b/params/config.go index 23e1770834..ed85231172 100644 --- a/params/config.go +++ b/params/config.go @@ -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" ) @@ -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 ( diff --git a/params/config_libevm.go b/params/config_libevm.go index 104b3b6f35..4bb4d112d4 100644 --- a/params/config_libevm.go +++ b/params/config_libevm.go @@ -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" @@ -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] diff --git a/plugin/evm/customtypes/aliases_test.go b/plugin/evm/customtypes/aliases_test.go new file mode 100644 index 0000000000..fea81f6e4a --- /dev/null +++ b/plugin/evm/customtypes/aliases_test.go @@ -0,0 +1,41 @@ +// 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 diff --git a/plugin/evm/customtypes/block_ext_test.go b/plugin/evm/customtypes/block_ext_test.go index 762411c9f8..51d15b610c 100644 --- a/plugin/evm/customtypes/block_ext_test.go +++ b/plugin/evm/customtypes/block_ext_test.go @@ -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) { diff --git a/plugin/evm/customtypes/header_ext_test.go b/plugin/evm/customtypes/header_ext_test.go index 8791ec4a4a..1cd09849b1 100644 --- a/plugin/evm/customtypes/header_ext_test.go +++ b/plugin/evm/customtypes/header_ext_test.go @@ -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) { diff --git a/plugin/evm/customtypes/libevm.go b/plugin/evm/customtypes/libevm.go index 4ef0fe9246..132ac4abf3 100644 --- a/plugin/evm/customtypes/libevm.go +++ b/plugin/evm/customtypes/libevm.go @@ -3,7 +3,11 @@ package customtypes -import ethtypes "github.com/ava-labs/libevm/core/types" +import ( + "github.com/ava-labs/libevm/libevm" + + ethtypes "github.com/ava-labs/libevm/core/types" +) var extras ethtypes.ExtraPayloads[*HeaderExtra, *BlockBodyExtra, isMultiCoin] @@ -21,3 +25,22 @@ func Register() { isMultiCoin, ]() } + +// 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 func() { extras = old }() + + return ethtypes.WithTempRegisteredExtras[HeaderExtra, BlockBodyExtra, isMultiCoin]( + lock, + func(e ethtypes.ExtraPayloads[*HeaderExtra, *BlockBodyExtra, isMultiCoin]) error { + extras = e + return fn() + }, + ) +} diff --git a/plugin/evm/customtypes/rlp_fuzzer_test.go b/plugin/evm/customtypes/rlp_fuzzer_test.go index 18f7871c20..46d7e507b6 100644 --- a/plugin/evm/customtypes/rlp_fuzzer_test.go +++ b/plugin/evm/customtypes/rlp_fuzzer_test.go @@ -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 { diff --git a/plugin/evm/customtypes/types_test.go b/plugin/evm/customtypes/types_test.go index f14ca6d260..8563f7b112 100644 --- a/plugin/evm/customtypes/types_test.go +++ b/plugin/evm/customtypes/types_test.go @@ -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) { diff --git a/plugin/evm/libevm.go b/plugin/evm/libevm.go index b1f7dff8e5..8bd86faf89 100644 --- a/plugin/evm/libevm.go +++ b/plugin/evm/libevm.go @@ -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" @@ -24,3 +26,21 @@ 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(fn func() error) error { + return libevm.WithTemporaryExtrasLock(func(lock libevm.ExtrasLock) error { + for _, wrap := range []func(libevm.ExtrasLock, func() error) error{ + core.WithTempRegisteredExtras, + customtypes.WithTempRegisteredExtras, + extstate.WithTempRegisteredExtras, + params.WithTempRegisteredExtras, + } { + inner := fn + fn = func() error { return wrap(lock, inner) } + } + return fn() + }) +} diff --git a/plugin/evm/tempextrastest/tempextras_test.go b/plugin/evm/tempextrastest/tempextras_test.go new file mode 100644 index 0000000000..ecb08bb124 --- /dev/null +++ b/plugin/evm/tempextrastest/tempextras_test.go @@ -0,0 +1,84 @@ +// Copyright (C) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// Package tempextrastest exists solely to test [evm.WithTempRegisteredLibEVMExtras] +// because the primary [evm] tests leak goroutines. These result in race +// conditions with the temporary registration of extras, which is intended to be +// done separately. +package tempextrastest + +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/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.IsAccountMultiCoin(&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 := evm.WithTempRegisteredLibEVMExtras(func() error { + 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) + } + }) + }) +} diff --git a/tests/init.go b/tests/init.go index 2f0149318c..b588e66584 100644 --- a/tests/init.go +++ b/tests/init.go @@ -37,13 +37,19 @@ import ( "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/libevm" ) // Forks table defines supported forks and their chain config. var Forks map[string]*params.ChainConfig func init() { - params.WithTempRegisteredExtras(initializeForks) + libevm.WithTemporaryExtrasLock(func(l libevm.ExtrasLock) error { + return params.WithTempRegisteredExtras(l, func() error { + initializeForks() + return nil + }) + }) } // initializeForks MUST be called inside [params.WithTempRegisteredExtras] to