TestAccount TestAccount::create(SecretKey const& secretKey, uint64_t initialBalance) { auto toCreate = loadAccount(secretKey.getPublicKey(), mApp, false); auto self = loadAccount(getSecretKey().getPublicKey(), mApp); try { applyTx(tx({createAccount(secretKey.getPublicKey(), initialBalance)}), mApp); } catch (...) { auto toCreateAfter = loadAccount(secretKey.getPublicKey(), mApp, false); // check that the target account didn't change REQUIRE(!!toCreate == !!toCreateAfter); if (toCreate && toCreateAfter) { REQUIRE(toCreate->getAccount() == toCreateAfter->getAccount()); } throw; } REQUIRE(loadAccount(secretKey.getPublicKey(), mApp)); return TestAccount{mApp, secretKey}; }
static void createTestAccounts(Application& app, int nbAccounts, std::function<int64(int)> getBalance, std::function<int(int)> getVote) { // set up world SecretKey root = getRoot(); SequenceNumber rootSeq = getAccountSeqNum(root, app) + 1; auto& lm = app.getLedgerManager(); auto& db = app.getDatabase(); int64 setupBalance = lm.getMinBalance(0); LedgerDelta delta(lm.getCurrentLedgerHeader()); for (int i = 0; i < nbAccounts; i++) { int64 bal = getBalance(i); if (bal >= 0) { SecretKey to = getTestAccount(i); applyPaymentTx(app, root, to, rootSeq++, setupBalance); AccountFrame act; REQUIRE(AccountFrame::loadAccount(to.getPublicKey(), act, db)); act.getAccount().balance = bal; act.getAccount().inflationDest.activate() = getTestAccount(getVote(i)).getPublicKey(); act.storeChange(delta, db); } } }
Simulation::pointer Topologies::hierarchicalQuorumSimplified(int coreSize, int nbOuterNodes, Simulation::Mode mode, Hash const& networkID, std::function<Config()> confGen) { // outer nodes are independent validators that point to a [core network] auto sim = Topologies::core(coreSize, 0.75, mode, networkID, confGen); // each additional node considers themselves as validator // with a quorum set that also includes the core int n = coreSize + 1; SCPQuorumSet qSetBuilder; qSetBuilder.threshold = n - (n - 1) / 3; vector<NodeID> coreNodeIDs; for (auto const& coreNodeID : sim->getNodeIDs()) { qSetBuilder.validators.push_back(coreNodeID); coreNodeIDs.emplace_back(coreNodeID); } qSetBuilder.validators.emplace_back(); for (int i = 0; i < nbOuterNodes; i++) { SecretKey sk = SecretKey::fromSeed(sha256("OUTER_NODE_SEED_" + to_string(i))); auto const& pubKey = sk.getPublicKey(); qSetBuilder.validators.back() = pubKey; sim->addNode(sk, qSetBuilder, sim->getClock()); // connect it to one of the core nodes sim->addPendingConnection(pubKey, coreNodeIDs[i % coreSize]); } return sim; }
void LedgerManagerImpl::startNewLedger() { auto ledgerTime = mLedgerClose.TimeScope(); ByteSlice bytes("allmylifemyhearthasbeensearching"); SecretKey skey = SecretKey::fromSeed(bytes); AccountFrame masterAccount(skey.getPublicKey()); masterAccount.getAccount().balance = 100000000000000000; LedgerHeader genesisHeader; // all fields are initialized by default to 0 // set the ones that are not 0 genesisHeader.baseFee = 10; genesisHeader.baseReserve = 10000000; genesisHeader.totalCoins = masterAccount.getAccount().balance; genesisHeader.ledgerSeq = 1; LedgerDelta delta(genesisHeader); masterAccount.storeAdd(delta, this->getDatabase()); delta.commit(); mCurrentLedger = make_shared<LedgerHeaderFrame>(genesisHeader); CLOG(INFO, "Ledger") << "Established genesis ledger, closing"; closeLedgerHelper(delta); }
uint64_t getAccountBalance(SecretKey const& k, Application& app) { AccountFrame account; REQUIRE(AccountFrame::loadAccount(k.getPublicKey(), account, app.getDatabase())); return account.getBalance(); }
SequenceNumber getAccountSeqNum(SecretKey const& k, Application& app) { AccountFrame account; REQUIRE(AccountFrame::loadAccount(k.getPublicKey(), account, app.getDatabase())); return account.getSeqNum(); }
void applyPaymentTx(Application& app, SecretKey& from, SecretKey& to, SequenceNumber seq, int64_t amount, PaymentResultCode result) { TransactionFramePtr txFrame; AccountFrame fromAccount; AccountFrame toAccount; bool beforeToExists = AccountFrame::loadAccount( to.getPublicKey(), toAccount, app.getDatabase()); REQUIRE(AccountFrame::loadAccount(from.getPublicKey(), fromAccount, app.getDatabase())); txFrame = createPaymentTx(from, to, seq, amount); LedgerDelta delta(app.getLedgerManager().getCurrentLedgerHeader()); txFrame->apply(delta, app); checkTransaction(*txFrame); auto txResult = txFrame->getResult(); auto innerCode = PaymentOpFrame::getInnerCode(txResult.result.results()[0]); REQUIRE(innerCode == result); REQUIRE(txResult.feeCharged == app.getLedgerManager().getTxFee()); AccountFrame toAccountAfter; bool afterToExists = AccountFrame::loadAccount( to.getPublicKey(), toAccountAfter, app.getDatabase()); if (!(innerCode == PAYMENT_SUCCESS || innerCode == PAYMENT_SUCCESS_MULTI)) { // check that the target account didn't change REQUIRE(beforeToExists == afterToExists); if (beforeToExists && afterToExists) { REQUIRE(memcmp(&toAccount.getAccount(), &toAccountAfter.getAccount(), sizeof(AccountEntry)) == 0); } } else { REQUIRE(afterToExists); } }
DecoratedSignature sign(SecretKey const& secretKey, Hash const& hash) { DecoratedSignature result; result.signature = secretKey.sign(hash); result.hint = getHint(secretKey.getPublicKey().ed25519()); return result; }
Currency makeCurrency(SecretKey& issuer, std::string const& code) { Currency currency; currency.type(CURRENCY_TYPE_ALPHANUM); currency.alphaNum().issuer = issuer.getPublicKey(); strToCurrencyCode(currency.alphaNum().currencyCode, code); return currency; }
void TransactionFrame::addSignature(SecretKey const& secretKey) { clearCached(); DecoratedSignature sig; sig.signature = secretKey.sign(getContentsHash()); memcpy(&sig.hint, secretKey.getPublicKey().data(), sizeof(sig.hint)); mEnvelope.signatures.push_back(sig); }
SequenceNumber getSeq(SecretKey const& k, Application& app) { AccountFrame::pointer account; account = AccountFrame::loadAccount(k.getPublicKey(), app.getDatabase()); if (account) { return account->getSeqNum(); } return 0; }
TransactionFramePtr createPaymentTx(SecretKey& from, SecretKey& to, SequenceNumber seq, int64_t amount) { Operation op; op.body.type(PAYMENT); op.body.paymentOp().amount = amount; op.body.paymentOp().destination = to.getPublicKey(); op.body.paymentOp().sendMax = INT64_MAX; op.body.paymentOp().currency.type(CURRENCY_TYPE_NATIVE); return transactionFromOperation(from, seq, op); }
TransactionFramePtr createChangeTrust(SecretKey& from, SecretKey& to, SequenceNumber seq, std::string const& currencyCode, int64_t limit) { Operation op; op.body.type(CHANGE_TRUST); op.body.changeTrustOp().limit = limit; op.body.changeTrustOp().line.type(CURRENCY_TYPE_ALPHANUM); strToCurrencyCode(op.body.changeTrustOp().line.alphaNum().currencyCode, currencyCode); op.body.changeTrustOp().line.alphaNum().issuer = to.getPublicKey(); return transactionFromOperation(from, seq, op); }
TransactionFramePtr createAllowTrust(SecretKey& from, SecretKey& trustor, SequenceNumber seq, std::string const& currencyCode, bool authorize) { Operation op; op.body.type(ALLOW_TRUST); op.body.allowTrustOp().trustor = trustor.getPublicKey(); op.body.allowTrustOp().currency.type(CURRENCY_TYPE_ALPHANUM); strToCurrencyCode(op.body.allowTrustOp().currency.currencyCode(), currencyCode); op.body.allowTrustOp().authorize = authorize; return transactionFromOperation(from, seq, op); }
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}; }
// can't lower the limit below balance applyChangeTrust(app, root, gateway, rootSeq++, "IDR", 89, CHANGE_TRUST_INVALID_LIMIT); // can't delete if there is a balance applyChangeTrust(app, root, gateway, rootSeq++, "IDR", 0, CHANGE_TRUST_INVALID_LIMIT); // lower the limit at the balance applyChangeTrust(app, root, gateway, rootSeq++, "IDR", 90); // clear the balance applyCreditPaymentTx(app, root, gateway, idrCur, rootSeq++, 90); // delete the trust line applyChangeTrust(app, root, gateway, rootSeq++, "IDR", 0); REQUIRE(!(TrustFrame::loadTrustLine(root.getPublicKey(), idrCur, db))); } SECTION("issuer does not exist") { SECTION("new trust line") { applyChangeTrust(app, root, gateway, rootSeq, "USD", 100, CHANGE_TRUST_NO_ISSUER); } SECTION("edit existing") { const int64_t minBalance2 = app.getLedgerManager().getMinBalance(2); applyCreateAccountTx(app, root, gateway, rootSeq++, minBalance2); SequenceNumber gateway_seq = getAccountSeqNum(gateway, app) + 1;
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()); } } } } }
{{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()); CHECK(enc == pair.second); auto dec = hexToBin(pair.second); CHECK(pair.first == dec);
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; }