Commit 616066a5 authored by obscuren's avatar obscuren

rework vm

parent 1bce02ef
...@@ -5,11 +5,10 @@ import ( ...@@ -5,11 +5,10 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
) )
type Environment interface { type Environment interface {
State() *state.State //State() *state.State
Origin() []byte Origin() []byte
BlockNumber() *big.Int BlockNumber() *big.Int
...@@ -19,8 +18,16 @@ type Environment interface { ...@@ -19,8 +18,16 @@ type Environment interface {
Difficulty() *big.Int Difficulty() *big.Int
BlockHash() []byte BlockHash() []byte
GasLimit() *big.Int GasLimit() *big.Int
Transfer(from, to Account, amount *big.Int) error 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 { type Object interface {
...@@ -43,9 +50,5 @@ func Transfer(from, to Account, amount *big.Int) error { ...@@ -43,9 +50,5 @@ func Transfer(from, to Account, amount *big.Int) error {
from.SubBalance(amount) from.SubBalance(amount)
to.AddBalance(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 return nil
} }
...@@ -90,6 +90,6 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte, ...@@ -90,6 +90,6 @@ func (self *Execution) exec(code, caddr []byte, caller ClosureRef) (ret []byte,
return 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) return self.exec(self.input, nil, caller)
} }
...@@ -6,7 +6,6 @@ import ( ...@@ -6,7 +6,6 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/state"
) )
type DebugVm struct { type DebugVm struct {
...@@ -29,6 +28,13 @@ type DebugVm struct { ...@@ -29,6 +28,13 @@ type DebugVm struct {
depth int depth int
} }
type Options struct {
Address, Caller []byte
Data []byte
Code []byte
Value, Gas, Price *big.Int
}
func NewDebugVm(env Environment) *DebugVm { func NewDebugVm(env Environment) *DebugVm {
lt := LogTyPretty lt := LogTyPretty
if ethutil.Config.Diff { if ethutil.Config.Diff {
...@@ -38,7 +44,13 @@ func NewDebugVm(env Environment) *DebugVm { ...@@ -38,7 +44,13 @@ func NewDebugVm(env Environment) *DebugVm {
return &DebugVm{env: env, logTy: lt, Recoverable: true} 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++ self.depth++
if self.Recoverable { if self.Recoverable {
...@@ -47,41 +59,49 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -47,41 +59,49 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
if r := recover(); r != nil { if r := recover(); r != nil {
self.Endl() self.Endl()
closure.UseGas(closure.Gas) gas = new(big.Int)
ret = closure.Return(nil)
err = fmt.Errorf("%v", r) err = fmt.Errorf("%v", r)
} }
}() }()
} }
gas = new(big.Int).Set(opt.Gas)
var ( var (
op OpCode op OpCode
destinations = analyseJumpDests(closure.Code) destinations = analyseJumpDests(call.Code)
mem = NewMemory() mem = NewMemory()
stack = NewStack() stack = NewStack()
pc = big.NewInt(0) pc = big.NewInt(0)
step = 0 step = 0
prevStep = 0 prevStep = 0
statedb = self.env.State() //statedb = self.env.State()
require = func(m int) { require = func(m int) {
if stack.Len() < m { if stack.Len() < m {
panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, 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) { jump = func(from, to *big.Int) {
p := int(to.Int64()) p := to.Uint64()
self.Printf(" ~> %v", to) self.Printf(" ~> %v", to)
// Return to start // Return to start
if p == 0 { if p == 0 {
pc = big.NewInt(0) pc = big.NewInt(0)
} else { } else {
nop := OpCode(closure.GetOp(p)) nop := OpCode(call.GetOp(p))
if !(nop == JUMPDEST || destinations[from.Int64()] != nil) { if !(nop == JUMPDEST || destinations[from.Int64()] != nil) {
panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p)) panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p))
} else if nop == JUMP || nop == JUMPI { } else if nop == JUMP || nop == JUMPI {
...@@ -96,17 +116,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -96,17 +116,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
} }
) )
// Debug hook vmlogger.Debugf("(%d) %x gas: %v (d) %x\n", self.depth, call.Address, gas, call.Data)
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)
for { for {
prevStep = step prevStep = step
...@@ -115,10 +125,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -115,10 +125,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
step++ step++
// Get the memory location of pc // 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. // XXX Leave this Println intact. Don't change this to the log system.
// Used for creating diffs between implementations // Used for creating diffs between implementations
/*
if self.logTy == LogTyDiff { if self.logTy == LogTyDiff {
switch op { switch op {
case STOP, RETURN, SUICIDE: case STOP, RETURN, SUICIDE:
...@@ -135,11 +146,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -135,11 +146,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
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) { addStepGasUsage := func(amount *big.Int) {
if amount.Cmp(ethutil.Big0) >= 0 { 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) { ...@@ -166,42 +178,43 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
require(n + 2) require(n + 2)
mSize, mStart := stack.Peekn() mSize, mStart := stack.Peekn()
gas.Set(GasLog) reqGs.Set(GasLog)
addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog)) addStepGasUsage(new(big.Int).Mul(big.NewInt(int64(n)), GasLog))
addStepGasUsage(new(big.Int).Add(mSize, mStart)) addStepGasUsage(new(big.Int).Add(mSize, mStart))
// Gas only // Gas only
case STOP: case STOP:
gas.Set(ethutil.Big0) reqGas.Set(ethutil.Big0)
case SUICIDE: case SUICIDE:
require(1) require(1)
gas.Set(ethutil.Big0) reqGas.Set(ethutil.Big0)
case SLOAD: case SLOAD:
require(1) require(1)
gas.Set(GasSLoad) reqGas.Set(GasSLoad)
// Memory resize & Gas // Memory resize & Gas
case SSTORE: case SSTORE:
require(2) require(2)
var mult *big.Int var mult *big.Int
y, x := stack.Peekn() 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 { if val.BigInt().Cmp(ethutil.Big0) == 0 && len(y.Bytes()) > 0 {
// 0 => non 0 // 0 => non 0
mult = ethutil.Big3 mult = ethutil.Big3
} else if val.BigInt().Cmp(ethutil.Big0) != 0 && len(y.Bytes()) == 0 { } 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 mult = ethutil.Big0
} else { } else {
// non 0 => non 0 // non 0 => non 0
mult = ethutil.Big1 mult = ethutil.Big1
} }
gas.Set(new(big.Int).Mul(mult, GasSStore)) reqGas.Set(new(big.Int).Mul(mult, GasSStore))
case BALANCE: case BALANCE:
require(1) require(1)
gas.Set(GasBalance) reqGas.Set(GasBalance)
case MSTORE: case MSTORE:
require(2) require(2)
newMemSize = calcMemSize(stack.Peek(), u256(32)) newMemSize = calcMemSize(stack.Peek(), u256(32))
...@@ -219,7 +232,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -219,7 +232,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
case SHA3: case SHA3:
require(2) require(2)
gas.Set(GasSha) reqGas.Set(GasSha)
newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2]) newMemSize = calcMemSize(stack.Peek(), stack.data[stack.Len()-2])
case CALLDATACOPY: case CALLDATACOPY:
...@@ -236,7 +249,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -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]) newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-4])
case CALL, CALLCODE: case CALL, CALLCODE:
require(7) require(7)
gas.Set(GasCall) reqGas.Set(GasCall)
addStepGasUsage(stack.data[stack.Len()-1]) addStepGasUsage(stack.data[stack.Len()-1])
x := calcMemSize(stack.data[stack.Len()-6], stack.data[stack.Len()-7]) 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) { ...@@ -245,7 +258,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
newMemSize = ethutil.BigMax(x, y) newMemSize = ethutil.BigMax(x, y)
case CREATE: case CREATE:
require(3) require(3)
gas.Set(GasCreate) reqGas.Set(GasCreate)
newMemSize = calcMemSize(stack.data[stack.Len()-2], stack.data[stack.Len()-3]) 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) { ...@@ -255,6 +268,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
newMemSize.Div(newMemSize, u256(32)) newMemSize.Div(newMemSize, u256(32))
newMemSize.Mul(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 { if newMemSize.Cmp(u256(int64(mem.Len()))) > 0 {
memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len()))) memGasUsage := new(big.Int).Sub(newMemSize, u256(int64(mem.Len())))
memGasUsage.Mul(GasMemory, memGasUsage) memGasUsage.Mul(GasMemory, memGasUsage)
...@@ -268,16 +287,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -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("(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() self.Endl()
tmp := new(big.Int).Set(closure.Gas) return nil, new(big.Int), OOG(reqGas, gas)
closure.UseGas(closure.Gas)
return closure.Return(nil), OOG(gas, tmp)
} }
switch op { switch op {
...@@ -553,13 +568,15 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -553,13 +568,15 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
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(closure.Address()))
stack.Push(ethutil.BigD(call.Address))
self.Printf(" => %x", closure.Address()) self.Printf(" => %x", call.Address)
case BALANCE: case BALANCE:
addr := stack.Pop().Bytes() addr := stack.Pop().Bytes()
balance := statedb.GetBalance(addr) //balance := statedb.GetBalance(addr)
balance := self.env.GetBalance(addr)
stack.Push(balance) stack.Push(balance)
...@@ -571,41 +588,42 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -571,41 +588,42 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
self.Printf(" => %x", origin) self.Printf(" => %x", origin)
case CALLER: case CALLER:
caller := closure.caller.Address() //caller := closure.caller.Address()
stack.Push(ethutil.BigD(caller)) //stack.Push(ethutil.BigD(caller))
stack.Push(call.Caller)
self.Printf(" => %x", caller) self.Printf(" => %x", call.Caller)
case CALLVALUE: 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: case CALLDATALOAD:
var ( var (
offset = stack.Pop() offset = stack.Pop()
data = make([]byte, 32) data = make([]byte, 32)
lenData = big.NewInt(int64(len(closure.Args))) lenData = big.NewInt(int64(len(call.Data)))
) )
if lenData.Cmp(offset) >= 0 { if lenData.Cmp(offset) >= 0 {
length := new(big.Int).Add(offset, ethutil.Big32) length := new(big.Int).Add(offset, ethutil.Big32)
length = ethutil.BigMin(length, lenData) 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) self.Printf(" => 0x%x", data)
stack.Push(ethutil.BigD(data)) stack.Push(ethutil.BigD(data))
case CALLDATASIZE: case CALLDATASIZE:
l := int64(len(closure.Args)) l := int64(len(call.Data))
stack.Push(big.NewInt(l)) stack.Push(big.NewInt(l))
self.Printf(" => %d", l) self.Printf(" => %d", l)
case CALLDATACOPY: case CALLDATACOPY:
var ( var (
size = int64(len(closure.Args)) size = int64(len(call.Data))
mOff = stack.Pop().Int64() mOff = stack.Pop().Int64()
cOff = stack.Pop().Int64() cOff = stack.Pop().Int64()
l = stack.Pop().Int64() l = stack.Pop().Int64()
...@@ -618,7 +636,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -618,7 +636,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
l = 0 l = 0
} }
code := closure.Args[cOff : cOff+l] code := call.Data[cOff : cOff+l]
mem.Set(mOff, l, code) mem.Set(mOff, l, code)
...@@ -628,9 +646,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -628,9 +646,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
if op == EXTCODESIZE { if op == EXTCODESIZE {
addr := stack.Pop().Bytes() addr := stack.Pop().Bytes()
code = statedb.GetCode(addr) self.env.GetCode(addr)
} else { } else {
code = closure.Code code = call.Code
} }
l := big.NewInt(int64(len(code))) l := big.NewInt(int64(len(code)))
...@@ -642,9 +660,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -642,9 +660,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
if op == EXTCODECOPY { if op == EXTCODECOPY {
addr := stack.Pop().Bytes() addr := stack.Pop().Bytes()
code = statedb.GetCode(addr) code = self.env.GetCode(addr)
} else { } else {
code = closure.Code code = call.Code
} }
var ( var (
...@@ -667,9 +685,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -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]) self.Printf(" => [%v, %v, %v] %x", mOff, cOff, l, code[cOff:cOff+l])
case GASPRICE: case GASPRICE:
stack.Push(closure.Price) stack.Push(call.Price)
self.Printf(" => %v", closure.Price) self.Printf(" => %v", call.Price)
// 0x40 range // 0x40 range
case PREVHASH: case PREVHASH:
...@@ -707,17 +725,17 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -707,17 +725,17 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
// 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 := big.NewInt(int64(op) - int64(PUSH1) + 1) a := uint64(op) - uint64(PUSH1) + 1
pc.Add(pc, ethutil.Big1) pc.Add(pc, ethutil.Big1)
data := closure.Gets(pc, a) data := call.Get(pc.Uint64(), a) //closure.Gets(pc, a)
val := ethutil.BigD(data.Bytes()) val := ethutil.BigD(data)
// Push value to stack // Push value to stack
stack.Push(val) 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: case POP:
stack.Pop() stack.Pop()
case DUP1, DUP2, DUP3, DUP4, DUP5, DUP6, DUP7, DUP8, DUP9, DUP10, DUP11, DUP12, DUP13, DUP14, DUP15, DUP16: 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) { ...@@ -725,10 +743,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
v := stack.Dupn(n) v := stack.Dupn(n)
self.Printf(" => [%d] 0x%x", n, stack.Peek().Bytes()) 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: case SWAP1, SWAP2, SWAP3, SWAP4, SWAP5, SWAP6, SWAP7, SWAP8, SWAP9, SWAP10, SWAP11, SWAP12, SWAP13, SWAP14, SWAP15, SWAP16:
n := int(op - SWAP1 + 2) n := int(op - SWAP1 + 2)
x, y := stack.Swapn(n) x, y := stack.Swapn(n)
...@@ -743,8 +757,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -743,8 +757,8 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
topics[i] = stack.Pop().Bytes() topics[i] = stack.Pop().Bytes()
} }
log := &state.Log{closure.Address(), topics, data} //log := &state.Log{closure.Address(), topics, data}
self.env.AddLog(log) self.env.AddLog(call.Address, topics, data)
self.Printf(" => %v", log) self.Printf(" => %v", log)
case MLOAD: case MLOAD:
...@@ -768,18 +782,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -768,18 +782,16 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
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(self.env.GetState(call.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) self.env.SetState(call.Address, loc.Bytes(), val.Bytes())
//statedb.SetState(closure.Address(), loc.Bytes(), val)
// Debug sessions are allowed to run without message //closure.message.AddStorageChange(loc.Bytes())
if closure.message != nil {
closure.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:
...@@ -802,7 +814,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -802,7 +814,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
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(call.Gas)
// 0x60 range // 0x60 range
case CREATE: case CREATE:
var ( var (
...@@ -810,7 +822,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -810,7 +822,7 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
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(call.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.
...@@ -818,16 +830,19 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -818,16 +830,19 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
) )
// Generate a new address // Generate a new address
n := statedb.GetNonce(closure.Address()) //n := statedb.GetNonce(closure.Address())
addr := crypto.CreateAddress(closure.Address(), n) //addr := crypto.CreateAddress(closure.Address(), n)
statedb.SetNonce(closure.Address(), n+1) //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() self.Printf(" (*) %x", addr).Endl()
closure.UseGas(closure.Gas) //closure.UseGas(closure.Gas)
msg := NewExecution(self, addr, input, gas, closure.Price, value) msg := NewExecution(self, addr, input, gas, call.Price, value)
ret, err := msg.Create(closure) ret, lgas, err := msg.Create(call.Address)
if err != nil { if err != nil {
stack.Push(ethutil.BigFalse) stack.Push(ethutil.BigFalse)
...@@ -841,12 +856,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -841,12 +856,9 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
stack.Push(ethutil.BigD(addr)) stack.Push(ethutil.BigD(addr))
} }
self.Endl() gas = lgas
// Debug hook self.Endl()
if self.Dbg != nil {
self.Dbg.SetCode(closure.Code)
}
case CALL, CALLCODE: case CALL, CALLCODE:
self.Endl() self.Endl()
...@@ -863,12 +875,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -863,12 +875,12 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
var executeAddr []byte var executeAddr []byte
if op == CALLCODE { if op == CALLCODE {
executeAddr = closure.Address() executeAddr = call.Address //closure.Address()
} else { } else {
executeAddr = addr.Bytes() 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) ret, err := msg.Exec(addr.Bytes(), closure)
if err != nil { if err != nil {
stack.Push(ethutil.BigFalse) stack.Push(ethutil.BigFalse)
...@@ -881,24 +893,22 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -881,24 +893,22 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
} }
self.Printf("resume %x", closure.Address()) self.Printf("resume %x", closure.Address())
// Debug hook
if self.Dbg != nil {
self.Dbg.SetCode(closure.Code)
}
case RETURN: case RETURN:
size, offset := stack.Popn() size, offset := stack.Popn()
ret := mem.Get(offset.Int64(), size.Int64()) ret := mem.Get(offset.Int64(), size.Int64())
self.Printf(" => (%d) 0x%x", len(ret), ret).Endl() self.Printf(" => (%d) 0x%x", len(ret), ret).Endl()
return closure.Return(ret), nil return ret, gas, nil
case SUICIDE:
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())) self.env.AddBalance(stack.Pop().Bytes(), self.env.Balance(call.Address))
statedb.Delete(closure.Address()) self.env.DeleteAccount(call.Address)
fallthrough fallthrough
case STOP: // Stop the closure case STOP: // Stop the closure
...@@ -917,23 +927,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { ...@@ -917,23 +927,6 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) {
pc.Add(pc, ethutil.Big1) pc.Add(pc, ethutil.Big1)
self.Endl() 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
}
}
}
}
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment