aboutsummaryrefslogtreecommitdiff
path: root/src/p2pool
diff options
context:
space:
mode:
authorluigi1111 <luigi1111w@gmail.com>2022-04-19 22:27:27 -0500
committerluigi1111 <luigi1111w@gmail.com>2022-04-19 22:27:27 -0500
commit28f0645d9eded642c2571e11240b67fffeb29ff4 (patch)
tree0dcde11444dc505c07224232ead60bd4c4b16b7f /src/p2pool
parent002fe8eefa5616ee7eb7c21a4dc827e357f3fcb0 (diff)
parent377a1a96800176fbcf2cde5777f921752b0bb0a8 (diff)
downloadmonzero-gui-28f0645d9eded642c2571e11240b67fffeb29ff4.tar.gz
monzero-gui-28f0645d9eded642c2571e11240b67fffeb29ff4.tar.xz
monzero-gui-28f0645d9eded642c2571e11240b67fffeb29ff4.zip
Merge pull request #3829
377a1a9 Integrate P2Pool (devhyper)
Diffstat (limited to 'src/p2pool')
-rw-r--r--src/p2pool/P2PoolManager.cpp238
-rw-r--r--src/p2pool/P2PoolManager.h72
2 files changed, 310 insertions, 0 deletions
diff --git a/src/p2pool/P2PoolManager.cpp b/src/p2pool/P2PoolManager.cpp
new file mode 100644
index 00000000..ccfe4f94
--- /dev/null
+++ b/src/p2pool/P2PoolManager.cpp
@@ -0,0 +1,238 @@
+// Copyright (c) 2014-2022, 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.
+
+#include "P2PoolManager.h"
+#include "net/http_client.h"
+#include "common/util.h"
+#include "qt/utils.h"
+#include <QElapsedTimer>
+#include <QFile>
+#include <QMutexLocker>
+#include <QFileInfo>
+#include <QDir>
+#include <QDebug>
+#include <QUrl>
+#include <QtConcurrent/QtConcurrent>
+#include <QApplication>
+#include <QProcess>
+#include <QMap>
+#include <QCryptographicHash>
+
+void P2PoolManager::download() {
+ m_scheduler.run([this] {
+ QUrl url;
+ QString fileName;
+ QString validHash;
+ #ifdef Q_OS_WIN
+ url = "https://github.com/SChernykh/p2pool/releases/download/v1.9/p2pool-v1.9-windows-x64.zip";
+ fileName = "p2pool-v1.9-windows-x64.zip";
+ validHash = "2587903dc04a4879dca2b6f5c5b584e869928e716274a7660e24b219c9f18839";
+ #elif defined(Q_OS_LINUX)
+ url = "https://github.com/SChernykh/p2pool/releases/download/v1.9/p2pool-v1.9-linux-x64.tar.gz";
+ fileName = "p2pool-v1.9-linux-x64.tar.gz";
+ validHash = "0cd85d933ac4a76708d326698d9db3155bb29d0be82984c735fabd9e9a351b8e";
+ #elif defined(Q_OS_MACOS)
+ url = "https://github.com/SChernykh/p2pool/releases/download/v1.9/p2pool-v1.9-macos-x64.tar.gz";
+ fileName = "p2pool-v1.9-macos-x64.tar.gz";
+ validHash = "47fbdd69d719da80597dd5487f109b61e30b540499cced7b93de1ee01344351e";
+ #endif
+ QFile file(fileName);
+ epee::net_utils::http::http_simple_client http_client;
+ const epee::net_utils::http::http_response_info* response = NULL;
+ std::string userAgent = randomUserAgent().toStdString();
+ std::chrono::milliseconds timeout = std::chrono::seconds(10);
+ http_client.set_server(url.host().toStdString(), "443", {});
+ bool success = http_client.invoke_get(url.path().toStdString(), timeout, {}, std::addressof(response), {{"User-Agent", userAgent}});
+ if (response->m_response_code == 302) {
+ epee::net_utils::http::fields_list fields = response->m_header_info.m_etc_fields;
+ for (std::pair<std::string, std::string> i : fields) {
+ if (i.first == "Location") {
+ url = QString::fromStdString(i.second);
+ http_client.set_server(url.host().toStdString(), "443", {});
+ std::string query = url.query(QUrl::FullyEncoded).toStdString();
+ std::string path = url.path().toStdString() + "?" + query;
+ http_client.wipe_response();
+ success = http_client.invoke_get(path, timeout, {}, std::addressof(response), {{"User-Agent", userAgent}});
+ }
+ }
+ }
+ if (!success) {
+ emit p2poolDownloadFailure();
+ }
+ else {
+ std::string stringData = response->m_body;
+ QByteArray data(stringData.c_str(), stringData.length());
+ QByteArray hashData = QCryptographicHash::hash(data, QCryptographicHash::Sha256);
+ QString hash = hashData.toHex();
+ if (hash != validHash) {
+ emit p2poolDownloadFailure();
+ }
+ else {
+ file.open(QIODevice::WriteOnly);
+ file.write(data);
+ file.close();
+ QProcess::execute("tar", {"-xzf", fileName, "--strip=1", "-C", QApplication::applicationDirPath()});
+ QFile::remove(fileName);
+ if (isInstalled()) {
+ emit p2poolDownloadSuccess();
+ }
+ else {
+ emit p2poolDownloadFailure();
+ }
+ }
+ }
+ });
+ return;
+}
+
+bool P2PoolManager::isInstalled() {
+ if (!QFileInfo(m_p2pool).isFile())
+ {
+ return false;
+ }
+ return true;
+}
+
+void P2PoolManager::getStatus() {
+ QString statsPath = QApplication::applicationDirPath() + "/stats/local/miner";
+ bool status = true;
+ if (!QFileInfo(statsPath).isFile() || !started)
+ {
+ status = started;
+ emit p2poolStatus(status, 0);
+ return;
+ }
+ QFile statsFile(statsPath);
+ statsFile.open(QIODevice::ReadOnly);
+ QTextStream statsOut(&statsFile);
+ QByteArray data;
+ statsOut >> data;
+ statsFile.close();
+ QJsonDocument json = QJsonDocument::fromJson(data);
+ QJsonObject jsonObj = json.object();
+ int hashrate = jsonObj.value("current_hashrate").toInt();
+ emit p2poolStatus(status, hashrate);
+ return;
+}
+
+bool P2PoolManager::start(const QString &flags, const QString &address, const QString &chain, const QString &threads)
+{
+ // prepare command line arguments and pass to p2pool
+ QStringList arguments;
+
+ // Custom startup flags for p2pool
+ foreach (const QString &str, flags.split(" ")) {
+ qDebug() << QString(" [%1] ").arg(str);
+ if (!str.isEmpty())
+ arguments << str;
+ }
+
+ if (!arguments.contains("--local-api")) {
+ arguments << "--local-api";
+ }
+
+ if (!arguments.contains("--data-api")) {
+ QDir dir;
+ QString dirName = QApplication::applicationDirPath() + "/stats/";
+ QDir statsDir(dirName);
+ if (dir.exists(dirName)) {
+ statsDir.removeRecursively();
+ }
+ dir.mkdir(dirName);
+ arguments << "--data-api" << dirName;
+ }
+
+ if (!arguments.contains("--start-mining")) {
+ arguments << "--start-mining" << threads;
+ }
+
+ if (chain == "mini") {
+ arguments << "--mini";
+ }
+
+ if (!arguments.contains("--wallet")) {
+ arguments << "--wallet" << address;
+ }
+
+ qDebug() << "starting p2pool " + m_p2pool;
+ qDebug() << "With command line arguments " << arguments;
+
+ QMutexLocker locker(&m_p2poolMutex);
+
+ m_p2poold.reset(new QProcess());
+
+ // Set program parameters
+ m_p2poold->setProgram(m_p2pool);
+ m_p2poold->setArguments(arguments);
+ m_p2poold->setWorkingDirectory(QApplication::applicationDirPath());
+
+ // Start p2pool
+ started = m_p2poold->startDetached();
+
+ if (!started) {
+ qDebug() << "P2Pool start error: " + m_p2poold->errorString();
+ emit p2poolStartFailure();
+ return false;
+ }
+
+ return true;
+}
+
+void P2PoolManager::exit()
+{
+ qDebug("P2PoolManager: exit()");
+ #ifdef Q_OS_WIN
+ QProcess::execute("taskkill", {"/F", "/IM", "p2pool.exe"});
+ #else
+ QProcess::execute("pkill", {"p2pool"});
+ #endif
+ started = false;
+ QString dirName = QApplication::applicationDirPath() + "/stats/";
+ QDir dir(dirName);
+ dir.removeRecursively();
+}
+
+P2PoolManager::P2PoolManager(QObject *parent)
+ : QObject(parent)
+ , m_scheduler(this)
+{
+ started = false;
+ // Platform dependent path to p2pool
+#ifdef Q_OS_WIN
+ m_p2pool = QApplication::applicationDirPath() + "/p2pool.exe";
+#elif defined(Q_OS_UNIX)
+ m_p2pool = QApplication::applicationDirPath() + "/p2pool";
+#endif
+ if (m_p2pool.length() == 0) {
+ qCritical() << "no p2pool binary defined for current platform";
+ }
+}
+
+P2PoolManager::~P2PoolManager() {
+ m_scheduler.shutdownWaitForFinished();
+}
diff --git a/src/p2pool/P2PoolManager.h b/src/p2pool/P2PoolManager.h
new file mode 100644
index 00000000..82e7832d
--- /dev/null
+++ b/src/p2pool/P2PoolManager.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2014-2022, 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.
+
+#ifndef P2POOLMANAGER_H
+#define P2POOLMANAGER_H
+
+#include <memory>
+
+#include <QMutex>
+#include <QObject>
+#include <QUrl>
+#include <QProcess>
+#include "NetworkType.h"
+#include "qt/FutureScheduler.h"
+
+class P2PoolManager : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit P2PoolManager(QObject *parent = 0);
+ ~P2PoolManager();
+
+ Q_INVOKABLE bool start(const QString &flags, const QString &address, const QString &chain, const QString &threads);
+ Q_INVOKABLE void exit();
+ Q_INVOKABLE bool isInstalled();
+ Q_INVOKABLE void getStatus();
+ Q_INVOKABLE void download();
+private:
+
+ bool running(NetworkType::Type nettype) const;
+signals:
+ void p2poolStartFailure() const;
+ void p2poolStatus(bool isMining, int hashrate) const;
+ void p2poolDownloadFailure() const;
+ void p2poolDownloadSuccess() const;
+
+private:
+ std::unique_ptr<QProcess> m_p2poold;
+ QMutex m_p2poolMutex;
+ QString m_p2pool;
+ bool started = false;
+
+ mutable FutureScheduler m_scheduler;
+};
+
+#endif // P2POOLMANAGER_H