int main(int argc, char* const* argv) { using namespace stellar; Logging::init(); if (sodium_init() != 0) { LOG(FATAL) << "Could not initialize crypto"; return 1; } std::string cfgFile("stellar-core.cfg"); std::string command; el::Level logLevel = el::Level::Info; std::vector<char*> rest; optional<bool> forceSCP = nullptr; bool base64 = false; bool doCatchupAt = false; uint32_t catchupAtTarget = 0; bool doCatchupComplete = false; bool doCatchupRecent = false; uint32_t catchupRecentCount = 0; bool doCatchupTo = false; uint32_t catchupToTarget = 0; bool inferQuorum = false; bool checkQuorum = false; bool graphQuorum = false; bool newDB = false; bool getOfflineInfo = false; auto doReportLastHistoryCheckpoint = false; std::string outputFile; std::string loadXdrBucket; std::vector<std::string> newHistories; std::vector<std::string> metrics; int opt; while ((opt = getopt_long_only(argc, argv, "c:", stellar_core_options, nullptr)) != -1) { switch (opt) { case OPT_BASE64: base64 = true; break; case OPT_CATCHUP_AT: doCatchupAt = true; catchupAtTarget = parseLedger(optarg); break; case OPT_CATCHUP_COMPLETE: doCatchupComplete = true; break; case OPT_CATCHUP_RECENT: doCatchupRecent = true; catchupRecentCount = parseLedgerCount(optarg); break; case OPT_CATCHUP_TO: doCatchupTo = true; catchupToTarget = parseLedger(optarg); break; case 'c': case OPT_CMD: command = optarg; rest.insert(rest.begin(), argv + optind, argv + argc); optind = argc; break; case OPT_CONF: cfgFile = std::string(optarg); break; case OPT_CONVERTID: StrKeyUtils::logKey(std::cout, std::string(optarg)); return 0; case OPT_DUMPXDR: dumpxdr(std::string(optarg)); return 0; case OPT_PRINTTXN: printtxn(std::string(optarg), base64); return 0; case OPT_SIGNTXN: signtxn(std::string(optarg), base64); return 0; case OPT_SEC2PUB: priv2pub(); return 0; case OPT_NETID: signtxn_network_id = optarg; return 0; case OPT_LOADXDR: loadXdrBucket = std::string(optarg); break; case OPT_FORCESCP: forceSCP = make_optional<bool>(optarg == nullptr || string(optarg) == "true"); break; case OPT_FUZZ: fuzz(std::string(optarg), logLevel, metrics); return 0; case OPT_GENFUZZ: genfuzz(std::string(optarg)); return 0; case OPT_GENSEED: { SecretKey key = SecretKey::random(); std::cout << "Secret seed: " << key.getStrKeySeed().value << std::endl; std::cout << "Public: " << key.getStrKeyPublic() << std::endl; return 0; } case OPT_INFERQUORUM: inferQuorum = true; break; case OPT_CHECKQUORUM: checkQuorum = true; break; case OPT_GRAPHQUORUM: graphQuorum = true; break; case OPT_OFFLINEINFO: getOfflineInfo = true; break; case OPT_OUTPUT_FILE: outputFile = optarg; break; case OPT_LOGLEVEL: logLevel = Logging::getLLfromString(std::string(optarg)); break; case OPT_METRIC: metrics.push_back(std::string(optarg)); break; case OPT_NEWDB: newDB = true; break; case OPT_NEWHIST: newHistories.push_back(std::string(optarg)); break; case OPT_REPORT_LAST_HISTORY_CHECKPOINT: doReportLastHistoryCheckpoint = true; break; case OPT_TEST: { rest.push_back(*argv); rest.insert(++rest.begin(), argv + optind, argv + argc); return test(static_cast<int>(rest.size()), &rest[0], logLevel, metrics); } case OPT_VERSION: std::cout << STELLAR_CORE_VERSION << std::endl; return 0; case OPT_HELP: default: usage(0); return 0; } } Config cfg; try { // yes you really have to do this 3 times Logging::setLogLevel(logLevel, nullptr); if (cfgFile == "-" || fs::exists(cfgFile)) { cfg.load(cfgFile); } else { std::string s; s = "No config file "; s += cfgFile + " found"; throw std::invalid_argument(s); } Logging::setFmt(KeyUtils::toShortString(cfg.NODE_SEED.getPublicKey())); Logging::setLogLevel(logLevel, nullptr); if (command.size()) { sendCommand(command, rest, cfg.HTTP_PORT); return 0; } // don't log to file if just sending a command if (cfg.LOG_FILE_PATH.size()) Logging::setLoggingToFile(cfg.LOG_FILE_PATH); Logging::setLogLevel(logLevel, nullptr); cfg.REPORT_METRICS = metrics; if (forceSCP || newDB || getOfflineInfo || !loadXdrBucket.empty() || inferQuorum || graphQuorum || checkQuorum || doCatchupAt || doCatchupComplete || doCatchupRecent || doCatchupTo || doReportLastHistoryCheckpoint) { Json::Value catchupInfo; auto result = 0; setNoListen(cfg); if ((result == 0) && newDB) initializeDatabase(cfg); if ((result == 0) && doCatchupAt) result = catchupAt(cfg, catchupAtTarget, catchupInfo); if ((result == 0) && doCatchupComplete) result = catchupComplete(cfg, catchupInfo); if ((result == 0) && doCatchupRecent) result = catchupRecent(cfg, catchupRecentCount, catchupInfo); if ((result == 0) && doCatchupTo) result = catchupTo(cfg, catchupToTarget, catchupInfo); if (!catchupInfo.isNull()) writeCatchupInfo(catchupInfo, outputFile); if ((result == 0) && forceSCP) setForceSCPFlag(cfg, *forceSCP); if ((result == 0) && getOfflineInfo) showOfflineInfo(cfg); if ((result == 0) && doReportLastHistoryCheckpoint) result = reportLastHistoryCheckpoint(cfg, outputFile); if ((result == 0) && !loadXdrBucket.empty()) loadXdr(cfg, loadXdrBucket); if ((result == 0) && inferQuorum) inferQuorumAndWrite(cfg); if ((result == 0) && checkQuorum) checkQuorumIntersection(cfg); if ((result == 0) && graphQuorum) writeQuorumGraph(cfg, outputFile); return result; } else if (!newHistories.empty()) { setNoListen(cfg); return initializeHistories(cfg, newHistories); } if (cfg.MANUAL_CLOSE) { // in manual close mode, we set FORCE_SCP // so that the node starts fully in sync // (this is to avoid to force scp all the time when testing) cfg.FORCE_SCP = true; } } catch (std::exception& e) { LOG(FATAL) << "Got an exception: " << e.what(); return 1; } // run outside of catch block so that we properly capture crashes return startApp(cfgFile, cfg); }
static std::map<std::vector<uint8_t>, std::string> hexTestVectors = { {{}, ""}, {{0x72}, "72"}, {{0x54, 0x4c}, "544c"}, {{0x34, 0x75, 0x52, 0x45, 0x34, 0x75}, "347552453475"}, {{0x4f, 0x46, 0x79, 0x58, 0x43, 0x6d, 0x68, 0x37, 0x51}, "4f467958436d683751"}}; TEST_CASE("random", "[crypto]") { SecretKey k1 = SecretKey::random(); SecretKey k2 = SecretKey::random(); LOG(DEBUG) << "k1: " << k1.getStrKeySeed().value; LOG(DEBUG) << "k2: " << k2.getStrKeySeed().value; CHECK(k1.getStrKeySeed() != k2.getStrKeySeed()); SecretKey k1b = SecretKey::fromStrKeySeed(k1.getStrKeySeed().value); REQUIRE(k1 == k1b); REQUIRE(k1.getPublicKey() == k1b.getPublicKey()); } TEST_CASE("hex tests", "[crypto]") { // Do some fixed test vectors. for (auto const& pair : hexTestVectors) { LOG(DEBUG) << "fixed test vector hex: \"" << pair.second << "\""; auto enc = binToHex(pair.first); CHECK(enc.size() == pair.second.size());
static std::map<std::vector<uint8_t>, std::string> hexTestVectors = { {{}, ""}, {{0x72}, "72"}, {{0x54, 0x4c}, "544c"}, {{0x34, 0x75, 0x52, 0x45, 0x34, 0x75}, "347552453475"}, {{0x4f, 0x46, 0x79, 0x58, 0x43, 0x6d, 0x68, 0x37, 0x51}, "4f467958436d683751"}}; TEST_CASE("random", "[crypto]") { SecretKey k1 = SecretKey::random(); SecretKey k2 = SecretKey::random(); LOG(DEBUG) << "k1: " << k1.getStrKeySeed(); LOG(DEBUG) << "k2: " << k2.getStrKeySeed(); CHECK(k1.getStrKeySeed() != k2.getStrKeySeed()); } TEST_CASE("hex tests", "[crypto]") { // Do some fixed test vectors. for (auto const& pair : hexTestVectors) { LOG(DEBUG) << "fixed test vector hex: \"" << pair.second << "\""; auto enc = binToHex(pair.first); CHECK(enc.size() == pair.second.size()); CHECK(enc == pair.second); auto dec = hexToBin(pair.second); CHECK(pair.first == dec);
int main(int argc, char* const* argv) { using namespace stellar; sodium_init(); Logging::init(); std::string cfgFile("stellar-core.cfg"); std::string command; el::Level logLevel = el::Level::Info; std::vector<char*> rest; optional<bool> forceSCP = nullptr; bool newDB = false; bool getInfo = false; std::vector<std::string> newHistories; std::vector<std::string> metrics; int opt; while ((opt = getopt_long_only(argc, argv, "", stellar_core_options, nullptr)) != -1) { switch (opt) { case OPT_CMD: command = optarg; rest.insert(rest.begin(), argv + optind, argv + argc); break; case OPT_CONF: cfgFile = std::string(optarg); break; case OPT_CONVERTID: StrKeyUtils::logKey(std::cout, std::string(optarg)); return 0; case OPT_DUMPXDR: dumpxdr(std::string(optarg)); return 0; case OPT_FORCESCP: forceSCP = make_optional<bool>(optarg == nullptr || string(optarg) == "true"); break; case OPT_FUZZ: fuzz(std::string(optarg), logLevel, metrics); return 0; case OPT_GENFUZZ: genfuzz(std::string(optarg)); return 0; case OPT_GENSEED: { SecretKey key = SecretKey::random(); std::cout << "Secret seed: " << key.getStrKeySeed() << std::endl; std::cout << "Public: " << key.getStrKeyPublic() << std::endl; return 0; } case OPT_INFO: getInfo = true; break; case OPT_LOGLEVEL: logLevel = Logging::getLLfromString(std::string(optarg)); break; case OPT_METRIC: metrics.push_back(std::string(optarg)); break; case OPT_NEWDB: newDB = true; break; case OPT_NEWHIST: newHistories.push_back(std::string(optarg)); break; case OPT_TEST: { rest.push_back(*argv); rest.insert(++rest.begin(), argv + optind, argv + argc); return test(static_cast<int>(rest.size()), &rest[0], logLevel, metrics); } case OPT_VERSION: std::cout << STELLAR_CORE_VERSION; return 0; default: usage(0); return 0; } } Config cfg; try { // yes you really have to do this 3 times Logging::setLogLevel(logLevel, nullptr); if (cfgFile == "-" || fs::exists(cfgFile)) { cfg.load(cfgFile); } else { std::string s; s = "No config file "; s += cfgFile + " found"; throw std::invalid_argument(s); } Logging::setFmt( PubKeyUtils::toShortString(cfg.NODE_SEED.getPublicKey())); Logging::setLogLevel(logLevel, nullptr); if (command.size()) { sendCommand(command, rest, cfg.HTTP_PORT); return 0; } // don't log to file if just sending a command if (cfg.LOG_FILE_PATH.size()) Logging::setLoggingToFile(cfg.LOG_FILE_PATH); Logging::setLogLevel(logLevel, nullptr); cfg.REBUILD_DB = newDB; cfg.REPORT_METRICS = metrics; if (forceSCP || newDB || getInfo) { setNoListen(cfg); if (newDB) initializeDatabase(cfg); if (forceSCP) setForceSCPFlag(cfg, *forceSCP); if (getInfo) showInfo(cfg); return 0; } else if (!newHistories.empty()) { setNoListen(cfg); return initializeHistories(cfg, newHistories); } if (cfg.MANUAL_CLOSE) { // in manual close mode, we set FORCE_SCP // so that the node starts fully in sync // (this is to avoid to force scp all the time when testing) cfg.FORCE_SCP = true; } } catch (std::exception& e) { LOG(FATAL) << "Got an exception: " << e.what(); return 1; } // run outside of catch block so that we properly capture crashes return startApp(cfgFile, cfg); }