mirror of
https://github.com/monero-project/monero-gui.git
synced 2025-01-03 17:39:54 +00:00
p2pool: Detailed statistics
This commit is contained in:
parent
bea3032df9
commit
7d0e9d137d
6 changed files with 260 additions and 0 deletions
|
@ -78,6 +78,7 @@ ColumnLayout {
|
||||||
property Item currentView
|
property Item currentView
|
||||||
property Item previousView
|
property Item previousView
|
||||||
property Mining miningView: Mining { }
|
property Mining miningView: Mining { }
|
||||||
|
property MiningStats miningStatsView: MiningStats { }
|
||||||
property TxKey prooveView: TxKey { }
|
property TxKey prooveView: TxKey { }
|
||||||
property SharedRingDB sharedRingDBView: SharedRingDB { }
|
property SharedRingDB sharedRingDBView: SharedRingDB { }
|
||||||
property Sign signView: Sign { }
|
property Sign signView: Sign { }
|
||||||
|
@ -106,6 +107,10 @@ ColumnLayout {
|
||||||
name: "Mining"
|
name: "Mining"
|
||||||
PropertyChanges { target: stateView; currentView: stateView.miningView }
|
PropertyChanges { target: stateView; currentView: stateView.miningView }
|
||||||
PropertyChanges { target: root; panelHeight: stateView.miningView.miningHeight + 140 }
|
PropertyChanges { target: root; panelHeight: stateView.miningView.miningHeight + 140 }
|
||||||
|
}, State {
|
||||||
|
name: "MiningStats"
|
||||||
|
PropertyChanges { target: stateView; currentView: stateView.miningStatsView }
|
||||||
|
PropertyChanges { target: root; panelHeight: stateView.miningStatsView.miningStatsHeight + 140 }
|
||||||
}, State {
|
}, State {
|
||||||
name: "Prove"
|
name: "Prove"
|
||||||
PropertyChanges { target: stateView; currentView: stateView.prooveView }
|
PropertyChanges { target: stateView; currentView: stateView.prooveView }
|
||||||
|
|
|
@ -379,6 +379,37 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment : Qt.AlignTop | Qt.AlignLeft
|
||||||
|
|
||||||
|
MoneroComponents.Label {
|
||||||
|
id: statisticsLabel
|
||||||
|
visible: persistentSettings.allow_p2pool_mining
|
||||||
|
color: MoneroComponents.Style.defaultFontColor
|
||||||
|
text: qsTr("Statistics") + translationManager.emptyString
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
spacing: 16
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: miningStatsButton
|
||||||
|
small: true
|
||||||
|
primary: false
|
||||||
|
text: qsTr("Open mining statistics") + translationManager.emptyString
|
||||||
|
enabled: appWindow.isMining
|
||||||
|
visible: persistentSettings.allow_p2pool_mining
|
||||||
|
onClicked: {
|
||||||
|
p2poolManager.getStats();
|
||||||
|
stateView.state = "MiningStats";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
id: chainModel
|
id: chainModel
|
||||||
|
|
||||||
|
|
203
pages/MiningStats.qml
Normal file
203
pages/MiningStats.qml
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
// Copyright (c) 2014-2019, The Monero Project
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
// permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
// conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
// of conditions and the following disclaimer in the documentation and/or other
|
||||||
|
// materials provided with the distribution.
|
||||||
|
//
|
||||||
|
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||||
|
// used to endorse or promote products derived from this software without specific
|
||||||
|
// prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||||
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||||
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
import QtQml.Models 2.2
|
||||||
|
import QtQuick 2.9
|
||||||
|
import QtQuick.Layouts 1.1
|
||||||
|
import "../components" as MoneroComponents
|
||||||
|
import moneroComponents.P2PoolManager 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
color: "transparent"
|
||||||
|
property alias miningStatsHeight: miningStatsContentColumn.height
|
||||||
|
property int entryHeight: 24
|
||||||
|
property int entryPixelSize: 14
|
||||||
|
property bool showFullStats: false
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: timer
|
||||||
|
interval: 5000
|
||||||
|
running: stateView.state === "MiningStats";
|
||||||
|
repeat: true
|
||||||
|
onTriggered: update()
|
||||||
|
}
|
||||||
|
|
||||||
|
function update()
|
||||||
|
{
|
||||||
|
if (persistentSettings.allow_p2pool_mining) {
|
||||||
|
p2poolManager.getStats();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function recursivelyFindPairs(statsMap, depth)
|
||||||
|
{
|
||||||
|
for (var key in statsMap)
|
||||||
|
{
|
||||||
|
var value = statsMap[key];
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
miningStatsModel.append({"key": key + ":", "value": "", "depth": depth});
|
||||||
|
recursivelyFindPairs(value, depth + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
miningStatsModel.append({"key": key + ":", "value": value.toString(), "depth": depth});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSimpleMiningStats(statsMap)
|
||||||
|
{
|
||||||
|
var pool_statistics = statsMap["pool_statistics"];
|
||||||
|
|
||||||
|
if (pool_statistics != null)
|
||||||
|
{
|
||||||
|
var statsData = [
|
||||||
|
{"key": "Your hashrate:", "value": statsMap["current_hashrate"] + " H/s"},
|
||||||
|
|
||||||
|
{"key": "Main chain height:", "value": statsMap["height"]},
|
||||||
|
{"key": "Side chain height:", "value": pool_statistics["sidechainHeight"]},
|
||||||
|
{"key": "PPLNS window:", "value": pool_statistics["pplnsWindowSize"] + " blocks"},
|
||||||
|
{"key": "Your shares:", "value": statsMap["shares_found"] + " blocks"},
|
||||||
|
{"key": "Block reward share:", "value": statsMap["block_reward_share_percent"] + "%"},
|
||||||
|
|
||||||
|
{"key": "Connections: ", "value": statsMap["connections"] + " (" + statsMap["incoming_connections"] + " incoming)"},
|
||||||
|
{"key": "Peer list size: ", "value": statsMap["peer_list_size"]},
|
||||||
|
{"key": "Uptime: ", "value": statsMap["uptime"] + "s"}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var element of statsData)
|
||||||
|
{
|
||||||
|
if (element.value != null)
|
||||||
|
{
|
||||||
|
simpleMiningStatsModel.append({"key": element["key"], "value": element["value"].toString(), "depth": 0});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMiningStats(statsMap)
|
||||||
|
{
|
||||||
|
simpleMiningStatsModel.clear();
|
||||||
|
updateSimpleMiningStats(statsMap);
|
||||||
|
|
||||||
|
miningStatsModel.clear();
|
||||||
|
recursivelyFindPairs(statsMap, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel { id: simpleMiningStatsModel }
|
||||||
|
ListModel { id: miningStatsModel }
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: miningStatsContentColumn
|
||||||
|
spacing: entryHeight
|
||||||
|
|
||||||
|
MoneroComponents.StandardButton {
|
||||||
|
id: backButton
|
||||||
|
text: qsTr("Back") + translationManager.emptyString;
|
||||||
|
width: 100
|
||||||
|
primary: false
|
||||||
|
onClicked: {
|
||||||
|
stateView.state = "Mining";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: simpleMiningStatsView
|
||||||
|
width: root.width
|
||||||
|
height: count * entryHeight + entryHeight
|
||||||
|
model: simpleMiningStatsModel
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: miningStatsDelegate
|
||||||
|
color: "transparent"
|
||||||
|
height: entryHeight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: depth * entryPixelSize
|
||||||
|
font.pixelSize: entryPixelSize
|
||||||
|
text: key + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
font.pixelSize: entryPixelSize
|
||||||
|
text: value + translationManager.emptyString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.CheckBox2 {
|
||||||
|
id: showFullStatsCheckbox
|
||||||
|
checked: showFullStats
|
||||||
|
onClicked: showFullStats = !showFullStats
|
||||||
|
text: qsTr("Show full statistics") + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
visible: showFullStats
|
||||||
|
id: miningStatsView
|
||||||
|
width: root.width
|
||||||
|
height: count * entryHeight + entryHeight
|
||||||
|
model: miningStatsModel
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
delegate: Rectangle {
|
||||||
|
id: miningStatsDelegate
|
||||||
|
color: "transparent"
|
||||||
|
height: entryHeight
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: depth * entryPixelSize
|
||||||
|
font.pixelSize: entryPixelSize
|
||||||
|
text: key + translationManager.emptyString
|
||||||
|
}
|
||||||
|
|
||||||
|
MoneroComponents.TextBlock {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
color: MoneroComponents.Style.dimmedFontColor
|
||||||
|
font.pixelSize: entryPixelSize
|
||||||
|
text: value + translationManager.emptyString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
p2poolManager.p2poolStats.connect(updateMiningStats);
|
||||||
|
}
|
||||||
|
}
|
1
qml.qrc
1
qml.qrc
|
@ -26,6 +26,7 @@
|
||||||
<file>pages/History.qml</file>
|
<file>pages/History.qml</file>
|
||||||
<file>pages/AddressBook.qml</file>
|
<file>pages/AddressBook.qml</file>
|
||||||
<file>pages/Mining.qml</file>
|
<file>pages/Mining.qml</file>
|
||||||
|
<file>pages/MiningStats.qml</file>
|
||||||
<file>components/ContextMenu.qml</file>
|
<file>components/ContextMenu.qml</file>
|
||||||
<file>components/ContextMenuItem.qml</file>
|
<file>components/ContextMenuItem.qml</file>
|
||||||
<file>components/NetworkStatusItem.qml</file>
|
<file>components/NetworkStatusItem.qml</file>
|
||||||
|
|
|
@ -151,6 +151,24 @@ void P2PoolManager::getStatus() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void P2PoolManager::getStats()
|
||||||
|
{
|
||||||
|
QVariantMap statsMap;
|
||||||
|
QString statsPath = m_p2poolPath + "/stats";
|
||||||
|
QDirIterator it(statsPath, QDir::Filter::Files, QDirIterator::Subdirectories);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
QFile statsFile(it.next());
|
||||||
|
statsFile.open(QIODevice::ReadOnly);
|
||||||
|
QTextStream statsOut(&statsFile);
|
||||||
|
QByteArray data;
|
||||||
|
statsOut >> data;
|
||||||
|
statsFile.close();
|
||||||
|
QVariantMap jsonMap = QJsonDocument::fromJson(data).object().toVariantMap();
|
||||||
|
statsMap.insert(jsonMap);
|
||||||
|
}
|
||||||
|
emit p2poolStats(statsMap);
|
||||||
|
}
|
||||||
|
|
||||||
bool P2PoolManager::start(const QString &flags, const QString &address, const QString &chain, const QString &threads)
|
bool P2PoolManager::start(const QString &flags, const QString &address, const QString &chain, const QString &threads)
|
||||||
{
|
{
|
||||||
// prepare command line arguments and pass to p2pool
|
// prepare command line arguments and pass to p2pool
|
||||||
|
|
|
@ -50,6 +50,7 @@ public:
|
||||||
Q_INVOKABLE void exit();
|
Q_INVOKABLE void exit();
|
||||||
Q_INVOKABLE bool isInstalled();
|
Q_INVOKABLE bool isInstalled();
|
||||||
Q_INVOKABLE void getStatus();
|
Q_INVOKABLE void getStatus();
|
||||||
|
Q_INVOKABLE void getStats();
|
||||||
Q_INVOKABLE void download();
|
Q_INVOKABLE void download();
|
||||||
|
|
||||||
enum DownloadError {
|
enum DownloadError {
|
||||||
|
@ -68,6 +69,7 @@ signals:
|
||||||
void p2poolStatus(bool isMining, int hashrate) const;
|
void p2poolStatus(bool isMining, int hashrate) const;
|
||||||
void p2poolDownloadFailure(int errorCode) const;
|
void p2poolDownloadFailure(int errorCode) const;
|
||||||
void p2poolDownloadSuccess() const;
|
void p2poolDownloadSuccess() const;
|
||||||
|
void p2poolStats(QVariantMap statsMap) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<QProcess> m_p2poold;
|
std::unique_ptr<QProcess> m_p2poold;
|
||||||
|
|
Loading…
Reference in a new issue