fix xmrig bundling issues

This commit is contained in:
dan_s
2026-03-11 21:14:03 -05:00
parent 06c80ef51c
commit 36b67e69d0
6 changed files with 86 additions and 12 deletions

View File

@@ -1855,10 +1855,34 @@ bool App::startEmbeddedDaemon()
}
DEBUG_LOGF("Sapling params extracted successfully\n");
} else {
daemon_status_ = "Sapling parameters not found. They should be in: " + rpc::Connection::getSaplingParamsDir();
DEBUG_LOGF("Sapling params not found and no embedded resources available!\n");
DEBUG_LOGF("Expected location: %s\n", rpc::Connection::getSaplingParamsDir().c_str());
return false;
// Fallback: check for params bundled alongside the executable
// (zip distributions bundle sapling-*.params next to the binary)
namespace fs = std::filesystem;
std::string exe_dir = util::Platform::getExecutableDirectory();
std::string daemon_dir = resources::getDaemonDirectory();
const char* paramFiles[] = { "sapling-spend.params", "sapling-output.params", "asmap.dat" };
bool copied = false;
if (!exe_dir.empty()) {
std::error_code ec;
fs::create_directories(daemon_dir, ec);
for (const char* name : paramFiles) {
fs::path src = fs::path(exe_dir) / name;
fs::path dst = fs::path(daemon_dir) / name;
if (fs::exists(src) && !fs::exists(dst)) {
DEBUG_LOGF("Copying bundled %s from exe dir to %s\n", name, daemon_dir.c_str());
fs::copy_file(src, dst, ec);
if (!ec) copied = true;
}
}
}
if (copied && rpc::Connection::verifySaplingParams()) {
DEBUG_LOGF("Sapling params copied from exe directory successfully\n");
} else {
daemon_status_ = "Sapling parameters not found. They should be in: " + rpc::Connection::getSaplingParamsDir();
DEBUG_LOGF("Sapling params not found and no embedded resources available!\n");
DEBUG_LOGF("Expected location: %s\n", rpc::Connection::getSaplingParamsDir().c_str());
return false;
}
}
}

View File

@@ -466,6 +466,18 @@ bool XmrigManager::startProcess(const std::string& xmrigPath, const std::string&
dup2(pipefd[1], STDERR_FILENO);
close(pipefd[1]);
// Detach from controlling terminal's stdin to prevent SIGTTIN/SIGTTOU
// when running in a new process group (setpgid below).
int devnull = open("/dev/null", O_RDONLY);
if (devnull >= 0) {
dup2(devnull, STDIN_FILENO);
close(devnull);
}
// Ignore job-control signals that a background process group may receive
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
// New process group so we can kill the whole group
setpgid(0, 0);

View File

@@ -509,6 +509,18 @@ std::string getXmrigPath()
return xmrigName;
}
// Check alongside the wallet executable (zip / AppImage distributions)
{
std::string exeDir = util::Platform::getExecutableDirectory();
if (!exeDir.empty()) {
std::string exeDirPath = exeDir + "/" + xmrigName;
if (std::filesystem::exists(exeDirPath)) {
DEBUG_LOGF("[INFO] getXmrigPath: found alongside wallet at %s\n", exeDirPath.c_str());
return exeDirPath;
}
}
}
// Check development paths
#ifdef _WIN32
// Not applicable for cross-compiled Windows builds

View File

@@ -153,10 +153,15 @@ void RenderMiningTab(App* app)
s_pool_mode = app->settings()->getPoolMode();
strncpy(s_pool_url, app->settings()->getPoolUrl().c_str(), sizeof(s_pool_url) - 1);
strncpy(s_pool_worker, app->settings()->getPoolWorker().c_str(), sizeof(s_pool_worker) - 1);
// If pool worker is empty or placeholder, default to user's first address
s_pool_state_loaded = true;
}
// Default pool worker to user's first shielded address once addresses are available
{
static bool s_pool_worker_defaulted = false;
std::string workerStr(s_pool_worker);
if (workerStr.empty() || workerStr == "x") {
if (!s_pool_worker_defaulted && !state.addresses.empty() &&
(workerStr.empty() || workerStr == "x")) {
std::string defaultAddr;
for (const auto& addr : state.addresses) {
if (addr.type == "shielded" && !addr.address.empty()) {
@@ -175,9 +180,10 @@ void RenderMiningTab(App* app)
if (!defaultAddr.empty()) {
strncpy(s_pool_worker, defaultAddr.c_str(), sizeof(s_pool_worker) - 1);
s_pool_worker[sizeof(s_pool_worker) - 1] = '\0';
s_pool_settings_dirty = true;
}
s_pool_worker_defaulted = true;
}
s_pool_state_loaded = true;
}
// Persist pool settings when dirty and no field is active