diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/blocktest/main.go | 3 | ||||
-rw-r--r-- | cmd/ethereum/main.go | 43 | ||||
-rw-r--r-- | cmd/mist/assets/qml/main.qml | 25 | ||||
-rw-r--r-- | cmd/mist/assets/qml/views/chain.qml | 17 | ||||
-rw-r--r-- | cmd/mist/debugger.go | 369 | ||||
-rw-r--r-- | cmd/mist/ui_lib.go | 27 | ||||
-rw-r--r-- | cmd/utils/cmd.go | 50 |
7 files changed, 62 insertions, 472 deletions
diff --git a/cmd/blocktest/main.go b/cmd/blocktest/main.go index d9d97abc9..ec2779e2e 100644 --- a/cmd/blocktest/main.go +++ b/cmd/blocktest/main.go @@ -187,6 +187,9 @@ func loadBlocksFromTestFile(filePath string) (blocks types.Blocks, err error) { } gb := types.NewBlockWithHeader(gbh) + //gb.uncles = *new([]*types.Header) + //gb.transactions = *new(types.Transactions) + gb.Td = new(big.Int) gb.Reward = new(big.Int) testBlock := new(types.Block) diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index ed17fcc1f..7b912cf6e 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -105,6 +105,11 @@ runtime will execute the file and exit. Name: "import", Usage: `import a blockchain file`, }, + { + Action: exportchain, + Name: "export", + Usage: `export blockchain into file`, + }, } app.Flags = []cli.Flag{ utils.BootnodesFlag, @@ -232,25 +237,39 @@ func importchain(ctx *cli.Context) { if len(ctx.Args()) != 1 { utils.Fatalf("This command requires an argument.") } - chain, _, _ := utils.GetChain(ctx) + chainmgr, _, _ := utils.GetChain(ctx) start := time.Now() - err := utils.ImportChain(chain, ctx.Args().First()) + err := utils.ImportChain(chainmgr, ctx.Args().First()) if err != nil { utils.Fatalf("Import error: %v\n", err) } - fmt.Printf("Import done in", time.Since(start)) + fmt.Printf("Import done in %v", time.Since(start)) + return +} + +func exportchain(ctx *cli.Context) { + if len(ctx.Args()) != 1 { + utils.Fatalf("This command requires an argument.") + } + chainmgr, _, _ := utils.GetChain(ctx) + start := time.Now() + err := utils.ExportChain(chainmgr, ctx.Args().First()) + if err != nil { + utils.Fatalf("Export error: %v\n", err) + } + fmt.Printf("Export done in %v", time.Since(start)) return } func dump(ctx *cli.Context) { - chain, _, stateDb := utils.GetChain(ctx) + chainmgr, _, stateDb := utils.GetChain(ctx) for _, arg := range ctx.Args() { var block *types.Block if hashish(arg) { - block = chain.GetBlock(ethutil.Hex2Bytes(arg)) + block = chainmgr.GetBlock(ethutil.Hex2Bytes(arg)) } else { num, _ := strconv.Atoi(arg) - block = chain.GetBlockByNumber(uint64(num)) + block = chainmgr.GetBlockByNumber(uint64(num)) } if block == nil { fmt.Println("{}") @@ -264,13 +283,15 @@ func dump(ctx *cli.Context) { } func version(c *cli.Context) { - fmt.Printf(`%v %v -PV=%d -GOOS=%s -GO=%s + fmt.Printf(`%v +Version: %v +Protocol Version: %d +Network Id: %d +GO: %s +OS: %s GOPATH=%s GOROOT=%s -`, ClientIdentifier, Version, eth.ProtocolVersion, runtime.GOOS, runtime.Version(), os.Getenv("GOPATH"), runtime.GOROOT()) +`, ClientIdentifier, Version, eth.ProtocolVersion, eth.NetworkId, runtime.Version(), runtime.GOOS, os.Getenv("GOPATH"), runtime.GOROOT()) } // hashish returns true for strings that look like hashes. diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 1626a63a9..8558ebd51 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -200,13 +200,6 @@ ApplicationWindow { Menu { title: "Developer" MenuItem { - iconSource: "../icecream.png" - text: "Debugger" - shortcut: "Ctrl+d" - onTriggered: eth.startDebugger() - } - - MenuItem { text: "Import Tx" onTriggered: { txImportDialog.visible = true @@ -761,24 +754,6 @@ ApplicationWindow { } } - Rectangle { - height: 55 - color: "transparent" - visible: true - Text { - text: "DEBUG" - font.family: sourceSansPro.name - font.weight: Font.DemiBold - anchors { - left: parent.left - top: parent.verticalCenter - leftMargin: 16 - } - color: "#AAA0A0" - } - } - - ColumnLayout { id: menuLegacy visible: true diff --git a/cmd/mist/assets/qml/views/chain.qml b/cmd/mist/assets/qml/views/chain.qml index 4d1bc0e03..9892beddf 100644 --- a/cmd/mist/assets/qml/views/chain.qml +++ b/cmd/mist/assets/qml/views/chain.qml @@ -178,7 +178,6 @@ Rectangle { } function showContractData(tx) { - txDetailsDebugButton.tx = tx if(tx.createsContract) { contractData.text = tx.data contractLabel.text = "<h4> Transaction created contract " + tx.address + "</h4>" @@ -202,22 +201,6 @@ Rectangle { id: contractLabel anchors.leftMargin: 10 } - Button { - property var tx - id: txDetailsDebugButton - anchors.right: parent.right - anchors.rightMargin: 10 - anchors.top: parent.top - anchors.topMargin: 10 - text: "Debug contract" - onClicked: { - if(tx && tx.createsContract){ - eth.startDbWithCode(tx.rawData) - }else { - eth.startDbWithContractAndData(tx.address, tx.rawData) - } - } - } TextArea { id: contractData text: "Contract" diff --git a/cmd/mist/debugger.go b/cmd/mist/debugger.go deleted file mode 100644 index bd8ddde37..000000000 --- a/cmd/mist/debugger.go +++ /dev/null @@ -1,369 +0,0 @@ -/* - This file is part of go-ethereum - - go-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - go-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. -*/ -/** - * @authors - * Jeffrey Wilcke <i@jev.io> - */ -package main - -import ( - "fmt" - "math/big" - "strconv" - "strings" - "unicode" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethutil" - "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/vm" - "github.com/obscuren/qml" -) - -type DebuggerWindow struct { - win *qml.Window - engine *qml.Engine - lib *UiLib - - vm *vm.Vm - Db *Debugger - - state *state.StateDB -} - -func NewDebuggerWindow(lib *UiLib) *DebuggerWindow { - engine := qml.NewEngine() - component, err := engine.LoadFile(lib.AssetPath("debugger/debugger.qml")) - if err != nil { - fmt.Println(err) - - return nil - } - - win := component.CreateWindow(nil) - - w := &DebuggerWindow{engine: engine, win: win, lib: lib, vm: &vm.Vm{}} - w.Db = NewDebugger(w) - - return w -} - -func (self *DebuggerWindow) Show() { - context := self.engine.Context() - context.SetVar("dbg", self) - - go func() { - self.win.Show() - self.win.Wait() - }() -} - -func (self *DebuggerWindow) SetCode(code string) { - self.win.Set("codeText", code) -} - -func (self *DebuggerWindow) SetData(data string) { - self.win.Set("dataText", data) -} - -func (self *DebuggerWindow) SetAsm(data []byte) { - self.win.Root().Call("clearAsm") - - dis := core.Disassemble(data) - for _, str := range dis { - self.win.Root().Call("setAsm", str) - } -} - -func (self *DebuggerWindow) Compile(code string) { - var err error - script := ethutil.StringToByteFunc(code, func(s string) (ret []byte) { - ret, err = ethutil.Compile(s, true) - return - }) - - if err == nil { - self.SetAsm(script) - } -} - -// Used by QML -func (self *DebuggerWindow) AutoComp(code string) { - if self.Db.done { - self.Compile(code) - } -} - -func (self *DebuggerWindow) ClearLog() { - self.win.Root().Call("clearLog") -} - -func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, dataStr string) { - self.Stop() - - defer func() { - if r := recover(); r != nil { - self.Logf("compile FAULT: %v", r) - } - }() - - data := utils.FormatTransactionData(dataStr) - - var err error - script := ethutil.StringToByteFunc(scriptStr, func(s string) (ret []byte) { - ret, err = ethutil.Compile(s, false) - return - }) - - if err != nil { - self.Logln(err) - - return - } - - // TODO: improve this - allAccounts, _ := self.lib.eth.AccountManager().Accounts() - - var ( - gas = ethutil.Big(gasStr) - gasPrice = ethutil.Big(gasPriceStr) - value = ethutil.Big(valueStr) - acc = allAccounts[0] - ) - - statedb := self.lib.eth.ChainManager().TransState() - account := self.lib.eth.ChainManager().TransState().GetAccount(acc.Address) - contract := statedb.NewStateObject([]byte{0}) - contract.SetCode(script) - contract.SetBalance(value) - - self.SetAsm(script) - - block := self.lib.eth.ChainManager().CurrentBlock() - - msg := types.NewTransactionMessage(nil, value, gas, gasPrice, data) - env := core.NewEnv(statedb, self.lib.eth.ChainManager(), msg, block) - - self.Logf("callsize %d", len(script)) - go func() { - pgas := new(big.Int).Set(gas) - ret, err := env.Call(account, contract.Address(), data, gas, gasPrice, ethutil.Big0) - - rgas := new(big.Int).Sub(pgas, gas) - tot := new(big.Int).Mul(rgas, gasPrice) - self.Logf("gas usage %v total price = %v (%v)", rgas, tot, ethutil.CurrencyToString(tot)) - if err != nil { - self.Logln("exited with errors:", err) - } else { - if len(ret) > 0 { - self.Logf("exited: % x", ret) - } else { - self.Logf("exited: nil") - } - } - - statedb.Reset() - - if !self.Db.interrupt { - self.Db.done = true - } else { - self.Db.interrupt = false - } - }() -} - -func (self *DebuggerWindow) Logf(format string, v ...interface{}) { - self.win.Root().Call("setLog", fmt.Sprintf(format, v...)) -} - -func (self *DebuggerWindow) Logln(v ...interface{}) { - str := fmt.Sprintln(v...) - self.Logf("%s", str[:len(str)-1]) -} - -func (self *DebuggerWindow) Next() { - self.Db.Next() -} - -func (self *DebuggerWindow) Continue() { - self.vm.Stepping = false - self.Next() -} - -func (self *DebuggerWindow) Stop() { - if !self.Db.done { - self.Db.Q <- true - } -} - -func (self *DebuggerWindow) ExecCommand(command string) { - if len(command) > 0 { - cmd := strings.Split(command, " ") - switch cmd[0] { - case "help": - self.Logln("Debugger commands:") - self.Logln("break, bp Set breakpoint on instruction") - self.Logln("clear [log, break, bp] Clears previous set sub-command(s)") - case "break", "bp": - if len(cmd) > 1 { - lineNo, err := strconv.Atoi(cmd[1]) - if err != nil { - self.Logln(err) - break - } - self.Db.breakPoints = append(self.Db.breakPoints, int64(lineNo)) - self.Logf("break point set on instruction %d", lineNo) - } else { - self.Logf("'%s' requires line number", cmd[0]) - } - case "clear": - if len(cmd) > 1 { - switch cmd[1] { - case "break", "bp": - self.Db.breakPoints = nil - - self.Logln("Breakpoints cleared") - case "log": - self.ClearLog() - default: - self.Logf("clear '%s' is not valid", cmd[1]) - } - } else { - self.Logln("'clear' requires sub command") - } - - default: - self.Logf("Unknown command %s", cmd[0]) - } - } -} - -type Debugger struct { - N chan bool - Q chan bool - done, interrupt bool - breakPoints []int64 - main *DebuggerWindow - win *qml.Window -} - -func NewDebugger(main *DebuggerWindow) *Debugger { - db := &Debugger{make(chan bool), make(chan bool), true, false, nil, main, main.win} - - return db -} - -type storeVal struct { - Key, Value string -} - -func (self *Debugger) Step(evm vm.VirtualMachine, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, context *vm.Context) { -} - -func (self *Debugger) BreakHook(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, stateObject *state.StateObject) bool { - self.main.Logln("break on instr:", pc) - - return self.halting(pc, op, mem, stack, stateObject) -} - -func (self *Debugger) StepHook(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, stateObject *state.StateObject) bool { - return self.halting(pc, op, mem, stack, stateObject) -} - -func (self *Debugger) SetCode(byteCode []byte) { - self.main.SetAsm(byteCode) -} - -func (self *Debugger) BreakPoints() []int64 { - return self.breakPoints -} - -func (d *Debugger) halting(pc int, op vm.OpCode, mem *vm.Memory, stack *vm.Stack, stateObject *state.StateObject) bool { - d.win.Root().Call("setInstruction", pc) - d.win.Root().Call("clearMem") - d.win.Root().Call("clearStack") - d.win.Root().Call("clearStorage") - - addr := 0 - for i := 0; i+16 <= mem.Len(); i += 16 { - dat := mem.Data()[i : i+16] - var str string - - for _, d := range dat { - if unicode.IsGraphic(rune(d)) { - str += string(d) - } else { - str += "?" - } - } - - d.win.Root().Call("setMem", memAddr{fmt.Sprintf("%03d", addr), fmt.Sprintf("%s % x", str, dat)}) - addr += 16 - } - - for _, val := range stack.Data() { - d.win.Root().Call("setStack", val.String()) - } - - it := stateObject.Trie().Iterator() - for it.Next() { - d.win.Root().Call("setStorage", storeVal{fmt.Sprintf("% x", it.Key), fmt.Sprintf("% x", it.Value)}) - - } - - stackFrameAt := new(big.Int).SetBytes(mem.Get(0, 32)) - psize := mem.Len() - int(new(big.Int).SetBytes(mem.Get(0, 32)).Uint64()) - d.win.Root().ObjectByName("stackFrame").Set("text", fmt.Sprintf(`<b>stack ptr</b>: %v`, stackFrameAt)) - d.win.Root().ObjectByName("stackSize").Set("text", fmt.Sprintf(`<b>stack size</b>: %d`, psize)) - d.win.Root().ObjectByName("memSize").Set("text", fmt.Sprintf(`<b>mem size</b>: %v`, mem.Len())) - -out: - for { - select { - case <-d.N: - break out - case <-d.Q: - d.interrupt = true - d.clearBuffers() - - return false - } - } - - return true -} - -func (d *Debugger) clearBuffers() { -out: - // drain - for { - select { - case <-d.N: - case <-d.Q: - default: - break out - } - } -} - -func (d *Debugger) Next() { - if !d.done { - d.N <- true - } -} diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index 32e8ce5af..4198c6316 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -47,9 +47,7 @@ type UiLib struct { connected bool assetPath string // The main application window - win *qml.Window - Db *Debugger - DbWindow *DebuggerWindow + win *qml.Window jsEngine *javascript.JSRE @@ -126,29 +124,6 @@ func (ui *UiLib) AssetPath(p string) string { return path.Join(ui.assetPath, p) } -func (self *UiLib) StartDbWithContractAndData(contractHash, data string) { - dbWindow := NewDebuggerWindow(self) - object := self.eth.ChainManager().State().GetStateObject(ethutil.Hex2Bytes(contractHash)) - if len(object.Code()) > 0 { - dbWindow.SetCode(ethutil.Bytes2Hex(object.Code())) - } - dbWindow.SetData(data) - - dbWindow.Show() -} - -func (self *UiLib) StartDbWithCode(code string) { - dbWindow := NewDebuggerWindow(self) - dbWindow.SetCode(code) - dbWindow.Show() -} - -func (self *UiLib) StartDebugger() { - dbWindow := NewDebuggerWindow(self) - - dbWindow.Show() -} - func (self *UiLib) Transact(params map[string]interface{}) (string, error) { object := mapToTxParams(params) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index c5568948d..6b99b841f 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -33,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/state" ) var clilogger = logger.NewLogger("CLI") @@ -123,6 +122,15 @@ func StartEthereum(ethereum *eth.Ethereum) { }) } +func StartEthereumForTest(ethereum *eth.Ethereum) { + clilogger.Infoln("Starting ", ethereum.Name()) + ethereum.StartForTest() + RegisterInterrupt(func(sig os.Signal) { + ethereum.Stop() + logger.Flush() + }) +} + func FormatTransactionData(data string) []byte { d := ethutil.StringToByteFunc(data, func(s string) (ret []byte) { slice := regexp.MustCompile("\\n|\\s").Split(s, 1000000000) @@ -136,27 +144,8 @@ func FormatTransactionData(data string) []byte { return d } -// Replay block -func BlockDo(ethereum *eth.Ethereum, hash []byte) error { - block := ethereum.ChainManager().GetBlock(hash) - if block == nil { - return fmt.Errorf("unknown block %x", hash) - } - - parent := ethereum.ChainManager().GetBlock(block.ParentHash()) - - statedb := state.New(parent.Root(), ethereum.StateDb()) - _, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block, true) - if err != nil { - return err - } - - return nil - -} - -func ImportChain(chain *core.ChainManager, fn string) error { - fmt.Printf("importing chain '%s'\n", fn) +func ImportChain(chainmgr *core.ChainManager, fn string) error { + fmt.Printf("importing blockchain '%s'\n", fn) fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm) if err != nil { return err @@ -168,11 +157,24 @@ func ImportChain(chain *core.ChainManager, fn string) error { return err } - chain.Reset() - if err := chain.InsertChain(blocks); err != nil { + chainmgr.Reset() + if err := chainmgr.InsertChain(blocks); err != nil { return err } fmt.Printf("imported %d blocks\n", len(blocks)) return nil } + +func ExportChain(chainmgr *core.ChainManager, fn string) error { + fmt.Printf("exporting blockchain '%s'\n", fn) + + data := chainmgr.Export() + + if err := ethutil.WriteFile(fn, data); err != nil { + return err + } + fmt.Printf("exported blockchain\n") + + return nil +} |