State dumps from gui

This commit is contained in:
obscuren 2014-08-17 12:41:23 +02:00
parent 2eab964a00
commit 27735bbdfc
10 changed files with 158 additions and 26 deletions

@ -6,7 +6,8 @@ window.eth = {
test: function() { test: function() {
var t = undefined; var t = undefined;
navigator.qt.onmessage = function(d) { t = d; } postData({call: "test"})
navigator.qt.onmessage = function(d) {console.log("onmessage called"); t = d; }
for(;;) { for(;;) {
if(t !== undefined) { if(t !== undefined) {
return t return t
@ -14,7 +15,8 @@ window.eth = {
} }
}, },
mutan: function(code) { mutan: function(code, cb) {
postData({call: "mutan", args: [code]}, cb)
}, },
toHex: function(str) { toHex: function(str) {
@ -281,3 +283,13 @@ navigator.qt.onmessage = function(ev) {
} }
} }
} }
eth.on("chain:changed", function() {
})
eth.on("messages", { /* filters */}, function(messages){
})
eth.on("pending:changed", function() {
})

@ -32,6 +32,10 @@ function test() {
eth.getBlock("f70097659f329a09642a27f11338d9269de64f1d4485786e36bfc410832148cd", function(block) { eth.getBlock("f70097659f329a09642a27f11338d9269de64f1d4485786e36bfc410832148cd", function(block) {
console.log(block) console.log(block)
}) })
eth.mutan("var a = 10", function(code) {
console.log("code", code)
});
} }
</script> </script>

@ -25,9 +25,57 @@ Rectangle {
model: blockModel model: blockModel
onDoubleClicked: { itemDelegate: Item {
Text {
anchors {
left: parent.left
right: parent.right
leftMargin: 10
verticalCenter: parent.verticalCenter
}
color: styleData.textColor
elide: styleData.elideMode
text: styleData.value
font.pixelSize: 11
MouseArea {
acceptedButtons: Qt.RightButton
propagateComposedEvents: true
anchors.fill: parent
onClicked: {
blockTable.selection.clear()
blockTable.selection.select(styleData.row)
contextMenu.row = styleData.row;
contextMenu.popup()
}
}
}
}
Menu {
id: contextMenu
property var row;
MenuItem {
text: "Details"
onTriggered: {
popup.visible = true popup.visible = true
popup.setDetails(blockModel.get(row)) popup.setDetails(blockModel.get(this.row))
}
}
MenuSeparator{}
MenuItem {
text: "Dump State"
onTriggered: {
generalFileDialog.show(false, function(path) {
var hash = blockModel.get(this.row).hash;
gui.dumpState(hash, path);
});
}
}
} }
} }

@ -49,8 +49,7 @@ ApplicationWindow {
text: "Import App" text: "Import App"
shortcut: "Ctrl+o" shortcut: "Ctrl+o"
onTriggered: { onTriggered: {
generalFileDialog.callback = importApp; generalFileDialog.show(true, importApp)
generalFileDialog.open()
} }
} }
@ -62,10 +61,9 @@ ApplicationWindow {
MenuItem { MenuItem {
text: "Add plugin" text: "Add plugin"
onTriggered: { onTriggered: {
generalFileDialog.callback = function(path) { generalFileDialog.show(true, function(path) {
addPlugin(path, {canClose: true}) addPlugin(path, {canClose: true})
} })
generalFileDialog.open()
} }
} }
@ -75,10 +73,9 @@ ApplicationWindow {
text: "Import key" text: "Import key"
shortcut: "Ctrl+i" shortcut: "Ctrl+i"
onTriggered: { onTriggered: {
generalFileDialog.callback = function(path) { generalFileDialog.show(true, function(path) {
ui.importKey(path) gui.importKey(path)
} })
generalFileDialog.open()
} }
} }
@ -86,9 +83,8 @@ ApplicationWindow {
text: "Export keys" text: "Export keys"
shortcut: "Ctrl+e" shortcut: "Ctrl+e"
onTriggered: { onTriggered: {
generalFileDialog.callback = function(path) { generalFileDialog.show(false, function(path) {
} })
generalFileDialog.open()
} }
} }
} }
@ -111,10 +107,19 @@ ApplicationWindow {
MenuItem { MenuItem {
text: "Run JS file" text: "Run JS file"
onTriggered: { onTriggered: {
generalFileDialog.callback = function(path) { generalFileDialog.show(true, function(path) {
eth.evalJavascriptFile(path) eth.evalJavascriptFile(path)
})
} }
generalFileDialog.open() }
MenuItem {
text: "Dump state"
onTriggered: {
generalFileDialog.show(false, function(path) {
// Empty hash for latest
gui.dumpState("", path)
})
} }
} }
} }
@ -396,8 +401,15 @@ ApplicationWindow {
id: generalFileDialog id: generalFileDialog
property var callback; property var callback;
onAccepted: { onAccepted: {
var path = this.fileUrl.toString() var path = this.fileUrl.toString();
callback.call(this, path) callback.call(this, path);
}
function show(selectExisting, callback) {
generalFileDialog.callback = callback;
generalFileDialog.selectExisting = selectExisting;
this.open();
} }
} }

