diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index fe68fa8c7e..b95eb34ead 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -342,7 +342,7 @@ func (b *SimulatedBackend) CallContractWithState(call tomochain.CallMsg, chain c evmContext := core.NewEVMContext(msg, chain.CurrentHeader(), chain, nil) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. - vmenv := vm.NewEVM(evmContext, statedb, nil, chain.Config(), vm.Config{}) + vmenv := vm.NewEVM(evmContext, statedb, nil, chain.Config(), *b.blockchain.GetVMConfig()) gaspool := new(core.GasPool).AddGas(1000000) owner := common.Address{} rval, _, _, err := core.NewStateTransition(vmenv, msg, gaspool).TransitionDb(owner) diff --git a/core/blockchain.go b/core/blockchain.go index 1186ea2ac3..42a5cb3cf6 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -699,6 +699,11 @@ func (bc *BlockChain) Genesis() *types.Block { return bc.genesisBlock } +// GetVMConfig returns the blockchain VM config. +func (bc *BlockChain) GetVMConfig() *vm.Config { + return &bc.vmConfig +} + // GetBody retrieves a block body (transactions and uncles) from the database by // hash, caching it if found. func (bc *BlockChain) GetBody(hash common.Hash) *types.Body { diff --git a/core/vm/eips.go b/core/vm/eips.go index 46d2c0727b..72ccda5e38 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -103,6 +103,7 @@ func enable3198(jt *JumpTable) { constantGas: GasQuickStep, minStack: minStack(0, 1), maxStack: maxStack(0, 1), + valid: true, } } diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 3c97467150..4c73193e2d 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -98,35 +98,33 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { // We use the STOP instruction whether to see // the jump table was initialised. If it was not // we'll set the default jump table. - if !cfg.JumpTable[STOP].valid { - var jt JumpTable - switch { - case evm.chainRules.IsLondon: - jt = londonInstructionSet - case evm.chainRules.IsIstanbul: - jt = istanbulInstructionSet - case evm.chainRules.IsConstantinople: - jt = constantinopleInstructionSet - case evm.chainRules.IsByzantium: - jt = byzantiumInstructionSet - case evm.chainRules.IsEIP158: - jt = spuriousDragonInstructionSet - case evm.chainRules.IsEIP150: - jt = tangerineWhistleInstructionSet - case evm.chainRules.IsHomestead: - jt = homesteadInstructionSet - default: - jt = frontierInstructionSet - } - for i, eip := range cfg.ExtraEips { - if err := EnableEIP(eip, &jt); err != nil { - // Disable it, so caller can check if it's activated or not - cfg.ExtraEips = append(cfg.ExtraEips[:i], cfg.ExtraEips[i+1:]...) - log.Error("EIP activation failed", "eip", eip, "error", err) - } + var jt JumpTable + switch { + case evm.chainRules.IsLondon: + jt = londonInstructionSet + case evm.chainRules.IsIstanbul: + jt = istanbulInstructionSet + case evm.chainRules.IsConstantinople: + jt = constantinopleInstructionSet + case evm.chainRules.IsByzantium: + jt = byzantiumInstructionSet + case evm.chainRules.IsEIP158: + jt = spuriousDragonInstructionSet + case evm.chainRules.IsEIP150: + jt = tangerineWhistleInstructionSet + case evm.chainRules.IsHomestead: + jt = homesteadInstructionSet + default: + jt = frontierInstructionSet + } + for i, eip := range cfg.ExtraEips { + if err := EnableEIP(eip, &jt); err != nil { + // Disable it, so caller can check if it's activated or not + cfg.ExtraEips = append(cfg.ExtraEips[:i], cfg.ExtraEips[i+1:]...) + log.Error("EIP activation failed", "eip", eip, "error", err) } - cfg.JumpTable = jt } + cfg.JumpTable = jt return &EVMInterpreter{ evm: evm, diff --git a/eth/api_backend.go b/eth/api_backend.go index 815b1e22e4..fb2964abbc 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -220,12 +220,15 @@ func (b *EthApiBackend) GetTd(blockHash common.Hash) *big.Int { return b.eth.blockchain.GetTdByHash(blockHash) } -func (b *EthApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, tomoxState *tradingstate.TradingStateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) { +func (b *EthApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, tomoxState *tradingstate.TradingStateDB, header *types.Header, vmCfg *vm.Config) (*vm.EVM, func() error, error) { + if vmCfg == nil { + vmCfg = b.eth.blockchain.GetVMConfig() + } state.SetBalance(msg.From, math.MaxBig256) vmError := func() error { return nil } context := core.NewEVMContext(msg, header, b.eth.BlockChain(), nil) - return vm.NewEVM(context, state, tomoxState, b.eth.chainConfig, vmCfg), vmError, nil + return vm.NewEVM(context, state, tomoxState, b.eth.chainConfig, *vmCfg), vmError, nil } func (b *EthApiBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 0b7e8e6979..413062e45a 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1108,7 +1108,7 @@ func (s *PublicBlockChainAPI) doCall(ctx context.Context, args TransactionArgs, return nil, 0, false, err } // Get a new instance of the EVM. - evm, vmError, err := s.b.GetEVM(ctx, msg, statedb, tomoxState, header, vm.Config{NoBaseFee: true}) + evm, vmError, err := s.b.GetEVM(ctx, msg, statedb, tomoxState, header, &vm.Config{NoBaseFee: true}) if err != nil { return nil, 0, false, err } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 9a88c2310b..7c44b34b1f 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -68,7 +68,7 @@ type Backend interface { GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error) GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error) GetTd(blockHash common.Hash) *big.Int - GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, tomoxState *tradingstate.TradingStateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) + GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, tomoxState *tradingstate.TradingStateDB, header *types.Header, vmCfg *vm.Config) (*vm.EVM, func() error, error) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription diff --git a/les/api_backend.go b/les/api_backend.go index cafeb5858f..f72e861a6a 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -154,10 +154,13 @@ func (b *LesApiBackend) GetTd(blockHash common.Hash) *big.Int { return b.eth.blockchain.GetTdByHash(blockHash) } -func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, tomoxState *tradingstate.TradingStateDB, header *types.Header, vmCfg vm.Config) (*vm.EVM, func() error, error) { +func (b *LesApiBackend) GetEVM(ctx context.Context, msg *core.Message, state *state.StateDB, tomoxState *tradingstate.TradingStateDB, header *types.Header, vmCfg *vm.Config) (*vm.EVM, func() error, error) { + if vmCfg == nil { + vmCfg = new(vm.Config) + } state.SetBalance(msg.From, math.MaxBig256) context := core.NewEVMContext(msg, header, b.eth.blockchain, nil) - return vm.NewEVM(context, state, tomoxState, b.eth.chainConfig, vmCfg), state.Error, nil + return vm.NewEVM(context, state, tomoxState, b.eth.chainConfig, *vmCfg), state.Error, nil } func (b *LesApiBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { diff --git a/miner/worker.go b/miner/worker.go index d2b0c991d8..e0773cbbf0 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -41,7 +41,6 @@ import ( "github.com/tomochain/tomochain/core" "github.com/tomochain/tomochain/core/state" "github.com/tomochain/tomochain/core/types" - "github.com/tomochain/tomochain/core/vm" "github.com/tomochain/tomochain/ethdb" "github.com/tomochain/tomochain/event" "github.com/tomochain/tomochain/log" @@ -1091,7 +1090,7 @@ func (env *Work) commitTransactions(mux *event.TypeMux, balanceFee map[common.Ad func (env *Work) commitTransaction(balanceFee map[common.Address]*big.Int, tx *types.Transaction, bc *core.BlockChain, coinbase common.Address, gp *core.GasPool) (error, []*types.Log, bool, uint64) { snap := env.state.Snapshot() - receipt, gas, err, tokenFeeUsed := core.ApplyTransaction(env.config, balanceFee, bc, &coinbase, gp, env.state, env.tradingState, env.header, tx, &env.header.GasUsed, vm.Config{}) + receipt, gas, err, tokenFeeUsed := core.ApplyTransaction(env.config, balanceFee, bc, &coinbase, gp, env.state, env.tradingState, env.header, tx, &env.header.GasUsed, *bc.GetVMConfig()) if err != nil { env.state.RevertToSnapshot(snap) return err, nil, false, 0 diff --git a/params/config.go b/params/config.go index 4ca56255d8..52bba84eae 100644 --- a/params/config.go +++ b/params/config.go @@ -39,6 +39,7 @@ var ( EIP155Block: big.NewInt(3), EIP158Block: big.NewInt(3), ByzantiumBlock: big.NewInt(4), + LondonBlock: big.NewInt(5), Posv: &PosvConfig{ Period: 2, Epoch: 900, @@ -109,8 +110,8 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllPosvProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &PosvConfig{Period: 0, Epoch: 30000}} - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + AllPosvProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, big.NewInt(0), nil, nil, &PosvConfig{Period: 0, Epoch: 30000}} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, big.NewInt(0), new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int)) ) @@ -137,7 +138,7 @@ type ChainConfig struct { ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) - LondonBlock *big.Int `json:"londonBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) + LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` diff --git a/tests/init.go b/tests/init.go index de6bb71cf4..216e5e12e4 100644 --- a/tests/init.go +++ b/tests/init.go @@ -76,6 +76,16 @@ var Forks = map[string]*params.ChainConfig{ EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(5), }, + "London": { + ChainId: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + }, } // UnsupportedForkError is returned when a test requests a fork that isn't implemented.