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 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
10 changes: 9 additions & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +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"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"

// Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
Expand Down Expand Up @@ -397,7 +401,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 +813,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
31 changes: 24 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,23 @@ 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 {
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