|
|
@ -37,7 +37,7 @@ func NewDebugVm(env Environment) *DebugVm { |
|
|
|
return &DebugVm{env: env, logTy: lt, Recoverable: true} |
|
|
|
return &DebugVm{env: env, logTy: lt, Recoverable: true} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { |
|
|
|
func (self *DebugVm) Run(me, caller ContextRef, code []byte, value, gas, price *big.Int, callData []byte) (ret []byte, err error) { |
|
|
|
self.env.SetDepth(self.env.Depth() + 1) |
|
|
|
self.env.SetDepth(self.env.Depth() + 1) |
|
|
|
|
|
|
|
|
|
|
|
msg := self.env.State().Manifest().AddMessage(&state.Message{ |
|
|
|
msg := self.env.State().Manifest().AddMessage(&state.Message{ |
|
|
@ -47,7 +47,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), |
|
|
|
Block: self.env.BlockHash(), Timestamp: self.env.Time(), Coinbase: self.env.Coinbase(), Number: self.env.BlockNumber(), |
|
|
|
Value: value, |
|
|
|
Value: value, |
|
|
|
}) |
|
|
|
}) |
|
|
|
closure := NewClosure(msg, caller, me, code, gas, price) |
|
|
|
context := NewContext(msg, caller, me, code, gas, price) |
|
|
|
|
|
|
|
|
|
|
|
if self.Recoverable { |
|
|
|
if self.Recoverable { |
|
|
|
// Recover from any require exception
|
|
|
|
// Recover from any require exception
|
|
|
@ -55,9 +55,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
if r := recover(); r != nil { |
|
|
|
if r := recover(); r != nil { |
|
|
|
self.Printf(" %v", r).Endl() |
|
|
|
self.Printf(" %v", r).Endl() |
|
|
|
|
|
|
|
|
|
|
|
closure.UseGas(closure.Gas) |
|
|
|
context.UseGas(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
ret = closure.Return(nil) |
|
|
|
ret = context.Return(nil) |
|
|
|
|
|
|
|
|
|
|
|
err = fmt.Errorf("%v", r) |
|
|
|
err = fmt.Errorf("%v", r) |
|
|
|
|
|
|
|
|
|
|
@ -66,13 +66,13 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if p := Precompiled[string(me.Address())]; p != nil { |
|
|
|
if p := Precompiled[string(me.Address())]; p != nil { |
|
|
|
return self.RunPrecompiled(p, callData, closure) |
|
|
|
return self.RunPrecompiled(p, callData, context) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
var ( |
|
|
|
op OpCode |
|
|
|
op OpCode |
|
|
|
|
|
|
|
|
|
|
|
destinations = analyseJumpDests(closure.Code) |
|
|
|
destinations = analyseJumpDests(context.Code) |
|
|
|
mem = NewMemory() |
|
|
|
mem = NewMemory() |
|
|
|
stack = NewStack() |
|
|
|
stack = NewStack() |
|
|
|
pc uint64 = 0 |
|
|
|
pc uint64 = 0 |
|
|
@ -84,11 +84,19 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
p := to.Uint64() |
|
|
|
p := to.Uint64() |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" ~> %v", to) |
|
|
|
self.Printf(" ~> %v", to) |
|
|
|
|
|
|
|
/* NOTE: new model. Will change soon |
|
|
|
|
|
|
|
nop := OpCode(context.GetOp(p)) |
|
|
|
|
|
|
|
if nop != JUMPDEST { |
|
|
|
|
|
|
|
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pc = to.Uint64() |
|
|
|
|
|
|
|
*/ |
|
|
|
// Return to start
|
|
|
|
// Return to start
|
|
|
|
if p == 0 { |
|
|
|
if p == 0 { |
|
|
|
pc = 0 |
|
|
|
pc = 0 |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
nop := OpCode(closure.GetOp(p)) |
|
|
|
nop := OpCode(context.GetOp(p)) |
|
|
|
if !(nop == JUMPDEST || destinations[from] != nil) { |
|
|
|
if !(nop == JUMPDEST || destinations[from] != nil) { |
|
|
|
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p)) |
|
|
|
panic(fmt.Sprintf("invalid jump destination (%v) %v", nop, p)) |
|
|
|
} else if nop == JUMP || nop == JUMPI { |
|
|
|
} else if nop == JUMP || nop == JUMPI { |
|
|
@ -103,11 +111,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], closure.Address(), len(code), closure.Gas, callData) |
|
|
|
vmlogger.Debugf("(%d) (%x) %x (code=%d) gas: %v (d) %x\n", self.env.Depth(), caller.Address()[:4], context.Address(), len(code), context.Gas, callData) |
|
|
|
|
|
|
|
|
|
|
|
// Don't bother with the execution if there's no code.
|
|
|
|
// Don't bother with the execution if there's no code.
|
|
|
|
if len(code) == 0 { |
|
|
|
if len(code) == 0 { |
|
|
|
return closure.Return(nil), nil |
|
|
|
return context.Return(nil), nil |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for { |
|
|
|
for { |
|
|
@ -117,22 +125,22 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
step++ |
|
|
|
step++ |
|
|
|
// Get the memory location of pc
|
|
|
|
// Get the memory location of pc
|
|
|
|
op = closure.GetOp(pc) |
|
|
|
op = context.GetOp(pc) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len()) |
|
|
|
self.Printf("(pc) %-3d -o- %-14s (m) %-4d (s) %-4d ", pc, op.String(), mem.Len(), stack.Len()) |
|
|
|
|
|
|
|
|
|
|
|
newMemSize, gas := self.calculateGasAndSize(closure, caller, op, statedb, mem, stack) |
|
|
|
newMemSize, gas := self.calculateGasAndSize(context, caller, op, statedb, mem, stack) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf("(g) %-3v (%v)", gas, closure.Gas) |
|
|
|
self.Printf("(g) %-3v (%v)", gas, context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
if !closure.UseGas(gas) { |
|
|
|
if !context.UseGas(gas) { |
|
|
|
self.Endl() |
|
|
|
self.Endl() |
|
|
|
|
|
|
|
|
|
|
|
tmp := new(big.Int).Set(closure.Gas) |
|
|
|
tmp := new(big.Int).Set(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
closure.UseGas(closure.Gas) |
|
|
|
context.UseGas(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
return closure.Return(nil), OOG(gas, tmp) |
|
|
|
return context.Return(nil), OOG(gas, tmp) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mem.Resize(newMemSize.Uint64()) |
|
|
|
mem.Resize(newMemSize.Uint64()) |
|
|
@ -410,9 +418,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
self.Printf(" => %x", data) |
|
|
|
self.Printf(" => %x", data) |
|
|
|
// 0x30 range
|
|
|
|
// 0x30 range
|
|
|
|
case ADDRESS: |
|
|
|
case ADDRESS: |
|
|
|
stack.Push(ethutil.BigD(closure.Address())) |
|
|
|
stack.Push(ethutil.BigD(context.Address())) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => %x", closure.Address()) |
|
|
|
self.Printf(" => %x", context.Address()) |
|
|
|
case BALANCE: |
|
|
|
case BALANCE: |
|
|
|
|
|
|
|
|
|
|
|
addr := stack.Pop().Bytes() |
|
|
|
addr := stack.Pop().Bytes() |
|
|
@ -428,7 +436,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => %x", origin) |
|
|
|
self.Printf(" => %x", origin) |
|
|
|
case CALLER: |
|
|
|
case CALLER: |
|
|
|
caller := closure.caller.Address() |
|
|
|
caller := context.caller.Address() |
|
|
|
stack.Push(ethutil.BigD(caller)) |
|
|
|
stack.Push(ethutil.BigD(caller)) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => %x", caller) |
|
|
|
self.Printf(" => %x", caller) |
|
|
@ -485,7 +493,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
code = statedb.GetCode(addr) |
|
|
|
code = statedb.GetCode(addr) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
code = closure.Code |
|
|
|
code = context.Code |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
l := big.NewInt(int64(len(code))) |
|
|
|
l := big.NewInt(int64(len(code))) |
|
|
@ -497,7 +505,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
if op == EXTCODECOPY { |
|
|
|
if op == EXTCODECOPY { |
|
|
|
code = statedb.GetCode(stack.Pop().Bytes()) |
|
|
|
code = statedb.GetCode(stack.Pop().Bytes()) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
code = closure.Code |
|
|
|
code = context.Code |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
var ( |
|
|
@ -519,9 +527,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy) |
|
|
|
self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, codeCopy) |
|
|
|
case GASPRICE: |
|
|
|
case GASPRICE: |
|
|
|
stack.Push(closure.Price) |
|
|
|
stack.Push(context.Price) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => %v", closure.Price) |
|
|
|
self.Printf(" => %v", context.Price) |
|
|
|
|
|
|
|
|
|
|
|
// 0x40 range
|
|
|
|
// 0x40 range
|
|
|
|
case PREVHASH: |
|
|
|
case PREVHASH: |
|
|
@ -560,7 +568,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
// 0x50 range
|
|
|
|
// 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: |
|
|
|
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 := uint64(op - PUSH1 + 1) |
|
|
|
a := uint64(op - PUSH1 + 1) |
|
|
|
byts := closure.GetRangeValue(pc+1, a) |
|
|
|
byts := context.GetRangeValue(pc+1, a) |
|
|
|
// Push value to stack
|
|
|
|
// Push value to stack
|
|
|
|
stack.Push(ethutil.BigD(byts)) |
|
|
|
stack.Push(ethutil.BigD(byts)) |
|
|
|
pc += a |
|
|
|
pc += a |
|
|
@ -589,7 +597,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
data := mem.Geti(mStart.Int64(), mSize.Int64()) |
|
|
|
data := mem.Geti(mStart.Int64(), mSize.Int64()) |
|
|
|
log := &Log{closure.Address(), topics, data} |
|
|
|
log := &Log{context.Address(), topics, data} |
|
|
|
self.env.AddLog(log) |
|
|
|
self.env.AddLog(log) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => %v", log) |
|
|
|
self.Printf(" => %v", log) |
|
|
@ -614,15 +622,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
self.Printf(" => [%v] 0x%x", off, val) |
|
|
|
self.Printf(" => [%v] 0x%x", off, val) |
|
|
|
case SLOAD: |
|
|
|
case SLOAD: |
|
|
|
loc := stack.Pop() |
|
|
|
loc := stack.Pop() |
|
|
|
val := ethutil.BigD(statedb.GetState(closure.Address(), loc.Bytes())) |
|
|
|
val := ethutil.BigD(statedb.GetState(context.Address(), loc.Bytes())) |
|
|
|
stack.Push(val) |
|
|
|
stack.Push(val) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) |
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) |
|
|
|
case SSTORE: |
|
|
|
case SSTORE: |
|
|
|
val, loc := stack.Popn() |
|
|
|
val, loc := stack.Popn() |
|
|
|
statedb.SetState(closure.Address(), loc.Bytes(), val) |
|
|
|
statedb.SetState(context.Address(), loc.Bytes(), val) |
|
|
|
|
|
|
|
|
|
|
|
closure.message.AddStorageChange(loc.Bytes()) |
|
|
|
context.message.AddStorageChange(loc.Bytes()) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) |
|
|
|
self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) |
|
|
|
case JUMP: |
|
|
|
case JUMP: |
|
|
@ -644,7 +652,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
case MSIZE: |
|
|
|
case MSIZE: |
|
|
|
stack.Push(big.NewInt(int64(mem.Len()))) |
|
|
|
stack.Push(big.NewInt(int64(mem.Len()))) |
|
|
|
case GAS: |
|
|
|
case GAS: |
|
|
|
stack.Push(closure.Gas) |
|
|
|
stack.Push(context.Gas) |
|
|
|
// 0x60 range
|
|
|
|
// 0x60 range
|
|
|
|
case CREATE: |
|
|
|
case CREATE: |
|
|
|
|
|
|
|
|
|
|
@ -653,7 +661,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
value = stack.Pop() |
|
|
|
value = stack.Pop() |
|
|
|
size, offset = stack.Popn() |
|
|
|
size, offset = stack.Popn() |
|
|
|
input = mem.Get(offset.Int64(), size.Int64()) |
|
|
|
input = mem.Get(offset.Int64(), size.Int64()) |
|
|
|
gas = new(big.Int).Set(closure.Gas) |
|
|
|
gas = new(big.Int).Set(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
// Snapshot the current stack so we are able to
|
|
|
|
// Snapshot the current stack so we are able to
|
|
|
|
// revert back to it later.
|
|
|
|
// revert back to it later.
|
|
|
@ -661,15 +669,15 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// Generate a new address
|
|
|
|
// Generate a new address
|
|
|
|
n := statedb.GetNonce(closure.Address()) |
|
|
|
n := statedb.GetNonce(context.Address()) |
|
|
|
addr := crypto.CreateAddress(closure.Address(), n) |
|
|
|
addr := crypto.CreateAddress(context.Address(), n) |
|
|
|
statedb.SetNonce(closure.Address(), n+1) |
|
|
|
statedb.SetNonce(context.Address(), n+1) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" (*) %x", addr).Endl() |
|
|
|
self.Printf(" (*) %x", addr).Endl() |
|
|
|
|
|
|
|
|
|
|
|
closure.UseGas(closure.Gas) |
|
|
|
context.UseGas(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
ret, err, ref := self.env.Create(closure, addr, input, gas, price, value) |
|
|
|
ret, err, ref := self.env.Create(context, addr, input, gas, price, value) |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
stack.Push(ethutil.BigFalse) |
|
|
|
stack.Push(ethutil.BigFalse) |
|
|
|
|
|
|
|
|
|
|
@ -678,7 +686,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
// gas < len(ret) * CreateDataGas == NO_CODE
|
|
|
|
// gas < len(ret) * CreateDataGas == NO_CODE
|
|
|
|
dataGas := big.NewInt(int64(len(ret))) |
|
|
|
dataGas := big.NewInt(int64(len(ret))) |
|
|
|
dataGas.Mul(dataGas, GasCreateByte) |
|
|
|
dataGas.Mul(dataGas, GasCreateByte) |
|
|
|
if closure.UseGas(dataGas) { |
|
|
|
if context.UseGas(dataGas) { |
|
|
|
ref.SetCode(ret) |
|
|
|
ref.SetCode(ret) |
|
|
|
msg.Output = ret |
|
|
|
msg.Output = ret |
|
|
|
} |
|
|
|
} |
|
|
@ -690,7 +698,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
// Debug hook
|
|
|
|
// Debug hook
|
|
|
|
if self.Dbg != nil { |
|
|
|
if self.Dbg != nil { |
|
|
|
self.Dbg.SetCode(closure.Code) |
|
|
|
self.Dbg.SetCode(context.Code) |
|
|
|
} |
|
|
|
} |
|
|
|
case CALL, CALLCODE: |
|
|
|
case CALL, CALLCODE: |
|
|
|
self.Endl() |
|
|
|
self.Endl() |
|
|
@ -711,9 +719,9 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
err error |
|
|
|
err error |
|
|
|
) |
|
|
|
) |
|
|
|
if op == CALLCODE { |
|
|
|
if op == CALLCODE { |
|
|
|
ret, err = self.env.CallCode(closure, addr.Bytes(), args, gas, price, value) |
|
|
|
ret, err = self.env.CallCode(context, addr.Bytes(), args, gas, price, value) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
ret, err = self.env.Call(closure, addr.Bytes(), args, gas, price, value) |
|
|
|
ret, err = self.env.Call(context, addr.Bytes(), args, gas, price, value) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
@ -726,11 +734,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret) |
|
|
|
mem.Set(retOffset.Uint64(), retSize.Uint64(), ret) |
|
|
|
} |
|
|
|
} |
|
|
|
self.Printf("resume %x (%v)", closure.Address(), closure.Gas) |
|
|
|
self.Printf("resume %x (%v)", context.Address(), context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
// Debug hook
|
|
|
|
// Debug hook
|
|
|
|
if self.Dbg != nil { |
|
|
|
if self.Dbg != nil { |
|
|
|
self.Dbg.SetCode(closure.Code) |
|
|
|
self.Dbg.SetCode(context.Code) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
case RETURN: |
|
|
|
case RETURN: |
|
|
@ -739,27 +747,27 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl() |
|
|
|
self.Printf(" => [%v, %v] (%d) 0x%x", offset, size, len(ret), ret).Endl() |
|
|
|
|
|
|
|
|
|
|
|
return closure.Return(ret), nil |
|
|
|
return context.Return(ret), nil |
|
|
|
case SUICIDE: |
|
|
|
case SUICIDE: |
|
|
|
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes()) |
|
|
|
receiver := statedb.GetOrNewStateObject(stack.Pop().Bytes()) |
|
|
|
balance := statedb.GetBalance(closure.Address()) |
|
|
|
balance := statedb.GetBalance(context.Address()) |
|
|
|
|
|
|
|
|
|
|
|
self.Printf(" => (%x) %v", receiver.Address()[:4], balance) |
|
|
|
self.Printf(" => (%x) %v", receiver.Address()[:4], balance) |
|
|
|
|
|
|
|
|
|
|
|
receiver.AddAmount(balance) |
|
|
|
receiver.AddAmount(balance) |
|
|
|
statedb.Delete(closure.Address()) |
|
|
|
statedb.Delete(context.Address()) |
|
|
|
|
|
|
|
|
|
|
|
fallthrough |
|
|
|
fallthrough |
|
|
|
case STOP: // Stop the closure
|
|
|
|
case STOP: // Stop the context
|
|
|
|
self.Endl() |
|
|
|
self.Endl() |
|
|
|
|
|
|
|
|
|
|
|
return closure.Return(nil), nil |
|
|
|
return context.Return(nil), nil |
|
|
|
default: |
|
|
|
default: |
|
|
|
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op) |
|
|
|
vmlogger.Debugf("(pc) %-3v Invalid opcode %x\n", pc, op) |
|
|
|
|
|
|
|
|
|
|
|
closure.ReturnGas(big.NewInt(1), nil) |
|
|
|
context.ReturnGas(big.NewInt(1), nil) |
|
|
|
|
|
|
|
|
|
|
|
return closure.Return(nil), fmt.Errorf("Invalid opcode %x", op) |
|
|
|
return context.Return(nil), fmt.Errorf("Invalid opcode %x", op) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pc++ |
|
|
|
pc++ |
|
|
@ -771,11 +779,11 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
if pc == uint64(instrNo) { |
|
|
|
if pc == uint64(instrNo) { |
|
|
|
self.Stepping = true |
|
|
|
self.Stepping = true |
|
|
|
|
|
|
|
|
|
|
|
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) { |
|
|
|
if !self.Dbg.BreakHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) { |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
} else if self.Stepping { |
|
|
|
} else if self.Stepping { |
|
|
|
if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(closure.Address())) { |
|
|
|
if !self.Dbg.StepHook(prevStep, op, mem, stack, statedb.GetStateObject(context.Address())) { |
|
|
|
return nil, nil |
|
|
|
return nil, nil |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -785,7 +793,7 @@ func (self *DebugVm) Run(me, caller ClosureRef, code []byte, value, gas, price * |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) { |
|
|
|
func (self *DebugVm) calculateGasAndSize(context *Context, caller ContextRef, op OpCode, statedb *state.StateDB, mem *Memory, stack *Stack) (*big.Int, *big.Int) { |
|
|
|
gas := new(big.Int) |
|
|
|
gas := new(big.Int) |
|
|
|
addStepGasUsage := func(amount *big.Int) { |
|
|
|
addStepGasUsage := func(amount *big.Int) { |
|
|
|
if amount.Cmp(ethutil.Big0) >= 0 { |
|
|
|
if amount.Cmp(ethutil.Big0) >= 0 { |
|
|
@ -844,7 +852,7 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op |
|
|
|
|
|
|
|
|
|
|
|
var mult *big.Int |
|
|
|
var mult *big.Int |
|
|
|
y, x := stack.Peekn() |
|
|
|
y, x := stack.Peekn() |
|
|
|
val := statedb.GetState(closure.Address(), x.Bytes()) |
|
|
|
val := statedb.GetState(context.Address(), x.Bytes()) |
|
|
|
if len(val) == 0 && len(y.Bytes()) > 0 { |
|
|
|
if len(val) == 0 && len(y.Bytes()) > 0 { |
|
|
|
// 0 => non 0
|
|
|
|
// 0 => non 0
|
|
|
|
mult = ethutil.Big3 |
|
|
|
mult = ethutil.Big3 |
|
|
@ -940,22 +948,22 @@ func (self *DebugVm) calculateGasAndSize(closure *Closure, caller ClosureRef, op |
|
|
|
return newMemSize, gas |
|
|
|
return newMemSize, gas |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, closure *Closure) (ret []byte, err error) { |
|
|
|
func (self *DebugVm) RunPrecompiled(p *PrecompiledAccount, callData []byte, context *Context) (ret []byte, err error) { |
|
|
|
gas := p.Gas(len(callData)) |
|
|
|
gas := p.Gas(len(callData)) |
|
|
|
if closure.UseGas(gas) { |
|
|
|
if context.UseGas(gas) { |
|
|
|
ret = p.Call(callData) |
|
|
|
ret = p.Call(callData) |
|
|
|
self.Printf("NATIVE_FUNC => %x", ret) |
|
|
|
self.Printf("NATIVE_FUNC => %x", ret) |
|
|
|
self.Endl() |
|
|
|
self.Endl() |
|
|
|
|
|
|
|
|
|
|
|
return closure.Return(ret), nil |
|
|
|
return context.Return(ret), nil |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
self.Endl() |
|
|
|
self.Endl() |
|
|
|
|
|
|
|
|
|
|
|
tmp := new(big.Int).Set(closure.Gas) |
|
|
|
tmp := new(big.Int).Set(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
closure.UseGas(closure.Gas) |
|
|
|
context.UseGas(context.Gas) |
|
|
|
|
|
|
|
|
|
|
|
return closure.Return(nil), OOG(gas, tmp) |
|
|
|
return context.Return(nil), OOG(gas, tmp) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|