476 for (
auto& line : strVec)
479 if (
std::count(line.begin(), line.end(),
':') != 1)
485 if (result.
size() == line.size())
498 boost::filesystem::path p(dbPath);
499 legacy(
"database_path", boost::filesystem::absolute(p).
string());
507 if (strTemp ==
"main")
509 else if (strTemp ==
"testnet")
511 else if (strTemp ==
"devnet")
514 NETWORK_ID = beast::lexicalCastThrow<uint32_t>(strTemp);
522 PEERS_MAX = beast::lexicalCastThrow<std::size_t>(strTemp);
529 peers_in_max = beast::lexicalCastThrow<std::size_t>(strTemp);
530 if (*peers_in_max > 1000)
531 Throw<std::runtime_error>(
532 "Invalid value specified in [" SECTION_PEERS_IN_MAX
533 "] section; the value must be less or equal than 1000");
539 peers_out_max = beast::lexicalCastThrow<std::size_t>(strTemp);
540 if (*peers_out_max < 10 || *peers_out_max > 1000)
541 Throw<std::runtime_error>(
542 "Invalid value specified in [" SECTION_PEERS_OUT_MAX
543 "] section; the value must be in range 10-1000");
547 if ((peers_in_max && !peers_out_max) ||
548 (peers_out_max && !peers_in_max))
549 Throw<std::runtime_error>(
"Both sections [" SECTION_PEERS_IN_MAX
551 "and [" SECTION_PEERS_OUT_MAX
552 "] must be configured");
554 if (peers_in_max && peers_out_max)
563 if (boost::iequals(strTemp,
"tiny"))
565 else if (boost::iequals(strTemp,
"small"))
567 else if (boost::iequals(strTemp,
"medium"))
569 else if (boost::iequals(strTemp,
"large"))
571 else if (boost::iequals(strTemp,
"huge"))
575 4, beast::lexicalCastThrow<std::size_t>(strTemp));
582 ELB_SUPPORT = beast::lexicalCastThrow<bool>(strTemp);
588 SSL_VERIFY = beast::lexicalCastThrow<bool>(strTemp);
592 if (boost::iequals(strTemp,
"all"))
594 else if (boost::iequals(strTemp,
"trusted"))
596 else if (boost::iequals(strTemp,
"drop_untrusted"))
599 Throw<std::runtime_error>(
600 "Invalid value specified in [" SECTION_RELAY_VALIDATIONS
606 if (boost::iequals(strTemp,
"all"))
608 else if (boost::iequals(strTemp,
"trusted"))
610 else if (boost::iequals(strTemp,
"drop_untrusted"))
613 Throw<std::runtime_error>(
614 "Invalid value specified in [" SECTION_RELAY_PROPOSALS
618 if (
exists(SECTION_VALIDATION_SEED) &&
exists(SECTION_VALIDATOR_TOKEN))
619 Throw<std::runtime_error>(
"Cannot have both [" SECTION_VALIDATION_SEED
620 "] and [" SECTION_VALIDATOR_TOKEN
621 "] config sections");
635 if (boost::iequals(strTemp,
"full"))
638 else if (boost::iequals(strTemp,
"none"))
646 if (boost::iequals(strTemp,
"none"))
648 else if (boost::iequals(strTemp,
"full"))
651 FETCH_DEPTH = beast::lexicalCastThrow<std::uint32_t>(strTemp);
659 if (
exists(SECTION_VALIDATION_SEED) ||
exists(SECTION_VALIDATOR_TOKEN))
665 PATH_SEARCH = beast::lexicalCastThrow<int>(strTemp);
678 if (SWEEP_INTERVAL < 10 || SWEEP_INTERVAL > 600)
679 Throw<std::runtime_error>(
"Invalid " SECTION_SWEEP_INTERVAL
680 ": must be between 10 and 600 inclusive");
685 WORKERS = beast::lexicalCastThrow<int>(strTemp);
687 if (WORKERS < 1 || WORKERS > 1024)
688 Throw<std::runtime_error>(
689 "Invalid " SECTION_WORKERS
690 ": must be between 1 and 1024 inclusive.");
695 IO_WORKERS = beast::lexicalCastThrow<int>(strTemp);
697 if (IO_WORKERS < 1 || IO_WORKERS > 1024)
698 Throw<std::runtime_error>(
699 "Invalid " SECTION_IO_WORKERS
700 ": must be between 1 and 1024 inclusive.");
707 if (PREFETCH_WORKERS < 1 || PREFETCH_WORKERS > 1024)
708 Throw<std::runtime_error>(
709 "Invalid " SECTION_PREFETCH_WORKERS
710 ": must be between 1 and 1024 inclusive.");
714 COMPRESSION = beast::lexicalCastThrow<bool>(strTemp);
719 if (
exists(SECTION_REDUCE_RELAY))
721 auto sec =
section(SECTION_REDUCE_RELAY);
729 if (sec.exists(
"vp_base_squelch_enable") && sec.exists(
"vp_enable"))
730 Throw<std::runtime_error>(
731 "Invalid " SECTION_REDUCE_RELAY
732 " cannot specify both vp_base_squelch_enable and vp_enable "
734 "vp_enable was deprecated and replaced by "
735 "vp_base_squelch_enable");
737 if (sec.exists(
"vp_base_squelch_enable"))
739 sec.value_or(
"vp_base_squelch_enable",
false);
740 else if (sec.exists(
"vp_enable"))
742 sec.value_or(
"vp_enable",
false);
752 sec.value_or(
"vp_base_squelch_max_selected_peers", 5);
754 Throw<std::runtime_error>(
755 "Invalid " SECTION_REDUCE_RELAY
756 " vp_base_squelch_max_selected_peers must be "
757 "greater than or equal to 3");
764 if (TX_RELAY_PERCENTAGE < 10 || TX_RELAY_PERCENTAGE > 100 ||
766 Throw<std::runtime_error>(
767 "Invalid " SECTION_REDUCE_RELAY
768 ", tx_min_peers must be greater than or equal to 10"
769 ", tx_relay_percentage must be greater than or equal to 10 "
770 "and less than or equal to 100");
776 beast::lexicalCastThrow<int>(strTemp),
785 Throw<std::runtime_error>(
786 "Invalid " SECTION_SERVER_DOMAIN
787 ": the domain name does not appear to meet the requirements.");
793 if (
exists(SECTION_OVERLAY))
795 auto const sec =
section(SECTION_OVERLAY);
801 if (
auto val = sec.get(
"max_unknown_time"))
803 seconds{beast::lexicalCastThrow<std::uint32_t>(*val)};
807 Throw<std::runtime_error>(
808 "Invalid value 'max_unknown_time' in " SECTION_OVERLAY
809 ": must be of the form '<number>' representing seconds.");
813 Throw<std::runtime_error>(
814 "Invalid value 'max_unknown_time' in " SECTION_OVERLAY
815 ": the time must be between 300 and 1800 seconds, inclusive.");
819 if (
auto val = sec.get(
"max_diverged_time"))
821 seconds{beast::lexicalCastThrow<std::uint32_t>(*val)};
825 Throw<std::runtime_error>(
826 "Invalid value 'max_diverged_time' in " SECTION_OVERLAY
827 ": must be of the form '<number>' representing seconds.");
832 Throw<std::runtime_error>(
833 "Invalid value 'max_diverged_time' in " SECTION_OVERLAY
834 ": the time must be between 60 and 900 seconds, inclusive.");
839 secConfig, SECTION_AMENDMENT_MAJORITY_TIME, strTemp,
j_))
842 boost::regex
const re(
843 "^\\s*(\\d+)\\s*(minutes|hours|days|weeks)\\s*(\\s+.*)?$");
845 if (!boost::regex_match(strTemp,
match, re))
846 Throw<std::runtime_error>(
847 "Invalid " SECTION_AMENDMENT_MAJORITY_TIME
848 ", must be: [0-9]+ [minutes|hours|days|weeks]");
851 beast::lexicalCastThrow<std::uint32_t>(
match[1].str());
853 if (boost::iequals(
match[2],
"minutes"))
855 else if (boost::iequals(
match[2],
"hours"))
857 else if (boost::iequals(
match[2],
"days"))
859 else if (boost::iequals(
match[2],
"weeks"))
863 Throw<std::runtime_error>(
864 "Invalid " SECTION_AMENDMENT_MAJORITY_TIME
865 ", the minimum amount of time an amendment must hold a "
866 "majority is 15 minutes");
883 boost::filesystem::path validatorsFile;
887 validatorsFile = strTemp;
889 if (validatorsFile.empty())
890 Throw<std::runtime_error>(
891 "Invalid path specified in [" SECTION_VALIDATORS_FILE
"]");
893 if (!validatorsFile.is_absolute() && !
CONFIG_DIR.empty())
896 if (!boost::filesystem::exists(validatorsFile))
897 Throw<std::runtime_error>(
898 "The file specified in [" SECTION_VALIDATORS_FILE
901 validatorsFile.string());
904 !boost::filesystem::is_regular_file(validatorsFile) &&
905 !boost::filesystem::is_symlink(validatorsFile))
906 Throw<std::runtime_error>(
907 "Invalid file specified in [" SECTION_VALIDATORS_FILE
909 validatorsFile.string());
915 if (!validatorsFile.empty())
917 if (!boost::filesystem::exists(validatorsFile))
918 validatorsFile.clear();
920 !boost::filesystem::is_regular_file(validatorsFile) &&
921 !boost::filesystem::is_symlink(validatorsFile))
922 validatorsFile.clear();
926 if (!validatorsFile.empty() &&
927 boost::filesystem::exists(validatorsFile) &&
928 (boost::filesystem::is_regular_file(validatorsFile) ||
929 boost::filesystem::is_symlink(validatorsFile)))
931 boost::system::error_code ec;
935 Throw<std::runtime_error>(
936 "Failed to read '" + validatorsFile.string() +
"'." +
953 auto valSiteEntries =
957 section(SECTION_VALIDATOR_LIST_SITES).
append(*valSiteEntries);
965 auto valListThreshold =
968 if (valListThreshold)
969 section(SECTION_VALIDATOR_LIST_THRESHOLD)
970 .
append(*valListThreshold);
972 if (!entries && !valKeyEntries && !valListKeys)
973 Throw<std::runtime_error>(
974 "The file specified in [" SECTION_VALIDATORS_FILE
976 "does not contain a [" SECTION_VALIDATORS
978 "[" SECTION_VALIDATOR_KEYS
980 "[" SECTION_VALIDATOR_LIST_KEYS
983 validatorsFile.string());
987 auto const& listThreshold =
988 section(SECTION_VALIDATOR_LIST_THRESHOLD);
989 if (listThreshold.lines().empty())
991 else if (listThreshold.values().size() == 1)
993 auto strTemp = listThreshold.values()[0];
994 auto const listThreshold =
995 beast::lexicalCastThrow<std::size_t>(strTemp);
996 if (listThreshold == 0)
1000 section(SECTION_VALIDATOR_LIST_KEYS).values().size())
1002 Throw<std::runtime_error>(
1003 "Value in config section "
1004 "[" SECTION_VALIDATOR_LIST_THRESHOLD
1005 "] exceeds the number of configured list keys");
1007 return listThreshold;
1011 Throw<std::runtime_error>(
1013 "[" SECTION_VALIDATOR_LIST_THRESHOLD
1014 "] should contain single value only");
1022 if (!
section(SECTION_VALIDATOR_LIST_SITES).lines().empty() &&
1023 section(SECTION_VALIDATOR_LIST_KEYS).lines().empty())
1025 Throw<std::runtime_error>(
1027 "] config section is missing");
1032 auto const part =
section(
"features");
1033 for (
auto const& s : part.values())
1038 Throw<std::runtime_error>(
1039 "Unknown feature: " + s +
" in config file.");
1055 Throw<std::runtime_error>(
1056 "The minimum number of required peers (network_quorum) exceeds "
1057 "the maximum number of allowed peers (peers_max)");