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 } diff --git a/ethereum.go b/ethereum.go index 35d98e831..2806dfd9d 100644 --- a/ethereum.go +++ b/ethereum.go @@ -20,6 +20,8 @@ import ( "time" ) +const seedTextFileUri string = "http://www.ethereum.org/servers.poc3.txt" + var ethlogger = ethlog.NewLogger("SERV") func eachPeer(peers *list.List, callback func(*Peer, *list.Element)) { @@ -416,7 +418,7 @@ func (s *Ethereum) Seed() { s.ProcessPeerList(peers) } else { // Fallback to servers.poc3.txt - resp, err := http.Get("http://www.ethereum.org/servers.poc3.txt") + resp, err := http.Get(seedTextFileUri) if err != nil { ethlogger.Warnln("Fetching seed failed:", err) return diff --git a/ethutil/config.go b/ethutil/config.go index c9b86100b..2f3d706fe 100644 --- a/ethutil/config.go +++ b/ethutil/config.go @@ -13,6 +13,7 @@ type ConfigManager struct { ExecPath string Debug bool + Diff bool Paranoia bool conf *globalconf.GlobalConf