20 #include <ripple/core/Config.h>
21 #include <ripple/core/ConfigSections.h>
22 #include <ripple/basics/contract.h>
23 #include <ripple/basics/FileUtilities.h>
24 #include <ripple/basics/Log.h>
25 #include <ripple/json/json_reader.h>
26 #include <ripple/protocol/Feature.h>
27 #include <ripple/protocol/SystemParameters.h>
28 #include <ripple/net/HTTPClient.h>
29 #include <ripple/beast/core/LexicalCast.h>
30 #include <boost/beast/core/string.hpp>
31 #include <boost/algorithm/string.hpp>
32 #include <boost/format.hpp>
33 #include <boost/regex.hpp>
34 #include <boost/system/error_code.hpp>
50 {{ 10, 30, 60, 90, 120 }} },
52 {{ 128000, 256000, 512000, 768000, 2048000 }} },
54 {{ 30, 60, 90, 120, 900 }} },
56 {{ 32, 128, 256, 384, 768 }} },
58 {{ 30, 90, 180, 240, 900 }} },
60 {{ 2, 3, 4, 5, 8 }} },
62 {{ 16384, 32768, 131072, 262144, 524288 }} },
64 {{ 60, 90, 120, 900, 1800 }} },
66 {{ 4, 12, 24, 64, 128 }} },
68 {{ 4, 12, 24, 64, 128 }} },
70 {{ 4, 8, 16, 32, 128 }} },
75 static_assert([]() constexpr ->
bool
88 }(),
"Mismatch between sized item enum & array indices");
94 #define SECTION_DEFAULT_NAME ""
104 boost::algorithm::replace_all (strData,
"\r\n",
"\n");
107 boost::algorithm::replace_all (strData,
"\r",
"\n");
109 boost::algorithm::split (vLines, strData,
110 boost::algorithm::is_any_of (
"\n"));
116 secResult[strSection] = IniFileSections::mapped_type ();
119 for (
auto& strValue : vLines)
122 boost::algorithm::trim (strValue);
124 if (strValue.empty () || strValue[0] ==
'#')
128 else if (strValue[0] ==
'[' && strValue[strValue.length () - 1] ==
']')
131 strSection = strValue.
substr (1, strValue.length () - 2);
132 secResult.
emplace(strSection, IniFileSections::mapped_type{});
137 if (!strValue.empty ())
138 secResult[strSection].push_back (strValue);
145 IniFileSections::mapped_type*
148 IniFileSections::iterator it;
149 IniFileSections::mapped_type* smtResult;
150 it = secSource.
find (strSection);
151 if (it == secSource.
end ())
154 smtResult = & (it->second);
161 IniFileSections::mapped_type* pmtEntries =
163 bool bSingle = pmtEntries && 1 == pmtEntries->size ();
167 strValue = (*pmtEntries)[0];
171 JLOG (j.
warn()) << boost::str (
172 boost::format (
"Section [%s]: requires 1 line not %d lines.") %
173 strSection % pmtEntries->
size ());
195 auto const v = getenv (name);
206 bool bSilent,
bool bStandalone)
208 QUIET = bQuiet || bSilent;
214 bool bSilent,
bool bStandalone)
216 boost::filesystem::path dataDir;
229 if (!strConf.
empty())
230 strConfFile = strConf;
234 if (!strConf.
empty ())
244 CONFIG_DIR = boost::filesystem::current_path ();
256 || (strHome.
empty () && (strXdgConfigHome.
empty () || strXdgDataHome.
empty ())))
262 if (strXdgConfigHome.
empty ())
265 strXdgConfigHome = strHome +
"/.config";
268 if (strXdgDataHome.
empty ())
271 strXdgDataHome = strHome +
"/.local/share";
276 dataDir = strXdgDataHome +
"/" +
systemName ();
292 if (!dbPath.
empty ())
293 dataDir = boost::filesystem::path (dbPath);
298 if (!dataDir.empty())
300 boost::system::error_code ec;
301 boost::filesystem::create_directories(dataDir, ec);
304 Throw<std::runtime_error>(
305 boost::str(boost::format(
"Can not create %s") % dataDir));
307 legacy(
"database_path", boost::filesystem::absolute(dataDir).
string());
324 boost::system::error_code ec;
330 ec.value() <<
": " << ec.message() <<
std::endl;
356 boost::filesystem::path p(dbPath);
358 boost::filesystem::absolute (p).
string ());
365 PEER_PRIVATE = beast::lexicalCastThrow <bool> (strTemp);
368 PEERS_MAX = beast::lexicalCastThrow <std::size_t> (strTemp);
372 if (boost::iequals(strTemp,
"tiny"))
374 else if (boost::iequals(strTemp,
"small"))
376 else if (boost::iequals(strTemp,
"medium"))
378 else if (boost::iequals(strTemp,
"large"))
380 else if (boost::iequals(strTemp,
"huge"))
384 beast::lexicalCastThrow<std::size_t>(strTemp));
391 ELB_SUPPORT = beast::lexicalCastThrow <bool> (strTemp);
400 SSL_VERIFY = beast::lexicalCastThrow <bool> (strTemp);
402 if (
exists(SECTION_VALIDATION_SEED) &&
exists(SECTION_VALIDATOR_TOKEN))
403 Throw<std::runtime_error> (
404 "Cannot have both [" SECTION_VALIDATION_SEED
"] "
405 "and [" SECTION_VALIDATOR_TOKEN
"] config sections");
417 FEE_DEFAULT = beast::lexicalCastThrow <std::uint64_t>(strTemp);
421 if (boost::iequals(strTemp,
"full"))
423 else if (boost::iequals(strTemp,
"none"))
426 LEDGER_HISTORY = beast::lexicalCastThrow <std::uint32_t> (strTemp);
431 if (boost::iequals(strTemp,
"none"))
433 else if (boost::iequals(strTemp,
"full"))
436 FETCH_DEPTH = beast::lexicalCastThrow <std::uint32_t> (strTemp);
445 PATH_SEARCH = beast::lexicalCastThrow <int> (strTemp);
455 WORKERS = beast::lexicalCastThrow <std::size_t> (strTemp);
458 COMPRESSION = beast::lexicalCastThrow <bool> (strTemp);
471 boost::filesystem::path validatorsFile;
475 validatorsFile = strTemp;
477 if (validatorsFile.empty ())
478 Throw<std::runtime_error> (
479 "Invalid path specified in [" SECTION_VALIDATORS_FILE
"]");
481 if (!validatorsFile.is_absolute() && !
CONFIG_DIR.empty())
484 if (!boost::filesystem::exists (validatorsFile))
485 Throw<std::runtime_error> (
486 "The file specified in [" SECTION_VALIDATORS_FILE
"] "
487 "does not exist: " + validatorsFile.string());
489 else if (!boost::filesystem::is_regular_file (validatorsFile) &&
490 !boost::filesystem::is_symlink (validatorsFile))
491 Throw<std::runtime_error> (
492 "Invalid file specified in [" SECTION_VALIDATORS_FILE
"]: " +
493 validatorsFile.string());
499 if (!validatorsFile.empty ())
501 if(!boost::filesystem::exists (validatorsFile))
502 validatorsFile.clear();
503 else if (!boost::filesystem::is_regular_file (validatorsFile) &&
504 !boost::filesystem::is_symlink (validatorsFile))
505 validatorsFile.clear();
509 if (!validatorsFile.empty () &&
510 boost::filesystem::exists (validatorsFile) &&
511 (boost::filesystem::is_regular_file (validatorsFile) ||
512 boost::filesystem::is_symlink (validatorsFile)))
514 boost::system::error_code ec;
518 Throw<std::runtime_error>(
"Failed to read '" +
519 validatorsFile.string() +
"'." +
534 SECTION_VALIDATOR_KEYS);
541 SECTION_VALIDATOR_LIST_SITES);
544 section (SECTION_VALIDATOR_LIST_SITES).
append (*valSiteEntries);
548 SECTION_VALIDATOR_LIST_KEYS);
553 if (!entries && !valKeyEntries && !valListKeys)
554 Throw<std::runtime_error> (
555 "The file specified in [" SECTION_VALIDATORS_FILE
"] "
556 "does not contain a [" SECTION_VALIDATORS
"], "
557 "[" SECTION_VALIDATOR_KEYS
"] or "
558 "[" SECTION_VALIDATOR_LIST_KEYS
"]"
560 validatorsFile.string());
565 section (SECTION_VALIDATOR_KEYS).lines ());
567 if (!
section (SECTION_VALIDATOR_LIST_SITES).lines().empty() &&
568 section (SECTION_VALIDATOR_LIST_KEYS).lines().empty())
570 Throw<std::runtime_error> (
572 "] config section is missing");
577 auto const part =
section(
"features");
578 for(
auto const& s : part.values())
583 Throw<std::runtime_error>(
584 "Unknown feature: " + s +
" in config file.");
600 Throw<std::runtime_error>(
601 "The minimum number of required peers (network_quorum) exceeds "
602 "the maximum number of allowed peers (peers_max)");
611 if (!log_file.empty () && !log_file.is_absolute ())
615 log_file = boost::filesystem::absolute (
619 if (!log_file.empty ())
621 auto log_dir = log_file.parent_path ();
623 if (!boost::filesystem::is_directory (log_dir))
625 boost::system::error_code ec;
626 boost::filesystem::create_directories (log_dir, ec);
633 "Unable to create log file path " << log_dir <<
634 ": " << ec.message() <<
'\n';
647 assert(!node || *node <= 4);