forked from cerc-io/laconicd-deprecated
imp(evm): stateless custom precompiles (#1272)
* release: v0.17.0 changelog (#1153) * release: v0.17.0 changelog * rm newline * update link * imp(evm): EVM interface * fixes * fix lint * fix lint pt 2 * initial wiring for stateful contracts * Apply suggestions from code review Co-authored-by: Vladislav Varadinov <vladislav.varadinov@gmail.com> * changelog * comments from review * lint Co-authored-by: Vladislav Varadinov <vladislav.varadinov@gmail.com>
This commit is contained in:
co-authored by
Vladislav Varadinov
parent
67f1e97531
commit
acf15474e7
+25
-11
@@ -19,6 +19,7 @@ import (
|
||||
ethermint "github.com/evmos/ethermint/types"
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
"github.com/evmos/ethermint/x/evm/types"
|
||||
evm "github.com/evmos/ethermint/x/evm/vm"
|
||||
)
|
||||
|
||||
// Keeper grants access to the EVM module state and implements the go-ethereum StateDB interface.
|
||||
@@ -54,14 +55,25 @@ type Keeper struct {
|
||||
|
||||
// EVM Hooks for tx post-processing
|
||||
hooks types.EvmHooks
|
||||
|
||||
// custom stateless precompiled smart contracts
|
||||
customPrecompiles evm.PrecompiledContracts
|
||||
|
||||
// evm constructor function
|
||||
evmConstructor evm.Constructor
|
||||
}
|
||||
|
||||
// NewKeeper generates new evm module keeper
|
||||
func NewKeeper(
|
||||
cdc codec.BinaryCodec,
|
||||
storeKey, transientKey storetypes.StoreKey, paramSpace paramtypes.Subspace,
|
||||
ak types.AccountKeeper, bankKeeper types.BankKeeper, sk types.StakingKeeper,
|
||||
storeKey, transientKey storetypes.StoreKey,
|
||||
paramSpace paramtypes.Subspace,
|
||||
ak types.AccountKeeper,
|
||||
bankKeeper types.BankKeeper,
|
||||
sk types.StakingKeeper,
|
||||
fmk types.FeeMarketKeeper,
|
||||
customPrecompiles evm.PrecompiledContracts,
|
||||
evmConstructor evm.Constructor,
|
||||
tracer string,
|
||||
) *Keeper {
|
||||
// ensure evm module account is set
|
||||
@@ -76,15 +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,
|
||||
tracer: tracer,
|
||||
cdc: cdc,
|
||||
paramSpace: paramSpace,
|
||||
accountKeeper: ak,
|
||||
bankKeeper: bankKeeper,
|
||||
stakingKeeper: sk,
|
||||
feeMarketKeeper: fmk,
|
||||
storeKey: storeKey,
|
||||
transientKey: transientKey,
|
||||
customPrecompiles: customPrecompiles,
|
||||
evmConstructor: evmConstructor,
|
||||
tracer: tracer,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
ethermint "github.com/evmos/ethermint/types"
|
||||
"github.com/evmos/ethermint/x/evm/statedb"
|
||||
"github.com/evmos/ethermint/x/evm/types"
|
||||
evm "github.com/evmos/ethermint/x/evm/vm"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
@@ -77,7 +78,7 @@ func (k *Keeper) NewEVM(
|
||||
cfg *types.EVMConfig,
|
||||
tracer vm.EVMLogger,
|
||||
stateDB vm.StateDB,
|
||||
) *vm.EVM {
|
||||
) evm.EVM {
|
||||
blockCtx := vm.BlockContext{
|
||||
CanTransfer: core.CanTransfer,
|
||||
Transfer: core.Transfer,
|
||||
@@ -95,7 +96,7 @@ func (k *Keeper) NewEVM(
|
||||
tracer = k.Tracer(ctx, msg, cfg.ChainConfig)
|
||||
}
|
||||
vmConfig := k.VMConfig(ctx, msg, cfg, tracer)
|
||||
return vm.NewEVM(blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig)
|
||||
return k.evmConstructor(blockCtx, txCtx, stateDB, cfg.ChainConfig, vmConfig, k.customPrecompiles)
|
||||
}
|
||||
|
||||
// VMConfig creates an EVM configuration from the debug setting and the extra EIPs enabled on the
|
||||
@@ -366,17 +367,19 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
|
||||
evm := k.NewEVM(ctx, msg, cfg, tracer, stateDB)
|
||||
|
||||
leftoverGas := msg.Gas()
|
||||
|
||||
// Allow the tracer captures the tx level events, mainly the gas consumption.
|
||||
if evm.Config.Debug {
|
||||
evm.Config.Tracer.CaptureTxStart(leftoverGas)
|
||||
vmCfg := evm.Config()
|
||||
if vmCfg.Debug {
|
||||
vmCfg.Tracer.CaptureTxStart(leftoverGas)
|
||||
defer func() {
|
||||
evm.Config.Tracer.CaptureTxEnd(leftoverGas)
|
||||
vmCfg.Tracer.CaptureTxEnd(leftoverGas)
|
||||
}()
|
||||
}
|
||||
|
||||
sender := vm.AccountRef(msg.From())
|
||||
contractCreation := msg.To() == nil
|
||||
isLondon := cfg.ChainConfig.IsLondon(evm.Context.BlockNumber)
|
||||
isLondon := cfg.ChainConfig.IsLondon(evm.Context().BlockNumber)
|
||||
|
||||
intrinsicGas, err := k.GetEthIntrinsicGas(ctx, msg, cfg.ChainConfig, contractCreation)
|
||||
if err != nil {
|
||||
@@ -394,7 +397,7 @@ func (k *Keeper) ApplyMessageWithConfig(ctx sdk.Context,
|
||||
// access list preparation is moved from ante handler to here, because it's needed when `ApplyMessage` is called
|
||||
// under contexts where ante handlers are not run, for example `eth_call` and `eth_estimateGas`.
|
||||
if rules := cfg.ChainConfig.Rules(big.NewInt(ctx.BlockHeight()), cfg.ChainConfig.MergeNetsplitBlock != nil); rules.IsBerlin {
|
||||
stateDB.PrepareAccessList(msg.From(), msg.To(), vm.ActivePrecompiles(rules), msg.AccessList())
|
||||
stateDB.PrepareAccessList(msg.From(), msg.To(), evm.ActivePrecompiles(rules), msg.AccessList())
|
||||
}
|
||||
|
||||
if contractCreation {
|
||||
|
||||
Reference in New Issue
Block a user