Skip to content

Commit

Permalink
Make contract size limit configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
ganeshvanahalli committed Sep 21, 2023
1 parent e9028a6 commit a1f8141
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 9 deletions.
4 changes: 2 additions & 2 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,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:
Expand Down
4 changes: 2 additions & 2 deletions core/txpool/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,8 +615,8 @@ func (pool *TxPool) validateTxBasics(tx *types.Transaction, local bool) error {
return ErrOversizedData
}
// Check whether the init code size has been exceeded.
if pool.shanghai.Load() && 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 pool.shanghai.Load() && tx.To() == nil && len(tx.Data()) > int(*pool.chainconfig.MaxInitCodeSize) {
return fmt.Errorf("%w: code size %v limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), int(*pool.chainconfig.MaxInitCodeSize))
}
// Transactions can't be negative. This may never happen using RLP decoded
// transactions but may occur if you create a transaction using the RPC.
Expand Down
2 changes: 1 addition & 1 deletion core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,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
}

Expand Down
8 changes: 4 additions & 4 deletions core/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,10 +308,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
Expand All @@ -324,10 +324,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
Expand Down
22 changes: 22 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package params

import (
"encoding/json"
"fmt"
"math/big"

Expand Down Expand Up @@ -307,6 +308,27 @@ type ChainConfig struct {
Clique *CliqueConfig `json:"clique,omitempty"`

ArbitrumChainParams ArbitrumChainParams `json:"arbitrum,omitempty"`

MaxCodeSize *uint64 `json:"maxCodeSize,omitempty,"` // Maximum bytecode to permit for a contract
MaxInitCodeSize *uint64 `json:"maxInitCodeSize,omitempty"` // Maximum initcode to permit in a creation transaction and create instructions
}

// UnmarshalJSON implements the json.Unmarshaler interface by decoding the json
// string values into the config fields
func (c *ChainConfig) UnmarshalJSON(data []byte) error {
type chainConfigJSON ChainConfig
var cfgJSON chainConfigJSON
if err := json.Unmarshal(data, &cfgJSON); err != nil {
return err
}
if cfgJSON.MaxCodeSize == nil {
cfgJSON.MaxCodeSize = newUint64(MaxCodeSize)
}
if cfgJSON.MaxInitCodeSize == nil {
cfgJSON.MaxInitCodeSize = newUint64(MaxInitCodeSize)
}
*c = ChainConfig(cfgJSON)
return nil
}

// EthashConfig is the consensus engine configs for proof-of-work based sealing.
Expand Down
31 changes: 31 additions & 0 deletions params/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package params

import (
"encoding/json"
"math/big"
"reflect"
"testing"
Expand Down Expand Up @@ -140,3 +141,33 @@ func TestConfigRules(t *testing.T) {
t.Errorf("expected %v to be shanghai", currentArbosVersion)
}
}

type marshalUnMarshalTest struct {
input interface{}
want interface{}
}

var unmarshalChainConfigTests = []marshalUnMarshalTest{
{input: `{"maxCodeSize": 10, "maxInitCodeSize": 10}`,
want: [2]uint64{10, 10}},
{input: `{"maxCodeSize": 10}`,
want: [2]uint64{10, MaxInitCodeSize}},
{input: `{"maxInitCodeSize": 10}`,
want: [2]uint64{MaxCodeSize, 10}},
{input: `{}`,
want: [2]uint64{MaxCodeSize, MaxInitCodeSize}},
}

func TestUnmarshalChainConfig(t *testing.T) {
var c ChainConfig
for _, test := range unmarshalChainConfigTests {
if err := json.Unmarshal([]byte(test.input.(string)), &c); err != nil {
t.Errorf("failed to unmarshal. Error: %q", err)
}
expected := test.want.([2]uint64)
if *c.MaxCodeSize != expected[0] || *c.MaxInitCodeSize != expected[1] {
t.Errorf("failed to unmarshal MaxCodeSize and MaxInitCodeSize correctly. unmarshalled as (%d %d) want (%d %d))",
*c.MaxCodeSize, *c.MaxInitCodeSize, expected[0], expected[1])
}
}
}

0 comments on commit a1f8141

Please sign in to comment.