Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ jobs:
cmake --build build_ci \
--target test_hardening test_share_messages test_coin_broadcaster \
test_redistribute_address test_redistribute test_auto_ratchet \
test_stratum_extensions \
test_stratum_extensions test_stratum_hotel_interim \
core_test sharechain_test share_test btc_share_test \
test_threading test_weights \
test_header_chain test_mempool test_template_builder \
Expand Down Expand Up @@ -267,7 +267,7 @@ jobs:
boost_sentinel \
test_hardening test_share_messages \
test_redistribute_address test_redistribute test_auto_ratchet \
test_stratum_extensions \
test_stratum_extensions test_stratum_hotel_interim \
core_test sharechain_test share_test btc_share_test \
test_threading test_weights \
test_header_chain test_mempool test_template_builder \
Expand Down
13 changes: 13 additions & 0 deletions src/c2pool/main_dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <impl/dash/coin/subsidy.hpp>

#include <core/coin_params.hpp>
#include <core/core_util.hpp> // raise_nofile_limit (hotel interim fix #4)
#include <core/uint256.hpp>
#include <core/netaddress.hpp> // NetService (dashd RPC endpoint)

Expand Down Expand Up @@ -539,6 +540,18 @@ int run_mine_block(bool testnet, const std::string& rpc_endpoint,

int main(int argc, char** argv)
{
// Mining-hotel interim fix #4: raise RLIMIT_NOFILE to 65536 at startup
// (one fd per stratum/miner session + RPC + sharechain P2P; distro-default
// 1024 starves the accept loop). Report the effective soft limit.
{
const uint64_t nofile = core::raise_nofile_limit(65536);
if (nofile == 0)
std::cout << "[init] RLIMIT_NOFILE: unsupported on this platform (or query failed)\n";
else
std::cout << "[init] RLIMIT_NOFILE soft limit: " << nofile
<< (nofile < 65536 ? " (< 65536; hard limit too low)" : "") << "\n";
}

bool want_help = false;
bool want_run = false;
bool want_mine = false;
Expand Down
30 changes: 27 additions & 3 deletions src/c2pool/main_ltc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
// Core includes
#include <core/settings.hpp>
#include <core/fileconfig.hpp>
#include <core/core_util.hpp>
#include <core/coinbase_builder.hpp>
#include <c2pool/storage/the_checkpoint.hpp>
#include <core/pack.hpp>
Expand Down Expand Up @@ -427,7 +428,8 @@
std::cout << " --stratum-max-diff N Maximum per-connection difficulty (default: 65536)\n";
std::cout << " --stratum-target-time N Target seconds per pseudoshare (default: 3)\n";
std::cout << " --no-vardiff Disable automatic difficulty adjustment\n";
std::cout << " --max-coinbase-outputs N Max coinbase outputs per block (default: 4000, matches p2pool)\n\n";
std::cout << " --max-coinbase-outputs N Max coinbase outputs per block (default: 4000, matches p2pool)\n";
std::cout << " --max-stratum-connections N Max concurrent miners on this node (default: 100, 0 = unlimited)\n\n";

std::cout << "EMBEDDED NODE OPTIONS:\n";
std::cout << " --embedded-ltc Use embedded LTC SPV node (no daemon needed)\n";
Expand Down Expand Up @@ -536,7 +538,22 @@

// Initialize logging
core::log::Logger::init();


// Mining-hotel interim fix #4: raise RLIMIT_NOFILE to 65536 at startup.
// One fd per stratum session + HTTP + RPC + P2P + LevelDB — distro-default
// 1024 starves the accept loop under miner churn. Log the effective limit.
{
const uint64_t nofile = core::raise_nofile_limit(65536);
if (nofile == 0)
LOG_WARNING << "RLIMIT_NOFILE: unsupported on this platform (or query failed)";
else if (nofile < 65536)
LOG_WARNING << "RLIMIT_NOFILE soft limit is " << nofile
<< " (< 65536; hard limit too low — raise with ulimit -Hn / limits.conf)";
else
LOG_INFO << "RLIMIT_NOFILE soft limit: " << nofile;
}


// Banner intentionally deferred — only the bordered log-file banner is
// emitted (see post-parse section below). Printing an unbordered copy
// here too cluttered journalctl output with duplicate headers.
Expand Down Expand Up @@ -1042,6 +1059,10 @@
stratum_config.max_coinbase_outputs = static_cast<size_t>(std::stoul(argv[++i]));
cli_explicit.insert("max_coinbase_outputs");
}
else if (arg == "--max-stratum-connections" && i + 1 < argc) {
stratum_config.max_stratum_connections = static_cast<size_t>(std::stoul(argv[++i]));

Check notice

Code scanning / CodeQL

For loop variable changed in body Note

Loop counters should not be modified in the body of the
loop
.
cli_explicit.insert("max_stratum_connections");
}
// Operational tuning
else if (arg == "--log-file" && i + 1 < argc) {
log_file = argv[++i];
Expand Down Expand Up @@ -1252,6 +1273,8 @@
stratum_config.vardiff_enabled = cfg["vardiff_enabled"].as<bool>();
if (!cli_explicit.count("max_coinbase_outputs") && cfg["max_coinbase_outputs"])
stratum_config.max_coinbase_outputs = cfg["max_coinbase_outputs"].as<size_t>();
if (!cli_explicit.count("max_stratum_connections") && cfg["max_stratum_connections"])
stratum_config.max_stratum_connections = cfg["max_stratum_connections"].as<size_t>();

// Operational tuning
if (!cli_explicit.count("log_file") && cfg["log_file"])
Expand Down Expand Up @@ -1890,7 +1913,8 @@
<< " max_diff=" << stratum_config.max_difficulty
<< " target_time=" << stratum_config.target_time << "s"
<< " vardiff=" << (stratum_config.vardiff_enabled ? "on" : "off")
<< " max_cb_outputs=" << stratum_config.max_coinbase_outputs;
<< " max_cb_outputs=" << stratum_config.max_coinbase_outputs
<< " max_stratum_connections=" << stratum_config.max_stratum_connections;
LOG_INFO << "Operational config: p2p_max_peers=" << p2p_max_peers
<< " ban_duration=" << p2p_ban_duration << "s"
<< " rss_limit=" << rss_limit_mb << "MB"
Expand Down
36 changes: 36 additions & 0 deletions src/core/core_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

#include <ctime>

#ifndef _WIN32
#include <sys/resource.h>
#endif

namespace core
{

Expand All @@ -10,4 +14,36 @@ uint32_t timestamp()
return std::time(nullptr);
}

uint64_t raise_nofile_limit(uint64_t target)
{
#ifndef _WIN32
struct rlimit rl{};
if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
return 0;

if (rl.rlim_cur != RLIM_INFINITY && static_cast<uint64_t>(rl.rlim_cur) < target) {
struct rlimit want = rl;
// Clamp to the hard limit — unprivileged processes cannot exceed it.
if (rl.rlim_max == RLIM_INFINITY
|| static_cast<uint64_t>(rl.rlim_max) >= target)
want.rlim_cur = static_cast<rlim_t>(target);
else
want.rlim_cur = rl.rlim_max;
// Best effort: on failure the original soft limit stays in effect.
(void)setrlimit(RLIMIT_NOFILE, &want);
}

if (getrlimit(RLIMIT_NOFILE, &rl) != 0)
return 0;
if (rl.rlim_cur == RLIM_INFINITY)
return UINT64_MAX;
return static_cast<uint64_t>(rl.rlim_cur);
#else
// Windows: no setrlimit; socket handles are not fd-table bound the same
// way. Report "unsupported" and let the caller log accordingly.
(void)target;
return 0;
#endif
}

} // namespace core
10 changes: 10 additions & 0 deletions src/core/core_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,14 @@ namespace core
// core <-> {pool, ltc, c2pool} static-link cycle (V36 SCC gate).
uint32_t timestamp();

// Raise the process RLIMIT_NOFILE soft limit to `target` (default 65536),
// clamped to the hard limit. Mining-hotel interim fix #4: a capped node
// still holds one fd per stratum session + HTTP + RPC + P2P + LevelDB —
// distro defaults (1024) starve the accept loop under miner churn.
//
// Returns the soft limit actually in effect after the call (even if raising
// failed), or 0 where unsupported (non-POSIX). Deliberately log-free (this
// leaf is dependency-free) — callers log the returned value at startup.
uint64_t raise_nofile_limit(uint64_t target = 65536);

} // namespace core
Loading
Loading