Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion core/vm/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Contract struct {

Code []byte
CodeHash common.Hash
CodeAddr *common.Address // Address where the code was loaded from (for CODECOPY in optimized mode)
Input []byte

// is the execution frame represented by this object a contract deployment
Expand Down Expand Up @@ -173,9 +174,10 @@ func (c *Contract) Value() *uint256.Int {

// SetCallCode sets the code of the contract and address of the backing data
// object
func (c *Contract) SetCallCode(hash common.Hash, code []byte) {
func (c *Contract) SetCallCode(codeAddr *common.Address, hash common.Hash, code []byte) {
c.Code = code
c.CodeHash = hash
c.CodeAddr = codeAddr
}

// SetOptimizedForTest returns a contract with optimized equals true for test purpose only
Expand Down
1 change: 1 addition & 0 deletions core/vm/contract_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func GetContract(caller common.Address, address common.Address, value *uint256.I
contract.Gas = gas
contract.Code = nil
contract.CodeHash = common.Hash{}
contract.CodeAddr = nil
contract.Input = nil
contract.IsDeployment = false
contract.IsSystemCall = false
Expand Down
26 changes: 17 additions & 9 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
ret, err = nil, nil // gas is unchanged
} else {
if evm.Config.EnableOpcodeOptimizations {
addrCopy := addr
// If the account has no code, we can abort here
// The depth-check is already done, and precompiles handled above
contract := GetContract(caller, addr, value, gas, evm.jumpDests)
Expand All @@ -281,17 +282,18 @@ func (evm *EVM) Call(caller common.Address, addr common.Address, input []byte, g
evm.UseBaseInterpreter()
}
contract.IsSystemCall = isSystemCall(caller)
contract.SetCallCode(codeHash, code)
contract.SetCallCode(&addrCopy, codeHash, code)
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
} else {
addrCopy := addr
// If the account has no code, we can abort here
// The depth-check is already done, and precompiles handled above
contract := GetContract(caller, addr, value, gas, evm.jumpDests)
defer ReturnContract(contract)

contract.IsSystemCall = isSystemCall(caller)
contract.SetCallCode(evm.resolveCodeHash(addr), code)
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addr), code)
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
Expand Down Expand Up @@ -349,14 +351,15 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
if evm.Config.EnableOpcodeOptimizations {
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := GetContract(caller, caller, value, gas, evm.jumpDests)
defer ReturnContract(contract)
code := evm.resolveCode(addr)
codeHash := evm.resolveCodeHash(addr)
contract.optimized, code = tryGetOptimizedCode(evm, codeHash, code)
contract.SetCallCode(codeHash, code)
contract.SetCallCode(&addrCopy, codeHash, code)

if contract.optimized {
evm.UseOptInterpreter()
Expand All @@ -368,12 +371,13 @@ func (evm *EVM) CallCode(caller common.Address, addr common.Address, input []byt
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
} else {
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := GetContract(caller, caller, value, gas, evm.jumpDests)
defer ReturnContract(contract)

contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addr), evm.resolveCode(addr))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
Expand Down Expand Up @@ -415,13 +419,14 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
if evm.Config.EnableOpcodeOptimizations {
addrCopy := addr
// Initialise a new contract and make initialise the delegate values
contract := GetContract(originCaller, caller, value, gas, evm.jumpDests)
defer ReturnContract(contract)
code := evm.resolveCode(addr)
codeHash := evm.resolveCodeHash(addr)
contract.optimized, code = tryGetOptimizedCode(evm, codeHash, code)
contract.SetCallCode(codeHash, code)
contract.SetCallCode(&addrCopy, codeHash, code)
if contract.optimized {
evm.UseOptInterpreter()
contract.codeBitmapFunc = codeBitmapWhitSI
Expand All @@ -431,11 +436,12 @@ func (evm *EVM) DelegateCall(originCaller common.Address, caller common.Address,
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
} else {
addrCopy := addr
// Initialise a new contract and make initialise the delegate values
contract := GetContract(originCaller, caller, value, gas, evm.jumpDests)
defer ReturnContract(contract)

contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addr), evm.resolveCode(addr))
ret, err = evm.interpreter.Run(contract, input, false)
gas = contract.Gas
}
Expand Down Expand Up @@ -485,6 +491,7 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
ret, gas, err = RunPrecompiledContract(p, input, gas, evm.Config.Tracer)
} else {
if evm.Config.EnableOpcodeOptimizations {
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := GetContract(caller, addr, new(uint256.Int), gas, evm.jumpDests)
Expand All @@ -498,19 +505,20 @@ func (evm *EVM) StaticCall(caller common.Address, addr common.Address, input []b
} else {
evm.UseBaseInterpreter()
}
contract.SetCallCode(codeHash, code)
contract.SetCallCode(&addrCopy, codeHash, code)
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in Homestead this also counts for code storage gas errors.
ret, err = evm.interpreter.Run(contract, input, true)
gas = contract.Gas
} else {
addrCopy := addr
// Initialise a new contract and set the code that is to be used by the EVM.
// The contract is a scoped environment for this execution context only.
contract := GetContract(caller, addr, new(uint256.Int), gas, evm.jumpDests)
defer ReturnContract(contract)

contract.SetCallCode(evm.resolveCodeHash(addr), evm.resolveCode(addr))
contract.SetCallCode(&addrCopy, evm.resolveCodeHash(addr), evm.resolveCode(addr))
// When an error was returned by the EVM or when setting the creation code
// above we revert to the snapshot and consume any gas remaining. Additionally
// when we're in Homestead this also counts for code storage gas errors.
Expand Down Expand Up @@ -635,7 +643,7 @@ func (evm *EVM) create(caller common.Address, code []byte, gas uint64, value *ui

// Explicitly set the code to a null hash to prevent caching of jump analysis
// for the initialization code.
contract.SetCallCode(common.Hash{}, code)
contract.SetCallCode(&address, common.Hash{}, code)
contract.IsDeployment = true

ret, err = evm.initNewContract(contract, address)
Expand Down
4 changes: 2 additions & 2 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
code := scope.Contract.Code
if scope.Contract.optimized {
code = interpreter.evm.resolveCode(scope.Contract.address)
code = interpreter.evm.resolveCode(*scope.Contract.CodeAddr)
}
scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(code))))
return nil, nil
Expand All @@ -359,7 +359,7 @@ func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
}
code := scope.Contract.Code
if scope.Contract.optimized {
code = interpreter.evm.resolveCode(scope.Contract.address)
code = interpreter.evm.resolveCode(*scope.Contract.CodeAddr)
}
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
Expand Down
2 changes: 1 addition & 1 deletion core/vm/interpreter_si.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ func (in *EVMInterpreter) executeSingleOpcode(pc *uint64, op OpCode, contract *C
func (in *EVMInterpreter) tryFallbackForSuperInstruction(pc *uint64, seq []OpCode, contract *Contract, stack *Stack, mem *Memory, callCtx *ScopeContext) error {
for _, sub := range seq {
if err := in.executeSingleOpcode(pc, sub, contract, stack, mem, callCtx); err != nil {
log.Error("[FALLBACK-EXEC]", "op", sub.String(), "err", err, "gasLeft", contract.Gas)
log.Debug("[FALLBACK-EXEC]", "op", sub.String(), "err", err, "gasLeft", contract.Gas)
return err // OutOfGas or other errors, will let upper level handle
}
}
Expand Down
Loading