From fbec4dca553e6a0d01fb4f764a4e303a93e40813 Mon Sep 17 00:00:00 2001 From: Marius van der Wijden Date: Fri, 28 Jun 2024 17:04:09 +0200 Subject: [PATCH] core/vm: fix opEOFCreate hashing charge --- core/vm/eips.go | 17 ++++++++++++++++- core/vm/gas_table.go | 13 +------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index 4bf6718d9f..d13a3fdc8e 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -889,12 +889,19 @@ func opEOFCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ( } subcontainer := scope.Contract.Container.ContainerSections[idx] + // Deduct hashing charge + // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow + hashingCharge := (params.Keccak256WordGas) * ((uint64(len(scope.Contract.Container.ContainerCode[idx])) + 31) / 32) + if ok := scope.Contract.UseGas(hashingCharge, interpreter.evm.Config.Tracer, tracing.GasChangeUnspecified); !ok { + return nil, ErrGasUintOverflow + } // Reuse last popped value from stack stackvalue := size // Apply EIP150 gas -= gas / 64 scope.Contract.UseGas(gas, interpreter.evm.Config.Tracer, tracing.GasChangeCallContractCreation2) - + // Skip the immediate + *pc += 1 res, addr, returnGas, suberr := interpreter.evm.EOFCreate(scope.Contract, input, subcontainer.MarshalBinary(), gas, &value, &salt) if suberr != nil { stackvalue.Clear() @@ -990,6 +997,14 @@ func opReturnContract(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte if len(deployedCode) == 0 { return nil, errors.New("nonexistant subcontainer") } + // Restore context + var ( + last = len(scope.ReturnStack) - 1 + retCtx = scope.ReturnStack[last] + ) + scope.ReturnStack = scope.ReturnStack[:last] + scope.CodeSection = retCtx.Section + *pc = retCtx.Pc - 1 return deployedCode, errStopToken } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index b0e3b70720..e79a56f053 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -586,17 +586,6 @@ func gasEOFCreate(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memor if err != nil { return 0, err } - size, overflow := stack.Back(3).Uint64WithOverflow() - if overflow { - return 0, ErrGasUintOverflow - } - if size > params.MaxInitCodeSize { - return 0, fmt.Errorf("%w: size %d", ErrMaxInitCodeSizeExceeded, size) - } - // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow - moreGas := (params.Keccak256WordGas) * ((size + 31) / 32) - if gas, overflow = math.SafeAdd(gas, moreGas); overflow { - return 0, ErrGasUintOverflow - } + // hashing charge needs to be deducted in the opcode itself, since it depends on the immediate return gas, nil }