495 for (
auto& line : strVec)
498 if (
std::count(line.begin(), line.end(),
':') != 1)
504 if (result.
size() == line.size())
517 boost::filesystem::path p(dbPath);
518 legacy(
"database_path", boost::filesystem::absolute(p).
string());
526 if (strTemp ==
"main")
528 else if (strTemp ==
"testnet")
530 else if (strTemp ==
"devnet")
533 NETWORK_ID = beast::lexicalCastThrow<uint32_t>(strTemp);
541 PEERS_MAX = beast::lexicalCastThrow<std::size_t>(strTemp);
548 peers_in_max = beast::lexicalCastThrow<std::size_t>(strTemp);
549 if (*peers_in_max > 1000)
550 Throw<std::runtime_error>(
551 "Invalid value specified in [" SECTION_PEERS_IN_MAX
552 "] section; the value must be less or equal than 1000");
558 peers_out_max = beast::lexicalCastThrow<std::size_t>(strTemp);
559 if (*peers_out_max < 10 || *peers_out_max > 1000)
560 Throw<std::runtime_error>(
561 "Invalid value specified in [" SECTION_PEERS_OUT_MAX
562 "] section; the value must be in range 10-1000");
566 if ((peers_in_max && !peers_out_max) ||
567 (peers_out_max && !peers_in_max))
568 Throw<std::runtime_error>(
"Both sections [" SECTION_PEERS_IN_MAX
570 "and [" SECTION_PEERS_OUT_MAX
571 "] must be configured");
573 if (peers_in_max && peers_out_max)
582 if (boost::iequals(strTemp,
"tiny"))
584 else if (boost::iequals(strTemp,
"small"))
586 else if (boost::iequals(strTemp,
"medium"))
588 else if (boost::iequals(strTemp,
"large"))
590 else if (boost::iequals(strTemp,
"huge"))
594 4, beast::lexicalCastThrow<std::size_t>(strTemp));
601 ELB_SUPPORT = beast::lexicalCastThrow<bool>(strTemp);
607 SSL_VERIFY = beast::lexicalCastThrow<bool>(strTemp);
611 if (boost::iequals(strTemp,
"all"))
613 else if (boost::iequals(strTemp,
"trusted"))
615 else if (boost::iequals(strTemp,
"drop_untrusted"))
618 Throw<std::runtime_error>(
619 "Invalid value specified in [" SECTION_RELAY_VALIDATIONS
625 if (boost::iequals(strTemp,
"all"))
627 else if (boost::iequals(strTemp,
"trusted"))
629 else if (boost::iequals(strTemp,
"drop_untrusted"))
632 Throw<std::runtime_error>(
633 "Invalid value specified in [" SECTION_RELAY_PROPOSALS
637 if (
exists(SECTION_VALIDATION_SEED) &&
exists(SECTION_VALIDATOR_TOKEN))
638 Throw<std::runtime_error>(
"Cannot have both [" SECTION_VALIDATION_SEED
639 "] and [" SECTION_VALIDATOR_TOKEN
640 "] config sections");
654 if (boost::iequals(strTemp,
"full"))
657 else if (boost::iequals(strTemp,
"none"))
665 if (boost::iequals(strTemp,
"none"))
667 else if (boost::iequals(strTemp,
"full"))
670 FETCH_DEPTH = beast::lexicalCastThrow<std::uint32_t>(strTemp);
678 if (
exists(SECTION_VALIDATION_SEED) ||
exists(SECTION_VALIDATOR_TOKEN))
684 PATH_SEARCH = beast::lexicalCastThrow<int>(strTemp);
697 if (SWEEP_INTERVAL < 10 || SWEEP_INTERVAL > 600)
698 Throw<std::runtime_error>(
"Invalid " SECTION_SWEEP_INTERVAL
699 ": must be between 10 and 600 inclusive");
704 WORKERS = beast::lexicalCastThrow<int>(strTemp);
706 if (WORKERS < 1 || WORKERS > 1024)
707 Throw<std::runtime_error>(
708 "Invalid " SECTION_WORKERS
709 ": must be between 1 and 1024 inclusive.");
714 IO_WORKERS = beast::lexicalCastThrow<int>(strTemp);
716 if (IO_WORKERS < 1 || IO_WORKERS > 1024)
717 Throw<std::runtime_error>(
718 "Invalid " SECTION_IO_WORKERS
719 ": must be between 1 and 1024 inclusive.");
726 if (PREFETCH_WORKERS < 1 || PREFETCH_WORKERS > 1024)
727 Throw<std::runtime_error>(
728 "Invalid " SECTION_PREFETCH_WORKERS
729 ": must be between 1 and 1024 inclusive.");
733 COMPRESSION = beast::lexicalCastThrow<bool>(strTemp);
738 if (
exists(SECTION_REDUCE_RELAY))
740 auto sec =
section(SECTION_REDUCE_RELAY);
748 if (sec.exists(
"vp_base_squelch_enable") && sec.exists(
"vp_enable"))
749 Throw<std::runtime_error>(
750 "Invalid " SECTION_REDUCE_RELAY
751 " cannot specify both vp_base_squelch_enable and vp_enable "
753 "vp_enable was deprecated and replaced by "
754 "vp_base_squelch_enable");
756 if (sec.exists(
"vp_base_squelch_enable"))
758 sec.value_or(
"vp_base_squelch_enable",
false);
759 else if (sec.exists(
"vp_enable"))
761 sec.value_or(
"vp_enable",
false);
771 sec.value_or(
"vp_base_squelch_max_selected_peers", 5);
773 Throw<std::runtime_error>(
774 "Invalid " SECTION_REDUCE_RELAY
775 " vp_base_squelch_max_selected_peers must be "
776 "greater than or equal to 3");
783 if (TX_RELAY_PERCENTAGE < 10 || TX_RELAY_PERCENTAGE > 100 ||
785 Throw<std::runtime_error>(
786 "Invalid " SECTION_REDUCE_RELAY
787 ", tx_min_peers must be greater than or equal to 10"
788 ", tx_relay_percentage must be greater than or equal to 10 "
789 "and less than or equal to 100");
795 beast::lexicalCastThrow<int>(strTemp),
804 Throw<std::runtime_error>(
805 "Invalid " SECTION_SERVER_DOMAIN
806 ": the domain name does not appear to meet the requirements.");
812 if (
exists(SECTION_OVERLAY))
814 auto const sec =
section(SECTION_OVERLAY);
820 if (
auto val = sec.get(
"max_unknown_time"))
822 seconds{beast::lexicalCastThrow<std::uint32_t>(*val)};
826 Throw<std::runtime_error>(
827 "Invalid value 'max_unknown_time' in " SECTION_OVERLAY
828 ": must be of the form '<number>' representing seconds.");
832 Throw<std::runtime_error>(
833 "Invalid value 'max_unknown_time' in " SECTION_OVERLAY
834 ": the time must be between 300 and 1800 seconds, inclusive.");
838 if (
auto val = sec.get(
"max_diverged_time"))
840 seconds{beast::lexicalCastThrow<std::uint32_t>(*val)};
844 Throw<std::runtime_error>(
845 "Invalid value 'max_diverged_time' in " SECTION_OVERLAY
846 ": must be of the form '<number>' representing seconds.");
851 Throw<std::runtime_error>(
852 "Invalid value 'max_diverged_time' in " SECTION_OVERLAY
853 ": the time must be between 60 and 900 seconds, inclusive.");
858 secConfig, SECTION_AMENDMENT_MAJORITY_TIME, strTemp,
j_))
861 boost::regex
const re(
862 "^\\s*(\\d+)\\s*(minutes|hours|days|weeks)\\s*(\\s+.*)?$");
864 if (!boost::regex_match(strTemp,
match, re))
865 Throw<std::runtime_error>(
866 "Invalid " SECTION_AMENDMENT_MAJORITY_TIME
867 ", must be: [0-9]+ [minutes|hours|days|weeks]");
870 beast::lexicalCastThrow<std::uint32_t>(
match[1].str());
872 if (boost::iequals(
match[2],
"minutes"))
874 else if (boost::iequals(
match[2],
"hours"))
876 else if (boost::iequals(
match[2],
"days"))
878 else if (boost::iequals(
match[2],
"weeks"))
882 Throw<std::runtime_error>(
883 "Invalid " SECTION_AMENDMENT_MAJORITY_TIME
884 ", the minimum amount of time an amendment must hold a "
885 "majority is 15 minutes");
902 boost::filesystem::path validatorsFile;
906 validatorsFile = strTemp;
908 if (validatorsFile.empty())
909 Throw<std::runtime_error>(
910 "Invalid path specified in [" SECTION_VALIDATORS_FILE
"]");
912 if (!validatorsFile.is_absolute() && !
CONFIG_DIR.empty())
915 if (!boost::filesystem::exists(validatorsFile))
916 Throw<std::runtime_error>(
917 "The file specified in [" SECTION_VALIDATORS_FILE
920 validatorsFile.string());
923 !boost::filesystem::is_regular_file(validatorsFile) &&
924 !boost::filesystem::is_symlink(validatorsFile))
925 Throw<std::runtime_error>(
926 "Invalid file specified in [" SECTION_VALIDATORS_FILE
928 validatorsFile.string());
934 if (!validatorsFile.empty())
936 if (!boost::filesystem::exists(validatorsFile))
937 validatorsFile.clear();
939 !boost::filesystem::is_regular_file(validatorsFile) &&
940 !boost::filesystem::is_symlink(validatorsFile))
941 validatorsFile.clear();
945 if (!validatorsFile.empty() &&
946 boost::filesystem::exists(validatorsFile) &&
947 (boost::filesystem::is_regular_file(validatorsFile) ||
948 boost::filesystem::is_symlink(validatorsFile)))
950 boost::system::error_code ec;
954 Throw<std::runtime_error>(
955 "Failed to read '" + validatorsFile.string() +
"'." +
972 auto valSiteEntries =
976 section(SECTION_VALIDATOR_LIST_SITES).
append(*valSiteEntries);
984 auto valListThreshold =
987 if (valListThreshold)
988 section(SECTION_VALIDATOR_LIST_THRESHOLD)
989 .
append(*valListThreshold);
991 if (!entries && !valKeyEntries && !valListKeys)
992 Throw<std::runtime_error>(
993 "The file specified in [" SECTION_VALIDATORS_FILE
995 "does not contain a [" SECTION_VALIDATORS
997 "[" SECTION_VALIDATOR_KEYS
999 "[" SECTION_VALIDATOR_LIST_KEYS
1002 validatorsFile.string());
1006 auto const& listThreshold =
1007 section(SECTION_VALIDATOR_LIST_THRESHOLD);
1008 if (listThreshold.lines().empty())
1010 else if (listThreshold.values().size() == 1)
1012 auto strTemp = listThreshold.values()[0];
1013 auto const listThreshold =
1014 beast::lexicalCastThrow<std::size_t>(strTemp);
1015 if (listThreshold == 0)
1019 section(SECTION_VALIDATOR_LIST_KEYS).values().size())
1021 Throw<std::runtime_error>(
1022 "Value in config section "
1023 "[" SECTION_VALIDATOR_LIST_THRESHOLD
1024 "] exceeds the number of configured list keys");
1026 return listThreshold;
1030 Throw<std::runtime_error>(
1032 "[" SECTION_VALIDATOR_LIST_THRESHOLD
1033 "] should contain single value only");
1041 if (!
section(SECTION_VALIDATOR_LIST_SITES).lines().empty() &&
1042 section(SECTION_VALIDATOR_LIST_KEYS).lines().empty())
1044 Throw<std::runtime_error>(
1046 "] config section is missing");
1051 auto const part =
section(
"features");
1052 for (
auto const& s : part.values())
1057 Throw<std::runtime_error>(
1058 "Unknown feature: " + s +
" in config file.");
1074 Throw<std::runtime_error>(
1075 "The minimum number of required peers (network_quorum) exceeds "
1076 "the maximum number of allowed peers (peers_max)");