Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: use libevm (params, core/vm) #1335

Draft
wants to merge 49 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
6d60741
wip: use libevm (params)
darioush Sep 5, 2024
d999563
base change
darioush Sep 6, 2024
1c7e25b
test unmarshal capability
darioush Sep 6, 2024
a119516
separate avalanche stuff to its own type
darioush Sep 6, 2024
25bb446
separate RulesExtra
darioush Sep 6, 2024
c371a3a
separate calls to extra
darioush Sep 6, 2024
9b27ebe
use darioush/access-list-for-hook
darioush Sep 9, 2024
784e2e6
config_extra: move methods off Rules/ChainConfig receivers
darioush Sep 9, 2024
a8a5c80
un-embed RulesExtra
darioush Sep 9, 2024
d74cea6
params: use gethparams.Rules
darioush Sep 9, 2024
ed1165b
unused
darioush Sep 9, 2024
e1088b1
update chainConfig.Rules callsites to pass params.IsMergeTODO
darioush Sep 10, 2024
846f52a
params/config: type alias ConfigCompatError
darioush Sep 10, 2024
932967d
bring in gethparams.ChainConfig (wip)
darioush Sep 10, 2024
053af95
params: add LondonBlock
darioush Sep 10, 2024
44db6c7
params: add ShanghaiTime
darioush Sep 10, 2024
cd5adc9
params: add BerlinBlock
darioush Sep 10, 2024
70659d3
params: unused code
darioush Sep 10, 2024
5d5fb59
reduce diff
darioush Sep 10, 2024
07203b0
update to darioush/json-root branch
darioush Sep 10, 2024
99c1b70
params: add IsLondon checks to Cancun (similar to upstream)
darioush Sep 10, 2024
e8febb8
race free impl for WithExtra, still hack
darioush Sep 11, 2024
04338c7
Merge branch 'master' of github.com:ava-labs/subnet-evm into use-libe…
darioush Sep 11, 2024
a5a43cc
use RulesExtra (instead of ptr)
darioush Sep 11, 2024
4a41e81
bump libevm
darioush Sep 11, 2024
5049989
bump libevm
darioush Sep 11, 2024
2a46ead
chain hooks for create
darioush Sep 11, 2024
672f54e
use geth forks in core/vm/evm.go
darioush Sep 11, 2024
7b8ec21
core/types, core/state: import gethparams
darioush Sep 12, 2024
f30f450
core/vm: use gethparams and hook in precompiles
darioush Sep 12, 2024
dc4b361
core/types: use upstream Log type
darioush Sep 12, 2024
5038b15
core/types: use upstream for AccessList
darioush Sep 12, 2024
dad843a
core/vm: use libevm
darioush Sep 12, 2024
0fe10ff
linting
darioush Sep 12, 2024
5b073ad
fix mockgen
darioush Sep 12, 2024
34a17a6
adjustment for libevm chainconfig changes
darioush Sep 12, 2024
73b5559
populate vm.BlockContext.Random as Difficulty starting at Durango (to…
darioush Sep 13, 2024
61b1694
nit
darioush Sep 13, 2024
8d2493f
Merge branch 'master' of github.com:ava-labs/subnet-evm into use-libe…
darioush Sep 17, 2024
12cd83e
update libevm
darioush Sep 17, 2024
20854a1
update libevm
darioush Sep 17, 2024
e9ee414
rebase to latest libevm (+ fix commit on darioush/json-root)
darioush Sep 24, 2024
61eb933
add support for custom upstream tag
darioush Sep 24, 2024
28caecc
remove eth/tracers subdirs
darioush Sep 24, 2024
86cdfbe
update geth-allowed-packages.txt
darioush Sep 24, 2024
f1d77d2
Merge branch 'master' of github.com:ava-labs/subnet-evm into use-libe…
darioush Sep 24, 2024
7bfbe08
lint
darioush Sep 24, 2024
27a8bfb
more lint
darioush Sep 24, 2024
d72ff25
more lint
darioush Sep 24, 2024
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
9 changes: 4 additions & 5 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,11 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
if pre.Env.BaseFee != nil {
vmContext.BaseFee = new(big.Int).Set(pre.Env.BaseFee)
}
// NOTE: this has been removed
// If random is defined, add it to the vmContext.
// if pre.Env.Random != nil {
// rnd := common.BigToHash(pre.Env.Random)
// vmContext.Random = &rnd
// }
if pre.Env.Random != nil {
rnd := common.BigToHash(pre.Env.Random)
vmContext.Random = &rnd
}
// Calculate the BlobBaseFee
var excessBlobGas uint64
if pre.Env.ExcessBlobGas != nil {
Expand Down
4 changes: 2 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (b *BlockGen) addTx(bc *BlockChain, vmConfig vm.Config, tx *types.Transacti
// instruction will panic during execution if it attempts to access a block number outside
// of the range created by GenerateChain.
func (b *BlockGen) AddTx(tx *types.Transaction) {
b.addTx(nil, vm.Config{}, tx)
b.addTx(&BlockChain{chainConfig: params.TestChainConfig}, vm.Config{}, tx)
}

// AddTxWithChain adds a transaction to the generated block. If no coinbase has
Expand All @@ -166,7 +166,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
// been set, the block's coinbase is set to the zero address.
// The evm interpreter can be customized with the provided vm config.
func (b *BlockGen) AddTxWithVMConfig(tx *types.Transaction, config vm.Config) {
b.addTx(nil, config, tx)
b.addTx(&BlockChain{chainConfig: params.TestChainConfig}, config, tx)
}

// GetBalance returns the balance of the given address at the generated block.
Expand Down
18 changes: 16 additions & 2 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ import (
"github.com/ava-labs/subnet-evm/consensus"
"github.com/ava-labs/subnet-evm/consensus/misc/eip4844"
"github.com/ava-labs/subnet-evm/core/types"
"github.com/ava-labs/subnet-evm/params"
"github.com/ava-labs/subnet-evm/predicate"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/libevm"
"github.com/ethereum/go-ethereum/log"
"github.com/holiman/uint256"
)
Expand All @@ -47,6 +49,8 @@ type ChainContext interface {

// GetHeader returns the header corresponding to the hash/number argument pair.
GetHeader(common.Hash, uint64) *types.Header

Config() *params.ChainConfig
}

// NewEVMBlockContext creates a new context for use in the EVM.
Expand All @@ -73,15 +77,16 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common
// in header.Extra.
// This function is used to create a BlockContext when the header Extra data is not fully formed yet and it's more efficient to pass in predicateResults
// directly rather than re-encode the latest results when executing each individaul transaction.
func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateResults *predicate.Results) vm.BlockContext {
func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateResults libevm.PredicateResults) vm.BlockContext {
return newEVMBlockContext(header, chain, author, predicateResults)
}

func newEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, predicateResults *predicate.Results) vm.BlockContext {
func newEVMBlockContext(header *types.Header, chain ChainContext, author *common.Address, predicateResults libevm.PredicateResults) vm.BlockContext {
var (
beneficiary common.Address
baseFee *big.Int
blobBaseFee *big.Int
random *common.Hash
)

// If we don't have an explicit author (i.e. not mining), extract from the header
Expand All @@ -96,6 +101,14 @@ func newEVMBlockContext(header *types.Header, chain ChainContext, author *common
if header.ExcessBlobGas != nil {
blobBaseFee = eip4844.CalcBlobFee(*header.ExcessBlobGas)
}

// Durango enables the Shanghai upgrade of eth, which takes place after the
// Merge upgrade.
isDurango := params.GetExtra(chain.Config()).IsDurango(header.Time)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upstream avoids this dependency here (on chain config/rules) by checking if Difficulty is 0,
but we cannot rely on that because we already made blocks with difficulty set to 1.

if isDurango {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we rather introduce shangai (could be a different PR)

Copy link
Collaborator Author

@darioush darioush Oct 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is avalanche specific, so I think it is better to activate it via durango.
(i.e. activating shanghai doesn't set the random field to the difficulty value on ethereum networks)

random = new(common.Hash)
random.SetBytes(header.Difficulty.Bytes())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this potentially dangerous as we have activated Durango without this field set?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should not be dangerous since we will not serialize this value back.
it is used by the "random" opcode, so we keep it as "difficulty", which retains the previous semantics.
This way we can avoid changing the jump table compared with upstream, which seems better.
however, I do agree that it's not in correspondence with the block header.

}
return vm.BlockContext{
CanTransfer: CanTransfer,
Transfer: Transfer,
Expand All @@ -108,6 +121,7 @@ func newEVMBlockContext(header *types.Header, chain ChainContext, author *common
BaseFee: baseFee,
BlobBaseFee: blobBaseFee,
GasLimit: header.GasLimit,
Random: random,
}
}

Expand Down
1 change: 1 addition & 0 deletions core/vm/runtime/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func NewEnv(cfg *Config) *vm.EVM {
GasLimit: cfg.GasLimit,
BaseFee: cfg.BaseFee,
BlobBaseFee: cfg.BlobBaseFee,
Random: cfg.Random,
}

return vm.NewEVM(blockContext, txContext, cfg.State, cfg.ChainConfig, cfg.EVMConfig)
Expand Down
2 changes: 2 additions & 0 deletions core/vm/runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header {
return fakeHeader(n, parentHash)
}

func (d *dummyChain) Config() *params.ChainConfig { return params.TestChainConfig }

// TestBlockhash tests the blockhash operation. It's a bit special, since it internally
// requires access to a chain reader.
func TestBlockhash(t *testing.T) {
Expand Down
5 changes: 5 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ func (diff *BlockOverrides) Apply(blockCtx *vm.BlockContext) {
type ChainContextBackend interface {
Engine() consensus.Engine
HeaderByNumber(context.Context, rpc.BlockNumber) (*types.Header, error)
ChainConfig() *params.ChainConfig
}

// ChainContext is an implementation of core.ChainContext. It's main use-case
Expand All @@ -1050,6 +1051,10 @@ func NewChainContext(ctx context.Context, backend ChainContextBackend) *ChainCon
return &ChainContext{ctx: ctx, b: backend}
}

func (context *ChainContext) Config() *params.ChainConfig {
return context.b.ChainConfig()
}

func (context *ChainContext) Engine() consensus.Engine {
return context.b.Engine()
}
Expand Down
7 changes: 6 additions & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/libevm"
"github.com/ethereum/go-ethereum/log"
"github.com/holiman/uint256"
)
Expand Down Expand Up @@ -352,7 +353,11 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, coinb
}
env.predicateResults.SetTxResults(tx.Hash(), results)

blockContext = core.NewEVMBlockContextWithPredicateResults(env.header, w.chain, &coinbase, env.predicateResults)
var predicateResults libevm.PredicateResults
if env.predicateResults != nil {
predicateResults = env.predicateResults
}
blockContext = core.NewEVMBlockContextWithPredicateResults(env.header, w.chain, &coinbase, predicateResults)
} else {
blockContext = core.NewEVMBlockContext(env.header, w.chain, &coinbase)
}
Expand Down
6 changes: 0 additions & 6 deletions params/config_libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,6 @@ func constructRulesExtra(c *gethparams.ChainConfig, r *gethparams.Rules, cEx *Ch
return &rules
}
rules.AvalancheRules = cEx.GetAvalancheRules(timestamp)
if rules.AvalancheRules.IsDurango || rules.AvalancheRules.IsEtna {
// After Durango, geth rules should be used with isMerge set to true.
// We can't call c.Rules because it will recurse back here.
r.IsShanghai = c.IsShanghai(blockNum, timestamp)
r.IsCancun = c.IsCancun(blockNum, timestamp)
}
rules.gethrules = *r

// Initialize the stateful precompiles that should be enabled at [blockTimestamp].
Expand Down
11 changes: 2 additions & 9 deletions params/hooks_libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,13 @@ import (
"github.com/ava-labs/subnet-evm/precompile/precompileconfig"
"github.com/ava-labs/subnet-evm/vmerrs"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/libevm"
gethparams "github.com/ethereum/go-ethereum/params"
)

func (r RulesExtra) JumpTable() interface{} {
switch {
case r.gethrules.IsCancun:
return &vm.SubnetEVMCancunInstructionSet
case r.IsDurango:
return &vm.SubnetEVMDurangoInstructionSet
case r.IsSubnetEVM:
return &vm.SubnetEVMInstructionSet
}
// XXX: This does not account for the any possible differences in EIP-3529
// Do not merge without verifying.
return nil
}

Expand Down
13 changes: 6 additions & 7 deletions tests/gen_stenv.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tests/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ var Forks = map[string]*params.ChainConfig{
IstanbulBlock: big.NewInt(0),
BerlinBlock: big.NewInt(0),
LondonBlock: big.NewInt(0),
ShanghaiTime: utils.NewUint64(0),
CancunTime: utils.NewUint64(0),
},
&params.ChainConfigExtra{
Expand Down
10 changes: 7 additions & 3 deletions tests/state_test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ type stPostState struct {
//go:generate go run github.com/fjl/gencodec -type stEnv -field-override stEnvMarshaling -out gen_stenv.go
type stEnv struct {
Coinbase common.Address `json:"currentCoinbase" gencodec:"required"`
Difficulty *big.Int `json:"currentDifficulty" gencodec:"required"`
Difficulty *big.Int `json:"currentDifficulty" gencodec:"optional"`
Random *big.Int `json:"currentRandom" gencodec:"optional"`
GasLimit uint64 `json:"currentGasLimit" gencodec:"required"`
Number uint64 `json:"currentNumber" gencodec:"required"`
Expand Down Expand Up @@ -300,10 +300,14 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh

// Prepare the EVM.
txContext := core.NewEVMTxContext(msg)
context := core.NewEVMBlockContext(block.Header(), nil, &t.json.Env.Coinbase)
chainCtx := &withChainConfig{nil, config}
context := core.NewEVMBlockContext(block.Header(), chainCtx, &t.json.Env.Coinbase)
context.GetHash = vmTestBlockHash
context.BaseFee = baseFee
if params.GetExtra(config).IsSubnetEVM(0) && t.json.Env.Random != nil {
context.Random = nil
if config.IsLondon(new(big.Int)) && t.json.Env.Random != nil {
rnd := common.BigToHash(t.json.Env.Random)
context.Random = &rnd
context.Difficulty = big.NewInt(0)
}
if config.IsCancun(new(big.Int), block.Time()) && t.json.Env.ExcessBlobGas != nil {
Expand Down
41 changes: 41 additions & 0 deletions tests/state_test_util_ext.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// (c) 2024, Ava Labs, Inc.
//
// This file is a derived work, based on the go-ethereum library whose original
// notices appear below.
//
// It is distributed under a license compatible with the licensing terms of the
// original code from which it is derived.
//
// Much love to the original authors for their work.
// **********
// Copyright 2015 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it 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 go-ethereum library is distributed in the hope that it 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 tests

import (
"github.com/ava-labs/subnet-evm/core"
"github.com/ava-labs/subnet-evm/params"
)

type withChainConfig struct {
core.ChainContext
config *params.ChainConfig
}

func (w withChainConfig) Config() *params.ChainConfig {
return w.config
}
Loading