diff --git a/src/daemon/embedded_daemon.cpp b/src/daemon/embedded_daemon.cpp index 68c97cf..0e83df9 100644 --- a/src/daemon/embedded_daemon.cpp +++ b/src/daemon/embedded_daemon.cpp @@ -591,16 +591,23 @@ bool EmbeddedDaemon::start(const std::string& binary_path) args.push_back("-maxconnections=" + std::to_string(max_connections_)); } + // The user's own DRAGONX.conf wins over our flags (a command-line flag would override it): read the + // conf once, for a normal start only (an isolated start has its own datadir + conf and keeps the pin). + std::string conf; + if (override_datadir_.empty()) { + std::ifstream in((fs::path(util::Platform::getDragonXDataDir()) / "DRAGONX.conf").string(), std::ios::binary); + if (in) conf.assign(std::istreambuf_iterator(in), std::istreambuf_iterator()); + if (confSetsKey(conf, "dbcache")) { + DEBUG_LOGF("[INFO] DRAGONX.conf sets dbcache; not pinning -dbcache\n"); + } + dropPinnedDbcacheIfConfSets(args, conf); + } + // More RPC workers for a node we launch: dragonxd's default 8 workers + 16-deep queue fill up with // requests waiting behind a long cs_main holder (a witness rebuild), after which even "stop" is refused. // The GUI itself no longer floods it; this is headroom for dragonx-cli and other clients — a delay, // not a fix. Not for an isolated start, and DRAGONX.conf wins (a flag would override the user's own). if (override_datadir_.empty()) { - std::string conf; - { - std::ifstream in((fs::path(util::Platform::getDragonXDataDir()) / "DRAGONX.conf").string(), std::ios::binary); - if (in) conf.assign(std::istreambuf_iterator(in), std::istreambuf_iterator()); - } if (!confSetsKey(conf, "rpcthreads")) args.push_back("-rpcthreads=16"); } diff --git a/src/daemon/embedded_daemon.h b/src/daemon/embedded_daemon.h index d341b72..47be8b1 100644 --- a/src/daemon/embedded_daemon.h +++ b/src/daemon/embedded_daemon.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include @@ -424,6 +425,18 @@ public: return false; } + /** + * Drop the wallet's own -dbcache= pin from `args` when the user's DRAGONX.conf sets dbcache (a + * command-line flag overrides the conf, so the user's own value must win). Pure; no logging. + */ + static void dropPinnedDbcacheIfConfSets(std::vector& args, const std::string& conf) + { + if (!confSetsKey(conf, "dbcache")) return; + args.erase(std::remove_if(args.begin(), args.end(), + [](const std::string& a) { return a.rfind("-dbcache=", 0) == 0; }), + args.end()); + } + /** Decision returned by evaluateDatadirLockGate(): whether start() may spawn now. */ struct StartLockGateDecision { bool proceed = true; // false => bail before spawning diff --git a/tests/test_phase4.cpp b/tests/test_phase4.cpp index 34597ef..3a10869 100644 --- a/tests/test_phase4.cpp +++ b/tests/test_phase4.cpp @@ -6859,6 +6859,25 @@ void testConfSetsKey() EXPECT_FALSE(EmbeddedDaemon::confSetsKey("rpcworkqueue=64 # rpcthreads=4\n", "rpcthreads")); } +// C97: a user dbcache= in DRAGONX.conf wins over the wallet's -dbcache pin; default argv is unchanged. +void testDropPinnedDbcache() +{ + using dragonx::daemon::EmbeddedDaemon; + const std::vector base{"-a", "-dbcache=450", "-b"}; + auto run = [&](const std::string& conf) { + std::vector v = base; + EmbeddedDaemon::dropPinnedDbcacheIfConfSets(v, conf); + return v; + }; + const std::vector dropped{"-a", "-b"}; + EXPECT_TRUE(run("dbcache=1000") == dropped); + EXPECT_TRUE(run(" dbcache = 8\r\n") == dropped); + EXPECT_TRUE(run("rpcuser=x\ndbcache=2000\n") == dropped); + EXPECT_TRUE(run("#dbcache=1") == base); + EXPECT_TRUE(run("") == base); + EXPECT_TRUE(run("rpcuser=x") == base); +} + // S12: the ownership record names the node we launched, by pid AND start time, so a later session can // recognise it after "Leave running" — and a reused pid, or a record from before a reboot, never matches. void testOwnershipRecord() @@ -18655,6 +18674,7 @@ int main() testDatadirLockGate(); testDaemonProcessIdentity(); testConfSetsKey(); + testDropPinnedDbcache(); testOwnershipRecord(); testDebugLogTailRules(); testNoteConsolidation();