@ -78,6 +78,7 @@ ApplicationWindow {
} }
} }
WebView { WebView {
objectName: "webView" objectName: "webView"
id: webview id: webview
@ -127,6 +128,8 @@ ApplicationWindow {
this.cleanPath = false; this.cleanPath = false;
} }
} }
experimental.preferences.javascriptEnabled: true experimental.preferences.javascriptEnabled: true
experimental.preferences.navigatorQtObjectEnabled: true experimental.preferences.navigatorQtObjectEnabled: true
experimental.preferences.developerExtrasEnabled: true experimental.preferences.developerExtrasEnabled: true
@ -251,8 +254,12 @@ ApplicationWindow {
break break
case "debug": case "mutan":
console.log(data.args[0]); require(1)
var code = eth.compileMutan(data.args[0])
postData(data._seed, "0x"+code)
break; break;
} }
} catch(e) { } catch(e) {
@ -262,6 +269,11 @@ ApplicationWindow {
} }
} }
function post(seed, data) {
console.log("data", data)
postData(data._seed, data)
}
function require(args, num) { function require(args, num) {
if(args.length < num) { if(args.length < num) {
throw("required argument count of "+num+" got "+args.length); throw("required argument count of "+num+" got "+args.length);

@ -21,6 +21,7 @@ type AppContainer interface {
NewBlock(*ethchain.Block) NewBlock(*ethchain.Block)
NewWatcher(chan bool) NewWatcher(chan bool)
Messages(ethstate.Messages, string) Messages(ethstate.Messages, string)
Post(string, int)
} }
type ExtApplication struct { type ExtApplication struct {

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"math/big" "math/big"
"os"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -155,6 +156,40 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
return gui.win, nil return gui.win, nil
} }
func (self *Gui) DumpState(hash, path string) {
var stateDump []byte
if len(hash) == 0 {
stateDump = self.eth.StateManager().CurrentState().Dump()
} else {
var block *ethchain.Block
if hash[0] == '#' {
i, _ := strconv.Atoi(hash[1:])
block = self.eth.BlockChain().GetBlockByNumber(uint64(i))
} else {
block = self.eth.BlockChain().GetBlock(ethutil.Hex2Bytes(hash))
}
if block == nil {
logger.Infof("block err: not found %s\n", hash)
return
}
stateDump = block.State().Dump()
}
file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm)
if err != nil {
logger.Infoln("dump err: ", err)
return
}
defer file.Close()
logger.Infof("dumped state (%s) to %s\n", hash, path)
file.Write(stateDump)
}
// The done handler will be called by QML when all views have been loaded // The done handler will be called by QML when all views have been loaded
func (gui *Gui) Done() { func (gui *Gui) Done() {
gui.qmlDone = true gui.qmlDone = true

@ -3,6 +3,7 @@ package main
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"net/url" "net/url"
"os" "os"
@ -139,3 +140,8 @@ func (self *HtmlApplication) Messages(messages ethstate.Messages, id string) {
func (app *HtmlApplication) Destroy() { func (app *HtmlApplication) Destroy() {
app.engine.Destroy() app.engine.Destroy()
} }
func (app *HtmlApplication) Post(data string, seed int) {
fmt.Println("about to call 'post'")
app.webView.Call("post", seed, data)
}

@ -64,3 +64,5 @@ func (app *QmlApplication) Engine() *qml.Engine {
func (app *QmlApplication) Window() *qml.Window { func (app *QmlApplication) Window() *qml.Window {
return app.win return app.win
} }
func (app *QmlApplication) Post(data string, s int) {}

@ -71,7 +71,7 @@ func main() {
} }
// Leave the Println. This needs clean output for piping // Leave the Println. This needs clean output for piping
fmt.Println(block.State().Dump()) fmt.Printf("%s\n", block.State().Dump())
os.Exit(0) os.Exit(0)
} }