Skip to content

Commit

Permalink
don't charge creation gas + charge code chunks in create
Browse files Browse the repository at this point in the history
  • Loading branch information
gballet committed Mar 19, 2024
1 parent f8551db commit 19693bc
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 18 deletions.
4 changes: 2 additions & 2 deletions core/state_processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,8 @@ func TestProcessVerkle(t *testing.T) {

txCost1 := params.TxGas
txCost2 := params.TxGas
contractCreationCost := intrinsicContractCreationGas + uint64(5600+700+700+700 /* creation with value */ +2739 /* execution costs */)
codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + uint64(5600+700 /* creation */ +198644 /* execution costs */)
contractCreationCost := intrinsicContractCreationGas + uint64(5600+700+700+700 /* creation with value */ +1439 /* execution costs */)
codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + uint64(5600+700 /* creation */ +56344 /* execution costs */)
blockGasUsagesExpected := []uint64{
txCost1*2 + txCost2,
txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas,
Expand Down
28 changes: 17 additions & 11 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,20 +504,26 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// be stored due to not enough gas set an error and let it be handled
// by the error checking condition below.
if err == nil {
createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas) {
evm.StateDB.SetCode(address, ret)
if !evm.chainRules.IsEIP4762 {
createDataGas := uint64(len(ret)) * params.CreateDataGas
if contract.UseGas(createDataGas) {
} else {
err = ErrCodeStoreOutOfGas
}
} else {
err = ErrCodeStoreOutOfGas
// Contract creation completed, touch the missing field in the contract
if len(ret) > 0 {
if !contract.UseGas(evm.Accesses.TouchCodeChunkRangeAndChargeGas(address.Bytes(), 0, uint64(len(ret)), uint64(len(ret)), true)) {

Check failure on line 516 in core/vm/evm.go

View workflow job for this annotation

GitHub Actions / build

evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 516 in core/vm/evm.go

View workflow job for this annotation

GitHub Actions / test

evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 516 in core/vm/evm.go

View workflow job for this annotation

GitHub Actions / lint

evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 516 in core/vm/evm.go

View workflow job for this annotation

GitHub Actions / lint

evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)
err = ErrOutOfGas
}
}
if err == nil && !contract.UseGas(evm.Accesses.TouchFullAccount(address.Bytes()[:], true)) {
err = ErrOutOfGas
}
}
}

if err == nil && evm.chainRules.IsEIP4762 {
if len(ret) > 0 {
evm.Accesses.TouchCodeChunksRangeOnReadAndChargeGas(address.Bytes(), 0, uint64(len(ret)), uint64(len(ret)))
}
if !contract.UseGas(evm.Accesses.TouchFullAccount(address.Bytes()[:], true)) {
err = ErrOutOfGas
if err == nil {
evm.StateDB.SetCode(address, ret)
}
}

Expand Down
8 changes: 4 additions & 4 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
contractAddr := scope.Contract.Address()
paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(scope.Contract.Code, uint64CodeOffset, length.Uint64())
if interpreter.evm.chainRules.IsEIP4762 && !scope.Contract.IsDeployment {
statelessGas := interpreter.evm.Accesses.TouchCodeChunksRangeOnReadAndChargeGas(contractAddr[:], copyOffset, nonPaddedCopyLength, uint64(len(scope.Contract.Code)))
statelessGas := interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas(contractAddr[:], copyOffset, nonPaddedCopyLength, uint64(len(scope.Contract.Code)), false)

Check failure on line 374 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / build

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 374 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / test

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 374 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / lint

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 374 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / lint

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)
if !scope.Contract.UseGas(statelessGas) {
scope.Contract.Gas = 0
return nil, ErrOutOfGas
Expand Down Expand Up @@ -401,7 +401,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
self: AccountRef(addr),
}
paddedCodeCopy, copyOffset, nonPaddedCopyLength := getDataAndAdjustedBounds(code, uint64CodeOffset, length.Uint64())
statelessGas := interpreter.evm.Accesses.TouchCodeChunksRangeOnReadAndChargeGas(addr[:], copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)))
statelessGas := interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas(addr[:], copyOffset, nonPaddedCopyLength, uint64(len(contract.Code)), false)

Check failure on line 404 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / build

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 404 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / test

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 404 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / lint

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)
statelessGas += interpreter.evm.Accesses.TouchVersion(addr[:], false)
statelessGas += interpreter.evm.Accesses.TouchCodeSize(addr[:], false)
if !scope.Contract.UseGas(statelessGas) {
Expand Down Expand Up @@ -954,7 +954,7 @@ func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]by
// touch next chunk if PUSH1 is at the boundary. if so, *pc has
// advanced past this boundary.
contractAddr := scope.Contract.Address()
statelessGas := interpreter.evm.Accesses.TouchCodeChunksRangeOnReadAndChargeGas(contractAddr[:], *pc+1, uint64(1), uint64(len(scope.Contract.Code)))
statelessGas := interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas(contractAddr[:], *pc+1, uint64(1), uint64(len(scope.Contract.Code)), false)

Check failure on line 957 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / build

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 957 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / test

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 957 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / lint

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)
if !scope.Contract.UseGas(statelessGas) {
scope.Contract.Gas = 0
return nil, ErrOutOfGas
Expand Down Expand Up @@ -983,7 +983,7 @@ func makePush(size uint64, pushByteSize int) executionFunc {

if !scope.Contract.IsDeployment && interpreter.evm.chainRules.IsPrague {
contractAddr := scope.Contract.Address()
statelessGas := interpreter.evm.Accesses.TouchCodeChunksRangeOnReadAndChargeGas(contractAddr[:], uint64(startMin), uint64(pushByteSize), uint64(len(scope.Contract.Code)))
statelessGas := interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas(contractAddr[:], uint64(startMin), uint64(pushByteSize), uint64(len(scope.Contract.Code)), false)

Check failure on line 986 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / build

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 986 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / test

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 986 in core/vm/instructions.go

View workflow job for this annotation

GitHub Actions / lint

interpreter.evm.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)
if !scope.Contract.UseGas(statelessGas) {
scope.Contract.Gas = 0
return nil, ErrOutOfGas
Expand Down
2 changes: 1 addition & 1 deletion core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
// if the PC ends up in a new "chunk" of verkleized code, charge the
// associated costs.
contractAddr := contract.Address()
contract.Gas -= in.evm.TxContext.Accesses.TouchCodeChunksRangeOnReadAndChargeGas(contractAddr[:], pc, 1, uint64(len(contract.Code)))
contract.Gas -= in.evm.TxContext.Accesses.TouchCodeChunkRangeAndChargeGas(contractAddr[:], pc, 1, uint64(len(contract.Code)), false)

Check failure on line 186 in core/vm/interpreter.go

View workflow job for this annotation

GitHub Actions / build

in.evm.TxContext.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 186 in core/vm/interpreter.go

View workflow job for this annotation

GitHub Actions / test

in.evm.TxContext.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)

Check failure on line 186 in core/vm/interpreter.go

View workflow job for this annotation

GitHub Actions / lint

in.evm.TxContext.Accesses.TouchCodeChunkRangeAndChargeGas undefined (type *state.AccessWitness has no field or method TouchCodeChunkRangeAndChargeGas)) (typecheck)
}

// Get the operation from the jump table and validate the stack to ensure there are
Expand Down

0 comments on commit 19693bc

Please sign in to comment.