Esempio n. 1
0
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};
}
Esempio n. 2
0
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);
        }
    }
}
Esempio n. 3
0
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);
}
Esempio n. 5
0
uint64_t
getAccountBalance(SecretKey const& k, Application& app)
{
    AccountFrame account;
    REQUIRE(AccountFrame::loadAccount(k.getPublicKey(), account,
                                      app.getDatabase()));
    return account.getBalance();
}
Esempio n. 6
0
SequenceNumber
getAccountSeqNum(SecretKey const& k, Application& app)
{
    AccountFrame account;
    REQUIRE(AccountFrame::loadAccount(k.getPublicKey(), account,
                                      app.getDatabase()));
    return account.getSeqNum();
}
Esempio n. 7
0
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);
    }
}
Esempio n. 8
0
DecoratedSignature
sign(SecretKey const& secretKey, Hash const& hash)
{
    DecoratedSignature result;
    result.signature = secretKey.sign(hash);
    result.hint = getHint(secretKey.getPublicKey().ed25519());
    return result;
}
Esempio n. 9
0
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);
}
Esempio n. 11
0
SequenceNumber
getSeq(SecretKey const& k, Application& app)
{
    AccountFrame::pointer account;
    account = AccountFrame::loadAccount(k.getPublicKey(), app.getDatabase());
    if (account)
    {
        return account->getSeqNum();
    }
    return 0;
}
Esempio n. 12
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);
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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);
}
Esempio n. 15
0
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));
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
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;
Esempio n. 20
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());
                }
            }
        }
    }
}
Esempio n. 21
0
    {{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);
Esempio n. 22
0
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;
}