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 <test/jtx/TestSuite.h>
25 #include <test/unit_test/FileDirGuard.h>
26 #include <boost/filesystem.hpp>
27 #include <boost/format.hpp>
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;
122 configContentsTemplate % dbPathSection % valFileSection);
140 path const& validatorsFile,
141 bool useCounter =
true)
163 return file().string();
168 return boost::filesystem::is_directory (
dataDir_);
180 using namespace boost::filesystem;
184 test_.log <<
"Skipping rm dir: "
190 test_.log <<
"Error in ~RippledCfgGuard: "
200 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
201 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
202 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
203 n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
204 n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
207 nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
208 nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
209 nHUPDdcdb2Y5DZAJne4c2iabFuAP3F34xZUgYQT2NH7qfkdapgnz
211 [validator_list_sites]
212 recommendedripplevalidators.com
213 moreripplevalidators.net
215 [validator_list_keys]
216 03E74EE14CB525AFBB9F1B7D86CD58ECC4B91452294B42AB4E78F260BD905C091D
217 030775A669685BD6ABCEBD80385921C7851783D991A8055FD21D2F3966C96F1B56
229 path subDir,
path const& validatorsFileName,
230 bool useCounter =
true)
233 validatorsFileName.empty () ?
Config::validatorsFileName :
247 return absolute(
file()).string();
259 using path = boost::filesystem::path;
280 BEAST_EXPECT(c.legacy ("ssl_verify") ==
"0");
281 expectException ([&c] {c.
legacy (
"server");});
284 BEAST_EXPECT(c.
legacy (
"not_in_file") ==
"");
285 c.
legacy (
"not_in_file",
"new_value");
286 BEAST_EXPECT(c.
legacy (
"not_in_file") ==
"new_value");
290 testcase (
"database_path");
292 using namespace boost::filesystem;
294 boost::format cc (
"[database_path]\n%1%\n");
296 auto const cwd = current_path ();
297 path const dataDirRel (
"test_data_dir");
298 path const dataDirAbs (cwd / dataDirRel);
303 BEAST_EXPECT(c.
legacy (
"database_path") == dataDirAbs.string ());
309 BEAST_EXPECT(c.
legacy (
"database_path") == dataDirAbs.string ());
317 BEAST_EXPECT(c.
legacy (
"database_path") ==
"");
322 auto const cwd = current_path ();
324 path const dataDirRel (
"test_data_dir");
325 path const dataDirAbs(cwd / g0.
subdir () / dataDirRel);
327 dataDirAbs,
"",
false);
328 auto const& c (g.
config ());
331 BEAST_EXPECT(c.legacy (
"database_path") == dataDirAbs.string ());
337 auto const& c (g.
config ());
341 BEAST_EXPECT(c.legacy (
"database_path") == nativeDbPath);
346 auto const& c (g.
config ());
353 BEAST_EXPECT(c.legacy (
"database_path") == nativeDbPath);
359 testcase (
"validator keys");
364 "eyJ2YWxpZGF0aW9uX3ByaXZhdGVfa2V5IjoiOWVkNDVmODY2MjQxY2MxOGEyNzQ3Yj"
365 "U0Mzg3YzA2MjU5MDc5NzJmNGU3MTkwMjMxZmFhOTM3NDU3ZmE5ZGFmNiIsIm1hbmlm"
366 "ZXN0IjoiSkFBQUFBRnhJZTFGdHdtaW12R3RIMmlDY01KcUM5Z1ZGS2lsR2Z3MS92Q3"
367 "hIWFhMcGxjMkduTWhBa0UxYWdxWHhCd0R3RGJJRDZPTVNZdU0wRkRBbHBBZ05rOFNL"
368 "Rm43TU8yZmRrY3dSUUloQU9uZ3U5c0FLcVhZb3VKK2wyVjBXK3NBT2tWQitaUlM2UF"
369 "NobEpBZlVzWGZBaUJzVkpHZXNhYWRPSmMvYUFab2tTMXZ5bUdtVnJsSFBLV1gzWXl3"
370 "dTZpbjhIQVNRS1B1Z0JENjdrTWFSRkd2bXBBVEhsR0tKZHZERmxXUFl5NUFxRGVkRn"
371 "Y1VEphMncwaTIxZXEzTVl5d0xWSlpuRk9yN0Mwa3cyQWlUelNDakl6ZGl0UTg9In0=";
375 static boost::format configTemplate (R
"rippleConfig(
383 auto const expectedError =
384 "Cannot have both [validation_seed] "
385 "and [validator_token] config sections";
392 BEAST_EXPECT(error == expectedError);
398 testcase (
"validators_file");
400 using namespace boost::filesystem;
403 boost::format cc (
"[validators_file]\n%1%\n");
405 std::string const missingPath =
"/no/way/this/path/exists";
406 auto const expectedError =
407 "The file specified in [validators_file] does not exist: " +
415 BEAST_EXPECT(error == expectedError);
420 *
this,
"test_cfg",
"validators.cfg");
421 path const invalidFile = current_path () / vtg.
subdir ();
422 boost::format cc (
"[validators_file]\n%1%\n");
424 auto const expectedError =
425 "Invalid file specified in [validators_file]: " +
426 invalidFile.string ();
433 BEAST_EXPECT(error == expectedError);
440 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
441 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
442 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
445 nHUhG1PgAG8H8myUENypM35JgfqXAKNQvRVVAFDRzJrny5eZN8d5
446 nHBu9PTL9dn2GuZtdW4U2WzBwffyX9qsQCd9CNU4Z5YG3PQfViM8
449 BEAST_EXPECT(c.legacy ("validators_file").empty ());
456 [validator_list_sites]
458 trustthesevalidators.gov
460 [validator_list_keys]
461 021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
468 "ripplevalidators.com");
471 "trustthesevalidators.gov");
476 "021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566");
483 [validator_list_sites]
485 trustthesevalidators.gov
488 auto const expectedError =
489 "[validator_list_keys] config section is missing";
495 BEAST_EXPECT(error == expectedError);
500 *
this,
"test_cfg",
"validators.cfg");
503 boost::format cc (
"[validators_file]\n%1%\n");
517 *
this,
"test_cfg", valFileName);
519 *
this, vtg.
subdir (),
"", valFileName,
false);
522 auto const& c (rcg.
config ());
523 BEAST_EXPECT(c.legacy (
"validators_file") == valFileName);
524 BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
526 c.section (SECTION_VALIDATOR_LIST_SITES).values ().size () == 2);
528 c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
534 *
this,
"test_cfg",
"validators.txt");
535 auto const valFilePath =
".." / vtg.
subdir() /
"validators.txt";
537 *
this, vtg.
subdir (),
"", valFilePath,
false);
540 auto const& c (rcg.
config ());
541 BEAST_EXPECT(c.legacy (
"validators_file") == valFilePath);
542 BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
544 c.section (SECTION_VALIDATOR_LIST_SITES).values ().size () == 2);
546 c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
551 *
this,
"test_cfg",
"validators.txt");
556 auto const& c (rcg.
config ());
557 BEAST_EXPECT(c.legacy (
"validators_file").empty ());
558 BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
560 c.section (SECTION_VALIDATOR_LIST_SITES).values ().size () == 2);
562 c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
568 *
this,
"test_cfg",
"validators.cfg");
571 *
this, vtg.
subdir (),
"validators.txt",
false);
576 auto const& c (rcg.
config ());
577 BEAST_EXPECT(c.legacy (
"validators_file") == vtg.
validatorsFile ());
578 BEAST_EXPECT(c.section (SECTION_VALIDATORS).values ().size () == 8);
580 c.section (SECTION_VALIDATOR_LIST_SITES).values ().size () == 2);
582 c.section (SECTION_VALIDATOR_LIST_KEYS).values ().size () == 2);
587 boost::format cc (R
"rippleConfig(
592 n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
593 n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
594 n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
595 n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
596 n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
599 nHB1X37qrniVugfQcuBTAjswphC1drx7QjFFojJPZwKHHnt8kU7v
600 nHUkAWDR4cB8AgPg7VXMX6et8xRTQb2KJfgv1aBEXozwrawRKgMB
602 [validator_list_sites]
604 trustthesevalidators.gov
606 [validator_list_keys]
607 021A99A537FDEBC34E4FCA03B39BEADD04299BB19E85097EC92B15A3518801E566
610 *
this,
"test_cfg",
"validators.cfg");
626 boost::format cc (
"[validators_file]\n%1%\n");
629 *
this,
"test_cfg",
"validators.cfg");
631 auto const expectedError =
632 "The file specified in [validators_file] does not contain a "
633 "[validators], [validator_keys] or [validator_list_keys] section: " +
642 BEAST_EXPECT(error == expectedError);
649 explicitPath ?
"test_db" :
"",
"");
658 BEAST_EXPECT(!config.
quiet());
659 BEAST_EXPECT(!config.
silent());
662 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
668 BEAST_EXPECT(config.
quiet());
669 BEAST_EXPECT(!config.
silent());
672 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
678 BEAST_EXPECT(config.
quiet());
679 BEAST_EXPECT(config.
silent());
682 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
688 BEAST_EXPECT(config.
quiet());
689 BEAST_EXPECT(config.
silent());
692 BEAST_EXPECT(!config.
legacy(
"database_path").empty());
698 BEAST_EXPECT(!config.
quiet());
699 BEAST_EXPECT(!config.
silent());
702 BEAST_EXPECT(config.
legacy(
"database_path").empty() == !explicitPath);
708 BEAST_EXPECT(config.
quiet());
709 BEAST_EXPECT(!config.
silent());
712 BEAST_EXPECT(config.
legacy(
"database_path").empty() == !explicitPath);
718 BEAST_EXPECT(config.
quiet());
719 BEAST_EXPECT(config.
silent());
722 BEAST_EXPECT(config.
legacy(
"database_path").empty() == !explicitPath);
728 BEAST_EXPECT(config.
quiet());
729 BEAST_EXPECT(config.
silent());
732 BEAST_EXPECT(config.
legacy(
"database_path").empty() == !explicitPath);
739 auto const& conf = cfg.
config();
740 if (!BEAST_EXPECT(conf.exists(
"port_rpc")))
742 if (!BEAST_EXPECT(conf.exists(
"port_wss_admin")))
745 if (!unexcept([&]() {
parse_Port (rpc, conf[
"port_rpc"], log); }))
749 if (!unexcept([&]() {
parse_Port (wss, conf[
"port_wss_admin"], log); }))
760 [port_rpc])" "\x20" R
"(
767 [ips_fixed])" "\x20\x20" R
"(
775 cfg.exists ("port_rpc") &&
779 cfg.exists (SECTION_IPS) &&
780 cfg.section (SECTION_IPS).lines ().size () == 1 &&
781 cfg.section (SECTION_IPS).values ().size () == 1);
783 cfg.exists (SECTION_IPS_FIXED) &&
784 cfg.section (SECTION_IPS_FIXED).lines ().size () == 2 &&
785 cfg.section (SECTION_IPS_FIXED).values ().size () == 2);
791 struct TestCommentData
800 {
"password = aaaa\\#bbbb",
"password",
"aaaa#bbbb",
false},
801 {
"password = aaaa#bbbb",
"password",
"aaaa",
true},
802 {
"password = aaaa #bbbb",
"password",
"aaaa",
true},
804 {
"password = #aaaa #bbbb",
"",
"password =",
true},
805 {
"password = aaaa\\# #bbbb",
"password",
"aaaa#",
true},
806 {
"password = aaaa\\##bbbb",
"password",
"aaaa#",
true},
807 {
"aaaa#bbbb",
"",
"aaaa",
true},
808 {
"aaaa\\#bbbb",
"",
"aaaa#bbbb",
false},
809 {
"aaaa\\##bbbb",
"",
"aaaa#",
true},
810 {
"aaaa #bbbb",
"",
"aaaa",
true},
811 {
"1 #comment",
"",
"1",
true},
812 {
"#whole thing is comment",
"",
"",
false},
813 {
" #whole comment with space",
"",
"",
false}
816 for (
auto const& t : tests)
819 s.append(t.line.data());
820 BEAST_EXPECT(s.had_trailing_comments() == t.had_comment);
823 BEAST_EXPECTS(s.legacy() == t.expect, s.legacy());
828 BEAST_EXPECTS(
set(field, t.field.data(), s), t.line);
829 BEAST_EXPECTS(field == t.expect, t.line);
835 s.append(
"online_delete = 3000");
837 BEAST_EXPECT(
set(od,
"online_delete", s));
838 BEAST_EXPECTS(od == 3000, *(s.get<
std::string>(
"online_delete")));
843 s.
append(
"online_delete = 2000 #my comment on this");
845 BEAST_EXPECT(
set(od,
"online_delete", s));
846 BEAST_EXPECTS(od == 2000, *(s.
get<
std::string>(
"online_delete")));
852 using namespace std::string_literals;
853 Section s {
"MySection"};
854 s.
append(
"a_string = mystring");
855 s.
append(
"positive_int = 2");
856 s.
append(
"negative_int = -3");
860 auto val_1 =
"value 1"s;
861 BEAST_EXPECT(
set(val_1,
"a_string", s));
862 BEAST_EXPECT(val_1 ==
"mystring");
864 auto val_2 =
"value 2"s;
865 BEAST_EXPECT(!
set(val_2,
"not_a_key", s));
866 BEAST_EXPECT(val_2 ==
"value 2");
867 BEAST_EXPECT(!
set(val_2,
"default"s,
"not_a_key", s));
868 BEAST_EXPECT(val_2 ==
"default");
870 auto val_3 = get<std::string>(s,
"a_string");
871 BEAST_EXPECT(val_3 ==
"mystring");
872 auto val_4 = get<std::string>(s,
"not_a_key");
873 BEAST_EXPECT(val_4 ==
"");
874 auto val_5 = get<std::string>(s,
"not_a_key",
"default");
875 BEAST_EXPECT(val_5 ==
"default");
877 auto val_6 =
"value 6"s;
879 BEAST_EXPECT(val_6 ==
"mystring");
881 auto val_7 =
"value 7"s;
883 BEAST_EXPECT(val_7 ==
"value 7");
888 BEAST_EXPECT(
set(val_1,
"positive_int", s));
889 BEAST_EXPECT(val_1 == 2);
892 BEAST_EXPECT(
set(val_2,
"negative_int", s));
893 BEAST_EXPECT(val_2 == -3);
896 BEAST_EXPECT(!
set(val_3,
"a_string", s));
897 BEAST_EXPECT(val_3 == 3);
899 auto val_4 = get<int>(s,
"positive_int");
900 BEAST_EXPECT(val_4 == 2);
901 auto val_5 = get<int>(s,
"not_a_key");
902 BEAST_EXPECT(val_5 == 0);
903 auto val_6 = get<int>(s,
"not_a_key", 5);
904 BEAST_EXPECT(val_6 == 5);
905 auto val_7 = get<int>(s,
"a_string", 6);
906 BEAST_EXPECT(val_7 == 6);
910 BEAST_EXPECT(val_8 == 2);
914 BEAST_EXPECT(val_9 == 9);
918 BEAST_EXPECT(val_10 == 10);
920 BEAST_EXPECT(s.
get<
int>(
"not_a_key") == boost::none);
923 s.
get<
int>(
"a_string");
926 catch(boost::bad_lexical_cast&)
935 BEAST_EXPECT(flag_1 ==
true);
939 BEAST_EXPECT(flag_2 ==
false);
947 testValidatorKeys ();
948 testValidatorsFile ();