Skip to content

core/vm, params: raise codesize limit and initcode limit #32002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
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
7 changes: 5 additions & 2 deletions cmd/evm/internal/t8ntool/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/tests"
Expand Down Expand Up @@ -180,8 +181,10 @@ 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) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
r.Error = errors.New("max initcode size exceeded")
if tx.To() == nil {
if err := vm.CheckInitCodeSize(&rules, uint64(len(tx.Data()))); err != nil {
r.Error = err
}
}
results = append(results, r)
}
Expand Down
3 changes: 2 additions & 1 deletion core/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
)

var (
Expand Down Expand Up @@ -60,7 +61,7 @@ var (

// ErrMaxInitCodeSizeExceeded is returned if creation transaction provides the init code bigger
// than init code size limit.
ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded")
ErrMaxInitCodeSizeExceeded = vm.ErrMaxInitCodeSizeExceeded

// ErrInsufficientBalanceWitness is returned if the transaction sender has enough
// funds to cover the transfer, but not enough to pay for witness access/modification
Expand Down
6 changes: 4 additions & 2 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,10 @@ func (st *stateTransition) execute() (*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 contractCreation {
if err := vm.CheckInitCodeSize(&rules, uint64(len(msg.Data))); err != nil {
return nil, err
}
}

// Execute the preparatory steps for state transition which includes:
Expand Down
7 changes: 5 additions & 2 deletions core/txpool/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -87,8 +88,10 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
return fmt.Errorf("%w: type %d rejected, pool not yet in Prague", core.ErrTxTypeNotSupported, tx.Type())
}
// Check whether the init code size has been exceeded
if rules.IsShanghai && 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 tx.To() == nil {
if err := vm.CheckInitCodeSize(&rules, uint64(len(tx.Data()))); err != nil {
return err
}
}
// Transactions can't be negative. This may never happen using RLP decoded
// transactions but may occur for transactions created using the RPC.
Expand Down
16 changes: 16 additions & 0 deletions core/vm/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,28 @@
package vm

import (
"fmt"
"math"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
"github.com/holiman/uint256"
)

// CheckInitCodeSize checks the size of contract initcode against the protocol-defined limit.
func CheckInitCodeSize(rules *params.Rules, size uint64) error {
if rules.IsOsaka {
if size > params.MaxInitCodeSizeOsaka {
return fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, size, params.MaxInitCodeSizeOsaka)
}
} else if rules.IsShanghai {
if size > params.MaxInitCodeSize {
return fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, size, params.MaxInitCodeSize)
}
}
return nil
}

// calcMemSize64 calculates the required memory size, and returns
// the size and whether the result overflowed uint64
func calcMemSize64(off, l *uint256.Int) (uint64, bool) {
Expand Down
10 changes: 8 additions & 2 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,14 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
}

// Check whether the max code size has been exceeded, assign err if the case.
if evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
return ret, ErrMaxCodeSizeExceeded
if evm.chainRules.IsOsaka {
if len(ret) > params.MaxCodeSizeOsaka {
return ret, ErrMaxCodeSizeExceeded
}
} else if evm.chainRules.IsEIP158 {
if len(ret) > params.MaxCodeSize {
return ret, ErrMaxCodeSizeExceeded
}
}

// Reject code starting with 0xEF if EIP-3541 is enabled.
Expand Down
10 changes: 5 additions & 5 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package vm

import (
"errors"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
Expand Down Expand Up @@ -314,8 +313,8 @@ func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m
if overflow {
return 0, ErrGasUintOverflow
}
if size > params.MaxInitCodeSize {
return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size)
if err := CheckInitCodeSize(&evm.chainRules, size); err != nil {
return 0, err
}
// Since size <= params.MaxInitCodeSize, these multiplication cannot overflow
moreGas := params.InitCodeWordGas * ((size + 31) / 32)
Expand All @@ -324,6 +323,7 @@ func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m
}
return gas, nil
}

func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
gas, err := memoryGasCost(mem, memorySize)
if err != nil {
Expand All @@ -333,8 +333,8 @@ func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory,
if overflow {
return 0, ErrGasUintOverflow
}
if size > params.MaxInitCodeSize {
return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size)
if err := CheckInitCodeSize(&evm.chainRules, size); err != nil {
return 0, err
}
// Since size <= params.MaxInitCodeSize, these multiplication cannot overflow
moreGas := (params.InitCodeWordGas + params.Keccak256WordGas) * ((size + 31) / 32)
Expand Down
3 changes: 3 additions & 0 deletions params/protocol_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ const (
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions

MaxCodeSizeOsaka = 0xC000 // Maximum bytecode to permit for a contract
MaxInitCodeSizeOsaka = 0x12000 // Maximum initcode to permit in a creation transaction and create instructions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x18000?


// Precompiled contract gas prices

EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price
Expand Down
Loading