|
|
@@ -6,7 +6,6 @@ import (
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
"github.com/ethereum/go-ethereum/ethutil"
|
|
|
- "github.com/ethereum/go-ethereum/state"
|
|
|
)
|
|
|
|
|
|
type DebugVm struct {
|
|
|
@@ -29,6 +28,13 @@ type DebugVm struct {
|
|
|
depth int
|
|
|
}
|
|
|
|
|
|
+type Options struct {
|
|
|
+ Address, Caller []byte
|
|
|
+ Data []byte
|
|
|
+ Code []byte
|
|
|
+ Value, Gas, Price *big.Int
|
|
|
+}
|
|
|
+
|
|
|
func NewDebugVm(env Environment) *DebugVm {
|
|
|
lt := LogTyPretty
|
|
|
if ethutil.Config.Diff {
|
|
|
@@ -38,7 +44,13 @@ func NewDebugVm(env Environment) *DebugVm {
|
|
|
return &DebugVm{env: env, logTy: lt, Recoverable: true}
|
|
|
}
|
|
|
|
|
|
-func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
+//func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
+func (self *DebugVm) Run(call Options) (ret []byte, gas *big.Int, err error) {
|
|
|
+ // Don't bother with the execution if there's no code.
|
|
|
+ if len(call.Code) == 0 {
|
|
|
+ return nil, new(big.Int), nil
|
|
|
+ }
|
|
|
+
|
|
|
self.depth++
|
|
|
|
|
|
if self.Recoverable {
|
|
|
@@ -47,41 +59,49 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
if r := recover(); r != nil {
|
|
|
self.Endl()
|
|
|
|
|
|
- closure.UseGas(closure.Gas)
|
|
|
-
|
|
|
- ret = closure.Return(nil)
|
|
|
-
|
|
|
+ gas = new(big.Int)
|
|
|
err = fmt.Errorf("%v", r)
|
|
|
|
|
|
}
|
|
|
}()
|
|
|
}
|
|
|
|
|
|
+ gas = new(big.Int).Set(opt.Gas)
|
|
|
var (
|
|
|
op OpCode
|
|
|
|
|
|
- destinations = analyseJumpDests(closure.Code)
|
|
|
+ destinations = analyseJumpDests(call.Code)
|
|
|
mem = NewMemory()
|
|
|
stack = NewStack()
|
|
|
pc = big.NewInt(0)
|
|
|
step = 0
|
|
|
prevStep = 0
|
|
|
- statedb = self.env.State()
|
|
|
- require = func(m int) {
|
|
|
+ //statedb = self.env.State()
|
|
|
+ require = func(m int) {
|
|
|
if stack.Len() < m {
|
|
|
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m))
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ useGas = func(amount *big.Int) bool {
|
|
|
+ if amount.Cmp(gas) > 0 {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ gas.Sub(gas, amount)
|
|
|
+
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
jump = func(from, to *big.Int) {
|
|
|
- p := int(to.Int64())
|
|
|
+ p := to.Uint64()
|
|
|
|
|
|
self.Printf(" ~> %v", to)
|
|
|
// Return to start
|
|
|
if p == 0 {
|
|
|
pc = big.NewInt(0)
|
|
|
} else {
|
|
|
- nop := OpCode(closure.GetOp(p))
|
|
|
+ nop := OpCode(call.GetOp(p))
|
|
|
if !(nop == JUMPDEST || destinations[from.Int64()] != nil) {
|
|
|
panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
|
|
|
} else if nop == JUMP || nop == JUMPI {
|
|
|
@@ -96,17 +116,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
}
|
|
|
)
|
|
|
|
|
|
- // Debug hook
|
|
|
- if self.Dbg != nil {
|
|
|
- self.Dbg.SetCode(closure.Code)
|
|
|
- }
|
|
|
-
|
|
|
- // Don't bother with the execution if there's no code.
|
|
|
- if len(closure.Code) == 0 {
|
|
|
- return closure.Return(nil), nil
|
|
|
- }
|
|
|
-
|
|
|
- vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, closure.Address(), closure.Gas, closure.Args)
|
|
|
+ vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, call.Address, gas, call.Data)
|
|
|
|
|
|
for {
|
|
|
prevStep = step
|
|
|
@@ -115,31 +125,33 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
|
|
|
step++
|
|
|
// Get the memory location of pc
|
|
|
- op = closure.GetOp(int(pc.Uint64()))
|
|
|
+ op = call.GetOp(pc.Uint64())
|
|
|
|
|
|
// XXX Leave this Println intact. Don't change this to the log system.
|
|
|
// Used for creating diffs between implementations
|
|
|
- if self.logTy == LogTyDiff {
|
|
|
- switch op {
|
|
|
- case STOP, RETURN, SUICIDE:
|
|
|
- statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) {
|
|
|
- value.Decode()
|
|
|
- fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
|
|
|
- })
|
|
|
- }
|
|
|
+ /*
|
|
|
+ if self.logTy == LogTyDiff {
|
|
|
+ switch op {
|
|
|
+ case STOP, RETURN, SUICIDE:
|
|
|
+ statedb.GetStateObject(closure.Address()).EachStorage(func(key string, value *ethutil.Value) {
|
|
|
+ value.Decode()
|
|
|
+ fmt.Printf("%x %x\n", new(big.Int).SetBytes([]byte(key)).Bytes(), value.Bytes())
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
- b := pc.Bytes()
|
|
|
- if len(b) == 0 {
|
|
|
- b = []byte{0}
|
|
|
- }
|
|
|
+ b := pc.Bytes()
|
|
|
+ if len(b) == 0 {
|
|
|
+ b = []byte{0}
|
|
|
+ }
|
|
|
|
|
|
- fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
|
|
|
- }
|
|
|
+ fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
|
|
|
+ }
|
|
|
+ */
|
|
|
|
|
|
- gas := new(big.Int)
|
|
|
+ reqGas := new(big.Int)
|
|
|
addStepGasUsage := func(amount *big.Int) {
|
|
|
if amount.Cmp(ethutil.Big0) >= 0 {
|
|
|
- gas.Add(gas, amount)
|
|
|
+ reqGas.Add(reqGas, amount)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -166,42 +178,43 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
require(n + 2)
|
|
|
|
|
|
mSize, mStart := stack.Peekn()
|
|
|
- gas.Set(GasLog)
|
|
|
+ reqGs.Set(GasLog)
|
|
|
addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
|
|
|
addStepGasUsage(new(big.Int).Add(mSize, mStart))
|
|
|
// Gas only
|
|
|
case STOP:
|
|
|
- gas.Set(ethutil.Big0)
|
|
|
+ reqGas.Set(ethutil.Big0)
|
|
|
case SUICIDE:
|
|
|
require(1)
|
|
|
|
|
|
- gas.Set(ethutil.Big0)
|
|
|
+ reqGas.Set(ethutil.Big0)
|
|
|
case SLOAD:
|
|
|
require(1)
|
|
|
|
|
|
- gas.Set(GasSLoad)
|
|
|
+ reqGas.Set(GasSLoad)
|
|
|
// Memory resize & Gas
|
|
|
case SSTORE:
|
|
|
require(2)
|
|
|
|
|
|
var mult *big.Int
|
|
|
y, x := stack.Peekn()
|
|
|
- val := closure.GetStorage(x)
|
|
|
+ val := ethutil.BigD(self.env.GetState(x.Bytes())) //closure.GetStorage(x)
|
|
|
if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
|
|
|
// 0 => non 0
|
|
|
mult = ethutil.Big3
|
|
|
} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 {
|
|
|
- statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
|
|
|
+ //statedb.Refund(closure.caller.Address(), GasSStoreRefund, closure.Price)
|
|
|
+ self.env.Refund(call.Caller, GasSStoreRefund, call.Price)
|
|
|
|
|
|
mult = ethutil.Big0
|
|
|
} else {
|
|
|
// non 0 => non 0
|
|
|
mult = ethutil.Big1
|
|
|
}
|
|
|
- gas.Set(new(big.Int).Mul(mult, GasSStore))
|
|
|
+ reqGas.Set(new(big.Int).Mul(mult, GasSStore))
|
|
|
case BALANCE:
|
|
|
require(1)
|
|
|
- gas.Set(GasBalance)
|
|
|
+ reqGas.Set(GasBalance)
|
|
|
case MSTORE:
|
|
|
require(2)
|
|
|
newMemSize = calcMemSize(stack.Peek(), u256(32))
|
|
|
@@ -219,7 +232,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
case SHA3:
|
|
|
require(2)
|
|
|
|
|
|
- gas.Set(GasSha)
|
|
|
+ reqGas.Set(GasSha)
|
|
|
|
|
|
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
|
|
|
case CALLDATACOPY:
|
|
|
@@ -236,7 +249,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
|
|
|
case CALL, CALLCODE:
|
|
|
require(7)
|
|
|
- gas.Set(GasCall)
|
|
|
+ reqGas.Set(GasCall)
|
|
|
addStepGasUsage(stack.data[stack.Len()-1])
|
|
|
|
|
|
x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7])
|
|
|
@@ -245,7 +258,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
newMemSize = ethutil.BigMax(x, y)
|
|
|
case CREATE:
|
|
|
require(3)
|
|
|
- gas.Set(GasCreate)
|
|
|
+ reqGas.Set(GasCreate)
|
|
|
|
|
|
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3])
|
|
|
}
|
|
|
@@ -255,6 +268,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
newMemSize.Div(newMemSize, u256(32))
|
|
|
newMemSize.Mul(newMemSize, u256(32))
|
|
|
|
|
|
+ switch op {
|
|
|
+ // Additional gas usage on *CODPY
|
|
|
+ case CALLDATACOPY, CODECOPY, EXTCODECOPY:
|
|
|
+ addStepGasUsage(new(big.Int).Div(newMemSize, u256(32)))
|
|
|
+ }
|
|
|
+
|
|
|
if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
|
|
|
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
|
|
|
memGasUsage.Mul(GasMemory, memGasUsage)
|
|
|
@@ -268,16 +287,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
}
|
|
|
|
|
|
self.Printf("(pc) %-3d -o- %-14s", pc, op.String())
|
|
|
- self.Printf(" (m) %-4d (s) %-4d (g) %-3v (%v)", mem.Len(), stack.Len(), gas, closure.Gas)
|
|
|
+ self.Printf(" (m) %-4d (s) %-4d (g) %-3v (%v)", mem.Len(), stack.Len(), reqGas, gas)
|
|
|
|
|
|
- if !closure.UseGas(gas) {
|
|
|
+ if !useGas(regGas) {
|
|
|
self.Endl()
|
|
|
|
|
|
- tmp := new(big.Int).Set(closure.Gas)
|
|
|
-
|
|
|
- closure.UseGas(closure.Gas)
|
|
|
-
|
|
|
- return closure.Return(nil), OOG(gas, tmp)
|
|
|
+ return nil, new(big.Int), OOG(reqGas, gas)
|
|
|
}
|
|
|
|
|
|
switch op {
|
|
|
@@ -553,13 +568,15 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
self.Printf(" => %x", data)
|
|
|
// 0x30 range
|
|
|
case ADDRESS:
|
|
|
- stack.Push(ethutil.BigD(closure.Address()))
|
|
|
+ //stack.Push(ethutil.BigD(closure.Address()))
|
|
|
+ stack.Push(ethutil.BigD(call.Address))
|
|
|
|
|
|
- self.Printf(" => %x", closure.Address())
|
|
|
+ self.Printf(" => %x", call.Address)
|
|
|
case BALANCE:
|
|
|
|
|
|
addr := stack.Pop().Bytes()
|
|
|
- balance := statedb.GetBalance(addr)
|
|
|
+ //balance := statedb.GetBalance(addr)
|
|
|
+ balance := self.env.GetBalance(addr)
|
|
|
|
|
|
stack.Push(balance)
|
|
|
|
|
|
@@ -571,41 +588,42 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
|
|
|
self.Printf(" => %x", origin)
|
|
|
case CALLER:
|
|
|
- caller := closure.caller.Address()
|
|
|
- stack.Push(ethutil.BigD(caller))
|
|
|
+ //caller := closure.caller.Address()
|
|
|
+ //stack.Push(ethutil.BigD(caller))
|
|
|
+ stack.Push(call.Caller)
|
|
|
|
|
|
- self.Printf(" => %x", caller)
|
|
|
+ self.Printf(" => %x", call.Caller)
|
|
|
case CALLVALUE:
|
|
|
- value := closure.exe.value
|
|
|
+ //value := closure.exe.value
|
|
|
|
|
|
- stack.Push(value)
|
|
|
+ stack.Push(call.Value)
|
|
|
|
|
|
- self.Printf(" => %v", value)
|
|
|
+ self.Printf(" => %v", call.Value)
|
|
|
case CALLDATALOAD:
|
|
|
var (
|
|
|
offset = stack.Pop()
|
|
|
data = make([]byte, 32)
|
|
|
- lenData = big.NewInt(int64(len(closure.Args)))
|
|
|
+ lenData = big.NewInt(int64(len(call.Data)))
|
|
|
)
|
|
|
|
|
|
if lenData.Cmp(offset) >= 0 {
|
|
|
length := new(big.Int).Add(offset, ethutil.Big32)
|
|
|
length = ethutil.BigMin(length, lenData)
|
|
|
|
|
|
- copy(data, closure.Args[offset.Int64():length.Int64()])
|
|
|
+ copy(data, call.Data[offset.Int64():length.Int64()])
|
|
|
}
|
|
|
|
|
|
self.Printf(" => 0x%x", data)
|
|
|
|
|
|
stack.Push(ethutil.BigD(data))
|
|
|
case CALLDATASIZE:
|
|
|
- l := int64(len(closure.Args))
|
|
|
+ l := int64(len(call.Data))
|
|
|
stack.Push(big.NewInt(l))
|
|
|
|
|
|
self.Printf(" => %d", l)
|
|
|
case CALLDATACOPY:
|
|
|
var (
|
|
|
- size = int64(len(closure.Args))
|
|
|
+ size = int64(len(call.Data))
|
|
|
mOff = stack.Pop().Int64()
|
|
|
cOff = stack.Pop().Int64()
|
|
|
l = stack.Pop().Int64()
|
|
|
@@ -618,7 +636,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
l = 0
|
|
|
}
|
|
|
|
|
|
- code := closure.Args[cOff : cOff+l]
|
|
|
+ code := call.Data[cOff : cOff+l]
|
|
|
|
|
|
mem.Set(mOff, l, code)
|
|
|
|
|
|
@@ -628,9 +646,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
if op == EXTCODESIZE {
|
|
|
addr := stack.Pop().Bytes()
|
|
|
|
|
|
- code = statedb.GetCode(addr)
|
|
|
+ self.env.GetCode(addr)
|
|
|
} else {
|
|
|
- code = closure.Code
|
|
|
+ code = call.Code
|
|
|
}
|
|
|
|
|
|
l := big.NewInt(int64(len(code)))
|
|
|
@@ -642,9 +660,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
if op == EXTCODECOPY {
|
|
|
addr := stack.Pop().Bytes()
|
|
|
|
|
|
- code = statedb.GetCode(addr)
|
|
|
+ code = self.env.GetCode(addr)
|
|
|
} else {
|
|
|
- code = closure.Code
|
|
|
+ code = call.Code
|
|
|
}
|
|
|
|
|
|
var (
|
|
|
@@ -667,9 +685,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
|
|
|
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l])
|
|
|
case GASPRICE:
|
|
|
- stack.Push(closure.Price)
|
|
|
+ stack.Push(call.Price)
|
|
|
|
|
|
- self.Printf(" => %v", closure.Price)
|
|
|
+ self.Printf(" => %v", call.Price)
|
|
|
|
|
|
// 0x40 range
|
|
|
case PREVHASH:
|
|
|
@@ -707,17 +725,17 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
|
|
|
// 0x50 range
|
|
|
case PUSH1, PUSH2, PUSH3, PUSH4, PUSH5, PUSH6, PUSH7, PUSH8, PUSH9, PUSH10, PUSH11, PUSH12, PUSH13, PUSH14, PUSH15, PUSH16, PUSH17, PUSH18, PUSH19, PUSH20, PUSH21, PUSH22, PUSH23, PUSH24, PUSH25, PUSH26, PUSH27, PUSH28, PUSH29, PUSH30, PUSH31, PUSH32:
|
|
|
- a := big.NewInt(int64(op) - int64(PUSH1) + 1)
|
|
|
+ a := uint64(op) - uint64(PUSH1) + 1
|
|
|
pc.Add(pc, ethutil.Big1)
|
|
|
- data := closure.Gets(pc, a)
|
|
|
- val := ethutil.BigD(data.Bytes())
|
|
|
+ data := call.Get(pc.Uint64(), a) //closure.Gets(pc, a)
|
|
|
+ val := ethutil.BigD(data)
|
|
|
// Push value to stack
|
|
|
stack.Push(val)
|
|
|
- pc.Add(pc, a.Sub(a, big.NewInt(1)))
|
|
|
+ pc.Add(pc, big.NewInt(int64(a)-1))
|
|
|
|
|
|
- step += int(op) - int(PUSH1) + 1
|
|
|
+ step += uint64(op) - uint64(PUSH1) + 1
|
|
|
|
|
|
- self.Printf(" => 0x%x", data.Bytes())
|
|
|
+ self.Printf(" => 0x%x", data)
|
|
|
case POP:
|
|
|
stack.Pop()
|
|
|
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16:
|
|
|
@@ -725,10 +743,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
v := stack.Dupn(n)
|
|
|
|
|
|
self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes())
|
|
|
-
|
|
|
- if OpCode(closure.Get(new(big.Int).Add(pc, ethutil.Big1)).Uint()) == POP && OpCode(closure.Get(new(big.Int).Add(pc, big.NewInt(2))).Uint()) == POP {
|
|
|
- fmt.Println(toValue(v))
|
|
|
- }
|
|
|
case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
|
|
|
n := int(op - SWAP1 + 2)
|
|
|
x, y := stack.Swapn(n)
|
|
|
@@ -743,8 +757,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
topics[i] = stack.Pop().Bytes()
|
|
|
}
|
|
|
|
|
|
- log := &state.Log{closure.Address(), topics, data}
|
|
|
- self.env.AddLog(log)
|
|
|
+ //log := &state.Log{closure.Address(), topics, data}
|
|
|
+ self.env.AddLog(call.Address, topics, data)
|
|
|
|
|
|
self.Printf(" => %v", log)
|
|
|
case MLOAD:
|
|
|
@@ -768,18 +782,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
self.Printf(" => [%v] 0x%x", off, val)
|
|
|
case SLOAD:
|
|
|
loc := stack.Pop()
|
|
|
- val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes()))
|
|
|
+ val := ethutil.BigD(self.env.GetState(call.Address, loc.Bytes()))
|
|
|
stack.Push(val)
|
|
|
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
|
|
case SSTORE:
|
|
|
val, loc := stack.Popn()
|
|
|
- statedb.SetState(closure.Address(), loc.Bytes(), val)
|
|
|
+ self.env.SetState(call.Address, loc.Bytes(), val.Bytes())
|
|
|
+ //statedb.SetState(closure.Address(), loc.Bytes(), val)
|
|
|
|
|
|
- // Debug sessions are allowed to run without message
|
|
|
- if closure.message != nil {
|
|
|
- closure.message.AddStorageChange(loc.Bytes())
|
|
|
- }
|
|
|
+ //closure.message.AddStorageChange(loc.Bytes())
|
|
|
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes())
|
|
|
case JUMP:
|
|
|
@@ -802,7 +814,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
case MSIZE:
|
|
|
stack.Push(big.NewInt(int64(mem.Len())))
|
|
|
case GAS:
|
|
|
- stack.Push(closure.Gas)
|
|
|
+ stack.Push(call.Gas)
|
|
|
// 0x60 range
|
|
|
case CREATE:
|
|
|
var (
|
|
|
@@ -810,7 +822,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
value = stack.Pop()
|
|
|
size, offset = stack.Popn()
|
|
|
input = mem.Get(offset.Int64(), size.Int64())
|
|
|
- gas = new(big.Int).Set(closure.Gas)
|
|
|
+ gas = new(big.Int).Set(call.Gas)
|
|
|
|
|
|
// Snapshot the current stack so we are able to
|
|
|
// revert back to it later.
|
|
|
@@ -818,16 +830,19 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
)
|
|
|
|
|
|
// Generate a new address
|
|
|
- n := statedb.GetNonce(closure.Address())
|
|
|
- addr := crypto.CreateAddress(closure.Address(), n)
|
|
|
- statedb.SetNonce(closure.Address(), n+1)
|
|
|
+ //n := statedb.GetNonce(closure.Address())
|
|
|
+ //addr := crypto.CreateAddress(closure.Address(), n)
|
|
|
+ //statedb.SetNonce(closure.Address(), n+1)
|
|
|
+ n := self.env.GetNonce(call.Address)
|
|
|
+ addr := crypto.CreateAddress(call.Address, n)
|
|
|
+ self.env.SetNonce(call.Address, n+1)
|
|
|
|
|
|
self.Printf(" (*) %x", addr).Endl()
|
|
|
|
|
|
- closure.UseGas(closure.Gas)
|
|
|
+ //closure.UseGas(closure.Gas)
|
|
|
|
|
|
- msg := NewExecution(self, addr, input, gas, closure.Price, value)
|
|
|
- ret, err := msg.Create(closure)
|
|
|
+ msg := NewExecution(self, addr, input, gas, call.Price, value)
|
|
|
+ ret, lgas, err := msg.Create(call.Address)
|
|
|
if err != nil {
|
|
|
stack.Push(ethutil.BigFalse)
|
|
|
|
|
|
@@ -841,12 +856,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
stack.Push(ethutil.BigD(addr))
|
|
|
}
|
|
|
|
|
|
- self.Endl()
|
|
|
+ gas = lgas
|
|
|
|
|
|
- // Debug hook
|
|
|
- if self.Dbg != nil {
|
|
|
- self.Dbg.SetCode(closure.Code)
|
|
|
- }
|
|
|
+ self.Endl()
|
|
|
case CALL, CALLCODE:
|
|
|
self.Endl()
|
|
|
|
|
|
@@ -863,12 +875,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
|
|
|
var executeAddr []byte
|
|
|
if op == CALLCODE {
|
|
|
- executeAddr = closure.Address()
|
|
|
+ executeAddr = call.Address //closure.Address()
|
|
|
} else {
|
|
|
executeAddr = addr.Bytes()
|
|
|
}
|
|
|
|
|
|
- msg := NewExecution(self, executeAddr, args, gas, closure.Price, value)
|
|
|
+ msg := NewExecution(self, executeAddr, args, gas, call.Price, value)
|
|
|
ret, err := msg.Exec(addr.Bytes(), closure)
|
|
|
if err != nil {
|
|
|
stack.Push(ethutil.BigFalse)
|
|
|
@@ -881,24 +893,22 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
}
|
|
|
self.Printf("resume %x", closure.Address())
|
|
|
|
|
|
- // Debug hook
|
|
|
- if self.Dbg != nil {
|
|
|
- self.Dbg.SetCode(closure.Code)
|
|
|
- }
|
|
|
-
|
|
|
case RETURN:
|
|
|
size, offset := stack.Popn()
|
|
|
ret := mem.Get(offset.Int64(), size.Int64())
|
|
|
|
|
|
self.Printf(" => (%d) 0x%x", len(ret), ret).Endl()
|
|
|
|
|
|
- return closure.Return(ret), nil
|
|
|
- case SUICIDE:
|
|
|
+ return ret, gas, nil
|
|
|
|
|
|
- receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
|
|
+ //return closure.Return(ret), gas, nil
|
|
|
+ case SUICIDE:
|
|
|
+ //receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
|
|
+ //receiver.AddAmount(statedb.GetBalance(closure.Address()))
|
|
|
+ //statedb.Delete(closure.Address())
|
|
|
|
|
|
- receiver.AddAmount(statedb.GetBalance(closure.Address()))
|
|
|
- statedb.Delete(closure.Address())
|
|
|
+ self.env.AddBalance(stack.Pop().Bytes(), self.env.Balance(call.Address))
|
|
|
+ self.env.DeleteAccount(call.Address)
|
|
|
|
|
|
fallthrough
|
|
|
case STOP: // Stop the closure
|
|
|
@@ -917,23 +927,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
|
|
|
pc.Add(pc, ethutil.Big1)
|
|
|
|
|
|
self.Endl()
|
|
|
-
|
|
|
- if self.Dbg != nil {
|
|
|
- for _, instrNo := range self.Dbg.BreakPoints() {
|
|
|
- if pc.Cmp(big.NewInt(instrNo)) == 0 {
|
|
|
- self.Stepping = true
|
|
|
-
|
|
|
- if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
|
|
|
- return nil, nil
|
|
|
- }
|
|
|
- } else if self.Stepping {
|
|
|
- if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) {
|
|
|
- return nil, nil
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|