diff --git a/arbitrum/apibackend.go b/arbitrum/apibackend.go index 48edb37570e0..4419efce6074 100644 --- a/arbitrum/apibackend.go +++ b/arbitrum/apibackend.go @@ -504,7 +504,13 @@ func (a *APIBackend) GetEVM(ctx context.Context, msg *core.Message, state *state vmConfig = a.BlockChain().GetVMConfig() } txContext := core.NewEVMTxContext(msg) - return vm.NewEVM(*blockCtx, txContext, state, a.BlockChain().Config(), *vmConfig), vmError + var context vm.BlockContext + if blockCtx != nil { + context = *blockCtx + } else { + context = core.NewEVMBlockContext(header, a.BlockChain(), nil) + } + return vm.NewEVM(context, txContext, state, a.BlockChain().Config(), *vmConfig), vmError } func (a *APIBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index a4dc0e985414..c839f3b3a474 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -172,7 +172,7 @@ func Transaction(ctx *cli.Context) error { r.Error = errors.New("gas * maxFeePerGas exceeds 256 bits") } // Check whether the init code size has been exceeded. - if chainConfig.IsShanghai(new(big.Int), 0, 0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { + if chainConfig.IsShanghai(new(big.Int), 0, 0) && tx.To() == nil && len(tx.Data()) > int(chainConfig.MaxInitCodeSize()) { r.Error = errors.New("max initcode size exceeded") } results = append(results, r) diff --git a/core/state_transition.go b/core/state_transition.go index 1fae4601f898..53e94971fda7 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -449,8 +449,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } // Check whether the init code size has been exceeded. - if rules.IsShanghai && contractCreation && len(msg.Data) > params.MaxInitCodeSize { - return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize) + if rules.IsShanghai && contractCreation && len(msg.Data) > int(st.evm.ChainConfig().MaxInitCodeSize()) { + return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(msg.Data), int(st.evm.ChainConfig().MaxInitCodeSize())) } // Execute the preparatory steps for state transition which includes: diff --git a/core/txpool/validation.go b/core/txpool/validation.go index fa3c2a2cd193..9c82ad52c501 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -67,8 +67,8 @@ func ValidateTransaction(tx *types.Transaction, blobs []kzg4844.Blob, commits [] return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type()) } // Check whether the init code size has been exceeded - if opts.Config.IsShanghai(head.Number, head.Time, types.DeserializeHeaderExtraInformation(head).ArbOSFormatVersion) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { - return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize) + if opts.Config.IsShanghai(head.Number, head.Time, types.DeserializeHeaderExtraInformation(head).ArbOSFormatVersion) && tx.To() == nil && len(tx.Data()) > int(opts.Config.MaxInitCodeSize()) { + return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), int(opts.Config.MaxInitCodeSize())) } // Transactions can't be negative. This may never happen using RLP decoded // transactions but may occur for transactions created using the RPC. diff --git a/core/vm/evm.go b/core/vm/evm.go index 983e6a854014..b5b3044a7743 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -505,7 +505,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, ret, err := evm.interpreter.Run(contract, nil, false) // Check whether the max code size has been exceeded, assign err if the case. - if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { + if err == nil && evm.chainRules.IsEIP158 && len(ret) > int(evm.chainConfig.MaxCodeSize()) { err = ErrMaxCodeSizeExceeded } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 5153c8b7a3de..6a35cf19c9fb 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -310,10 +310,10 @@ func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m return 0, err } size, overflow := stack.Back(2).Uint64WithOverflow() - if overflow || size > params.MaxInitCodeSize { + if overflow || size > evm.chainConfig.MaxInitCodeSize() { return 0, ErrGasUintOverflow } - // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow + // Since size <= evm.chainConfig.MaxInitCodeSize(), these multiplication cannot overflow moreGas := params.InitCodeWordGas * ((size + 31) / 32) if gas, overflow = math.SafeAdd(gas, moreGas); overflow { return 0, ErrGasUintOverflow @@ -326,10 +326,10 @@ func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, return 0, err } size, overflow := stack.Back(2).Uint64WithOverflow() - if overflow || size > params.MaxInitCodeSize { + if overflow || size > evm.chainConfig.MaxInitCodeSize() { return 0, ErrGasUintOverflow } - // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow + // Since size <= evm.chainConfig.MaxInitCodeSize(), these multiplication cannot overflow moreGas := (params.InitCodeWordGas + params.Keccak256WordGas) * ((size + 31) / 32) if gas, overflow = math.SafeAdd(gas, moreGas); overflow { return 0, ErrGasUintOverflow diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index cca74f3fe702..670b6800b6e0 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1098,6 +1098,7 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S if err != nil { return nil, err } + msg.TxRunMode = runMode // make a new EVM for the scheduled Tx (an EVM must never be reused) evm, vmError := b.GetEVM(ctx, msg, state, header, &vm.Config{NoBaseFee: true}, &blockCtx) go func() { diff --git a/params/config_arbitrum.go b/params/config_arbitrum.go index 81201c498a7b..6d93a685e1de 100644 --- a/params/config_arbitrum.go +++ b/params/config_arbitrum.go @@ -29,6 +29,8 @@ type ArbitrumChainParams struct { InitialArbOSVersion uint64 InitialChainOwner common.Address GenesisBlockNum uint64 + MaxCodeSize uint64 `json:"MaxCodeSize,omitempty"` // Maximum bytecode to permit for a contract. 0 value implies params.MaxCodeSize + MaxInitCodeSize uint64 `json:"MaxInitCodeSize,omitempty"` // Maximum initcode to permit in a creation transaction and create instructions. 0 value implies params.MaxInitCodeSize } func (c *ChainConfig) IsArbitrum() bool { @@ -39,6 +41,20 @@ func (c *ChainConfig) IsArbitrumNitro(num *big.Int) bool { return c.IsArbitrum() && isBlockForked(new(big.Int).SetUint64(c.ArbitrumChainParams.GenesisBlockNum), num) } +func (c *ChainConfig) MaxCodeSize() uint64 { + if c.ArbitrumChainParams.MaxCodeSize == 0 { + return MaxCodeSize + } + return c.ArbitrumChainParams.MaxCodeSize +} + +func (c *ChainConfig) MaxInitCodeSize() uint64 { + if c.ArbitrumChainParams.MaxInitCodeSize == 0 { + return c.MaxCodeSize() * 2 + } + return c.ArbitrumChainParams.MaxInitCodeSize +} + func (c *ChainConfig) DebugMode() bool { return c.ArbitrumChainParams.AllowDebugPrecompiles }