diff --git a/ethchain/asm.go b/ethchain/asm.go index 09d6af56fc..2697953fd8 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 6d45c9e32c..8df79dcef2 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 a5afa50963..62fcda8a5c 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 6a64d3ff38..3ad4472ca2 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 35d98e8311..2806dfd9dd 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 c9b86100b4..2f3d706fe6 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