20 #include <ripple/basics/contract.h>
21 #include <ripple/core/Config.h>
22 #include <ripple/core/ConfigSections.h>
23 #include <ripple/server/Port.h>
24 #include <boost/filesystem.hpp>
25 #include <boost/format.hpp>
28 #include <test/jtx/TestSuite.h>
29 #include <test/unit_test/FileDirGuard.h>
36 static boost::format configContentsTemplate(R
"rippleConfig(
45 admin = 127.0.0.1, ::1
64 #-------------------------------------------------------------------------------
69 # This is primary persistent datastore for rippled. This includes transaction
70 # metadata, account states, and ledger headers. Helpful information can be
71 # found here: https://ripple.com/wiki/NodeBackEnd
72 # delete old ledgers while maintaining at least 2000. Do not require an
73 # external administrative command to initiate deletion.
76 path=/Users/dummy/ripple/config/db/rocksdb
87 # This needs to be an absolute directory reference, not a relative one.
88 # Modify this value as required.
90 /Users/dummy/ripple/config/log/debug.log
98 # Where to find some other servers speaking the Ripple protocol.
103 # Turn down default logging to save disk space in the long run.
104 # Valid values here are trace, debug, info, warning, error, and fatal
106 { "command": "log_level", "severity": "warning" }
108 # Defaults to 1 ("yes") so that certificates will be validated. To allow the use
109 # of self-signed certificates for development or internal use, set to 0 ("no").
118 dbPath.empty() ? "" :
"[database_path]\n" + dbPath;
120 validatorsFile.
empty() ?
"" :
"[validators_file]\n" + validatorsFile;
121 return boost::str(configContentsTemplate % dbPathSection % valFileSection);
138 beast::unit_test::suite& test,
141 path const& validatorsFile,
142 bool useCounter =
true)
171 return file().string();
177 return boost::filesystem::is_directory(
dataDir_);
190 using namespace boost::filesystem;
210 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
211 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
212 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
213 n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
214 n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
217 nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
218 nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
219 nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
221 [validator_list_sites]
222 recommendedripplevalidators.com
223 moreripplevalidators.net
225 [validator_list_keys]
226 03E74EE14CB525AFBB9F1B7D86CD58ECC4B91452294B42AB4E78F260BD905C091D
227 030775A669685BD6ABCEBD80385921C7851783D991A8055FD21D2F3966C96F1B56
239 beast::unit_test::suite& test,
241 path const& validatorsFileName,
242 bool useCounter =
true)
247 validatorsFileName.empty() ?
Config::validatorsFileName
248 : validatorsFileName),
263 return absolute(
file()).string();
275 using path = boost::filesystem::path;
297 BEAST_EXPECT(c.legacy("ssl_verify") ==
"0");
298 expectException([&c] { c.
legacy(
"server"); });
301 BEAST_EXPECT(c.
legacy(
"not_in_file") ==
"");
302 c.
legacy(
"not_in_file",
"new_value");
303 BEAST_EXPECT(c.
legacy(
"not_in_file") ==
"new_value");
308 testcase(
"database_path");
310 using namespace boost::filesystem;
312 boost::format cc(
"[database_path]\n%1%\n");
314 auto const cwd = current_path();
315 path const dataDirRel(
"test_data_dir");
316 path const dataDirAbs(cwd / dataDirRel);
321 BEAST_EXPECT(c.
legacy(
"database_path") == dataDirAbs.string());
327 BEAST_EXPECT(c.
legacy(
"database_path") == dataDirAbs.string());
335 BEAST_EXPECT(c.
legacy(
"database_path") ==
"");
340 auto const cwd = current_path();
342 path const dataDirRel(
"test_data_dir");
343 path const dataDirAbs(cwd / g0.
subdir() / dataDirRel);
345 *
this, g0.
subdir(), dataDirAbs,
"",
false);
346 auto const& c(g.
config());
349 BEAST_EXPECT(c.legacy(
"database_path") == dataDirAbs.string());
355 auto const& c(g.
config());
359 BEAST_EXPECT(c.legacy(
"database_path") == nativeDbPath);
364 auto const& c(g.
config());
369 BEAST_EXPECT(c.legacy(
"database_path") == nativeDbPath);
376 testcase(
"validator keys");
381 "eyJ2YWxpZGF0aW9uX3ByaXZhdGVfa2V5IjoiOWVkNDVmODY2MjQxY2MxOGEyNzQ3Yj"
382 "U0Mzg3YzA2MjU5MDc5NzJmNGU3MTkwMjMxZmFhOTM3NDU3ZmE5ZGFmNiIsIm1hbmlm"
383 "ZXN0IjoiSkFBQUFBRnhJZTFGdHdtaW12R3RIMmlDY01KcUM5Z1ZGS2lsR2Z3MS92Q3"
384 "hIWFhMcGxjMkduTWhBa0UxYWdxWHhCd0R3RGJJRDZPTVNZdU0wRkRBbHBBZ05rOFNL"
385 "Rm43TU8yZmRrY3dSUUloQU9uZ3U5c0FLcVhZb3VKK2wyVjBXK3NBT2tWQitaUlM2UF"
386 "NobEpBZlVzWGZBaUJzVkpHZXNhYWRPSmMvYUFab2tTMXZ5bUdtVnJsSFBLV1gzWXl3"
387 "dTZpbjhIQVNRS1B1Z0JENjdrTWFSRkd2bXBBVEhsR0tKZHZERmxXUFl5NUFxRGVkRn"
388 "Y1VEphMncwaTIxZXEzTVl5d0xWSlpuRk9yN0Mwa3cyQWlUelNDakl6ZGl0UTg9In0"
393 static boost::format configTemplate(R
"rippleConfig(
401 auto const expectedError =
402 "Cannot have both [validation_seed] "
403 "and [validator_token] config sections";
413 BEAST_EXPECT(error == expectedError);
420 testcase(
"validators_file");
422 using namespace boost::filesystem;
425 boost::format cc(
"[validators_file]\n%1%\n");
427 std::string const missingPath =
"/no/way/this/path/exists";
428 auto const expectedError =
429 "The file specified in [validators_file] does not exist: " +
440 BEAST_EXPECT(error == expectedError);
445 *
this,
"test_cfg",
"validators.cfg");
446 path const invalidFile = current_path() / vtg.
subdir();
447 boost::format cc(
"[validators_file]\n%1%\n");
449 auto const expectedError =
450 "Invalid file specified in [validators_file]: " +
451 invalidFile.string();
461 BEAST_EXPECT(error == expectedError);
468 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
469 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
470 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
473 nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
474 nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
477 BEAST_EXPECT(c.legacy("validators_file").empty());
484 [validator_list_sites]
486 trustthesevalidators.gov
488 [validator_list_keys]
489 021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
496 "ripplevalidators.com");
499 "trustthesevalidators.gov");
504 "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801"
512 [validator_list_sites]
514 trustthesevalidators.gov
517 auto const expectedError =
518 "[validator_list_keys] config section is missing";
527 BEAST_EXPECT(error == expectedError);
532 *
this,
"test_cfg",
"validators.cfg");
535 boost::format cc(
"[validators_file]\n%1%\n");
549 *
this,
"test_cfg", valFileName);
551 *
this, vtg.
subdir(),
"", valFileName,
false);
554 auto const& c(rcg.
config());
555 BEAST_EXPECT(c.legacy(
"validators_file") == valFileName);
556 BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
558 c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
560 c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
566 *
this,
"test_cfg",
"validators.txt");
567 auto const valFilePath =
".." / vtg.
subdir() /
"validators.txt";
569 *
this, vtg.
subdir(),
"", valFilePath,
false);
572 auto const& c(rcg.
config());
573 BEAST_EXPECT(c.legacy(
"validators_file") == valFilePath);
574 BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
576 c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
578 c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
583 *
this,
"test_cfg",
"validators.txt");
585 *
this, vtg.
subdir(),
"",
"",
false);
588 auto const& c(rcg.
config());
589 BEAST_EXPECT(c.legacy(
"validators_file").empty());
590 BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
592 c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
594 c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
600 *
this,
"test_cfg",
"validators.cfg");
603 *
this, vtg.
subdir(),
"validators.txt",
false);
608 auto const& c(rcg.
config());
609 BEAST_EXPECT(c.legacy(
"validators_file") == vtg.
validatorsFile());
610 BEAST_EXPECT(c.section(SECTION_VALIDATORS).values().size() == 8);
612 c.section(SECTION_VALIDATOR_LIST_SITES).values().size() == 2);
614 c.section(SECTION_VALIDATOR_LIST_KEYS).values().size() == 2);
619 boost::format cc(R
"rippleConfig(
624 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
625 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
626 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
627 n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
628 n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
631 nHB1X37qrniVugfQcuBTAjswphC1drx7QjFFojJPZwKHHnt8kU7v
632 nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
634 [validator_list_sites]
636 trustthesevalidators.gov
638 [validator_list_keys]
639 021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
642 *
this,
"test_cfg",
"validators.cfg");
658 boost::format cc(
"[validators_file]\n%1%\n");
661 *
this,
"test_cfg",
"validators.cfg");
663 auto const expectedError =
664 "The file specified in [validators_file] does not contain a "
665 "[validators], [validator_keys] or [validator_list_keys] "
678 BEAST_EXPECT(error == expectedError);
686 *
this,
"testSetup", explicitPath ?
"test_db" :
"",
"");
698 BEAST_EXPECT(!config.
quiet());
699 BEAST_EXPECT(!config.
silent());
702 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
711 BEAST_EXPECT(config.
quiet());
712 BEAST_EXPECT(!config.
silent());
715 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
724 BEAST_EXPECT(config.
quiet());
725 BEAST_EXPECT(config.
silent());
728 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
737 BEAST_EXPECT(config.
quiet());
738 BEAST_EXPECT(config.
silent());
741 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
750 BEAST_EXPECT(!config.
quiet());
751 BEAST_EXPECT(!config.
silent());
755 config.
legacy(
"database_path").empty() == !explicitPath);
764 BEAST_EXPECT(config.
quiet());
765 BEAST_EXPECT(!config.
silent());
769 config.
legacy(
"database_path").empty() == !explicitPath);
778 BEAST_EXPECT(config.
quiet());
779 BEAST_EXPECT(config.
silent());
783 config.
legacy(
"database_path").empty() == !explicitPath);
792 BEAST_EXPECT(config.
quiet());
793 BEAST_EXPECT(config.
silent());
797 config.
legacy(
"database_path").empty() == !explicitPath);
805 auto const& conf = cfg.
config();
806 if (!BEAST_EXPECT(conf.exists(
"port_rpc")))
808 if (!BEAST_EXPECT(conf.exists(
"port_wss_admin")))
811 if (!unexcept([&]() {
parse_Port(rpc, conf[
"port_rpc"], log); }))
815 if (!unexcept([&]() {
parse_Port(wss, conf[
"port_wss_admin"], log); }))
853 cfg.exists(SECTION_IPS) &&
854 cfg.section(SECTION_IPS).lines().size() == 1 &&
855 cfg.section(SECTION_IPS).values().size() == 1);
857 cfg.exists(SECTION_IPS_FIXED) &&
858 cfg.section(SECTION_IPS_FIXED).lines().size() == 2 &&
859 cfg.section(SECTION_IPS_FIXED).values().size() == 2);
865 struct TestCommentData
874 {{
"password = aaaa\\#bbbb",
"password",
"aaaa#bbbb",
false},
875 {
"password = aaaa#bbbb",
"password",
"aaaa",
true},
876 {
"password = aaaa #bbbb",
"password",
"aaaa",
true},
878 {
"password = #aaaa #bbbb",
"",
"password =",
true},
879 {
"password = aaaa\\# #bbbb",
"password",
"aaaa#",
true},
880 {
"password = aaaa\\##bbbb",
"password",
"aaaa#",
true},
881 {
"aaaa#bbbb",
"",
"aaaa",
true},
882 {
"aaaa\\#bbbb",
"",
"aaaa#bbbb",
false},
883 {
"aaaa\\##bbbb",
"",
"aaaa#",
true},
884 {
"aaaa #bbbb",
"",
"aaaa",
true},
885 {
"1 #comment",
"",
"1",
true},
886 {
"#whole thing is comment",
"",
"",
false},
887 {
" #whole comment with space",
"",
"",
false}}};
889 for (
auto const& t : tests)
892 s.append(t.line.data());
893 BEAST_EXPECT(s.had_trailing_comments() == t.had_comment);
896 BEAST_EXPECTS(s.legacy() == t.expect, s.legacy());
901 BEAST_EXPECTS(
set(field, t.field.data(), s), t.line);
902 BEAST_EXPECTS(field == t.expect, t.line);
908 s.append(
"online_delete = 3000");
910 BEAST_EXPECT(
set(od,
"online_delete", s));
911 BEAST_EXPECTS(od == 3000, *(s.get<
std::string>(
"online_delete")));
916 s.
append(
"online_delete = 2000 #my comment on this");
918 BEAST_EXPECT(
set(od,
"online_delete", s));
919 BEAST_EXPECTS(od == 2000, *(s.
get<
std::string>(
"online_delete")));
926 using namespace std::string_literals;
927 Section s{
"MySection"};
928 s.append(
"a_string = mystring");
929 s.append(
"positive_int = 2");
930 s.append(
"negative_int = -3");
931 s.append(
"bool_ish = 1");
934 auto val_1 =
"value 1"s;
935 BEAST_EXPECT(
set(val_1,
"a_string", s));
936 BEAST_EXPECT(val_1 ==
"mystring");
938 auto val_2 =
"value 2"s;
939 BEAST_EXPECT(!
set(val_2,
"not_a_key", s));
940 BEAST_EXPECT(val_2 ==
"value 2");
941 BEAST_EXPECT(!
set(val_2,
"default"s,
"not_a_key", s));
942 BEAST_EXPECT(val_2 ==
"default");
944 auto val_3 = get<std::string>(s,
"a_string");
945 BEAST_EXPECT(val_3 ==
"mystring");
946 auto val_4 = get<std::string>(s,
"not_a_key");
947 BEAST_EXPECT(val_4 ==
"");
948 auto val_5 = get<std::string>(s,
"not_a_key",
"default");
949 BEAST_EXPECT(val_5 ==
"default");
951 auto val_6 =
"value 6"s;
953 BEAST_EXPECT(val_6 ==
"mystring");
955 auto val_7 =
"value 7"s;
957 BEAST_EXPECT(val_7 ==
"value 7");
962 BEAST_EXPECT(
set(val_1,
"positive_int", s));
963 BEAST_EXPECT(val_1 == 2);
966 BEAST_EXPECT(
set(val_2,
"negative_int", s));
967 BEAST_EXPECT(val_2 == -3);
970 BEAST_EXPECT(!
set(val_3,
"a_string", s));
971 BEAST_EXPECT(val_3 == 3);
973 auto val_4 = get<int>(s,
"positive_int");
974 BEAST_EXPECT(val_4 == 2);
975 auto val_5 = get<int>(s,
"not_a_key");
976 BEAST_EXPECT(val_5 == 0);
977 auto val_6 = get<int>(s,
"not_a_key", 5);
978 BEAST_EXPECT(val_6 == 5);
979 auto val_7 = get<int>(s,
"a_string", 6);
980 BEAST_EXPECT(val_7 == 6);
984 BEAST_EXPECT(val_8 == 2);
988 BEAST_EXPECT(val_9 == 9);
992 BEAST_EXPECT(val_10 == 10);
994 BEAST_EXPECT(s.get<
int>(
"not_a_key") == boost::none);
997 s.get<
int>(
"a_string");
1000 catch (boost::bad_lexical_cast&)
1007 bool flag_1 =
false;
1009 BEAST_EXPECT(flag_1 ==
true);
1011 bool flag_2 =
false;
1013 BEAST_EXPECT(flag_2 ==
false);
1020 testcase(
"amendment");
1030 {
"seconds", 1, 15 * 60,
false},
1031 {
"minutes", 60, 14,
false},
1032 {
"minutes", 60, 15,
true},
1033 {
"hours", 3600, 10,
true},
1034 {
"days", 86400, 10,
true},
1035 {
"weeks", 604800, 2,
true},
1036 {
"months", 2592000, 1,
false},
1037 {
"years", 31536000, 1,
false}};
1040 for (
auto& [unit, sec, val, shouldPass] : units)
1044 [amendment_majority_time]
1051 c.loadFromString(toLoad);
1054 c.AMENDMENT_MAJORITY_TIME.count() == val * sec);
1071 testcase(
"overlay: unknown time");
1078 c.loadFromString(
"[overlay]\nmax_unknown_time=" + value);
1079 return c.MAX_UNKNOWN_TIME;
1088 BEAST_EXPECT(!testUnknown(
"none"));
1089 BEAST_EXPECT(!testUnknown(
"0.5"));
1090 BEAST_EXPECT(!testUnknown(
"180 seconds"));
1091 BEAST_EXPECT(!testUnknown(
"9 minutes"));
1094 BEAST_EXPECT(!testUnknown(
"299"));
1103 BEAST_EXPECT(!testUnknown(
"1801"));
1105 testcase(
"overlay: diverged time");
1113 c.loadFromString(
"[overlay]\nmax_diverged_time=" + value);
1114 return c.MAX_DIVERGED_TIME;
1123 BEAST_EXPECT(!testDiverged(
"none"));
1124 BEAST_EXPECT(!testDiverged(
"0.5"));
1125 BEAST_EXPECT(!testDiverged(
"180 seconds"));
1126 BEAST_EXPECT(!testDiverged(
"9 minutes"));
1129 BEAST_EXPECT(!testDiverged(
"0"));
1130 BEAST_EXPECT(!testDiverged(
"59"));
1139 BEAST_EXPECT(!testDiverged(
"901"));
1147 testValidatorKeys();
1148 testValidatorsFile();