aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/mist
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-11-07 19:18:48 +0800
committerobscuren <geffobscura@gmail.com>2014-11-07 19:18:48 +0800
commit429dd2a100f3b9e2b612b59bcb48f79a805cd6f9 (patch)
treec91fee673e461a192d4d783193c8ddbead4a97d2 /cmd/mist
parent48488017e498916c81122c01cfe1880afdd00d48 (diff)
downloadgo-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.pngbin0 -> 2100 bytes
-rw-r--r--cmd/mist/assets/qml/main.qml42
-rw-r--r--cmd/mist/assets/qml/views/miner.qml254
-rw-r--r--cmd/mist/bindings.go21
-rw-r--r--cmd/mist/gui.go51
-rw-r--r--cmd/mist/ui_lib.go38
6 files changed, 342 insertions, 64 deletions
diff --git a/cmd/mist/assets/miner.png b/cmd/mist/assets/miner.png
new file mode 100644
index 000000000..58e3f4dfe
--- /dev/null
+++ b/cmd/mist/assets/miner.png
Binary files differ
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
+ }
+}