diff --git a/.drone.yml b/.drone.yml
index b4aed15..9fee86d 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -14,11 +14,9 @@ steps:
commands:
- git config --global url."http://gitea:3000/tor/".insteadOf https://git.torproject.org/
- git config --global url."http://gitea:3000/".insteadOf https://github.com/
- - git submodule update --init --depth 50 contrib/tor
- - git submodule update --init --depth 50 contrib/torsocks
- git submodule update --init --depth 120 monero
- git submodule update --init --depth 120 --recursive monero
- - make -j8 release-static
+ - TOR="/usr/local/tor/bin/tor" XMRIG="/xmrig/xmrig" make -j6 release-static
environment:
OPENSSL_ROOT_DIR: /usr/local/openssl/
CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off
@@ -44,7 +42,7 @@ volumes:
path: /var/drone/ccache_linux_release/
- name: files_linux_release
host:
- path: /mnt/storage1/feather_files/files/linux-release/
+ path: /build/feather_files/files/linux-release/
---
@@ -75,7 +73,7 @@ steps:
volumes:
- name: files_linux_appimage
host:
- path: /mnt/storage1/feather_files/files/linux-release-appimage/
+ path: /build/feather_files/files/linux-release-appimage/
---
@@ -94,11 +92,9 @@ steps:
commands:
- git config --global url."http://gitea:3000/tor/".insteadOf https://git.torproject.org/
- git config --global url."http://gitea:3000/".insteadOf https://github.com/
- - git submodule update --init --depth 50 contrib/tor
- - git submodule update --init --depth 50 contrib/torsocks
- git submodule update --init --depth 120 monero
- git submodule update --init --depth 120 --recursive monero
- - PATH=/mxe/usr/bin/:$PATH make -j8 windows-mxe-release
+ - PATH="/mxe/usr/bin/:$PATH" TOR="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" XMRIG="/xmrig/xmrig.exe" make -j6 windows-mxe-release
environment:
CMAKEFLAGS_EXTRA: -DFETCH_DEPS=Off
- name: deploy
@@ -122,7 +118,7 @@ volumes:
path: /var/drone/ccache_win_release/
- name: files_win_release
host:
- path: /mnt/storage1/feather_files/files/windows-mxe-release/
+ path: /build/feather_files/files/windows-mxe-release/
---
@@ -157,9 +153,9 @@ steps:
volumes:
- name: files_mac_release
host:
- path: /mnt/storage1/feather_files/files/mac-release/
+ path: /build/feather_files/files/mac-release/
---
kind: signature
-hmac: 91e773a27d27f29ea62f5df500664b733df641b7c31202c8e5558174fd046fba
+hmac: 527d334190a8a824b3b781a05ae4c7d87f4fa2bc37ebc53a96db91f925fa4a52
...
diff --git a/BUILDING.md b/BUILDING.md
index 35efd02..912190c 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -35,7 +35,7 @@ Note: You only need to build the base image once.
#### 3. Build
```bash
-docker run --rm -it -v /tmp/ccache:/root/.ccache -v /root/feather:/feather -w /feather feather:win /bin/bash -c 'PATH=/mxe/usr/bin/:$PATH make windows-mxe-release -j8'
+docker run --rm -it -v /tmp/ccache:/root/.ccache -v /root/feather:/feather -w /feather feather:win /bin/bash -c 'PATH="/mxe/usr/bin/:$PATH" TOR="/mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe" XMRIG="/xmrig/xmrig.exe" make windows-mxe-release -j8'
```
Replace `PATH_TO_FEATHER` with the absolute path to Feather locally.
@@ -68,7 +68,7 @@ Note: You only need to build the base image once.
#### 3. Build
```bash
-docker run --env OPENSSL_ROOT_DIR=/usr/local/openssl/ --rm -it -v /tmp/ccache:/root/.ccache -v PATH_TO_FEATHER:/feather -w /feather feather:linux sh -c 'make release-static -j8'
+docker run --env OPENSSL_ROOT_DIR=/usr/local/openssl/ --rm -it -v /tmp/ccache:/root/.ccache -v PATH_TO_FEATHER:/feather -w /feather feather:linux sh -c 'TOR="/usr/local/tor/bin/tor" XMRIG="/xmrig/xmrig" make release-static -j8'
```
Replace `PATH_TO_FEATHER` with the absolute path to Feather locally.
@@ -98,4 +98,4 @@ Build Feather.
CMAKE_PREFIX_PATH=~/Qt5.15.1/5.15.1/clang_64 make mac-release
```
-The resulting Mac OS application can be found `build/bin/feather.app`.
+The resulting Mac OS application can be found `build/bin/feather.app` and will **not** have Tor embedded.
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3afe305..c9851a3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,8 +11,9 @@ set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}")
option(FETCH_DEPS "Download dependencies if they are not found" ON)
option(XMRTO "Include Xmr.To module" ON)
-option(XMRig "Include XMRig module" ON)
-option(BUILD_TOR "Build Tor" OFF)
+option(XMRIG "Path to XMRig binary to embed inside Feather" OFF)
+option(TOR "Path to Tor binary to embed inside Feather" OFF)
+option(TOR_VERSION "Optional git hash or tag of embedded Tor version" "tor-0.4.3.5")
option(STATIC "Link libraries statically, requires static Qt")
option(USE_DEVICE_TREZOR "Trezor support compilation" OFF)
option(DONATE_BEG "Prompt donation window every once in a while" ON)
@@ -175,47 +176,48 @@ if(UNIX AND NOT APPLE)
endif()
endif()
-# Tor/torsocks
-set(TOR_TAG "tor-0.4.3.5")
-set(TOR_DIR "${CMAKE_SOURCE_DIR}/contrib/tor")
-
-if(BUILD_TOR AND APPLE)
- execute_process(COMMAND bash -c "touch ${CMAKE_SOURCE_DIR}/src/tor/libevent-2.1.7.dylib")
-ENDIF()
-
-if(UNIX AND NOT APPLE)
- set(TOR_LIB "libtorsocks.so")
-elseif(APPLE)
- set(TOR_LIB "libtorsocks.dylib")
+if("$ENV{DRONE}" STREQUAL "true")
+ message(STATUS "We are inside a static compile with Drone CI")
endif()
-if("$ENV{DRONE}" STREQUAL "true" AND APPLE)
- message(STATUS "We are inside a static compile with Drone CI")
- # @TODO: taken from Tor Browser official release for now
- execute_process(COMMAND bash -c "cp ~/tor/libevent-2.1.7.dylib ${CMAKE_SOURCE_DIR}/src/tor/libevent-2.1.7.dylib")
- execute_process(COMMAND bash -c "cp ~/tor/tor ${CMAKE_SOURCE_DIR}/src/tor/tor")
-elseif("$ENV{DRONE}" STREQUAL "true" AND BUILD_TOR)
- message(STATUS "We are inside a static compile with Drone CI")
- if(MINGW)
- execute_process(COMMAND bash -c "cp /mxe/usr/x86_64-w64-mingw32.static/bin/tor.exe ${CMAKE_SOURCE_DIR}/src/tor/tor.exe")
- elseif(UNIX AND NOT APPLE)
- execute_process(COMMAND bash -c "cp /usr/local/tor/bin/tor ${CMAKE_SOURCE_DIR}/src/tor/tor")
- execute_process(COMMAND bash -c "cp /usr/local/torsocks/lib/torsocks/* ${CMAKE_SOURCE_DIR}/src/tor/")
+# To build Feather with embedded (and static) Tor, pass CMake -DTOR=/path/to/tor
+if(TOR)
+ if(APPLE)
+ execute_process(COMMAND bash -c "touch ${CMAKE_CURRENT_SOURCE_DIR}/src/tor/libevent-2.1.7.dylib")
endif()
+
+ # on the buildbot Tor is baked into the image
+ # - linux: See `Dockerfile`
+ # - windows: https://github.com/mxe/mxe/blob/1024dc7d2db5eb7d5d3c64a2c12b5f592572f1ce/plugins/apps/tor.mk
+ # - macos: taken from Tor Browser official release
+ set(TOR_COPY_CMD "cp ${TOR} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/tor")
+ message(STATUS "${TOR_COPY_CMD}")
+ execute_process(COMMAND bash -c "${TOR_COPY_CMD}" RESULT_VARIABLE ret)
+ if(ret EQUAL "1")
+ message(FATAL_ERROR "Tor copy failure: ${TOR_COPY_CMD}")
+ endif()
+
+ message(STATUS "Embedding Tor binary at ${TOR}")
else()
- if(BUILD_TOR)
- if(UNIX OR APPLE)
- execute_process(COMMAND bash -c "ls -al src/tor/${TOR_LIB} 2>/dev/null" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE TOR_FOUND OUTPUT_STRIP_TRAILING_WHITESPACE)
- if(TOR_FOUND)
- message(STATUS "${TOR_LIB} found, skipping Tor build")
- else()
- message(STATUS "${TOR_LIB} not found, building Tor")
- execute_process(COMMAND bash -c "bash build_tor.sh ${TOR_TAG} ${CMAKE_SOURCE_DIR} 'ON'" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/contrib)
- endif()
- endif()
- else()
- message(STATUS "Skipping Tor build because -DBUILD_TOR=OFF")
+ message(STATUS "Skipping Tor inclusion because -DTOR=Off")
+endif()
+
+# To build Feather with embedded (and static) XMRig, pass CMake -DXMRIG=/path/to/xmrig
+if(XMRIG)
+ # on the buildbot XMRig is baked into the image
+ # - linux: See `Dockerfile`
+ # - windows: See `Dockerfile_windows`
+ # - macos: manually downloaded an official release
+ set(XMRIG_COPY_CMD "cp ${XMRIG} ${CMAKE_CURRENT_SOURCE_DIR}/src/assets/exec/xmrig")
+ message(STATUS "${XMRIG_COPY_CMD}")
+ execute_process(COMMAND bash -c "${XMRIG_COPY_CMD}" RESULT_VARIABLE ret)
+ if(ret EQUAL "1")
+ message(FATAL_ERROR "XMRig copy failure: ${XMRIG_COPY_CMD}")
endif()
+
+ message(STATUS "Embedding XMRig binary at ${XMRIG}")
+else()
+ message(STATUS "Skipping XMRig inclusion because -DXMRIG=Off")
endif()
if(MINGW)
diff --git a/Dockerfile b/Dockerfile
index 74e39a9..c499c6f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -305,3 +305,9 @@ RUN git clone https://git.wownero.com/feather/monero-seed.git && \
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
make -Cbuild -j$THREADS && \
make -Cbuild install
+
+RUN apt install -y curl && \
+ curl -LO "https://github.com/xmrig/xmrig/releases/download/v6.3.5/xmrig-6.3.5-linux-static-x64.tar.gz" && \
+ echo "24d4f07cf5850f00ab513b228f95769a5a5ed68d35808d98f9959b58d97985a0 xmrig-6.3.5-linux-static-x64.tar.gz" > hashsum.txt && \
+ sha256sum -c hashsum.txt && \
+ tar xvf xmrig-6.3.5-linux-static-x64.tar.gz --one-top-level=/xmrig --strip 1
diff --git a/Dockerfile_windows b/Dockerfile_windows
index 759d88c..3cbf4b9 100644
--- a/Dockerfile_windows
+++ b/Dockerfile_windows
@@ -72,3 +72,10 @@ RUN git clone https://git.wownero.com/feather/monero-seed.git && \
cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && \
make -Cbuild -j$THREADS && \
make -Cbuild install
+
+RUN apt install -y curl && \
+ curl -LO "https://github.com/xmrig/xmrig/releases/download/v6.3.5/xmrig-6.3.5-gcc-win64.zip" && \
+ echo "e45915ada7e6e30f6ab40abf33831056449d5914307d7706bb0ad439b6d64c12 xmrig-6.3.5-gcc-win64.zip" > hashsum.txt && \
+ sha256sum -c hashsum.txt && \
+ unzip -q xmrig-6.3.5-gcc-win64.zip -d /xmrig && \
+ mv /xmrig/xmrig-6.3.5/* /xmrig/
diff --git a/HACKING.md b/HACKING.md
index f644a4c..8285c63 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -42,7 +42,8 @@ via the `CMAKE_PREFIX_PATH` definition. For me this is:
There are some Monero/Feather related options/definitions that you may pass:
- `-DXMRTO=OFF` - disable Xmr.To feature
-- `-DBUILD_TOR=OFF` - disable embedded Tor
+- `-DTOR=/path/to/tor` - Embed a Tor executable inside Feather
+- `-DXMRIG=/path/to/xmrig` - Embed a XMRig executable inside Feather
- `-DDONATE_BEG=OFF` - disable the dreaded donate requests
And:
diff --git a/Makefile b/Makefile
index 88d2800..53684c4 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,8 @@ CMAKEFLAGS = \
-DBUILD_64=On \
-DBUILD_TESTS=Off \
-DXMRTO=ON \
+ -DXMRIG=Off \
+ -DTOR=Off \
-DCMAKE_CXX_STANDARD=11 \
-DCMAKE_VERBOSE_MAKEFILE=On \
-DINSTALL_VENDORED_LIBUNBOUND=Off \
@@ -40,29 +42,33 @@ CMAKEFLAGS = \
$(CMAKEFLAGS_EXTRA)
release-static: CMAKEFLAGS += -DBUILD_TAG="linux-x64"
-release-static: CMAKEFLAGS += -DBUILD_TOR=On
+release-static: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
+release-static: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
release-static: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
release-static:
cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild
windows-mxe-release: CMAKEFLAGS += -DBUILD_TAG="win-x64"
-windows-mxe-release: CMAKEFLAGS += -DBUILD_TOR=On
+windows-mxe-release: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
+windows-mxe-release: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
windows-mxe-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
windows-mxe-release:
cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild
windows-mxe-debug: CMAKEFLAGS += -DBUILD_TAG="win-x64"
-windows-mxe-debug: CMAKEFLAGS += -DBUILD_TOR=Off
+windows-mxe-debug: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
+windows-mxe-debug: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
windows-mxe-debug: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Debug
windows-mxe-debug:
cmake -Bbuild $(CMAKEFLAGS)
$(MAKE) -Cbuild
mac-release: CMAKEFLAGS += -DSTATIC=Off
+mac-release: CMAKEFLAGS += -DTOR=$(or ${TOR},OFF)
+mac-release: CMAKEFLAGS += -DXMRIG=$(or ${XMRIG},OFF)
mac-release: CMAKEFLAGS += -DBUILD_TAG="mac-x64"
-mac-release: CMAKEFLAGS += -DBUILD_TOR=Off
mac-release: CMAKEFLAGS += -DCMAKE_BUILD_TYPE=Release
mac-release:
cmake -Bbuild $(CMAKEFLAGS)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 14688dc..da2f614 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -42,14 +42,16 @@ file(GLOB SOURCE_FILES
"dialog/*.cpp"
)
-if((APPLE AND BUILD_TOR) OR (APPLE AND "$ENV{DRONE}" STREQUAL "true"))
- set(ASSETS_OS "assets_macos_tor.qrc")
-elseif(UNIX AND NOT APPLE AND BUILD_TOR)
- set(ASSETS_OS "assets_linux_tor.qrc")
-elseif(MINGW AND BUILD_TOR)
- set(ASSETS_OS "assets_windows_tor.qrc")
-else()
- message(STATUS "Building without embedded Tor")
+if(TOR)
+ if(APPLE)
+ set(ASSETS_TOR "assets_tor_macos.qrc")
+ else()
+ set(ASSETS_TOR "assets_tor.qrc")
+ endif()
+endif()
+
+if(XMRIG)
+ set(ASSETS_XMRIG "assets_mining.qrc")
endif()
set(EXECUTABLE_FLAG)
@@ -74,7 +76,8 @@ endif()
add_executable(feather ${EXECUTABLE_FLAG} main.cpp
${SOURCE_FILES}
${RESOURCES}
- ${ASSETS_OS}
+ ${ASSETS_TOR}
+ ${ASSETS_XMRIG}
)
# mac os bundle
@@ -122,16 +125,16 @@ if(DONATE_BEG)
target_compile_definitions(feather PRIVATE DONATE_BEG=1)
endif()
-if(BUILD_TOR)
- target_compile_definitions(feather PRIVATE BUILD_TOR=1)
-endif()
-
if(XMRTO)
target_compile_definitions(feather PRIVATE XMRTO=1)
endif()
-if(XMRig)
- target_compile_definitions(feather PRIVATE MINING=1)
+if(TOR)
+ target_compile_definitions(feather PRIVATE HAS_TOR=1)
+endif()
+
+if(XMRIG)
+ target_compile_definitions(feather PRIVATE HAS_XMRIG=1)
endif()
if(HAVE_SYS_PRCTL_H)
diff --git a/src/appcontext.cpp b/src/appcontext.cpp
index e1a8202..e2826a3 100644
--- a/src/appcontext.cpp
+++ b/src/appcontext.cpp
@@ -147,10 +147,17 @@ AppContext::AppContext(QCommandLineParser *cmdargs) {
AppContext::prices = new Prices();
// xmr.to
-#if defined(XMRTO)
+#ifdef XMRTO
this->XMRTo = new XmrTo(this);
#endif
+ // XMRig
+#ifdef HAS_XMRIG
+ this->XMRig = new XmRig(this->configDirectory, this);
+ if(!this->isTails)
+ this->XMRig->prepare();
+#endif
+
this->walletManager = WalletManager::instance();
QString logPath = QString("%1/daemon.log").arg(configDirectory);
Monero::Utils::onStartup();
@@ -393,7 +400,7 @@ void AppContext::onWSMessage(const QJsonObject &msg) {
else if(cmd == "nodes") {
this->onWSNodes(msg.value("data").toArray());
}
-#if defined(MINING)
+#if defined(HAS_XMRIG)
else if(cmd == "xmrig") {
this->XMRigDownloads(msg.value("data").toObject());
}
@@ -511,31 +518,17 @@ void AppContext::onWSCCS(const QJsonArray &ccs_data) {
}
void AppContext::createConfigDirectory(const QString &dir) {
- if(!Utils::dirExists(dir)) {
- qDebug() << QString("Creating directory: %1").arg(dir);
- if(!QDir().mkpath(dir))
- throw std::runtime_error("Could not create directory " + dir.toStdString());
- }
-
QString config_dir_tor = QString("%1%2").arg(dir).arg("tor");
- if(!Utils::dirExists(config_dir_tor)) {
- qDebug() << QString("Creating directory: %1").arg(config_dir_tor);
- if (!QDir().mkpath(config_dir_tor))
- throw std::runtime_error("Could not create directory " + config_dir_tor.toStdString());
- }
-
QString config_dir_tordata = QString("%1%2").arg(dir).arg("tor/data");
- if(!Utils::dirExists(config_dir_tordata)) {
- qDebug() << QString("Creating directory: %1").arg(config_dir_tordata);
- if (!QDir().mkpath(config_dir_tordata))
- throw std::runtime_error("Could not create directory " + config_dir_tordata.toStdString());
- }
+ QString config_dir_xmrig = QString("%1%2").arg(dir).arg("xmrig");
- QString config_dir_torsocks = QString("%1%2").arg(dir).arg("torsocks");
- if(!Utils::dirExists(config_dir_torsocks)) {
- qDebug() << QString("Creating directory: %1").arg(config_dir_torsocks);
- if (!QDir().mkpath(config_dir_torsocks))
- throw std::runtime_error("Could not create directory " + config_dir_torsocks.toStdString());
+ QStringList createDirs({dir, config_dir_tor, config_dir_tordata, config_dir_xmrig});
+ for(const auto &d: createDirs) {
+ if(!Utils::dirExists(d)) {
+ qDebug() << QString("Creating directory: %1").arg(d);
+ if (!QDir().mkpath(d))
+ throw std::runtime_error("Could not create directory " + d.toStdString());
+ }
}
}
diff --git a/src/appcontext.h b/src/appcontext.h
index 8f9bdda..dd9057c 100644
--- a/src/appcontext.h
+++ b/src/appcontext.h
@@ -14,6 +14,7 @@
#include "utils/networking.h"
#include "utils/tor.h"
#include "utils/xmrto.h"
+#include "utils/xmrig.h"
#include "utils/wsclient.h"
#include "utils/txfiathistory.h"
#include "widgets/RedditPost.h"
@@ -78,6 +79,7 @@ public:
Tor *tor;
WSClient *ws;
XmrTo *XMRTo;
+ XmRig *XMRig;
Nodes *nodes;
static Prices *prices;
static WalletKeysFilesModel *wallets;
diff --git a/src/tor/.gitkeep b/src/assets/exec/.gitkeep
similarity index 100%
rename from src/tor/.gitkeep
rename to src/assets/exec/.gitkeep
diff --git a/src/assets_macos_tor.qrc b/src/assets_macos_tor.qrc
deleted file mode 100644
index 5acecc2..0000000
--- a/src/assets_macos_tor.qrc
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- tor/tor
- tor/libevent-2.1.7.dylib
-
-
diff --git a/src/assets_windows_tor.qrc b/src/assets_mining.qrc
similarity index 68%
rename from src/assets_windows_tor.qrc
rename to src/assets_mining.qrc
index 70e0369..bbe426e 100644
--- a/src/assets_windows_tor.qrc
+++ b/src/assets_mining.qrc
@@ -1,5 +1,5 @@
- tor/tor.exe
+ assets/exec/xmrig
diff --git a/src/assets_linux_tor.qrc b/src/assets_tor.qrc
similarity index 69%
rename from src/assets_linux_tor.qrc
rename to src/assets_tor.qrc
index 4539da6..7f0c2cf 100644
--- a/src/assets_linux_tor.qrc
+++ b/src/assets_tor.qrc
@@ -1,5 +1,5 @@
- tor/tor
+ assets/exec/tor
diff --git a/src/assets_tor_macos.qrc b/src/assets_tor_macos.qrc
new file mode 100644
index 0000000..909796c
--- /dev/null
+++ b/src/assets_tor_macos.qrc
@@ -0,0 +1,6 @@
+
+
+ assets/exec/tor
+ assets/exec/libevent-2.1.7.dylib
+
+
diff --git a/src/main.cpp b/src/main.cpp
index a7cbf6f..5482d44 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -22,12 +22,14 @@ int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(assets);
-#if defined(Q_OS_MAC) && defined(BUILD_TOR)
- Q_INIT_RESOURCE(assets_macos_tor);
-#elif defined(Q_OS_LINUX) && defined(BUILD_TOR)
- Q_INIT_RESOURCE(assets_linux_tor);
-#elif defined(Q_OS_WIN) && defined(BUILD_TOR)
- Q_INIT_RESOURCE(assets_windows_tor);
+#if defined(Q_OS_MAC) && defined(HAS_TOR)
+ Q_INIT_RESOURCE(assets_tor_macos);
+#elif defined(HAS_TOR)
+ Q_INIT_RESOURCE(assets_tor);
+#endif
+
+#if defined(HAS_XMRIG)
+ Q_INIT_RESOURCE(assets_mining);
#endif
QStringList argv_;
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 34ca687..e4d247a 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -167,13 +167,20 @@ MainWindow::MainWindow(AppContext *ctx, QWidget *parent) :
connect(m_ctx->nodes, &Nodes::WSNodeExhausted, this, &MainWindow::showWSNodeExhaustedMessage);
// XMRig
+#ifdef HAS_XMRIG
m_xmrig = new XMRigWidget(m_ctx, this);
ui->xmrRigLayout->addWidget(m_xmrig);
+ connect(m_ctx->XMRig, &XmRig::output, m_xmrig, &XMRigWidget::onProcessOutput);
+ connect(m_ctx->XMRig, &XmRig::error, m_xmrig, &XMRigWidget::onProcessError);
+ connect(m_ctx->XMRig, &XmRig::hashrate, m_xmrig, &XMRigWidget::onHashrate);
+
+ connect(m_ctx, &AppContext::walletClosed, m_xmrig, &XMRigWidget::onWalletClosed);
connect(m_ctx, &AppContext::walletOpened, m_xmrig, &XMRigWidget::onWalletOpened);
connect(m_ctx, &AppContext::XMRigDownloads, m_xmrig, &XMRigWidget::onDownloads);
- connect(m_ctx, &AppContext::walletClosed, m_xmrig, &XMRigWidget::onWalletClosed);
+
connect(m_xmrig, &XMRigWidget::miningStarted, [=]{ m_ctx->setWindowTitle(true); });
connect(m_xmrig, &XMRigWidget::miningEnded, [=]{ m_ctx->setWindowTitle(false); });
+#endif
// CCS/Reddit widget
m_ccsWidget = new CCSWidget(this);
@@ -388,7 +395,7 @@ void MainWindow::initMenu() {
ui->actionShow_xmr_to->setVisible(false);
#endif
-#if defined(MINING)
+#if defined(HAS_XMRIG)
connect(ui->actionShow_XMRig, &QAction::triggered, m_tabShowHideSignalMapper, QOverload<>::of(&QSignalMapper::map));
m_tabShowHideMapper["XMRig"] = new ToggleTab(ui->tabXmrRig, "XMRig", "XMRig", ui->actionShow_XMRig, Config::showTabXMRig);
m_tabShowHideSignalMapper->setMapping(ui->actionShow_XMRig, "XMRig");
diff --git a/src/utils/tor.cpp b/src/utils/tor.cpp
index 3e763ed..5eb0411 100644
--- a/src/utils/tor.cpp
+++ b/src/utils/tor.cpp
@@ -43,9 +43,15 @@ Tor::Tor(AppContext *ctx, QObject *parent)
return;
}
+#ifndef HAS_TOR
+ qCritical() << "Feather built without embedded Tor. Assuming --use-local-tor";
+ this->localTor = true;
+ return;
+#endif
+
bool unpacked = this->unpackBins();
if (!unpacked) {
- qCritical() << "Feather built without embedded Tor. Assuming --use-local-tor";
+ qCritical() << "Error unpacking embedded Tor. Assuming --use-local-tor";
this->localTor = true;
return;
}
@@ -175,11 +181,9 @@ void Tor::handleProcessError(QProcess::ProcessError error) {
bool Tor::unpackBins() {
QString torFile;
- // @TODO: refactor for Mac OS - should compile Tor statically.
-#if defined(Q_OS_MAC) && defined(DRONE)
- // Tor on Mac requires libevent.dylib, borrowed the executable from
- // the official Tor Browser release for now.
- QString libEvent = ":/tor/libevent-2.1.7.dylib";
+ // On MacOS write libevent to disk
+#if defined(Q_OS_MAC)
+ QString libEvent = ":/assets/exec/libevent-2.1.7.dylib";
if (Utils::fileExists(libEvent)) {
QFile e(libEvent);
QFileInfo eventInfo(e);
@@ -190,18 +194,15 @@ bool Tor::unpackBins() {
}
#endif
-#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
- torFile = ":/tor/tor";
-#elif defined(Q_OS_WIN)
- torFile = ":/tor/tor.exe";
-#endif
-
+ torFile = ":/assets/exec/tor";
if (!Utils::fileExists(torFile))
return false;
+
+ // write to disk
QFile f(torFile);
QFileInfo fileInfo(f);
this->torPath = QDir(this->torDir).filePath(fileInfo.fileName());
- qDebug() << this->torPath;
+ qDebug() << "Writing Tor executable to " << this->torPath;
f.copy(torPath);
f.close();
@@ -209,7 +210,6 @@ bool Tor::unpackBins() {
QFile torBin(this->torPath);
torBin.setPermissions(QFile::ExeGroup | QFile::ExeOther | QFile::ExeOther | QFile::ExeUser);
#endif
-
return true;
}
diff --git a/src/utils/xmrig.cpp b/src/utils/xmrig.cpp
index df2c0f9..dc03ea5 100644
--- a/src/utils/xmrig.cpp
+++ b/src/utils/xmrig.cpp
@@ -13,28 +13,37 @@
#include "appcontext.h"
-XMRig::XMRig(QObject *parent) : QObject(parent)
-{
- qDebug() << "Using embedded tor instance";
- m_process.setProcessChannelMode(QProcess::MergedChannels);
-
- connect(&m_process, &QProcess::readyReadStandardOutput, this, &XMRig::handleProcessOutput);
- connect(&m_process, &QProcess::errorOccurred, this, &XMRig::handleProcessError);
- connect(&m_process, &QProcess::stateChanged, this, &XMRig::stateChanged);
+XmRig::XmRig(const QString &configDir, QObject *parent) : QObject(parent) {
+ this->rigDir = QDir(configDir).filePath("xmrig");
}
-void XMRig::stop() {
+void XmRig::prepare() {
+ // unpack and set process signals
+
+ if(!this->unpackBins()) {
+ qCritical() << "failed to write XMRig to config directory";
+ return;
+ }
+
+ m_process.setProcessChannelMode(QProcess::MergedChannels);
+ connect(&m_process, &QProcess::readyReadStandardOutput, this, &XmRig::handleProcessOutput);
+ connect(&m_process, &QProcess::errorOccurred, this, &XmRig::handleProcessError);
+ connect(&m_process, &QProcess::stateChanged, this, &XmRig::stateChanged);
+}
+
+void XmRig::stop() {
if(m_process.state() == QProcess::Running)
m_process.kill();
}
-void XMRig::terminate() {
+void XmRig::terminate() {
if(m_process.state() == QProcess::Running)
m_process.terminate();
}
-void XMRig::start(unsigned int threads,
- const QString &pool_name,
+void XmRig::start(const QString &path,
+ unsigned int threads,
+ const QString &address,
const QString &username,
const QString &password,
bool tor, bool tls) {
@@ -44,22 +53,22 @@ void XMRig::start(unsigned int threads,
return;
}
- auto path = config()->get(Config::xmrigPath).toString();
if(path.isEmpty()) {
- emit error("Please set path to XMRig binary before starting.");
+ emit error("XmRig->Start path parameter missing.");
return;
}
if(!Utils::fileExists(path)) {
- emit error("Path to XMRig binary invalid; file does not exist.");
+ emit error(QString("Path to XMRig binary invalid; file does not exist: %1").arg(path));
return;
}
QStringList arguments;
- arguments << "-o" << pool_name;
+ arguments << "-o" << address;
arguments << "-a" << "rx/0";
arguments << "-u" << username;
- arguments << "-p" << password;
+ if(!password.isEmpty())
+ arguments << "-p" << password;
arguments << "--no-color";
arguments << "-t" << QString::number(threads);
if(tor)
@@ -72,14 +81,14 @@ void XMRig::start(unsigned int threads,
m_process.start(path, arguments);
}
-void XMRig::stateChanged(QProcess::ProcessState state) {
+void XmRig::stateChanged(QProcess::ProcessState state) {
if(state == QProcess::ProcessState::Running)
emit output("XMRig started");
else if (state == QProcess::ProcessState::NotRunning)
emit output("XMRig stopped");
}
-void XMRig::handleProcessOutput() {
+void XmRig::handleProcessOutput() {
QByteArray _output = m_process.readAllStandardOutput();
if(_output.contains("miner") && _output.contains("speed")) {
// detect hashrate
@@ -93,7 +102,7 @@ void XMRig::handleProcessOutput() {
emit output(_output);
}
-void XMRig::handleProcessError(QProcess::ProcessError err) {
+void XmRig::handleProcessError(QProcess::ProcessError err) {
if (err == QProcess::ProcessError::Crashed)
emit error("XMRig crashed or killed");
else if (err == QProcess::ProcessError::FailedToStart) {
@@ -102,3 +111,24 @@ void XMRig::handleProcessError(QProcess::ProcessError err) {
}
}
+bool XmRig::unpackBins() {
+ QString rigFile;
+
+ rigFile = ":/assets/exec/xmrig";
+ if (!Utils::fileExists(rigFile))
+ return false;
+
+ // write to disk
+ QFile f(rigFile);
+ QFileInfo fileInfo(f);
+ this->rigPath = QDir(this->rigDir).filePath(fileInfo.fileName());
+ qDebug() << "Writing XMRig executable to " << this->rigPath;
+ f.copy(rigPath);
+ f.close();
+
+#if defined(Q_OS_UNIX)
+ QFile torBin(this->rigPath);
+ torBin.setPermissions(QFile::ExeGroup | QFile::ExeOther | QFile::ExeOther | QFile::ExeUser);
+#endif
+ return true;
+}
diff --git a/src/utils/xmrig.h b/src/utils/xmrig.h
index 42817f5..46e5b20 100644
--- a/src/utils/xmrig.h
+++ b/src/utils/xmrig.h
@@ -15,16 +15,21 @@
#include "utils/childproc.h"
-class XMRig : public QObject
+class XmRig : public QObject
{
Q_OBJECT
public:
- explicit XMRig(QObject *parent = nullptr);
+ explicit XmRig(const QString &configDir, QObject *parent = nullptr);
+ void prepare();
- void start(unsigned int threads, const QString &pool_name, const QString &username, const QString &password, bool tor = false, bool tls = true);
+ void start(const QString &path, unsigned int threads, const QString &address, const QString &username, const QString &password, bool tor = false, bool tls = true);
void stop();
void terminate();
+ bool unpackBins();
+
+ QString rigDir;
+ QString rigPath;
signals:
void error(const QString &msg);
diff --git a/src/widgets/xmrigwidget.cpp b/src/widgets/xmrigwidget.cpp
index f87fb03..4d541cf 100644
--- a/src/widgets/xmrigwidget.cpp
+++ b/src/widgets/xmrigwidget.cpp
@@ -33,12 +33,6 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
connect(ui->tableView, &QHeaderView::customContextMenuRequested, this, &XMRigWidget::showContextMenu);
connect(ui->tableView, &QTableView::doubleClicked, this, &XMRigWidget::linkClicked);
- // XMRig core
- m_rig = new XMRig(this);
- connect(m_rig, &XMRig::output, this, &XMRigWidget::onProcessOutput);
- connect(m_rig, &XMRig::error, this, &XMRigWidget::onProcessError);
- connect(m_rig, &XMRig::hashrate, this, &XMRigWidget::onHashrate);
-
// threads
ui->threadSlider->setMinimum(1);
int threads = QThread::idealThreadCount();
@@ -60,19 +54,29 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
ui->relayTor->setChecked(false);
ui->check_tls->setChecked(true);
ui->label_status->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ ui->label_status->hide();
+ ui->pathFrame->hide();
+ ui->soloFrame->hide();
+ ui->poolFrame->hide();
// XMRig binary
auto path = config()->get(Config::xmrigPath).toString();
- ui->lineEdit_path->setText(path);
- ui->label_status->hide();
- if(path.isEmpty())
- ui->tabWidget->setCurrentIndex(1);
+ if(!path.isEmpty()) {
+ ui->pathFrame->show();
+ ui->check_custompath->setChecked(true);
+ ui->lineEdit_path->setText(path);
+ }
// pools
+ ui->poolFrame->show();
ui->combo_pools->insertItems(0, m_pools);
auto preferredPool = config()->get(Config::xmrigPool).toString();
if (m_pools.contains(preferredPool))
ui->combo_pools->setCurrentIndex(m_pools.indexOf(preferredPool));
+ else {
+ preferredPool = m_pools.at(0);
+ config()->set(Config::xmrigPool, preferredPool);
+ }
connect(ui->combo_pools, QOverload::of(&QComboBox::currentIndexChanged), this, &XMRigWidget::onPoolChanged);
// info
@@ -81,18 +85,26 @@ XMRigWidget::XMRigWidget(AppContext *ctx, QWidget *parent) :
ui->console->appendPlainText("Invalid path to XMRig binary detected. Please reconfigure on the Settings tab.");
else
ui->console->appendPlainText(QString("XMRig path set to %1").arg(path));
- ui->console->appendPlainText("Ready to mine.");
+ if(m_ctx->isTails) {
+ ui->console->appendPlainText("Mining not available on Tails.");
+ ui->btn_start->setEnabled(false);
+ }
+ else
+ ui->console->appendPlainText("Ready to mine.");
// username/password
connect(ui->lineEdit_password, &QLineEdit::editingFinished, [=]() {
m_ctx->currentWallet->setCacheAttribute("feather.xmrig_password", ui->lineEdit_password->text());
m_ctx->currentWallet->store();
});
-
connect(ui->lineEdit_address, &QLineEdit::editingFinished, [=]() {
m_ctx->currentWallet->setCacheAttribute("feather.xmrig_username", ui->lineEdit_address->text());
m_ctx->currentWallet->store();
});
+
+ // checkbox connects
+ connect(ui->check_custompath, &QCheckBox::stateChanged, this, &XMRigWidget::onCustomPathChecked);
+ connect(ui->check_solo, &QCheckBox::stateChanged, this, &XMRigWidget::onSoloChecked);
}
void XMRigWidget::onWalletClosed() {
@@ -140,30 +152,40 @@ void XMRigWidget::onClearClicked() {
}
void XMRigWidget::onStartClicked() {
- auto pool_name = config()->get(Config::xmrigPool).toString();
+ QString xmrigPath;
+ bool solo = ui->check_solo->isChecked();
+ bool customBinary = ui->check_custompath->isChecked();
- // fix error in config
- if(!m_pools.contains(pool_name)) {
- pool_name = m_pools.at(0);
- config()->set(Config::xmrigPool, pool_name);
- }
+ if(customBinary)
+ xmrigPath = config()->get(Config::xmrigPath).toString();
+ else
+ xmrigPath = m_ctx->XMRig->rigPath;
+ // username is receiving address usually
auto username = m_ctx->currentWallet->getCacheAttribute("feather.xmrig_username");
auto password = m_ctx->currentWallet->getCacheAttribute("feather.xmrig_password");
if(username.isEmpty()) {
- Utils::showMessageBox("Error", "Please specify a receiving address on the Settings screen", true);
+ QString err = "Please specify a receiving address on the Settings screen";
+ ui->console->appendPlainText(err);
+ Utils::showMessageBox("Error", err, true);
return;
}
- m_rig->start(m_threads, pool_name, username, password, ui->relayTor->isChecked(), ui->check_tls->isChecked());
+ QString address;
+ if(solo)
+ address = ui->lineEdit_solo->text().trimmed();
+ else
+ address = config()->get(Config::xmrigPool).toString();
+
+ m_ctx->XMRig->start(xmrigPath, m_threads, address, username, password, ui->relayTor->isChecked(), ui->check_tls->isChecked());
ui->btn_start->setEnabled(false);
ui->btn_stop->setEnabled(true);
emit miningStarted();
}
void XMRigWidget::onStopClicked() {
- m_rig->terminate();
+ m_ctx->XMRig->terminate();
ui->btn_start->setEnabled(true);
ui->btn_stop->setEnabled(false);
ui->label_status->hide();
@@ -257,6 +279,28 @@ void XMRigWidget::showContextMenu(const QPoint &pos) {
m_contextMenu->exec(ui->tableView->viewport()->mapToGlobal(pos));
}
+void XMRigWidget::onCustomPathChecked(int state) {
+ if(state == 2) {
+ ui->pathFrame->show();
+ } else {
+ ui->lineEdit_path->setText("");
+ config()->set(Config::xmrigPath, "");
+ ui->pathFrame->hide();
+ }
+}
+
+void XMRigWidget::onSoloChecked(int state) {
+ if(state == 2) {
+ ui->poolFrame->hide();
+ ui->soloFrame->show();
+ ui->check_tls->setChecked(false);
+ }
+ else {
+ ui->poolFrame->show();
+ ui->soloFrame->hide();
+ }
+}
+
void XMRigWidget::linkClicked() {
QModelIndex index = ui->tableView->currentIndex();
auto download_link = m_urls.at(index.row());
diff --git a/src/widgets/xmrigwidget.h b/src/widgets/xmrigwidget.h
index 4517264..87cdeca 100644
--- a/src/widgets/xmrigwidget.h
+++ b/src/widgets/xmrigwidget.h
@@ -33,14 +33,16 @@ public slots:
void onClearClicked();
void onDownloads(const QJsonObject &data);
void linkClicked();
+ void onProcessError(const QString &msg);
+ void onProcessOutput(const QByteArray &msg);
+ void onHashrate(const QString &hashrate);
+ void onCustomPathChecked(int state);
+ void onSoloChecked(int state);
private slots:
void onBrowseClicked();
- void onProcessError(const QString &msg);
- void onProcessOutput(const QByteArray &msg);
void onThreadsValueChanged(int date);
void onPoolChanged(int pos);
- void onHashrate(const QString &hashrate);
signals:
void miningStarted();
@@ -56,7 +58,6 @@ private:
unsigned int m_threads;
QStringList m_urls;
QStringList m_pools{"pool.xmr.pt:9000", "pool.supportxmr.com:9000", "mine.xmrpool.net:443", "xmrpool.eu:9999", "xmr-eu1.nanopool.org:14433", "pool.minexmr.com:6666", "us-west.minexmr.com:6666", "monerohash.com:9999"};
- XMRig *m_rig;
};
#endif // REDDITWIDGET_H
diff --git a/src/widgets/xmrigwidget.ui b/src/widgets/xmrigwidget.ui
index ced7240..6151a4c 100644
--- a/src/widgets/xmrigwidget.ui
+++ b/src/widgets/xmrigwidget.ui
@@ -29,7 +29,7 @@
-
- 0
+ 1
@@ -125,86 +125,13 @@
Settings
-
+
-
-
-
-
-
- Path to XMRig executable
-
-
-
- -
-
-
-
-
-
- -
-
-
- Browse
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
- Pool
-
-
-
- -
-
-
-
-
-
-
- 0
- 0
-
-
-
-
- -
-
-
- TLS
-
-
-
- -
-
-
- Tor
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
-
+
-
-
@@ -227,22 +154,8 @@
-
-
- -
-
-
- Pool worker name (optional)
-
-
-
- -
-
-
-
-
- -
-
+
Qt::Horizontal
@@ -256,6 +169,204 @@
+ -
+
+
-
+
+
+ Solo mine
+
+
+
+ -
+
+
+ Custom XMRig executable
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+ /path/to/xmrig
+
+
+
+ -
+
+
+ Browse
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+ Pool
+
+
+
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+ Node address
+
+
+
+ -
+
+
-
+
+
+ 127.0.0.1:18081
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+
+
+
+
+
+
-
@@ -266,6 +377,71 @@
-
+ -
+
+
-
+
+
+ Password (optional)
+
+
+
+ -
+
+
-
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Maximum
+
+
+
+ 60
+ 20
+
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+ TLS
+
+
+
+ -
+
+
+ Tor
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
-
diff --git a/utils/build_macos.sh b/utils/build_macos.sh
index cdcbafd..f96db3e 100644
--- a/utils/build_macos.sh
+++ b/utils/build_macos.sh
@@ -10,12 +10,11 @@ rm ~/feather.zip 2>&1 >/dev/null
cd ~/feather
git fetch --all
git reset --hard "$HASH"
-git submodule update --init --depth 50 contrib/tor
-git submodule update --init --depth 50 contrib/torsocks
git submodule update --init --depth 120 monero
git submodule update --init --depth 120 --recursive monero
-CMAKE_PREFIX_PATH=~/Qt/5.15.1/clang_64 make -j3 mac-release
+cp "/Users/administrator/tor/libevent-2.1.7.dylib" "/Users/administrator/feather/src/assets/exec/libevent-2.1.7.dylib"
+CMAKE_PREFIX_PATH="~/Qt/5.15.1/clang_64" TOR="/Users/administrator/tor/tor" XMRIG="/Users/administrator/xmrig/xmrig" make -j3 mac-release
if [[ $? -eq 0 ]]; then
echo "[+] Feather built OK"