mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-12 06:53:46 +00:00
feat: adds zerofee with vm fix
This commit is contained in:
parent
e5d5a3806a
commit
b30ff9d58f
12 changed files with 158 additions and 11 deletions
|
|
@ -192,6 +192,14 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
||||||
cfg.Eth.OverrideVerkle = &v
|
cfg.Eth.OverrideVerkle = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.IsSet(utils.ZeroFeeAddressesFlag.Name) {
|
||||||
|
for _, addr := range ctx.StringSlice(utils.ZeroFeeAddressesFlag.Name) {
|
||||||
|
cfg.Eth.ZeroFeeAddresses = append(
|
||||||
|
cfg.Eth.ZeroFeeAddresses,
|
||||||
|
common.HexToAddress(strings.TrimSpace(addr)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
// Start metrics export if enabled
|
// Start metrics export if enabled
|
||||||
utils.SetupMetrics(&cfg.Metrics)
|
utils.SetupMetrics(&cfg.Metrics)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,7 @@ var (
|
||||||
utils.BeaconGenesisRootFlag,
|
utils.BeaconGenesisRootFlag,
|
||||||
utils.BeaconGenesisTimeFlag,
|
utils.BeaconGenesisTimeFlag,
|
||||||
utils.BeaconCheckpointFlag,
|
utils.BeaconCheckpointFlag,
|
||||||
|
utils.ZeroFeeAddressesFlag,
|
||||||
}, utils.NetworkFlags, utils.DatabaseFlags)
|
}, utils.NetworkFlags, utils.DatabaseFlags)
|
||||||
|
|
||||||
rpcFlags = []cli.Flag{
|
rpcFlags = []cli.Flag{
|
||||||
|
|
|
||||||
|
|
@ -527,6 +527,11 @@ var (
|
||||||
Value: "{}",
|
Value: "{}",
|
||||||
Category: flags.VMCategory,
|
Category: flags.VMCategory,
|
||||||
}
|
}
|
||||||
|
ZeroFeeAddressesFlag = &cli.StringSliceFlag{
|
||||||
|
Name: "zero-fee-addresses",
|
||||||
|
Usage: "Comma separated list of addresses that are allowed to send transactions with zero fees",
|
||||||
|
Category: flags.VMCategory,
|
||||||
|
}
|
||||||
// API options.
|
// API options.
|
||||||
RPCGlobalGasCapFlag = &cli.Uint64Flag{
|
RPCGlobalGasCapFlag = &cli.Uint64Flag{
|
||||||
Name: "rpc.gascap",
|
Name: "rpc.gascap",
|
||||||
|
|
@ -2184,6 +2189,14 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh
|
||||||
vmcfg.Tracer = t
|
vmcfg.Tracer = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ctx.IsSet(ZeroFeeAddressesFlag.Name) {
|
||||||
|
for _, addr := range ctx.StringSlice(ZeroFeeAddressesFlag.Name) {
|
||||||
|
vmcfg.ZeroFeeAddresses = append(
|
||||||
|
vmcfg.ZeroFeeAddresses,
|
||||||
|
common.HexToAddress(strings.TrimSpace(addr)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
// Disable transaction indexing/unindexing by default.
|
// Disable transaction indexing/unindexing by default.
|
||||||
chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil)
|
chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,11 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
@ -155,6 +157,19 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD
|
||||||
// Validate the state root against the received state root and throw
|
// Validate the state root against the received state root and throw
|
||||||
// an error if they don't match.
|
// an error if they don't match.
|
||||||
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
|
if root := statedb.IntermediateRoot(v.config.IsEIP158(header.Number)); header.Root != root {
|
||||||
|
// Add detailed debug logging for the state root mismatch
|
||||||
|
log.Error("State root mismatch during validation",
|
||||||
|
"block", header.Number,
|
||||||
|
"block_hash", header.Hash(),
|
||||||
|
"header_root", header.Root.String(),
|
||||||
|
"calculated_root", root.String(),
|
||||||
|
"error", statedb.Error())
|
||||||
|
|
||||||
|
// Log treasury account balance for debugging
|
||||||
|
treasuryAccount := common.HexToAddress("0xfA0B0f5d298d28EFE4d35641724141ef19C05684")
|
||||||
|
log.Error("Treasury account balance",
|
||||||
|
"balance", statedb.GetBalance(treasuryAccount))
|
||||||
|
|
||||||
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
|
return fmt.Errorf("invalid merkle root (remote: %x local: %x) dberr: %w", header.Root, root, statedb.Error())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -2539,3 +2539,26 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) {
|
||||||
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
|
func (bc *BlockChain) GetTrieFlushInterval() time.Duration {
|
||||||
return time.Duration(bc.flushInterval.Load())
|
return time.Duration(bc.flushInterval.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddZeroFeeAddress adds an address to the zero fee address list in the VM configuration
|
||||||
|
func (bc *BlockChain) AddZeroFeeAddress(address common.Address) {
|
||||||
|
// Check if the address is already in the list
|
||||||
|
for _, addr := range bc.vmConfig.ZeroFeeAddresses {
|
||||||
|
if addr == address {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Add the address to the list
|
||||||
|
bc.vmConfig.ZeroFeeAddresses = append(bc.vmConfig.ZeroFeeAddresses, address)
|
||||||
|
log.Info("Added zero fee address", "address", address.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetZeroFeeAddresses returns the current list of zero fee addresses
|
||||||
|
func (bc *BlockChain) GetZeroFeeAddresses() []common.Address {
|
||||||
|
return bc.vmConfig.ZeroFeeAddresses
|
||||||
|
}
|
||||||
|
|
||||||
|
// VMConfig returns the current VM configuration
|
||||||
|
func (bc *BlockChain) VMConfig() vm.Config {
|
||||||
|
return bc.vmConfig
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -798,12 +798,15 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
|
||||||
workers.SetLimit(1)
|
workers.SetLimit(1)
|
||||||
}
|
}
|
||||||
for addr, op := range s.mutations {
|
for addr, op := range s.mutations {
|
||||||
|
// Log the operation and address for debugging purposes
|
||||||
|
log.Info("Processing state mutation", "operation", op.typ, "address", addr.Hex())
|
||||||
if op.applied || op.isDelete() {
|
if op.applied || op.isDelete() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
obj := s.stateObjects[addr] // closure for the task runner below
|
obj := s.stateObjects[addr] // closure for the task runner below
|
||||||
workers.Go(func() error {
|
workers.Go(func() error {
|
||||||
if s.db.TrieDB().IsVerkle() {
|
if s.db.TrieDB().IsVerkle() {
|
||||||
|
log.Warn("Updating Verkle trie", "addr", addr.Hex())
|
||||||
obj.updateTrie()
|
obj.updateTrie()
|
||||||
} else {
|
} else {
|
||||||
obj.updateRoot()
|
obj.updateRoot()
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -82,6 +83,20 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
context = NewEVMBlockContext(header, p.chain, nil)
|
context = NewEVMBlockContext(header, p.chain, nil)
|
||||||
evm := vm.NewEVM(context, tracingStateDB, p.config, cfg)
|
evm := vm.NewEVM(context, tracingStateDB, p.config, cfg)
|
||||||
|
|
||||||
|
// Add logging for VM configuration during block processing
|
||||||
|
log.Debug("Created EVM for block processing",
|
||||||
|
"block_number", header.Number,
|
||||||
|
"block_hash", block.Hash().String(),
|
||||||
|
"zero_fee_addresses_count", len(cfg.ZeroFeeAddresses))
|
||||||
|
|
||||||
|
if len(cfg.ZeroFeeAddresses) > 0 {
|
||||||
|
for i, addr := range cfg.ZeroFeeAddresses {
|
||||||
|
log.Debug("Zero fee address in block processing",
|
||||||
|
"index", i,
|
||||||
|
"address", addr.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
ProcessBeaconBlockRoot(*beaconRoot, evm)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"slices"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
@ -156,7 +158,12 @@ type Message struct {
|
||||||
|
|
||||||
// TransactionToMessage converts a transaction into a Message.
|
// TransactionToMessage converts a transaction into a Message.
|
||||||
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
|
func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.Int) (*Message, error) {
|
||||||
|
from, err := s.Sender(tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
msg := &Message{
|
msg := &Message{
|
||||||
|
From: from,
|
||||||
Nonce: tx.Nonce(),
|
Nonce: tx.Nonce(),
|
||||||
GasLimit: tx.Gas(),
|
GasLimit: tx.Gas(),
|
||||||
GasPrice: new(big.Int).Set(tx.GasPrice()),
|
GasPrice: new(big.Int).Set(tx.GasPrice()),
|
||||||
|
|
@ -179,7 +186,6 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In
|
||||||
msg.GasPrice = msg.GasFeeCap
|
msg.GasPrice = msg.GasFeeCap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var err error
|
|
||||||
msg.From, err = types.Sender(s, tx)
|
msg.From, err = types.Sender(s, tx)
|
||||||
return msg, err
|
return msg, err
|
||||||
}
|
}
|
||||||
|
|
@ -285,6 +291,8 @@ func (st *stateTransition) buyGas() error {
|
||||||
|
|
||||||
st.initialGas = st.msg.GasLimit
|
st.initialGas = st.msg.GasLimit
|
||||||
mgvalU256, _ := uint256.FromBig(mgval)
|
mgvalU256, _ := uint256.FromBig(mgval)
|
||||||
|
// Log who the funds are being decremented from
|
||||||
|
log.Warn("Deducting gas fee from account", "from", st.msg.From.Hex(), "amount", mgvalU256)
|
||||||
st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy)
|
st.state.SubBalance(st.msg.From, mgvalU256, tracing.BalanceDecreaseGasBuy)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -503,18 +511,58 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
effectiveTipU256, _ := uint256.FromBig(effectiveTip)
|
effectiveTipU256, _ := uint256.FromBig(effectiveTip)
|
||||||
|
log.Info("Effective tip", "effectiveTip", effectiveTipU256)
|
||||||
if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 {
|
if st.evm.Config.NoBaseFee && msg.GasFeeCap.Sign() == 0 && msg.GasTipCap.Sign() == 0 {
|
||||||
// Skip fee payment when NoBaseFee is set and the fee fields
|
// Skip fee payment when NoBaseFee is set and the fee fields
|
||||||
// are 0. This avoids a negative effectiveTip being applied to
|
// are 0. This avoids a negative effectiveTip being applied to
|
||||||
// the coinbase when simulating calls.
|
// the coinbase when simulating calls.
|
||||||
} else {
|
} else {
|
||||||
fee := new(uint256.Int).SetUint64(st.gasUsed())
|
// Calculate priority fee (tip) paid to miner/validator
|
||||||
fee.Mul(fee, effectiveTipU256)
|
priorityFee := new(uint256.Int).SetUint64(st.gasUsed())
|
||||||
st.state.AddBalance(st.evm.Context.Coinbase, fee, tracing.BalanceIncreaseRewardTransactionFee)
|
priorityFee.Mul(priorityFee, effectiveTipU256)
|
||||||
|
|
||||||
// add the coinbase to the witness iff the fee is greater than 0
|
// Set the treasury account address
|
||||||
if rules.IsEIP4762 && fee.Sign() != 0 {
|
treasuryAccount := common.HexToAddress("0xfA0B0f5d298d28EFE4d35641724141ef19C05684")
|
||||||
|
|
||||||
|
// Add detailed logging for debugging
|
||||||
|
log.Info("Fee handling in state transition",
|
||||||
|
"sender", msg.From.String(),
|
||||||
|
"block_number", st.evm.Context.BlockNumber,
|
||||||
|
"zero_fee_addresses_count", len(st.evm.Config.ZeroFeeAddresses),
|
||||||
|
"is_in_zero_fee_list", slices.Contains(st.evm.Config.ZeroFeeAddresses, msg.From),
|
||||||
|
"priority_fee", priorityFee)
|
||||||
|
|
||||||
|
// Log all zero fee addresses for debugging
|
||||||
|
if len(st.evm.Config.ZeroFeeAddresses) > 0 {
|
||||||
|
for i, addr := range st.evm.Config.ZeroFeeAddresses {
|
||||||
|
log.Debug("Zero fee address in EVM config",
|
||||||
|
"index", i,
|
||||||
|
"address", addr.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Calculate total fee including base fee
|
||||||
|
totalFee := new(uint256.Int).SetUint64(st.gasUsed())
|
||||||
|
totalFee.Mul(totalFee, uint256.MustFromBig(msg.GasPrice))
|
||||||
|
// Handle zero fee addresses - they get their fees refunded
|
||||||
|
if slices.Contains(st.evm.Config.ZeroFeeAddresses, msg.From) {
|
||||||
|
log.Info("Refunding fee to zero-fee address",
|
||||||
|
"address", msg.From.String(),
|
||||||
|
"priority_fee", priorityFee,
|
||||||
|
"total_fee", totalFee)
|
||||||
|
st.state.AddBalance(msg.From, totalFee, tracing.BalanceIncreaseRewardTransactionFee)
|
||||||
|
} else {
|
||||||
|
log.Info("Sending fee to treasury",
|
||||||
|
"address", treasuryAccount.String(),
|
||||||
|
"amount", priorityFee,
|
||||||
|
"total_fee", totalFee)
|
||||||
|
st.state.AddBalance(treasuryAccount, priorityFee, tracing.BalanceIncreaseRewardTransactionFee)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Base fee is implicitly burned by not being transferred to anyone
|
||||||
|
// This maintains the economics of EIP-1559
|
||||||
|
|
||||||
|
// Check if the fee is greater than 0 for witness accounting
|
||||||
|
if rules.IsEIP4762 && priorityFee.Sign() != 0 {
|
||||||
st.evm.AccessEvents.AddAccount(st.evm.Context.Coinbase, true)
|
st.evm.AccessEvents.AddAccount(st.evm.Context.Coinbase, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,10 @@ import (
|
||||||
// Config are the configuration options for the Interpreter
|
// Config are the configuration options for the Interpreter
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Tracer *tracing.Hooks
|
Tracer *tracing.Hooks
|
||||||
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
|
NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls)
|
||||||
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
|
EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages
|
||||||
ExtraEips []int // Additional EIPS that are to be enabled
|
ExtraEips []int // Additional EIPS that are to be enabled
|
||||||
|
ZeroFeeAddresses []common.Address // Addresses that are allowed to send transactions with zero fees
|
||||||
|
|
||||||
StatelessSelfValidation bool // Generate execution witnesses and self-check against them (testing purpose)
|
StatelessSelfValidation bool // Generate execution witnesses and self-check against them (testing purpose)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
|
||||||
var (
|
var (
|
||||||
vmConfig = vm.Config{
|
vmConfig = vm.Config{
|
||||||
EnablePreimageRecording: config.EnablePreimageRecording,
|
EnablePreimageRecording: config.EnablePreimageRecording,
|
||||||
|
ZeroFeeAddresses: config.ZeroFeeAddresses,
|
||||||
}
|
}
|
||||||
cacheConfig = &core.CacheConfig{
|
cacheConfig = &core.CacheConfig{
|
||||||
TrieCleanLimit: config.TrieCleanCache,
|
TrieCleanLimit: config.TrieCleanCache,
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,9 @@ type Config struct {
|
||||||
|
|
||||||
// OverrideVerkle (TODO: remove after the fork)
|
// OverrideVerkle (TODO: remove after the fork)
|
||||||
OverrideVerkle *uint64 `toml:",omitempty"`
|
OverrideVerkle *uint64 `toml:",omitempty"`
|
||||||
|
|
||||||
|
// ZeroFeeAddresses is a list of addresses that are exempt from the zero fee policy.
|
||||||
|
ZeroFeeAddresses []common.Address `toml:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateConsensusEngine creates a consensus engine for the given chain config.
|
// CreateConsensusEngine creates a consensus engine for the given chain config.
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,22 @@ func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase
|
||||||
}
|
}
|
||||||
state.StartPrefetcher("miner", bundle)
|
state.StartPrefetcher("miner", bundle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the VM configuration from the blockchain to ensure consistency
|
||||||
|
vmConfig := miner.chain.VMConfig()
|
||||||
|
|
||||||
|
// Add debug logging about VM configuration
|
||||||
|
log.Debug("Making mining environment with VM config",
|
||||||
|
"zero_fee_addresses_count", len(vmConfig.ZeroFeeAddresses))
|
||||||
|
|
||||||
|
if len(vmConfig.ZeroFeeAddresses) > 0 {
|
||||||
|
for i, addr := range vmConfig.ZeroFeeAddresses {
|
||||||
|
log.Debug("Zero fee address in mining",
|
||||||
|
"index", i,
|
||||||
|
"address", addr.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note the passed coinbase may be different with header.Coinbase.
|
// Note the passed coinbase may be different with header.Coinbase.
|
||||||
return &environment{
|
return &environment{
|
||||||
signer: types.MakeSigner(miner.chainConfig, header.Number, header.Time),
|
signer: types.MakeSigner(miner.chainConfig, header.Number, header.Time),
|
||||||
|
|
@ -257,7 +273,7 @@ func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase
|
||||||
coinbase: coinbase,
|
coinbase: coinbase,
|
||||||
header: header,
|
header: header,
|
||||||
witness: state.Witness(),
|
witness: state.Witness(),
|
||||||
evm: vm.NewEVM(core.NewEVMBlockContext(header, miner.chain, &coinbase), state, miner.chainConfig, vm.Config{}),
|
evm: vm.NewEVM(core.NewEVMBlockContext(header, miner.chain, &coinbase), state, miner.chainConfig, vmConfig),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue