Skip to content

Commit

Permalink
migrate override and gas changes
Browse files Browse the repository at this point in the history
  • Loading branch information
lwedge99 committed Nov 6, 2023
1 parent be135a2 commit 52a4d28
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 17 deletions.
16 changes: 9 additions & 7 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,16 @@ func (st *StateTransition) TransitionDb(refunds bool, gasBailout bool) (*Executi
isEIP3860 := vmConfig.HasEip3860(rules)

// Check clauses 4-5, subtract intrinsic gas if everything is correct
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsIstanbul, isEIP3860)
if err != nil {
return nil, err
}
if st.gas < gas {
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
if !st.evm.Config().IgnoreGas {
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, rules.IsHomestead, rules.IsIstanbul, isEIP3860)
if err != nil {
return nil, err
}
if st.gas < gas {
return nil, fmt.Errorf("%w: have %d, want %d", ErrIntrinsicGas, st.gas, gas)
}
st.gas -= gas
}
st.gas -= gas

var bailout bool
// Gas bailout (for trace_call) should only be applied if there is not sufficient balance to perform value transfer
Expand Down
29 changes: 23 additions & 6 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,17 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
var gasConsumption uint64
depth := evm.interpreter.Depth()

if evm.config.CreateAddressOverride != nil {
address = *evm.config.CreateAddressOverride
}
if evm.config.CreationCodeOverrides != nil {
if code, ok := evm.config.CreationCodeOverrides[address]; ok {
codeAndHash.code = code
codeAndHash.hash = libcommon.Hash{}
_ = codeAndHash.Hash()
}
}

