eth/tracers, core: use scopecontext in tracers, provide statedb in capturestart (#22333)
Fixes the CaptureStart api to include the EVM, thus being able to set the statedb early on. This pr also exposes the struct we used internally in the interpreter to encapsulate the contract, mem, stack, rstack, so we pass it as a single struct to the tracer, and removes the error returns on the capture methods.
This commit is contained in:
committed by
GitHub
parent
c5df05b9a9
commit
0fda25e471
@ -24,68 +24,68 @@ import (
|
||||
"golang.org/x/crypto/sha3"
|
||||
)
|
||||
|
||||
func opAdd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opAdd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Add(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSub(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSub(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Sub(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMul(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opMul(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Mul(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opDiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opDiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Div(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSdiv(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSdiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.SDiv(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opMod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Mod(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.SMod(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opExp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
base, exponent := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opExp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
base, exponent := scope.Stack.pop(), scope.Stack.peek()
|
||||
exponent.Exp(&base, exponent)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSignExtend(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
back, num := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSignExtend(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
back, num := scope.Stack.pop(), scope.Stack.peek()
|
||||
num.ExtendSign(num, &back)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opNot(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x := callContext.stack.peek()
|
||||
func opNot(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x := scope.Stack.peek()
|
||||
x.Not(x)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opLt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opLt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
if x.Lt(y) {
|
||||
y.SetOne()
|
||||
} else {
|
||||
@ -94,8 +94,8 @@ func opLt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opGt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opGt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
if x.Gt(y) {
|
||||
y.SetOne()
|
||||
} else {
|
||||
@ -104,8 +104,8 @@ func opGt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSlt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSlt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
if x.Slt(y) {
|
||||
y.SetOne()
|
||||
} else {
|
||||
@ -114,8 +114,8 @@ func opSlt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSgt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSgt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
if x.Sgt(y) {
|
||||
y.SetOne()
|
||||
} else {
|
||||
@ -124,8 +124,8 @@ func opSgt(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opEq(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opEq(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
if x.Eq(y) {
|
||||
y.SetOne()
|
||||
} else {
|
||||
@ -134,8 +134,8 @@ func opEq(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opIszero(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x := callContext.stack.peek()
|
||||
func opIszero(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x := scope.Stack.peek()
|
||||
if x.IsZero() {
|
||||
x.SetOne()
|
||||
} else {
|
||||
@ -144,32 +144,32 @@ func opIszero(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opAnd(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opAnd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.And(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opOr(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opOr(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Or(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opXor(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opXor(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y := scope.Stack.pop(), scope.Stack.peek()
|
||||
y.Xor(&x, y)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opByte(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
th, val := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opByte(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
th, val := scope.Stack.pop(), scope.Stack.peek()
|
||||
val.Byte(&th)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opAddmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.peek()
|
||||
func opAddmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek()
|
||||
if z.IsZero() {
|
||||
z.Clear()
|
||||
} else {
|
||||
@ -178,8 +178,8 @@ func opAddmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMulmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x, y, z := callContext.stack.pop(), callContext.stack.pop(), callContext.stack.peek()
|
||||
func opMulmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek()
|
||||
z.MulMod(&x, &y, z)
|
||||
return nil, nil
|
||||
}
|
||||
@ -187,9 +187,9 @@ func opMulmod(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
|
||||
// opSHL implements Shift Left
|
||||
// The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2,
|
||||
// and pushes on the stack arg2 shifted to the left by arg1 number of bits.
|
||||
func opSHL(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opSHL(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
|
||||
shift, value := callContext.stack.pop(), callContext.stack.peek()
|
||||
shift, value := scope.Stack.pop(), scope.Stack.peek()
|
||||
if shift.LtUint64(256) {
|
||||
value.Lsh(value, uint(shift.Uint64()))
|
||||
} else {
|
||||
@ -201,9 +201,9 @@ func opSHL(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt
|
||||
// opSHR implements Logical Shift Right
|
||||
// The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2,
|
||||
// and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill.
|
||||
func opSHR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opSHR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
// Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards
|
||||
shift, value := callContext.stack.pop(), callContext.stack.peek()
|
||||
shift, value := scope.Stack.pop(), scope.Stack.peek()
|
||||
if shift.LtUint64(256) {
|
||||
value.Rsh(value, uint(shift.Uint64()))
|
||||
} else {
|
||||
@ -215,8 +215,8 @@ func opSHR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt
|
||||
// opSAR implements Arithmetic Shift Right
|
||||
// The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2,
|
||||
// and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension.
|
||||
func opSAR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
shift, value := callContext.stack.pop(), callContext.stack.peek()
|
||||
func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
shift, value := scope.Stack.pop(), scope.Stack.peek()
|
||||
if shift.GtUint64(256) {
|
||||
if value.Sign() >= 0 {
|
||||
value.Clear()
|
||||
@ -231,9 +231,9 @@ func opSAR(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byt
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
offset, size := callContext.stack.pop(), callContext.stack.peek()
|
||||
data := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
func opSha3(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
offset, size := scope.Stack.pop(), scope.Stack.peek()
|
||||
data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
|
||||
if interpreter.hasher == nil {
|
||||
interpreter.hasher = sha3.NewLegacyKeccak256().(keccakState)
|
||||
@ -251,37 +251,37 @@ func opSha3(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by
|
||||
size.SetBytes(interpreter.hasherBuf[:])
|
||||
return nil, nil
|
||||
}
|
||||
func opAddress(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Address().Bytes()))
|
||||
func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Address().Bytes()))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opBalance(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
slot := callContext.stack.peek()
|
||||
func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
slot := scope.Stack.peek()
|
||||
address := common.Address(slot.Bytes20())
|
||||
slot.SetFromBig(interpreter.evm.StateDB.GetBalance(address))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opOrigin(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
|
||||
func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes()))
|
||||
return nil, nil
|
||||
}
|
||||
func opCaller(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetBytes(callContext.contract.Caller().Bytes()))
|
||||
func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes()))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCallValue(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(callContext.contract.value)
|
||||
callContext.stack.push(v)
|
||||
func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(scope.Contract.value)
|
||||
scope.Stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
x := callContext.stack.peek()
|
||||
func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
x := scope.Stack.peek()
|
||||
if offset, overflow := x.Uint64WithOverflow(); !overflow {
|
||||
data := getData(callContext.contract.Input, offset, 32)
|
||||
data := getData(scope.Contract.Input, offset, 32)
|
||||
x.SetBytes(data)
|
||||
} else {
|
||||
x.Clear()
|
||||
@ -289,16 +289,16 @@ func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, callContext *callCt
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(callContext.contract.Input))))
|
||||
func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input))))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
memOffset = callContext.stack.pop()
|
||||
dataOffset = callContext.stack.pop()
|
||||
length = callContext.stack.pop()
|
||||
memOffset = scope.Stack.pop()
|
||||
dataOffset = scope.Stack.pop()
|
||||
length = scope.Stack.pop()
|
||||
)
|
||||
dataOffset64, overflow := dataOffset.Uint64WithOverflow()
|
||||
if overflow {
|
||||
@ -307,21 +307,21 @@ func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCt
|
||||
// These values are checked for overflow during gas cost calculation
|
||||
memOffset64 := memOffset.Uint64()
|
||||
length64 := length.Uint64()
|
||||
callContext.memory.Set(memOffset64, length64, getData(callContext.contract.Input, dataOffset64, length64))
|
||||
scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64))
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
|
||||
func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData))))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
memOffset = callContext.stack.pop()
|
||||
dataOffset = callContext.stack.pop()
|
||||
length = callContext.stack.pop()
|
||||
memOffset = scope.Stack.pop()
|
||||
dataOffset = scope.Stack.pop()
|
||||
length = scope.Stack.pop()
|
||||
)
|
||||
|
||||
offset64, overflow := dataOffset.Uint64WithOverflow()
|
||||
@ -335,42 +335,42 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, callContext *call
|
||||
if overflow || uint64(len(interpreter.returnData)) < end64 {
|
||||
return nil, ErrReturnDataOutOfBounds
|
||||
}
|
||||
callContext.memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
|
||||
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64])
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
slot := callContext.stack.peek()
|
||||
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
slot := scope.Stack.peek()
|
||||
slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20())))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCodeSize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
l := new(uint256.Int)
|
||||
l.SetUint64(uint64(len(callContext.contract.Code)))
|
||||
callContext.stack.push(l)
|
||||
l.SetUint64(uint64(len(scope.Contract.Code)))
|
||||
scope.Stack.push(l)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
memOffset = callContext.stack.pop()
|
||||
codeOffset = callContext.stack.pop()
|
||||
length = callContext.stack.pop()
|
||||
memOffset = scope.Stack.pop()
|
||||
codeOffset = scope.Stack.pop()
|
||||
length = scope.Stack.pop()
|
||||
)
|
||||
uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow()
|
||||
if overflow {
|
||||
uint64CodeOffset = 0xffffffffffffffff
|
||||
}
|
||||
codeCopy := getData(callContext.contract.Code, uint64CodeOffset, length.Uint64())
|
||||
callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
||||
codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64())
|
||||
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
stack = callContext.stack
|
||||
stack = scope.Stack
|
||||
a = stack.pop()
|
||||
memOffset = stack.pop()
|
||||
codeOffset = stack.pop()
|
||||
@ -382,7 +382,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx
|
||||
}
|
||||
addr := common.Address(a.Bytes20())
|
||||
codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64())
|
||||
callContext.memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
||||
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@ -413,8 +413,8 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx
|
||||
//
|
||||
// (6) Caller tries to get the code hash for an account which is marked as deleted,
|
||||
// this account should be regarded as a non-existent account and zero should be returned.
|
||||
func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
slot := callContext.stack.peek()
|
||||
func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
slot := scope.Stack.peek()
|
||||
address := common.Address(slot.Bytes20())
|
||||
if interpreter.evm.StateDB.Empty(address) {
|
||||
slot.Clear()
|
||||
@ -424,14 +424,14 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opGasprice(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.GasPrice)
|
||||
callContext.stack.push(v)
|
||||
scope.Stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
num := callContext.stack.peek()
|
||||
func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
num := scope.Stack.peek()
|
||||
num64, overflow := num.Uint64WithOverflow()
|
||||
if overflow {
|
||||
num.Clear()
|
||||
@ -452,88 +452,88 @@ func opBlockhash(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCoinbase(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
|
||||
func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes()))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opTimestamp(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.Context.Time)
|
||||
callContext.stack.push(v)
|
||||
scope.Stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opNumber(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber)
|
||||
callContext.stack.push(v)
|
||||
scope.Stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opDifficulty(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty)
|
||||
callContext.stack.push(v)
|
||||
scope.Stack.push(v)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
|
||||
func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opPop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.pop()
|
||||
func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.pop()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
v := callContext.stack.peek()
|
||||
func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
v := scope.Stack.peek()
|
||||
offset := int64(v.Uint64())
|
||||
v.SetBytes(callContext.memory.GetPtr(offset, 32))
|
||||
v.SetBytes(scope.Memory.GetPtr(offset, 32))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
// pop value of the stack
|
||||
mStart, val := callContext.stack.pop(), callContext.stack.pop()
|
||||
callContext.memory.Set32(mStart.Uint64(), &val)
|
||||
mStart, val := scope.Stack.pop(), scope.Stack.pop()
|
||||
scope.Memory.Set32(mStart.Uint64(), &val)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMstore8(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
off, val := callContext.stack.pop(), callContext.stack.pop()
|
||||
callContext.memory.store[off.Uint64()] = byte(val.Uint64())
|
||||
func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
off, val := scope.Stack.pop(), scope.Stack.pop()
|
||||
scope.Memory.store[off.Uint64()] = byte(val.Uint64())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSload(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
loc := callContext.stack.peek()
|
||||
func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
loc := scope.Stack.peek()
|
||||
hash := common.Hash(loc.Bytes32())
|
||||
val := interpreter.evm.StateDB.GetState(callContext.contract.Address(), hash)
|
||||
val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash)
|
||||
loc.SetBytes(val.Bytes())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSstore(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
loc := callContext.stack.pop()
|
||||
val := callContext.stack.pop()
|
||||
interpreter.evm.StateDB.SetState(callContext.contract.Address(),
|
||||
func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
loc := scope.Stack.pop()
|
||||
val := scope.Stack.pop()
|
||||
interpreter.evm.StateDB.SetState(scope.Contract.Address(),
|
||||
loc.Bytes32(), val.Bytes32())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opJump(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
pos := callContext.stack.pop()
|
||||
if !callContext.contract.validJumpdest(&pos) {
|
||||
func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
pos := scope.Stack.pop()
|
||||
if !scope.Contract.validJumpdest(&pos) {
|
||||
return nil, ErrInvalidJump
|
||||
}
|
||||
*pc = pos.Uint64()
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opJumpi(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
pos, cond := callContext.stack.pop(), callContext.stack.pop()
|
||||
func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
pos, cond := scope.Stack.pop(), scope.Stack.pop()
|
||||
if !cond.IsZero() {
|
||||
if !callContext.contract.validJumpdest(&pos) {
|
||||
if !scope.Contract.validJumpdest(&pos) {
|
||||
return nil, ErrInvalidJump
|
||||
}
|
||||
*pc = pos.Uint64()
|
||||
@ -543,31 +543,31 @@ func opJumpi(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]b
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opJumpdest(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opPc(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(*pc))
|
||||
func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetUint64(*pc))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opMsize(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(uint64(callContext.memory.Len())))
|
||||
func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len())))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opGas(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.push(new(uint256.Int).SetUint64(callContext.contract.Gas))
|
||||
func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
value = callContext.stack.pop()
|
||||
offset, size = callContext.stack.pop(), callContext.stack.pop()
|
||||
input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
gas = callContext.contract.Gas
|
||||
value = scope.Stack.pop()
|
||||
offset, size = scope.Stack.pop(), scope.Stack.pop()
|
||||
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
gas = scope.Contract.Gas
|
||||
)
|
||||
if interpreter.evm.chainRules.IsEIP150 {
|
||||
gas -= gas / 64
|
||||
@ -575,14 +575,14 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
|
||||
// reuse size int for stackvalue
|
||||
stackvalue := size
|
||||
|
||||
callContext.contract.UseGas(gas)
|
||||
scope.Contract.UseGas(gas)
|
||||
//TODO: use uint256.Int instead of converting with toBig()
|
||||
var bigVal = big0
|
||||
if !value.IsZero() {
|
||||
bigVal = value.ToBig()
|
||||
}
|
||||
|
||||
res, addr, returnGas, suberr := interpreter.evm.Create(callContext.contract, input, gas, bigVal)
|
||||
res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, bigVal)
|
||||
// Push item on the stack based on the returned error. If the ruleset is
|
||||
// homestead we must check for CodeStoreOutOfGasError (homestead only
|
||||
// rule) and treat as an error, if the ruleset is frontier we must
|
||||
@ -594,8 +594,8 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
|
||||
} else {
|
||||
stackvalue.SetBytes(addr.Bytes())
|
||||
}
|
||||
callContext.stack.push(&stackvalue)
|
||||
callContext.contract.Gas += returnGas
|
||||
scope.Stack.push(&stackvalue)
|
||||
scope.Contract.Gas += returnGas
|
||||
|
||||
if suberr == ErrExecutionReverted {
|
||||
return res, nil
|
||||
@ -603,18 +603,18 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
endowment = callContext.stack.pop()
|
||||
offset, size = callContext.stack.pop(), callContext.stack.pop()
|
||||
salt = callContext.stack.pop()
|
||||
input = callContext.memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
gas = callContext.contract.Gas
|
||||
endowment = scope.Stack.pop()
|
||||
offset, size = scope.Stack.pop(), scope.Stack.pop()
|
||||
salt = scope.Stack.pop()
|
||||
input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
gas = scope.Contract.Gas
|
||||
)
|
||||
|
||||
// Apply EIP150
|
||||
gas -= gas / 64
|
||||
callContext.contract.UseGas(gas)
|
||||
scope.Contract.UseGas(gas)
|
||||
// reuse size int for stackvalue
|
||||
stackvalue := size
|
||||
//TODO: use uint256.Int instead of converting with toBig()
|
||||
@ -622,7 +622,7 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
|
||||
if !endowment.IsZero() {
|
||||
bigEndowment = endowment.ToBig()
|
||||
}
|
||||
res, addr, returnGas, suberr := interpreter.evm.Create2(callContext.contract, input, gas,
|
||||
res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas,
|
||||
bigEndowment, &salt)
|
||||
// Push item on the stack based on the returned error.
|
||||
if suberr != nil {
|
||||
@ -630,8 +630,8 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
|
||||
} else {
|
||||
stackvalue.SetBytes(addr.Bytes())
|
||||
}
|
||||
callContext.stack.push(&stackvalue)
|
||||
callContext.contract.Gas += returnGas
|
||||
scope.Stack.push(&stackvalue)
|
||||
scope.Contract.Gas += returnGas
|
||||
|
||||
if suberr == ErrExecutionReverted {
|
||||
return res, nil
|
||||
@ -639,8 +639,8 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
stack := callContext.stack
|
||||
func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
stack := scope.Stack
|
||||
// Pop gas. The actual gas in interpreter.evm.callGasTemp.
|
||||
// We can use this as a temporary value
|
||||
temp := stack.pop()
|
||||
@ -649,7 +649,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by
|
||||
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
|
||||
toAddr := common.Address(addr.Bytes20())
|
||||
// Get the arguments from the memory.
|
||||
args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
|
||||
var bigVal = big0
|
||||
//TODO: use uint256.Int instead of converting with toBig()
|
||||
@ -660,7 +660,7 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by
|
||||
bigVal = value.ToBig()
|
||||
}
|
||||
|
||||
ret, returnGas, err := interpreter.evm.Call(callContext.contract, toAddr, args, gas, bigVal)
|
||||
ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, bigVal)
|
||||
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
@ -669,16 +669,16 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]by
|
||||
}
|
||||
stack.push(&temp)
|
||||
if err == nil || err == ErrExecutionReverted {
|
||||
callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
callContext.contract.Gas += returnGas
|
||||
scope.Contract.Gas += returnGas
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
|
||||
stack := callContext.stack
|
||||
stack := scope.Stack
|
||||
// We use it as a temporary value
|
||||
temp := stack.pop()
|
||||
gas := interpreter.evm.callGasTemp
|
||||
@ -686,7 +686,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
|
||||
addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
|
||||
toAddr := common.Address(addr.Bytes20())
|
||||
// Get arguments from the memory.
|
||||
args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
|
||||
//TODO: use uint256.Int instead of converting with toBig()
|
||||
var bigVal = big0
|
||||
@ -695,7 +695,7 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
|
||||
bigVal = value.ToBig()
|
||||
}
|
||||
|
||||
ret, returnGas, err := interpreter.evm.CallCode(callContext.contract, toAddr, args, gas, bigVal)
|
||||
ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, bigVal)
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
} else {
|
||||
@ -703,15 +703,15 @@ func opCallCode(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
|
||||
}
|
||||
stack.push(&temp)
|
||||
if err == nil || err == ErrExecutionReverted {
|
||||
callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
callContext.contract.Gas += returnGas
|
||||
scope.Contract.Gas += returnGas
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
stack := callContext.stack
|
||||
func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
stack := scope.Stack
|
||||
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
|
||||
// We use it as a temporary value
|
||||
temp := stack.pop()
|
||||
@ -720,9 +720,9 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCt
|
||||
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
|
||||
toAddr := common.Address(addr.Bytes20())
|
||||
// Get arguments from the memory.
|
||||
args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
|
||||
ret, returnGas, err := interpreter.evm.DelegateCall(callContext.contract, toAddr, args, gas)
|
||||
ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas)
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
} else {
|
||||
@ -730,16 +730,16 @@ func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCt
|
||||
}
|
||||
stack.push(&temp)
|
||||
if err == nil || err == ErrExecutionReverted {
|
||||
callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
callContext.contract.Gas += returnGas
|
||||
scope.Contract.Gas += returnGas
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
// Pop gas. The actual gas is in interpreter.evm.callGasTemp.
|
||||
stack := callContext.stack
|
||||
stack := scope.Stack
|
||||
// We use it as a temporary value
|
||||
temp := stack.pop()
|
||||
gas := interpreter.evm.callGasTemp
|
||||
@ -747,9 +747,9 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx)
|
||||
addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
|
||||
toAddr := common.Address(addr.Bytes20())
|
||||
// Get arguments from the memory.
|
||||
args := callContext.memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
|
||||
|
||||
ret, returnGas, err := interpreter.evm.StaticCall(callContext.contract, toAddr, args, gas)
|
||||
ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas)
|
||||
if err != nil {
|
||||
temp.Clear()
|
||||
} else {
|
||||
@ -757,36 +757,36 @@ func opStaticCall(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx)
|
||||
}
|
||||
stack.push(&temp)
|
||||
if err == nil || err == ErrExecutionReverted {
|
||||
callContext.memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
|
||||
}
|
||||
callContext.contract.Gas += returnGas
|
||||
scope.Contract.Gas += returnGas
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func opReturn(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
offset, size := callContext.stack.pop(), callContext.stack.pop()
|
||||
ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
offset, size := scope.Stack.pop(), scope.Stack.pop()
|
||||
ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func opRevert(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
offset, size := callContext.stack.pop(), callContext.stack.pop()
|
||||
ret := callContext.memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
offset, size := scope.Stack.pop(), scope.Stack.pop()
|
||||
ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64()))
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func opStop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
beneficiary := callContext.stack.pop()
|
||||
balance := interpreter.evm.StateDB.GetBalance(callContext.contract.Address())
|
||||
func opSuicide(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
beneficiary := scope.Stack.pop()
|
||||
balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address())
|
||||
interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance)
|
||||
interpreter.evm.StateDB.Suicide(callContext.contract.Address())
|
||||
interpreter.evm.StateDB.Suicide(scope.Contract.Address())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -794,18 +794,18 @@ func opSuicide(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([
|
||||
|
||||
// make log instruction function
|
||||
func makeLog(size int) executionFunc {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
topics := make([]common.Hash, size)
|
||||
stack := callContext.stack
|
||||
stack := scope.Stack
|
||||
mStart, mSize := stack.pop(), stack.pop()
|
||||
for i := 0; i < size; i++ {
|
||||
addr := stack.pop()
|
||||
topics[i] = addr.Bytes32()
|
||||
}
|
||||
|
||||
d := callContext.memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
|
||||
d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64()))
|
||||
interpreter.evm.StateDB.AddLog(&types.Log{
|
||||
Address: callContext.contract.Address(),
|
||||
Address: scope.Contract.Address(),
|
||||
Topics: topics,
|
||||
Data: d,
|
||||
// This is a non-consensus field, but assigned here because
|
||||
@ -818,24 +818,24 @@ func makeLog(size int) executionFunc {
|
||||
}
|
||||
|
||||
// opPush1 is a specialized version of pushN
|
||||
func opPush1(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
var (
|
||||
codeLen = uint64(len(callContext.contract.Code))
|
||||
codeLen = uint64(len(scope.Contract.Code))
|
||||
integer = new(uint256.Int)
|
||||
)
|
||||
*pc += 1
|
||||
if *pc < codeLen {
|
||||
callContext.stack.push(integer.SetUint64(uint64(callContext.contract.Code[*pc])))
|
||||
scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc])))
|
||||
} else {
|
||||
callContext.stack.push(integer.Clear())
|
||||
scope.Stack.push(integer.Clear())
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// make push instruction function
|
||||
func makePush(size uint64, pushByteSize int) executionFunc {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
codeLen := len(callContext.contract.Code)
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
codeLen := len(scope.Contract.Code)
|
||||
|
||||
startMin := codeLen
|
||||
if int(*pc+1) < startMin {
|
||||
@ -848,8 +848,8 @@ func makePush(size uint64, pushByteSize int) executionFunc {
|
||||
}
|
||||
|
||||
integer := new(uint256.Int)
|
||||
callContext.stack.push(integer.SetBytes(common.RightPadBytes(
|
||||
callContext.contract.Code[startMin:endMin], pushByteSize)))
|
||||
scope.Stack.push(integer.SetBytes(common.RightPadBytes(
|
||||
scope.Contract.Code[startMin:endMin], pushByteSize)))
|
||||
|
||||
*pc += size
|
||||
return nil, nil
|
||||
@ -858,8 +858,8 @@ func makePush(size uint64, pushByteSize int) executionFunc {
|
||||
|
||||
// make dup instruction function
|
||||
func makeDup(size int64) executionFunc {
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.dup(int(size))
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.dup(int(size))
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
@ -868,8 +868,8 @@ func makeDup(size int64) executionFunc {
|
||||
func makeSwap(size int64) executionFunc {
|
||||
// switch n + 1 otherwise n would be swapped with n
|
||||
size++
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
|
||||
callContext.stack.swap(int(size))
|
||||
return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||
scope.Stack.swap(int(size))
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user