Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
void
Config::parseNodeID(std::string configStr, PublicKey& retKey, SecretKey& sKey,
                    bool isSeed)
{
    if (configStr.size() < 2)
        throw std::invalid_argument("invalid key");

    // check if configStr is a PublicKey or a common name
    if (configStr[0] == '$')
    {
        if (isSeed)
        {
            throw std::invalid_argument("aliases only store public keys");
        }
        if (!resolveNodeID(configStr, retKey))
        {
            std::stringstream msg;
            msg << "unknown key in config: " << configStr;
            throw std::invalid_argument(msg.str());
        }
    }
    else
    {
        std::istringstream iss(configStr);
        std::string nodestr;
        iss >> nodestr;
        if (isSeed)
        {
            sKey = SecretKey::fromStrKeySeed(nodestr);
            retKey = sKey.getPublicKey();
            nodestr = sKey.getStrKeyPublic();
        }
        else
        {
            retKey = PubKeyUtils::fromStrKey(nodestr);
        }

        if (iss)
        {   // get any common name they have added
            std::string commonName;
            iss >> commonName;
            if (commonName.size())
            {
                std::string cName = "$";
                cName += commonName;
                if (resolveNodeID(cName, retKey))
                {
                    throw std::invalid_argument("name already used");
                }

                if (!VALIDATOR_NAMES.emplace(std::make_pair(nodestr,
                                             commonName)).second)
                {
                    std::stringstream msg;
                    msg << "naming node twice: " << commonName;
                    throw std::invalid_argument(msg.str());
                }
            }
        }
    }
}