Skip to content

Commit 0fc5059

Browse files
jwasinger0xjvn
andcommitted
core: implement eip 7954 increase Maximum Contract Size
Co-authored-by: jeevan-sid <g1siddharthr@gmail.com>
1 parent ec95ab4 commit 0fc5059

File tree

7 files changed

+59
-17
lines changed

7 files changed

+59
-17
lines changed

cmd/evm/internal/t8ntool/transaction.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ import (
2727
"github.com/ethereum/go-ethereum/common"
2828
"github.com/ethereum/go-ethereum/common/hexutil"
2929
"github.com/ethereum/go-ethereum/core"
30+
3031
"github.com/ethereum/go-ethereum/core/types"
32+
"github.com/ethereum/go-ethereum/core/vm"
3133
"github.com/ethereum/go-ethereum/params"
3234
"github.com/ethereum/go-ethereum/rlp"
3335
"github.com/ethereum/go-ethereum/tests"
@@ -177,9 +179,12 @@ func Transaction(ctx *cli.Context) error {
177179
r.Error = errors.New("gas * maxFeePerGas exceeds 256 bits")
178180
}
179181
// Check whether the init code size has been exceeded.
180-
if chainConfig.IsShanghai(new(big.Int), 0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
181-
r.Error = errors.New("max initcode size exceeded")
182+
if tx.To() == nil {
183+
if err := vm.CheckMaxInitCodeSize(&rules, uint64(len(tx.Data()))); err != nil {
184+
r.Error = err
185+
}
182186
}
187+
183188
if chainConfig.IsOsaka(new(big.Int), 0) && tx.Gas() > params.MaxTxGas {
184189
r.Error = errors.New("gas limit exceeds maximum")
185190
}

core/state_transition.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,10 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
487487
}
488488

489489
// Check whether the init code size has been exceeded.
490-
if rules.IsShanghai && contractCreation && len(msg.Data) > params.MaxInitCodeSize {
491-
return nil, fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize)
490+
if contractCreation {
491+
if err := vm.CheckMaxInitCodeSize(&rules, uint64(len(msg.Data))); err != nil {
492+
return nil, err
493+
}
492494
}
493495

494496
// Execute the preparatory steps for state transition which includes:

core/txpool/validation.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/ethereum/go-ethereum/core"
2626
"github.com/ethereum/go-ethereum/core/state"
2727
"github.com/ethereum/go-ethereum/core/types"
28+
"github.com/ethereum/go-ethereum/core/vm"
2829
"github.com/ethereum/go-ethereum/crypto/kzg4844"
2930
"github.com/ethereum/go-ethereum/log"
3031
"github.com/ethereum/go-ethereum/params"
@@ -86,8 +87,10 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
8687
return fmt.Errorf("%w: type %d rejected, pool not yet in Prague", core.ErrTxTypeNotSupported, tx.Type())
8788
}
8889
// Check whether the init code size has been exceeded
89-
if rules.IsShanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
90-
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
90+
if tx.To() == nil {
91+
if err := vm.CheckMaxInitCodeSize(&rules, uint64(len(tx.Data()))); err != nil {
92+
return err
93+
}
9194
}
9295
if rules.IsOsaka && tx.Gas() > params.MaxTxGas {
9396
return fmt.Errorf("%w (cap: %d, tx: %d)", core.ErrGasLimitTooHigh, params.MaxTxGas, tx.Gas())

core/vm/common.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,43 @@
1717
package vm
1818

1919
import (
20+
"fmt"
2021
"math"
2122

2223
"github.com/ethereum/go-ethereum/common"
24+
"github.com/ethereum/go-ethereum/params"
2325
"github.com/holiman/uint256"
2426
)
2527

28+
// CheckMaxInitCodeSize checks the size of contract initcode against the protocol-defined limit.
29+
func CheckMaxInitCodeSize(rules *params.Rules, size uint64) error {
30+
if rules.IsAmsterdam {
31+
if size > params.MaxInitCodeSizeAmsterdam {
32+
return fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, size, params.MaxCodeSizeAmsterdam)
33+
}
34+
} else if rules.IsShanghai {
35+
if size > params.MaxInitCodeSize {
36+
return fmt.Errorf("%w: code size %v limit %v", ErrMaxInitCodeSizeExceeded, size, params.MaxInitCodeSize)
37+
}
38+
}
39+
40+
return nil
41+
}
42+
43+
// CheckMaxCodeSize checks the size of contract code against the protocol-defined limit.
44+
func CheckMaxCodeSize(rules *params.Rules, size uint64) error {
45+
if rules.IsAmsterdam {
46+
if size > params.MaxCodeSizeAmsterdam {
47+
return fmt.Errorf("%w: code size %v limit %v", ErrMaxCodeSizeExceeded, size, params.MaxCodeSizeAmsterdam)
48+
}
49+
} else if rules.IsEIP158 {
50+
if size > params.MaxCodeSize {
51+
return fmt.Errorf("%w: code size %v limit %v", ErrMaxCodeSizeExceeded, size, params.MaxCodeSize)
52+
}
53+
}
54+
return nil
55+
}
56+
2657
// calcMemSize64 calculates the required memory size, and returns
2758
// the size and whether the result overflowed uint64
2859
func calcMemSize64(off, l *uint256.Int) (uint64, bool) {

core/vm/evm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,8 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b
606606
}
607607

