diff options
Diffstat (limited to 'ethchain')
-rw-r--r-- | ethchain/asm.go | 4 | ||||
-rw-r--r-- | ethchain/state.go | 11 | ||||
-rw-r--r-- | ethchain/state_manager.go | 8 | ||||
-rw-r--r-- | ethchain/vm.go | 37 |
4 files changed, 53 insertions, 7 deletions
diff --git a/ethchain/asm.go b/ethchain/asm.go index 09d6af56f..2697953fd 100644 --- a/ethchain/asm.go +++ b/ethchain/asm.go @@ -24,6 +24,10 @@ func Disassemble(script []byte) (asm []string) { 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: pc.Add(pc, ethutil.Big1) a := int64(op) - int64(PUSH1) + 1 + if int(pc.Int64()+a) > len(script) { + return nil + } + data := script[pc.Int64() : pc.Int64()+a] if len(data) == 0 { data = []byte{0} diff --git a/ethchain/state.go b/ethchain/state.go index 6d45c9e32..8df79dcef 100644 --- a/ethchain/state.go +++ b/ethchain/state.go @@ -1,6 +1,7 @@ package ethchain import ( + "fmt" "github.com/ethereum/eth-go/ethcrypto" "github.com/ethereum/eth-go/ethtrie" "github.com/ethereum/eth-go/ethutil" @@ -208,6 +209,16 @@ func (self *State) Update() { } } +// Debug stuff +func (self *State) CreateOutputForDiff() { + for addr, stateObject := range self.stateObjects { + fmt.Printf("0x%x 0x%x 0x%x 0x%x\n", addr, stateObject.state.Root(), stateObject.Amount.Bytes(), stateObject.Nonce) + stateObject.state.EachStorage(func(addr string, value *ethutil.Value) { + fmt.Printf("0x%x 0x%x\n", addr, value.Bytes()) + }) + } +} + // Object manifest // // The object manifest is used to keep changes to the state so we can keep track of the changes diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go index a5afa5096..62fcda8a5 100644 --- a/ethchain/state_manager.go +++ b/ethchain/state_manager.go @@ -150,6 +150,10 @@ done: receipts = append(receipts, receipt) handled = append(handled, tx) + + if ethutil.Config.Diff { + state.CreateOutputForDiff() + } } parent.GasUsed = totalUsedGas @@ -183,6 +187,10 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) { // before that. defer state.Reset() + if ethutil.Config.Diff { + fmt.Printf("## 0x%x 0x%x ##\n", block.Hash(), block.Number) + } + receipts, err := sm.ApplyDiff(state, parent, block) defer func() { if err != nil { diff --git a/ethchain/vm.go b/ethchain/vm.go index 6a64d3ff3..3ad4472ca 100644 --- a/ethchain/vm.go +++ b/ethchain/vm.go @@ -31,6 +31,7 @@ type Debugger interface { BreakHook(step int, op OpCode, mem *Memory, stack *Stack, stateObject *StateObject) bool StepHook(step int, op OpCode, mem *Memory, stack *Stack, stateObject *StateObject) bool BreakPoints() []int64 + SetCode(byteCode []byte) } type Vm struct { @@ -90,7 +91,12 @@ func (self *Vm) Endl() *Vm { } func NewVm(state *State, stateManager *StateManager, vars RuntimeVars) *Vm { - return &Vm{vars: vars, state: state, stateManager: stateManager, logTy: LogTyPretty} + lt := LogTyPretty + if ethutil.Config.Diff { + lt = LogTyDiff + } + + return &Vm{vars: vars, state: state, stateManager: stateManager, logTy: lt} } var Pow256 = ethutil.BigPow(2, 256) @@ -107,12 +113,17 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { } }() + // Debug hook + if vm.Dbg != nil { + vm.Dbg.SetCode(closure.Script) + } + // Don't bother with the execution if there's no code. if len(closure.Script) == 0 { return closure.Return(nil), nil } - vmlogger.Debugf("(%s) %x gas: %v (d) %x\n", vm.Fn, closure.object.Address(), closure.Gas, closure.Args) + vmlogger.Debugf("(%s) %x gas: %v (d) %x\n", vm.Fn, closure.Address(), closure.Gas, closure.Args) var ( op OpCode @@ -149,7 +160,7 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { b = []byte{0} } - fmt.Printf("%x %x %x %x\n", closure.object.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) @@ -456,9 +467,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { vm.Printf(" => %x", data) // 0x30 range case ADDRESS: - stack.Push(ethutil.BigD(closure.Object().Address())) + stack.Push(ethutil.BigD(closure.Address())) - vm.Printf(" => %x", closure.Object().Address()) + vm.Printf(" => %x", closure.Address()) case BALANCE: require(1) @@ -664,9 +675,9 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { ) // Generate a new address - addr := ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce) + addr := ethcrypto.CreateAddress(closure.Address(), closure.N().Uint64()) for i := uint64(0); vm.state.GetStateObject(addr) != nil; i++ { - ethcrypto.CreateAddress(closure.object.Address(), closure.object.Nonce+i) + ethcrypto.CreateAddress(closure.Address(), closure.N().Uint64()+i) } closure.object.Nonce++ @@ -706,6 +717,11 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { vm.Printf("CREATE success") } vm.Endl() + + // Debug hook + if vm.Dbg != nil { + vm.Dbg.SetCode(closure.Script) + } case CALL: require(7) @@ -749,6 +765,11 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { mem.Set(retOffset.Int64(), retSize.Int64(), ret) } + + // Debug hook + if vm.Dbg != nil { + vm.Dbg.SetCode(closure.Script) + } } case RETURN: require(2) @@ -786,6 +807,8 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) { if vm.Dbg != nil { for _, instrNo := range vm.Dbg.BreakPoints() { if pc.Cmp(big.NewInt(instrNo)) == 0 { + vm.Stepping = true + if !vm.Dbg.BreakHook(prevStep, op, mem, stack, closure.Object()) { return nil, nil } |