core: fixups for devnet-2

This commit is contained in:
lightclient 2025-06-23 12:44:35 +02:00
parent 0c422021aa
commit 3e4cb3d7df
No known key found for this signature in database
GPG key ID: 657913021EF45A6A
5 changed files with 46 additions and 24 deletions

View file

@ -180,7 +180,7 @@ func Transaction(ctx *cli.Context) error {
r.Error = errors.New("gas * maxFeePerGas exceeds 256 bits") r.Error = errors.New("gas * maxFeePerGas exceeds 256 bits")
} }
// Check whether the init code size has been exceeded. // Check whether the init code size has been exceeded.
if chainConfig.IsShanghai(new(big.Int), 0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { if chainConfig.IsShanghai(new(big.Int), 0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSizeEIP3860 {
r.Error = errors.New("max initcode size exceeded") r.Error = errors.New("max initcode size exceeded")
} }
results = append(results, r) results = append(results, r)

View file

@ -1361,6 +1361,10 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d
al.AddAddress(sender) al.AddAddress(sender)
if dst != nil { if dst != nil {
al.AddAddress(*dst) al.AddAddress(*dst)
// TODO: add for devnet-3
// if rules.IsOsaka {
// al.AddAddressCode(*dst)
// }
// If it's a create-tx, the destination will be added inside evm.create // If it's a create-tx, the destination will be added inside evm.create
} }
for _, addr := range precompiles { for _, addr := range precompiles {

View file

@ -87,8 +87,8 @@ 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()) 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 // Check whether the init code size has been exceeded
if rules.IsShanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { if rules.IsShanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSizeEIP7907 {
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize) return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSizeEIP7907)
} }
// Transactions can't be negative. This may never happen using RLP decoded // Transactions can't be negative. This may never happen using RLP decoded
// transactions but may occur for transactions created using the RPC. // transactions but may occur for transactions created using the RPC.

View file

@ -18,6 +18,7 @@ package vm
import ( import (
"errors" "errors"
"fmt"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/common/math"
@ -318,12 +319,25 @@ var (
gasCallCodeEIP7907 = makeCallVariantGasCallEIP7907(gasCallCode) gasCallCodeEIP7907 = makeCallVariantGasCallEIP7907(gasCallCode)
) )
func getColdCodeAccessGasCost(evm *EVM, addr common.Address) uint64 { // Rounds n up to the nearest multiple of 32.
codeSize := evm.StateDB.GetCodeSize(addr) func ceil32(n int) uint64 {
if codeSize <= params.MaxCodeSizeEIP7907 { r := n % 32
if r == 0 {
return uint64(n)
} else {
return uint64(n + 32 - r)
}
}
func calcColdCodeAccessGasCost(evm *EVM, addr common.Address) uint64 {
size := evm.StateDB.GetCodeSize(addr)
// Only charge additional access cost for contracts larger than old limit.
if size <= params.MaxCodeSizeEIP170 {
return 0 return 0
} }
return (uint64(codeSize) - params.MaxCodeSizeEIP7907) * 2 / 32 excess := ceil32(size - params.MaxCodeSizeEIP170)
fmt.Println("excess", excess, "cost", (excess*params.CodeReadPerWordGasEIP7907)/32)
return (excess * params.CodeReadPerWordGasEIP7907) / 32
} }
func makeCallVariantGasCallEIP7907(oldCalculator gasFunc) gasFunc { func makeCallVariantGasCallEIP7907(oldCalculator gasFunc) gasFunc {
@ -346,9 +360,10 @@ func makeCallVariantGasCallEIP7907(oldCalculator gasFunc) gasFunc {
} }
total += coldCost total += coldCost
} }
// Check code presence in the access list // Check code presence in the access list
if !evm.StateDB.AddressCodeInAccessList(addr) { if !evm.StateDB.AddressCodeInAccessList(addr) {
cost := getColdCodeAccessGasCost(evm, addr) cost := calcColdCodeAccessGasCost(evm, addr)
evm.StateDB.AddAddressCodeToAccessList(addr) evm.StateDB.AddAddressCodeToAccessList(addr)
if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) {
return 0, ErrOutOfGas return 0, ErrOutOfGas
@ -356,6 +371,9 @@ func makeCallVariantGasCallEIP7907(oldCalculator gasFunc) gasFunc {
total += cost total += cost
} }
// TODO: reading code here would defeat the purpose of separate charging, so
// we should first see if the code size is 23 bytes before parsing.
// Check if code is a delegation and if so, charge for resolution. // Check if code is a delegation and if so, charge for resolution.
if target, ok := types.ParseDelegation(evm.StateDB.GetCode(addr)); ok { if target, ok := types.ParseDelegation(evm.StateDB.GetCode(addr)); ok {
var cost uint64 var cost uint64
@ -370,7 +388,7 @@ func makeCallVariantGasCallEIP7907(oldCalculator gasFunc) gasFunc {
} }
total += cost total += cost
if !evm.StateDB.AddressCodeInAccessList(target) { if !evm.StateDB.AddressCodeInAccessList(target) {
cost = getColdCodeAccessGasCost(evm, target) cost = calcColdCodeAccessGasCost(evm, target)
evm.StateDB.AddAddressCodeToAccessList(target) evm.StateDB.AddAddressCodeToAccessList(target)
if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) {
return 0, ErrOutOfGas return 0, ErrOutOfGas
@ -410,27 +428,25 @@ func gasExtCodeCopyEIP7907(evm *EVM, contract *Contract, stack *Stack, mem *Memo
return 0, err return 0, err
} }
addr := common.Address(stack.peek().Bytes20()) addr := common.Address(stack.peek().Bytes20())
var total uint64
// Check slot presence in the access list // Check slot presence in the access list
if !evm.StateDB.AddressInAccessList(addr) { if !evm.StateDB.AddressInAccessList(addr) {
evm.StateDB.AddAddressToAccessList(addr) evm.StateDB.AddAddressToAccessList(addr)
var overflow bool
// We charge (cold-warm), since 'warm' is already charged as constantGas // We charge (cold-warm), since 'warm' is already charged as constantGas
if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow {
if !contract.UseGas(gas, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { return 0, ErrGasUintOverflow
return 0, ErrOutOfGas
} }
total += gas
} }
// Check address code presence in the access list // Check address code presence in the access list
if !evm.StateDB.AddressCodeInAccessList(addr) { if !evm.StateDB.AddressCodeInAccessList(addr) {
cost := getColdCodeAccessGasCost(evm, addr) cost := calcColdCodeAccessGasCost(evm, addr)
evm.StateDB.AddAddressCodeToAccessList(addr) evm.StateDB.AddAddressCodeToAccessList(addr)
if !contract.UseGas(cost, evm.Config.Tracer, tracing.GasChangeCallStorageColdAccess) { var overflow bool
return 0, ErrOutOfGas // We charge (cold-warm), since 'warm' is already charged as constantGas
if gas, overflow = math.SafeAdd(gas, cost); overflow {
return 0, ErrGasUintOverflow
} }
total += cost
} }
return gas, nil
return total, nil
} }

View file

@ -132,10 +132,12 @@ const (
DefaultElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have. DefaultElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have.
InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks. InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks.
MaxCodeSizeEIP170 = 24576 // Maximum bytecode to permit for a contract MaxCodeSizeEIP170 = 24576 // Maximum bytecode to permit for a contract
MaxCodeSizeEIP7907 = 268435456 // Maximum bytecode permitted per contract after EIP-7907 MaxInitCodeSizeEIP3860 = 2 * MaxCodeSizeEIP170 // Maximum initcode to permit in a creation transaction and create instructions
MaxInitCodeSizeEIP3860 = 2 * MaxCodeSizeEIP170 // Maximum initcode to permit in a creation transaction and create instructions
MaxInitCodeSizeEIP7907 = 2 * MaxCodeSizeEIP7907 // Maximum initcode to permit in a creation transaction and create instructions MaxCodeSizeEIP7907 = 262144 // Maximum bytecode permitted per contract after EIP-7907
MaxInitCodeSizeEIP7907 = 2 * MaxCodeSizeEIP7907 // Maximum initcode to permit in a creation transaction and create instructions
CodeReadPerWordGasEIP7907 = 2 // Cost per word to read code from disk.
// Precompiled contract gas prices // Precompiled contract gas prices