608608
// Check whether the max code size has been exceeded, assign err if the case.
609-
if evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
610-
return ret, ErrMaxCodeSizeExceeded
609+
if err := CheckMaxCodeSize(&evm.chainRules, uint64(len(ret))); err != nil {
610+
return ret, err
611611
}
612612

613613
// Reject code starting with 0xEF if EIP-3541 is enabled.

core/vm/gas_table.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package vm
1818

1919
import (
2020
"errors"
21-
"fmt"
2221

2322
"github.com/ethereum/go-ethereum/common"
2423
"github.com/ethereum/go-ethereum/common/math"
@@ -318,10 +317,10 @@ func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, m
318317
if overflow {
319318
return 0, ErrGasUintOverflow
320319
}
321-
if size > params.MaxInitCodeSize {
322-
return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size)
320+
if err := CheckMaxInitCodeSize(&evm.chainRules, size); err != nil {
321+
return 0, err
323322
}
324-
// Since size <= params.MaxInitCodeSize, these multiplication cannot overflow
323+
// Since size <= the protocol-defined maximum initcode size limit, these multiplication cannot overflow
325324
moreGas := params.InitCodeWordGas * ((size + 31) / 32)
326325
if gas, overflow = math.SafeAdd(gas, moreGas); overflow {
327326
return 0, ErrGasUintOverflow
@@ -337,10 +336,10 @@ func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory,
337336
if overflow {
338337
return 0, ErrGasUintOverflow
339338
}
340-
if size > params.MaxInitCodeSize {
341-
return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size)
339+
if err := CheckMaxInitCodeSize(&evm.chainRules, size); err != nil {
340+
return 0, err
342341
}
343-
// Since size <= params.MaxInitCodeSize, these multiplication cannot overflow
342+
// Since size <= the protocol-defined maximum initcode size limit, these multiplication cannot overflow
344343
moreGas := (params.InitCodeWordGas + params.Keccak256WordGas) * ((size + 31) / 32)
345344
if gas, overflow = math.SafeAdd(gas, moreGas); overflow {
346345
return 0, ErrGasUintOverflow

params/protocol_params.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,10 @@ const (
134134
DefaultElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have.
135135
InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks.
136136

137-
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
138-
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions
137+
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
138+
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions
139+
MaxCodeSizeAmsterdam = 32768 // Maximum bytecode to permit for a contract post Amsterdam
140+
MaxInitCodeSizeAmsterdam = 2 * MaxCodeSizeAmsterdam // Maximum initcode to permit in a creation transaction and create instructions post Amsterdam
139141

140142
// Precompiled contract gas prices
141143

0 commit comments

Comments
 (0)