diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -11,3 +11,10 @@ the RPC commands `walletcreatefundedpsbt` and `fundrawtransaction` will now fail instead of rounding down the fee. Beware that the `feeRate` argument is specified in BCH per kilobyte, not satoshi per byte. + +Seeder +------ + +- Added the `datadir` option to the seeder allowing a directory to be + specified for the files the seeder writes to and reads from (default is the + `~/.bitcoin/seeder` directory). See help for more details. diff --git a/src/seeder/main.cpp b/src/seeder/main.cpp --- a/src/seeder/main.cpp +++ b/src/seeder/main.cpp @@ -96,6 +96,36 @@ ipv6_proxy = gArgs.GetArg("-proxyipv6", DEFAULT_IPV6_PROXY); SelectParams(gArgs.GetChainName()); + if (!gArgs.IsArgSet("-datadir")) { + fs::path path = GetDefaultDataDir() / "seeder"; + gArgs.ForceSetArg("-datadir", path.string()); + fs::create_directories(path); + } + + if (!CheckDataDirOption()) { + tfm::format(std::cerr, + "Specified data directory \"%s\" does not exist.\n", + gArgs.GetArg("-datadir", "")); + return EXIT_FAILURE; + } + + // Warn about relative -datadir path + if (gArgs.IsArgSet("-datadir") && + !fs::path(gArgs.GetArg("-datadir", "")).is_absolute()) { + tfm::format( + std::cout, + "Warning: relative datadir option '%s' specified, which will " + "be interpreted relative to the current working directory " + "'%s'. This is fragile, because if the seeder is started in " + "the future from a different location, it will be unable to " + "locate the current data files.\n", + gArgs.GetArg("-datadir", ""), fs::current_path().string()); + } + tfm::format(std::cout, "Default data directory %s\n", + GetDefaultDataDir().string() + "/seeder"); + tfm::format(std::cout, "Using data directory %s\n", + GetDataDir().string()); + if (gArgs.IsArgSet("-filter")) { // Parse whitelist additions std::string flagString = gArgs.GetArg("-filter", ""); @@ -156,6 +186,10 @@ gArgs.AddArg("-help-debug", "Show all debugging options (usage: --help -help-debug)", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + gArgs.AddArg( + "-datadir=", + "Specifies the directory that the seeder reads from and writes to.", + ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); SetupChainParamsBaseOptions(); gArgs.AddArg("-help", "", ArgsManager::ALLOW_ANY, @@ -384,15 +418,16 @@ { std::vector v = db.GetAll(); sort(v.begin(), v.end(), StatCompare); - FILE *f = fsbridge::fopen("dnsseed.dat.new", "w+"); + FILE *f = fsbridge::fopen(GetDataDir() / "dnsseed.dat.new", "w+"); if (f) { { CAutoFile cf(f, SER_DISK, CLIENT_VERSION); cf << db; } - rename("dnsseed.dat.new", "dnsseed.dat"); + rename(GetDataDir() / "dnsseed.dat.new", + GetDataDir() / "dnsseed.dat"); } - fsbridge::ofstream d{"dnsseed.dump"}; + fsbridge::ofstream d{GetDataDir() / "dnsseed.dump"}; tfm::format( d, "# address good " "lastSuccess %%(2h) %%(8h) %%(1d) %%(7d) " @@ -415,7 +450,8 @@ stat[3] += rep.uptime[3]; stat[4] += rep.uptime[4]; } - fsbridge::ofstream ff{"dnsstats.log", std::ios_base::app}; + fsbridge::ofstream ff{GetDataDir() / "dnsstats.log", + std::ios_base::app}; tfm::format(ff, "%llu %g %g %g %g %g\n", (unsigned long long)(time(nullptr)), stat[0], stat[1], stat[2], stat[3], stat[4]); @@ -536,7 +572,8 @@ tfm::format(std::cerr, "No e-mail address set. Please use -m.\n"); return EXIT_FAILURE; } - FILE *f = fsbridge::fopen("dnsseed.dat", "r"); + + FILE *f = fsbridge::fopen(GetDataDir() / "dnsseed.dat", "r"); if (f) { tfm::format(std::cout, "Loading dnsseed.dat..."); CAutoFile cf(f, SER_DISK, CLIENT_VERSION);