LocalNode::LocalNode(SecretKey const& secretKey, bool isValidator, SCPQuorumSet const& qSet, SCP* scp) : mNodeID(secretKey.getPublicKey()) , mSecretKey(secretKey) , mIsValidator(isValidator) , mQSet(qSet) , mSCP(scp) { adjustQSet(mQSet); mQSetHash = sha256(xdr::xdr_to_opaque(mQSet)); CLOG(INFO, "SCP") << "LocalNode::LocalNode" << "@" << PubKeyUtils::toShortString(mNodeID) << " qSet: " << hexAbbrev(mQSetHash); mSingleQSet = std::make_shared<SCPQuorumSet>(buildSingletonQSet(mNodeID)); gSingleQSetHash = sha256(xdr::xdr_to_opaque(*mSingleQSet)); }
TransactionFramePtr transactionFromOperation(SecretKey& from, SequenceNumber seq, Operation const& op) { TransactionEnvelope e; e.tx.sourceAccount = from.getPublicKey(); e.tx.maxLedger = UINT32_MAX; e.tx.minLedger = 0; e.tx.fee = 10; e.tx.seqNum = seq; e.tx.operations.push_back(op); TransactionFramePtr res = TransactionFrame::makeTransactionFromWire(e); res->addSignature(from); return res; }
TransactionFramePtr createCreditPaymentTx(SecretKey& from, SecretKey& to, Currency& ci, SequenceNumber seq, int64_t amount, std::vector<Currency>* path) { Operation op; op.body.type(PAYMENT); op.body.paymentOp().amount = amount; op.body.paymentOp().currency = ci; op.body.paymentOp().destination = to.getPublicKey(); op.body.paymentOp().sendMax = INT64_MAX; if (path) { for (auto const& cur : *path) { op.body.paymentOp().path.push_back(cur); } } return transactionFromOperation(from, seq, op); }
TestAccount TestAccount::create(SecretKey const& secretKey, uint64_t initialBalance) { auto publicKey = secretKey.getPublicKey(); std::unique_ptr<LedgerEntry> destBefore; { LedgerState ls(mApp.getLedgerStateRoot()); auto entry = stellar::loadAccount(ls, publicKey); if (entry) { destBefore = std::make_unique<LedgerEntry>(entry.current()); } } try { applyTx(tx({createAccount(publicKey, initialBalance)}), mApp); } catch (...) { LedgerState ls(mApp.getLedgerStateRoot()); auto destAfter = stellar::loadAccount(ls, publicKey); // check that the target account didn't change REQUIRE(!!destBefore == !!destAfter); if (destBefore && destAfter) { REQUIRE(*destBefore == destAfter.current()); } throw; } { LedgerState ls(mApp.getLedgerStateRoot()); REQUIRE(stellar::loadAccount(ls, publicKey)); } return TestAccount{mApp, secretKey}; }
Ed25519::Ed25519 ( SecretKey const& secretKey, PublicKey const& publicKey, Slice message) { if (publicKeyType (publicKey) != KeyType::ed25519) LogicError ("An Ed25519 public key is required."); // When PublicKey wraps an Ed25519 key it prefixes // the key itself with a 0xED byte. We carefully // skip that byte. std::memcpy ( payload_.data(), publicKey.data() + 1, publicKey.size() - 1); // Now sign: ed25519_sign ( message.data(), message.size(), secretKey.data(), payload_.data(), payload_.data() + pubkey_size_); }
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); }
#include <regex> #include <sodium.h> using namespace stellar; 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());
static CreateOfferResult applyCreateOfferHelper(Application& app, LedgerDelta& delta, uint64 offerId, SecretKey& source, Currency& takerGets, Currency& takerPays, Price const& price, int64_t amount, SequenceNumber seq) { uint64_t expectedOfferID = delta.getHeaderFrame().getLastGeneratedID() + 1; if (offerId != 0) { expectedOfferID = offerId; } TransactionFramePtr txFrame; txFrame = createOfferOp(offerId, source, takerGets, takerPays, price, amount, seq); txFrame->apply(delta, app); checkTransaction(*txFrame); auto& results = txFrame->getResult().result.results(); REQUIRE(results.size() == 1); auto& createOfferResult = results[0].tr().createOfferResult(); if (createOfferResult.code() == CREATE_OFFER_SUCCESS) { OfferFrame offer; auto& offerResult = createOfferResult.success().offer; auto& offerEntry = offer.getOffer(); switch (offerResult.effect()) { case CREATE_OFFER_CREATED: case CREATE_OFFER_UPDATED: REQUIRE(OfferFrame::loadOffer(source.getPublicKey(), expectedOfferID, offer, app.getDatabase())); REQUIRE(memcmp(&offerEntry, &offerResult.offer(), sizeof(OfferEntry)) == 0); REQUIRE(offerEntry.price == price); REQUIRE(memcmp(&offerEntry.takerGets, &takerGets, sizeof(Currency)) == 0); REQUIRE(memcmp(&offerEntry.takerPays, &takerPays, sizeof(Currency)) == 0); break; case CREATE_OFFER_DELETED: REQUIRE(!OfferFrame::loadOffer(source.getPublicKey(), expectedOfferID, offer, app.getDatabase())); break; default: abort(); } } return createOfferResult; }
#include <regex> #include <sodium.h> using namespace stellar; 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) {
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); }
#include <map> #include <regex> using namespace stellar; 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.getBase58Seed(); LOG(DEBUG) << "k2: " << k2.getBase58Seed(); CHECK(k1.getBase58Seed() != k2.getBase58Seed()); } 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());
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::Fatal; std::vector<char*> rest; bool newNetwork = false; bool newDB = 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_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_CONF: cfgFile = std::string(optarg); break; case OPT_CMD: command = optarg; rest.insert(rest.begin(), argv + optind, argv + argc); break; case OPT_VERSION: std::cout << STELLAR_CORE_VERSION; return 0; case OPT_FORCESCP: newNetwork = true; 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_LOGLEVEL: logLevel = Logging::getLLfromString(std::string(optarg)); break; case OPT_GENSEED: { SecretKey key = SecretKey::random(); std::cout << "Secret seed: " << key.getBase58Seed() << std::endl; std::cout << "Public: " << key.getBase58Public() << std::endl; return 0; } default: usage(0); return 0; } } Config cfg; try { if (fs::exists(cfgFile)) { cfg.load(cfgFile); Logging::setLoggingToFile(cfg.LOG_FILE_PATH); } else { LOG(WARNING) << "No config file " << cfgFile << " found"; cfgFile = ":default-settings:"; } Logging::setLogLevel(logLevel, nullptr); cfg.REBUILD_DB = newDB; cfg.START_NEW_NETWORK = newNetwork; cfg.REPORT_METRICS = metrics; if (command.size()) { sendCommand(command, rest, cfg.HTTP_PORT); return 0; } else if (newNetwork || newDB) { if (newDB) initializeDatabase(cfg); if (newNetwork) setForceSCPFlag(cfg); return 0; } else if (!newHistories.empty()) { return initializeHistories(cfg, newHistories); } } catch (std::invalid_argument e) { LOG(FATAL) << e.what(); return 1; } // run outside of catch block so that we properly capture crashes return startApp(cfgFile, cfg); }
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()); } } } } }
typedef std::unique_ptr<Application> appPtr; TEST_CASE("change trust", "[tx][changetrust]") { Config const& cfg = getTestConfig(); VirtualClock clock; Application::pointer appPtr = Application::create(clock, cfg); Application& app = *appPtr; Database& db = app.getDatabase(); app.start(); // set up world SecretKey root = getRoot(app.getNetworkID()); SecretKey gateway = getAccount("gw"); SequenceNumber rootSeq = getAccountSeqNum(root, app) + 1; SECTION("basic tests") { const int64_t minBalance2 = app.getLedgerManager().getMinBalance(2); applyCreateAccountTx(app, root, gateway, rootSeq++, minBalance2); SequenceNumber gateway_seq = getAccountSeqNum(gateway, app) + 1; Asset idrCur = makeAsset(gateway, "IDR"); // create a trustline with a limit of 0 applyChangeTrust(app, root, gateway, rootSeq++, "IDR", 0,