rework vm
This commit is contained in:
parent
1bce02eff7
commit
616066a598
@ -5,11 +5,10 @@ import (
|
||||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/ethutil"
|
||||
"github.com/ethereum/go-ethereum/state"
|
||||
)
|
||||
|
||||
type Environment interface {
|
||||
State() *state.State
|
||||
//State() *state.State
|
||||
|
||||
Origin() []byte
|
||||
BlockNumber() *big.Int
|
||||
@ -19,8 +18,16 @@ type Environment interface {
|
||||
Difficulty() *big.Int
|
||||
BlockHash() []byte
|
||||
GasLimit() *big.Int
|
||||
|
||||
Transfer(from, to Account, amount *big.Int) error
|
||||
AddLog(*state.Log)
|
||||
AddLog(addr []byte, topics [][]byte, data []byte)
|
||||
DeleteAccount(addr []byte)
|
||||
SetState(addr, key, value []byte)
|
||||
GetState(addr, key []byte) []byte
|
||||
Balance(addr []byte) *big.Int
|
||||
AddBalance(addr []byte, balance *big.Int)
|
||||
GetCode(addr []byte) []byte
|
||||
Refund(addr []byte, gas, price *big.Int)
|
||||
}
|
||||
|
||||
type Object interface {
|
||||
@ -43,9 +50,5 @@ func Transfer(from, to Account, amount *big.Int) error {
|
||||
from.SubBalance(amount)
|
||||
to.AddBalance(amount)
|
||||
|
||||
// Add default LOG. Default = big(sender.addr) + 1
|
||||
//addr := ethutil.BigD(receiver.Address())
|
||||
//tx.addLog(vm.Log{sender.Address(), [][]byte{ethutil.U256(addr.Add(addr, ethutil.Big1)).Bytes()}, nil})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -90,6 +90,6 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte,
|
||||
return
|
||||
}
|
||||
|
||||
func (self *Execution) Create(caller ClosureRef) (ret []byte, err error) {
|
||||
func (self *Execution) Create(caller []byte) (ret []byte, err error) {
|
||||
return self.exec(self.input, nil, caller)
|
||||
}
|
||||
|
269
vm/vm_debug.go
269
vm/vm_debug.go
@ -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}
|
||||
}
|
||||
|
||||
fmt.Printf("%x %x %x %x\n", closure.Address(), b, []byte{byte(op)}, closure.Gas.Bytes())
|
||||
}
|
||||
*/
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
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
|
||||
return ret, gas, nil
|
||||
|
||||
//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 := statedb.GetOrNewStateObject(stack.Pop().Bytes())
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user