Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Add sdk.Context and vm.EVM to precompiles #1433

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 8 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,15 @@ import (
"github.com/evmos/ethermint/x/evm"
evmkeeper "github.com/evmos/ethermint/x/evm/keeper"
evmtypes "github.com/evmos/ethermint/x/evm/types"
ethermintvm "github.com/evmos/ethermint/x/evm/vm"
"github.com/evmos/ethermint/x/evm/vm/geth"
"github.com/evmos/ethermint/x/feemarket"
feemarketkeeper "github.com/evmos/ethermint/x/feemarket/keeper"
feemarkettypes "github.com/evmos/ethermint/x/feemarket/types"

// Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
)
Expand Down Expand Up @@ -397,7 +400,7 @@ func NewEthermintApp(
app.EvmKeeper = evmkeeper.NewKeeper(
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName),
app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper,
nil, geth.NewEVM, tracer,
app.ExtendPrecompiles, geth.NewEVM, tracer,
)

// Create IBC Keeper
Expand Down Expand Up @@ -809,6 +812,10 @@ func (app *EthermintApp) RegisterTendermintService(clientCtx client.Context) {
)
}

func (app *EthermintApp) ExtendPrecompiles(ctx sdk.Context, evm *vm.EVM) ethermintvm.PrecompiledContracts {
return map[common.Address]vm.PrecompiledContract{}
}

// RegisterSwaggerAPI registers swagger route with API Server
func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) {
statikFS, err := fs.New()
Expand Down
28 changes: 14 additions & 14 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ type Keeper struct {
// EVM Hooks for tx post-processing
hooks types.EvmHooks

// custom stateless precompiled smart contracts
customPrecompiles evm.PrecompiledContracts
// Precompile extensions
getPrecompilesExtended func(ctx sdk.Context, evm *vm.EVM) evm.PrecompiledContracts
Copy link
Contributor

Choose a reason for hiding this comment

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

Could make this function take an address and return a singular precompile. Opens up more modularity.


// evm constructor function
evmConstructor evm.Constructor
Expand All @@ -72,7 +72,7 @@ func NewKeeper(
bankKeeper types.BankKeeper,
sk types.StakingKeeper,
fmk types.FeeMarketKeeper,
customPrecompiles evm.PrecompiledContracts,
pext func(ctx sdk.Context, evm *vm.EVM) evm.PrecompiledContracts,
evmConstructor evm.Constructor,
tracer string,
) *Keeper {
Expand All @@ -88,17 +88,17 @@ func NewKeeper(

// NOTE: we pass in the parameter space to the CommitStateDB in order to use custom denominations for the EVM operations
return &Keeper{
cdc: cdc,
paramSpace: paramSpace,
accountKeeper: ak,
bankKeeper: bankKeeper,
stakingKeeper: sk,
feeMarketKeeper: fmk,
storeKey: storeKey,
transientKey: transientKey,
customPrecompiles: customPrecompiles,
evmConstructor: evmConstructor,
tracer: tracer,
cdc: cdc,
paramSpace: paramSpace,
accountKeeper: ak,
bankKeeper: bankKeeper,
stakingKeeper: sk,
feeMarketKeeper: fmk,
storeKey: storeKey,
transientKey: transientKey,
getPrecompilesExtended: pext,
evmConstructor: evmConstructor,
tracer: tracer,
}
}

Expand Down
3 changes: 2 additions & 1 deletion x/evm/keeper/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ func (k *Keeper) NewEVM(
tracer = k.Tracer(ctx, msg, cfg.ChainConfig)
}
vmConfig := k.VMConfig(ctx, msg, cfg, tracer)
return k.evmConstructor(blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.customPrecompiles)

return k.evmConstructor(ctx, blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.getPrecompilesExtended)
}

// VMConfig creates an EVM configuration from the debug setting and the extra EIPs enabled on the
Expand Down
32 changes: 25 additions & 7 deletions x/evm/vm/geth/geth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package geth
import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
Expand All @@ -18,22 +20,34 @@ var (
// EVM is the wrapper for the go-ethereum EVM.
type EVM struct {
*vm.EVM
precompiles evm.PrecompiledContracts
}

// NewEVM defines the constructor function for the go-ethereum (geth) EVM. It uses
// the default precompiled contracts and the EVM concrete implementation from
// geth.
func NewEVM(
ctx sdk.Context,
blockCtx vm.BlockContext,
txCtx vm.TxContext,
stateDB vm.StateDB,
chainConfig *params.ChainConfig,
config vm.Config,
_ evm.PrecompiledContracts, // unused
getPrecompilesExtended func(ctx sdk.Context, evm *vm.EVM) evm.PrecompiledContracts,
) evm.EVM {
return &EVM{
newEvm := &EVM{
EVM: vm.NewEVM(blockCtx, txCtx, stateDB, chainConfig, config),
}

precompiles := GetPrecompiles(chainConfig, blockCtx.BlockNumber)
customPrecompiles := getPrecompilesExtended(ctx, newEvm.EVM)

for k, v := range customPrecompiles {
precompiles[k] = v
}
newEvm.precompiles = precompiles

return newEvm
}

// Context returns the EVM's Block Context
Expand All @@ -55,20 +69,24 @@ func (e EVM) Config() vm.Config {
// and the current chain configuration. If the contract cannot be found it returns
// nil.
func (e EVM) Precompile(addr common.Address) (p vm.PrecompiledContract, found bool) {
precompiles := GetPrecompiles(e.ChainConfig(), e.EVM.Context.BlockNumber)
p, found = precompiles[addr]
p, found = e.precompiles[addr]
return p, found
}

// ActivePrecompiles returns a list of all the active precompiled contract addresses
// for the current chain configuration.
func (EVM) ActivePrecompiles(rules params.Rules) []common.Address {
return vm.ActivePrecompiles(rules)
func (e EVM) ActivePrecompiles(rules params.Rules) []common.Address {
// TODO e.precompiles
Copy link
Contributor

Choose a reason for hiding this comment

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

This requires a geth fork right?

Copy link
Contributor Author

@loredanacirstea loredanacirstea Nov 6, 2022

Choose a reason for hiding this comment

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

Yes, this ActivePrecompiles is not actually used now. I changed it when I was testing and forgot to revert the changes. For clarity, I will remove them. (will return to this when I have some time later today)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ethermint uses its own ActivePrecompiles function in state_transition.go. The only other places I've seen vm.ActivePrecompiles used in go-ethereum is tracer-related.

precompiles := vm.ActivePrecompiles(rules)
for key := range e.precompiles {
precompiles = append(precompiles, key)
}
return precompiles
}

// RunPrecompiledContract runs a stateless precompiled contract and ignores the address and
// value arguments. It uses the RunPrecompiledContract function from the geth vm package.
func (EVM) RunPrecompiledContract(
func (e *EVM) RunPrecompiledContract(
p evm.StatefulPrecompiledContract,
_ common.Address, // address arg is unused
input []byte,
Expand Down
5 changes: 4 additions & 1 deletion x/evm/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package vm
import (
"math/big"

sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -57,10 +59,11 @@ type EVM interface {
// Constructor defines the function used to instantiate the EVM on
// each state transition.
type Constructor func(
ctx sdk.Context,
blockCtx vm.BlockContext,
txCtx vm.TxContext,
stateDB vm.StateDB,
chainConfig *params.ChainConfig,
config vm.Config,
customPrecompiles PrecompiledContracts,
getPrecompilesExtended func(ctx sdk.Context, evm *vm.EVM) PrecompiledContracts,
) EVM