diff options
author | obscuren <geffobscura@gmail.com> | 2014-11-07 19:18:48 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-11-07 19:18:48 +0800 |
commit | 429dd2a100f3b9e2b612b59bcb48f79a805cd6f9 (patch) | |
tree | c91fee673e461a192d4d783193c8ddbead4a97d2 /cmd/mist | |
parent | 48488017e498916c81122c01cfe1880afdd00d48 (diff) | |
download | go-tangerine-429dd2a100f3b9e2b612b59bcb48f79a805cd6f9.tar.gz go-tangerine-429dd2a100f3b9e2b612b59bcb48f79a805cd6f9.tar.zst go-tangerine-429dd2a100f3b9e2b612b59bcb48f79a805cd6f9.zip |
Implemented new miner w/ ui interface for merged mining. Closes #177
* Miner has been rewritten
* Added new miner pane
* Added option for local txs
* Added option to read from MergeMining contract and list them for
merged mining
Diffstat (limited to 'cmd/mist')
-rw-r--r-- | cmd/mist/assets/miner.png | bin | 0 -> 2100 bytes | |||
-rw-r--r-- | cmd/mist/assets/qml/main.qml | 42 | ||||
-rw-r--r-- | cmd/mist/assets/qml/views/miner.qml | 254 | ||||
-rw-r--r-- | cmd/mist/bindings.go | 21 | ||||
-rw-r--r-- | cmd/mist/gui.go | 51 | ||||
-rw-r--r-- | cmd/mist/ui_lib.go | 38 |
6 files changed, 342 insertions, 64 deletions
diff --git a/cmd/mist/assets/miner.png b/cmd/mist/assets/miner.png Binary files differnew file mode 100644 index 000000000..58e3f4dfe --- /dev/null +++ b/cmd/mist/assets/miner.png diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index cfd227b49..d2a8d1d63 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -12,7 +12,6 @@ import "../ext/http.js" as Http ApplicationWindow { id: root - property alias miningButtonText: miningButton.text property var ethx : Eth.ethx property var browser @@ -47,6 +46,7 @@ ApplicationWindow { Component.onCompleted: { var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true}); var browser = addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true}); + var browser = addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true}); root.browser = browser; addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); @@ -252,29 +252,18 @@ ApplicationWindow { } statusBar: StatusBar { - height: 32 + //height: 32 id: statusBar - RowLayout { - Button { - id: miningButton - text: "Start Mining" - onClicked: { - gui.toggleMining() - } - } - - RowLayout { - Label { - id: walletValueLabel + Label { + //y: 6 + id: walletValueLabel - font.pixelSize: 10 - styleColor: "#797979" - } - } + font.pixelSize: 10 + styleColor: "#797979" } Label { - y: 6 + //y: 6 objectName: "miningLabel" visible: true font.pixelSize: 10 @@ -283,7 +272,7 @@ ApplicationWindow { } Label { - y: 6 + //y: 6 id: lastBlockLabel objectName: "lastBlockLabel" visible: true @@ -297,14 +286,14 @@ ApplicationWindow { id: downloadIndicator value: 0 objectName: "downloadIndicator" - y: 3 + y: -4 x: statusBar.width / 2 - this.width / 2 width: 160 } Label { objectName: "downloadLabel" - y: 7 + //y: 7 anchors.left: downloadIndicator.right anchors.leftMargin: 5 font.pixelSize: 10 @@ -314,7 +303,7 @@ ApplicationWindow { RowLayout { id: peerGroup - y: 7 + //y: 7 anchors.right: parent.right MouseArea { onDoubleClicked: peerWindow.visible = true @@ -323,14 +312,9 @@ ApplicationWindow { Label { id: peerLabel - font.pixelSize: 8 + font.pixelSize: 10 text: "0 / 0" } - Image { - id: peerImage - width: 10; height: 10 - source: "../network.png" - } } } diff --git a/cmd/mist/assets/qml/views/miner.qml b/cmd/mist/assets/qml/views/miner.qml new file mode 100644 index 000000000..e162d60a4 --- /dev/null +++ b/cmd/mist/assets/qml/views/miner.qml @@ -0,0 +1,254 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; +import QtQuick.Dialogs 1.0; +import QtQuick.Window 2.1; +import QtQuick.Controls.Styles 1.1 +import Ethereum 1.0 + +Rectangle { + id: root + property var title: "Miner" + property var iconSource: "../miner.png" + property var menuItem + + color: "#00000000" + + ColumnLayout { + spacing: 10 + anchors.fill: parent + + Rectangle { + id: mainPane + color: "#00000000" + anchors { + top: parent.top + bottom: localTxPane.top + left: parent.left + right: parent.right + } + + Rectangle { + id: menu + height: 25 + anchors { + left: parent.left + } + + RowLayout { + id: tools + anchors { + left: parent.left + right: parent.right + } + + Button { + text: "Start" + onClicked: { + eth.setGasPrice(minGasPrice.text || "10000000000000"); + if (eth.toggleMining()) { + this.text = "Stop"; + } else { + this.text = "Start"; + } + } + } + + Rectangle { + anchors.top: parent.top + anchors.topMargin: 2 + width: 200 + TextField { + id: minGasPrice + placeholderText: "Min Gas: 10000000000000" + width: 200 + validator: RegExpValidator { regExp: /\d*/ } + } + } + } + } + + Column { + anchors { + left: parent.left + right: parent.right + top: menu.bottom + topMargin: 5 + } + + Text { + text: "<b>Merged mining options</b>" + } + + TableView { + id: mergedMiningTable + height: 300 + anchors { + left: parent.left + right: parent.right + } + Component { + id: checkBoxDelegate + + Item { + id: test + CheckBox { + anchors.fill: parent + checked: styleData.value + + onClicked: { + var model = mergedMiningModel.get(styleData.row) + + if (this.checked) { + model.id = txModel.createLocalTx(model.address, "0", "5000", "0", "") + } else { + txModel.removeWithId(model.id); + model.id = 0; + } + } + } + } + } + TableViewColumn{ role: "checked" ; title: "" ; width: 40 ; delegate: checkBoxDelegate } + TableViewColumn{ role: "name" ; title: "Name" ; width: 480 } + model: ListModel { + objectName: "mergedMiningModel" + id: mergedMiningModel + function addMergedMiningOption(model) { + this.append(model); + } + } + Component.onCompleted: { + /* interface test stuff + // XXX Temp. replace with above eventually + var tmpItems = ["JEVCoin", "Some coin", "Other coin", "Etc coin"]; + var address = "e6716f9544a56c530d868e4bfbacb172315bdead"; + for (var i = 0; i < tmpItems.length; i++) { + mergedMiningModel.append({checked: false, name: tmpItems[i], address: address, id: 0, itemId: i}); + } + */ + } + } + } + } + + Rectangle { + id: localTxPane + color: "#ececec" + border.color: "#cccccc" + border.width: 1 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: 300 + + ColumnLayout { + spacing: 10 + anchors.fill: parent + RowLayout { + id: newLocalTx + anchors { + left: parent.left + leftMargin: 5 + top: parent.top + topMargin: 5 + bottomMargin: 5 + } + + Text { + text: "Local tx" + } + + Rectangle { + width: 250 + color: "#00000000" + anchors.top: parent.top + anchors.topMargin: 2 + + TextField { + id: to + placeholderText: "To" + width: 250 + validator: RegExpValidator { regExp: /[abcdefABCDEF1234567890]*/ } + } + } + TextField { + property var defaultGas: "5000" + id: gas + placeholderText: "Gas" + text: defaultGas + validator: RegExpValidator { regExp: /\d*/ } + } + TextField { + id: gasPrice + placeholderText: "Price" + validator: RegExpValidator { regExp: /\d*/ } + } + TextField { + id: value + placeholderText: "Amount" + text: "0" + validator: RegExpValidator { regExp: /\d*/ } + } + TextField { + id: data + placeholderText: "Data" + validator: RegExpValidator { regExp: /[abcdefABCDEF1234567890]*/ } + } + Button { + text: "Create" + onClicked: { + if (to.text.length == 40 && gasPrice.text.length != 0 && value.text.length != 0 && gas.text.length != 0) { + txModel.createLocalTx(to.text, gasPrice.text, gas.text, value.text, data.text); + + to.text = ""; gasPrice.text = ""; + gas.text = gas.defaultGas; + value.text = "0" + } + } + } + } + + TableView { + id: txTableView + anchors { + top: newLocalTx.bottom + topMargin: 5 + left: parent.left + right: parent.right + bottom: parent.bottom + } + TableViewColumn{ role: "to" ; title: "To" ; width: 480 } + TableViewColumn{ role: "gas" ; title: "Gas" ; width: 100 } + TableViewColumn{ role: "gasPrice" ; title: "Gas Price" ; width: 100 } + TableViewColumn{ role: "value" ; title: "Amount" ; width: 100 } + TableViewColumn{ role: "data" ; title: "Data" ; width: 100 } + + model: ListModel { + id: txModel + Component.onCompleted: { + } + function removeWithId(id) { + for (var i = 0; i < this.count; i++) { + if (txModel.get(i).id == id) { + this.remove(i); + eth.removeLocalTransaction(id) + break; + } + } + } + + function createLocalTx(to, gasPrice, gas, value, data) { + var id = eth.addLocalTransaction(to, data, gas, gasPrice, value) + txModel.insert(0, {to: to, gas: gas, gasPrice: gasPrice, value: value, data: data, id: id}); + + return id + } + } + } + } + } + } +} diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go index ebdd8ec73..480c38b2e 100644 --- a/cmd/mist/bindings.go +++ b/cmd/mist/bindings.go @@ -70,10 +70,6 @@ func (gui *Gui) GetCustomIdentifier() string { return gui.clientIdentity.GetCustomIdentifier() } -func (gui *Gui) ToggleTurboMining() { - gui.miner.ToggleTurbo() -} - // functions that allow Gui to implement interface guilogger.LogSystem func (gui *Gui) SetLogLevel(level logger.LogLevel) { gui.logLevel = level @@ -137,20 +133,3 @@ func (self *Gui) DumpState(hash, path string) { file.Write(stateDump) } -func (gui *Gui) ToggleMining() { - var txt string - if gui.eth.Mining { - utils.StopMining(gui.eth) - txt = "Start mining" - - gui.getObjectByName("miningLabel").Set("visible", false) - } else { - utils.StartMining(gui.eth) - gui.miner = utils.GetMiner() - txt = "Stop mining" - - gui.getObjectByName("miningLabel").Set("visible", true) - } - - gui.win.Root().Set("miningButtonText", txt) -} diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 5af1b5c7b..295011244 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -272,8 +272,6 @@ type address struct { func (gui *Gui) loadAddressBook() { view := gui.getObjectByName("infoView") - view.Call("clearAddress") - nameReg := gui.pipe.World().Config().Get("NameReg") if nameReg != nil { nameReg.EachStorage(func(name string, value *ethutil.Value) { @@ -286,6 +284,28 @@ func (gui *Gui) loadAddressBook() { } } +func (self *Gui) loadMergedMiningOptions() { + view := self.getObjectByName("mergedMiningModel") + + nameReg := self.pipe.World().Config().Get("MergeMining") + if nameReg != nil { + i := 0 + nameReg.EachStorage(func(name string, value *ethutil.Value) { + if name[0] != 0 { + value.Decode() + + view.Call("addMergedMiningOption", struct { + Checked bool + Name, Address string + Id, ItemId int + }{false, name, ethutil.Bytes2Hex(value.Bytes()), 0, i}) + + i++ + } + }) + } +} + func (gui *Gui) insertTransaction(window string, tx *chain.Transaction) { pipe := xeth.New(gui.eth) nameReg := pipe.World().Config().Get("NameReg") @@ -382,6 +402,7 @@ func (gui *Gui) update() { go func() { go gui.setInitialChainManager() gui.loadAddressBook() + gui.loadMergedMiningOptions() gui.setPeerInfo() gui.readPreviousTransactions() }() @@ -410,7 +431,6 @@ func (gui *Gui) update() { chain.NewBlockEvent{}, chain.TxPreEvent{}, chain.TxPostEvent{}, - miner.Event{}, ) // nameReg := gui.pipe.World().Config().Get("NameReg") @@ -469,12 +489,14 @@ func (gui *Gui) update() { case eth.PeerListEvent: gui.setPeerInfo() - case miner.Event: - if ev.Type == miner.Started { - gui.miner = ev.Miner - } else { - gui.miner = nil - } + /* + case miner.Event: + if ev.Type == miner.Started { + gui.miner = ev.Miner + } else { + gui.miner = nil + } + */ } case <-peerUpdateTicker.C: @@ -483,10 +505,13 @@ func (gui *Gui) update() { statusText := "#" + gui.eth.ChainManager().CurrentBlock.Number.String() lastBlockLabel.Set("text", statusText) - if gui.miner != nil { - pow := gui.miner.GetPow() - miningLabel.Set("text", "Mining @ "+strconv.FormatInt(pow.GetHashrate(), 10)+"Khash") - } + miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash") + /* + if gui.miner != nil { + pow := gui.miner.GetPow() + miningLabel.Set("text", "Mining @ "+strconv.FormatInt(pow.GetHashrate(), 10)+"Khash") + } + */ blockLength := gui.eth.BlockPool().BlocksProcessed chainLength := gui.eth.BlockPool().ChainLength diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index bb978707d..bdf551325 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/javascript" + "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/state" "github.com/ethereum/go-ethereum/ui/qt" "github.com/ethereum/go-ethereum/xeth" @@ -55,10 +56,15 @@ type UiLib struct { jsEngine *javascript.JSRE filterCallbacks map[int][]int + + miner *miner.Miner } func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { - return &UiLib{JSXEth: xeth.NewJSXEth(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)} + lib := &UiLib{JSXEth: xeth.NewJSXEth(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)} + lib.miner = miner.New(eth.KeyManager().Address(), eth) + + return lib } func (self *UiLib) Notef(args []interface{}) { @@ -328,3 +334,33 @@ func (self *UiLib) Call(params map[string]interface{}) (string, error) { object["data"], ) } + +func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int { + return self.miner.AddLocalTx(&miner.LocalTx{ + To: ethutil.Hex2Bytes(to), + Data: ethutil.Hex2Bytes(data), + Gas: gas, + GasPrice: gasPrice, + Value: value, + }) - 1 +} + +func (self *UiLib) RemoveLocalTransaction(id int) { + self.miner.RemoveLocalTx(id) +} + +func (self *UiLib) SetGasPrice(price string) { + self.miner.MinAcceptedGasPrice = ethutil.Big(price) +} + +func (self *UiLib) ToggleMining() bool { + if !self.miner.Mining() { + self.miner.Start() + + return true + } else { + self.miner.Stop() + + return false + } +} |