p2pool: Detailed statistics

This commit is contained in:
devhyper 2023-10-02 20:50:36 -07:00
parent bea3032df9
commit 7d0e9d137d
No known key found for this signature in database
GPG key ID: D5F749908AE9DA70
6 changed files with 260 additions and 0 deletions

View file

@ -78,6 +78,7 @@ ColumnLayout {
property Item currentView
property Item previousView
property Mining miningView: Mining { }
property MiningStats miningStatsView: MiningStats { }
property TxKey prooveView: TxKey { }
property SharedRingDB sharedRingDBView: SharedRingDB { }
property Sign signView: Sign { }
@ -106,6 +107,10 @@ ColumnLayout {
name: "Mining"
PropertyChanges { target: stateView; currentView: stateView.miningView }
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 {
name: "Prove"
PropertyChanges { target: stateView; currentView: stateView.prooveView }

View file

@ -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 {
id: chainModel

203
pages/MiningStats.qml Normal file
View 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);
}
}

View file

@ -26,6 +26,7 @@
<file>pages/History.qml</file>
<file>pages/AddressBook.qml</file>
<file>pages/Mining.qml</file>
<file>pages/MiningStats.qml</file>
<file>components/ContextMenu.qml</file>
<file>components/ContextMenuItem.qml</file>
<file>components/NetworkStatusItem.qml</file>

View file

@ -151,6 +151,24 @@ void P2PoolManager::getStatus() {
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)
{
// prepare command line arguments and pass to p2pool

View file

@ -50,6 +50,7 @@ public:
Q_INVOKABLE void exit();
Q_INVOKABLE bool isInstalled();
Q_INVOKABLE void getStatus();
Q_INVOKABLE void getStats();
Q_INVOKABLE void download();
enum DownloadError {
@ -68,6 +69,7 @@ signals:
void p2poolStatus(bool isMining, int hashrate) const;
void p2poolDownloadFailure(int errorCode) const;
void p2poolDownloadSuccess() const;
void p2poolStats(QVariantMap statsMap) const;
private:
std::unique_ptr<QProcess> m_p2poold;