if evm.config.Debug {
if depth == 0 {
evm.config.Tracer.CaptureStart(evm, caller.Address(), address, false /* precompile */, true /* create */, codeAndHash.code, gas, value, nil)
Expand Down Expand Up @@ -369,12 +380,15 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
if evm.chainRules.IsBerlin {
evm.intraBlockState.AddAddressToAccessList(address)
}
// Ensure there's no existing contract already at the designated address
contractHash := evm.intraBlockState.GetCodeHash(address)
if evm.intraBlockState.GetNonce(address) != 0 || (contractHash != (libcommon.Hash{}) && contractHash != emptyCodeHash) {
err = ErrContractAddressCollision
return nil, libcommon.Address{}, 0, err
if evm.config.CreateAddressOverride == nil {
// Ensure there's no existing contract already at the designated address
contractHash := evm.intraBlockState.GetCodeHash(address)
if evm.intraBlockState.GetNonce(address) != 0 || (contractHash != (libcommon.Hash{}) && contractHash != emptyCodeHash) {
err = ErrContractAddressCollision
return nil, libcommon.Address{}, 0, err
}
}

// Create a new account on the state
snapshot := evm.intraBlockState.Snapshot()
evm.intraBlockState.CreateAccount(address, true)
Expand All @@ -395,7 +409,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
ret, err = run(evm, contract, nil, false)

// EIP-170: Contract code size limit
if err == nil && evm.chainRules.IsSpuriousDragon && len(ret) > params.MaxCodeSize {
if err == nil && !evm.config.IgnoreCodeSizeLimit && evm.chainRules.IsSpuriousDragon && len(ret) > params.MaxCodeSize {
// Gnosis Chain prior to Shanghai didn't have EIP-170 enabled,
// but EIP-3860 (part of Shanghai) requires EIP-170.
if !evm.chainRules.IsAura || evm.config.HasEip3860(evm.chainRules) {
Expand All @@ -413,6 +427,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
// by the error checking condition below.
if err == nil {
createDataGas := uint64(len(ret)) * params.CreateDataGas
if evm.config.IgnoreGas {
createDataGas = 0
}
if contract.UseGas(createDataGas) {
evm.intraBlockState.SetCode(address, ret)
} else if evm.chainRules.IsHomestead {
Expand Down
6 changes: 4 additions & 2 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
gas = scope.Contract.Gas
)
if interpreter.evm.ChainRules().IsTangerineWhistle {
if !interpreter.cfg.IgnoreGas && interpreter.evm.ChainRules().IsTangerineWhistle {
gas -= gas / 64
}
// reuse size int for stackvalue
Expand Down Expand Up @@ -689,7 +689,9 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
)

// Apply EIP150
gas -= gas / 64
if !interpreter.cfg.IgnoreGas {
gas -= gas / 64
}
scope.Contract.UseGas(gas)
// reuse size int for stackvalue
stackValue := size
Expand Down
23 changes: 23 additions & 0 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/hexutility"
"github.com/ledgerwatch/erigon-lib/common/math"
"github.com/ledgerwatch/log/v3"

Expand All @@ -42,6 +43,11 @@ type Config struct {
RestoreState bool // Revert all changes made to the state (useful for constant system calls)

ExtraEips []int // Additional EIPS that are to be enabled

CreationCodeOverrides map[libcommon.Address]hexutility.Bytes
CreateAddressOverride *libcommon.Address
IgnoreGas bool
IgnoreCodeSizeLimit bool
}

var pool = sync.Pool{
Expand Down Expand Up @@ -160,6 +166,23 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter {
}
}

if cfg.IgnoreGas {
jt = copyJumpTable(jt)
for i, op := range jt {
opCode := OpCode(i)
// retain call costs to prevent call stack from going too deep
// some contracts use a loop to burn gas
// if all codes in the loop have zero cost, it will run forever
if opCode == CALL || opCode == STATICCALL || opCode == CALLCODE || opCode == DELEGATECALL || opCode == GAS {
continue
}
op.constantGas = 0
op.dynamicGas = func(*EVM, *Contract, *stack.Stack, *Memory, uint64) (uint64, error) {
return 0, nil
}
}
}

return &EVMInterpreter{
VM: &VM{
evm: evm,
Expand Down
7 changes: 7 additions & 0 deletions eth/tracers/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package tracers
import (
"encoding/json"

libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/hexutility"
"github.com/ledgerwatch/erigon/eth/tracers/logger"
"github.com/ledgerwatch/erigon/turbo/adapter/ethapi"
)
Expand All @@ -17,6 +19,11 @@ type TraceConfig struct {
NoRefunds *bool // Turns off gas refunds when tracing
StateOverrides *ethapi.StateOverrides

IgnoreGas *bool
IgnoreCodeSizeLimit *bool
CreationCodeOverrides map[libcommon.Address]hexutility.Bytes
CreateAddressOverride *libcommon.Address

BorTraceEnabled *bool
BorTx *bool
}
10 changes: 9 additions & 1 deletion turbo/jsonrpc/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package jsonrpc
import (
"context"
"fmt"
"github.com/ledgerwatch/erigon-lib/common/hexutil"
"math/big"
"time"

"github.com/ledgerwatch/erigon-lib/common/hexutil"

"github.com/holiman/uint256"
jsoniter "github.com/json-iterator/go"
"github.com/ledgerwatch/erigon-lib/common"
Expand Down Expand Up @@ -250,6 +251,13 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo
stream.WriteNil()
return err
}

if config != nil && config.StateOverrides != nil {
if err := config.StateOverrides.Override(ibs); err != nil {
return fmt.Errorf("override state: %v", err)
}
}

// Trace the transaction and return
return transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream, api.evmCallTimeout)
}
Expand Down
16 changes: 15 additions & 1 deletion turbo/transactions/tracing.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,21 @@ func TraceTx(
streaming = true
}
// Run the transaction with tracing enabled.
vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer})
vmConfig := vm.Config{
Debug: true,
Tracer: tracer,
}
if config != nil {
vmConfig.CreateAddressOverride = config.CreateAddressOverride
vmConfig.CreationCodeOverrides = config.CreationCodeOverrides
if config.IgnoreCodeSizeLimit != nil {
vmConfig.IgnoreCodeSizeLimit = *config.IgnoreCodeSizeLimit
}
if config.IgnoreGas != nil {
vmConfig.IgnoreGas = *config.IgnoreGas
}
}
vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vmConfig)
var refunds = true
if config != nil && config.NoRefunds != nil && *config.NoRefunds {
refunds = false
Expand Down

0 comments on commit 52a4d28

Please sign in to comment.