示例#1
0
void
TrustFrame::storeChange(LedgerDelta& delta, Database& db)
{
    if (!isValid())
    {
        throw std::runtime_error("Invalid TrustEntry");
    }

    auto key = getKey();
    flushCachedEntry(key, db);

    if (mIsIssuer)
        return;

    touch(delta);

    std::string actIDStrKey, issuerStrKey, assetCode;
    getKeyFields(key, actIDStrKey, issuerStrKey, assetCode);

    auto prep = db.getPreparedStatement(
        "UPDATE trustlines "
        "SET balance=:b, tlimit=:tl, flags=:a, lastmodified=:lm "
        "WHERE accountid=:v1 AND issuer=:v2 AND assetcode=:v3");
    auto& st = prep.statement();
    st.exchange(use(mTrustLine.balance));
    st.exchange(use(mTrustLine.limit));
    st.exchange(use(mTrustLine.flags));
    st.exchange(use(getLastModified()));
    st.exchange(use(actIDStrKey));
    st.exchange(use(issuerStrKey));
    st.exchange(use(assetCode));
    st.define_and_bind();
    {
        auto timer = db.getUpdateTimer("trust");
        st.execute(true);
    }
    if (st.get_affected_rows() != 1)
    {
        throw std::runtime_error("Could not update data in SQL");
    }

    delta.modEntry(*this);
}
示例#2
0
void
OfferFrame::storeChange(LedgerDelta& delta, Database& db) const
{

    auto timer = db.getUpdateTimer("offer");

    soci::statement st =
        (db.getSession().prepare << "UPDATE offers SET amount=:a, pricen=:n, "
                                    "priced=:D, price=:p WHERE offerid=:s",
         use(mOffer.amount), use(mOffer.price.n), use(mOffer.price.d),
         use(computePrice()), use(mOffer.offerID));

    st.execute(true);

    if (st.get_affected_rows() != 1)
    {
        throw std::runtime_error("could not update SQL");
    }

    delta.modEntry(*this);
}
示例#3
0
void
AccountFrame::storeUpdate(LedgerDelta& delta, Database& db, bool insert)
{
    assert(isValid());

    touch(delta);

    flushCachedEntry(db);

    std::string actIDStrKey = PubKeyUtils::toStrKey(mAccountEntry.accountID);
    std::string sql;

    if (insert)
    {
        sql = std::string(
            "INSERT INTO accounts ( accountid, balance, seqnum, "
            "numsubentries, inflationdest, homedomain, thresholds, flags, "
            "lastmodified ) "
            "VALUES ( :id, :v1, :v2, :v3, :v4, :v5, :v6, :v7, :v8 )");
    }
    else
    {
        sql = std::string(
            "UPDATE accounts SET balance = :v1, seqnum = :v2, "
            "numsubentries = :v3, "
            "inflationdest = :v4, homedomain = :v5, thresholds = :v6, "
            "flags = :v7, lastmodified = :v8 WHERE accountid = :id");
    }

    auto prep = db.getPreparedStatement(sql);

    soci::indicator inflation_ind = soci::i_null;
    string inflationDestStrKey;

    if (mAccountEntry.inflationDest)
    {
        inflationDestStrKey =
            PubKeyUtils::toStrKey(*mAccountEntry.inflationDest);
        inflation_ind = soci::i_ok;
    }

    string thresholds(bn::encode_b64(mAccountEntry.thresholds));

    {
        soci::statement& st = prep.statement();
        st.exchange(use(actIDStrKey, "id"));
        st.exchange(use(mAccountEntry.balance, "v1"));
        st.exchange(use(mAccountEntry.seqNum, "v2"));
        st.exchange(use(mAccountEntry.numSubEntries, "v3"));
        st.exchange(use(inflationDestStrKey, inflation_ind, "v4"));
        string homeDomain(mAccountEntry.homeDomain);
        st.exchange(use(homeDomain, "v5"));
        st.exchange(use(thresholds, "v6"));
        st.exchange(use(mAccountEntry.flags, "v7"));
        st.exchange(use(getLastModified(), "v8"));
        st.define_and_bind();
        {
            auto timer = insert ? db.getInsertTimer("account")
                                : db.getUpdateTimer("account");
            st.execute(true);
        }

        if (st.get_affected_rows() != 1)
        {
            throw std::runtime_error("Could not update data in SQL");
        }
        if (insert)
        {
            delta.addEntry(*this);
        }
        else
        {
            delta.modEntry(*this);
        }
    }

    if (mUpdateSigners)
    {
        applySigners(db);
    }
}
示例#4
0
void
OfferFrame::storeUpdateHelper(LedgerDelta& delta, Database& db, bool insert)
{
    touch(delta);

    if (!isValid())
    {
        throw std::runtime_error("Invalid asset");
    }

    std::string actIDStrKey = PubKeyUtils::toStrKey(mOffer.sellerID);

    unsigned int sellingType = mOffer.selling.type();
    unsigned int buyingType = mOffer.buying.type();
    std::string sellingIssuerStrKey, buyingIssuerStrKey;
    std::string sellingAssetCode, buyingAssetCode;
    soci::indicator selling_ind = soci::i_null, buying_ind = soci::i_null;

    if (sellingType == ASSET_TYPE_CREDIT_ALPHANUM4)
    {
        sellingIssuerStrKey =
            PubKeyUtils::toStrKey(mOffer.selling.alphaNum4().issuer);
        assetCodeToStr(mOffer.selling.alphaNum4().assetCode, sellingAssetCode);
        selling_ind = soci::i_ok;
    }
    else if (sellingType == ASSET_TYPE_CREDIT_ALPHANUM12)
    {
        sellingIssuerStrKey =
            PubKeyUtils::toStrKey(mOffer.selling.alphaNum12().issuer);
        assetCodeToStr(mOffer.selling.alphaNum12().assetCode, sellingAssetCode);
        selling_ind = soci::i_ok;
    }

    if (buyingType == ASSET_TYPE_CREDIT_ALPHANUM4)
    {
        buyingIssuerStrKey =
            PubKeyUtils::toStrKey(mOffer.buying.alphaNum4().issuer);
        assetCodeToStr(mOffer.buying.alphaNum4().assetCode, buyingAssetCode);
        buying_ind = soci::i_ok;
    }
    else if (buyingType == ASSET_TYPE_CREDIT_ALPHANUM12)
    {
        buyingIssuerStrKey =
            PubKeyUtils::toStrKey(mOffer.buying.alphaNum12().issuer);
        assetCodeToStr(mOffer.buying.alphaNum12().assetCode, buyingAssetCode);
        buying_ind = soci::i_ok;
    }

    string sql;

    if (insert)
    {
        sql = "INSERT INTO offers (sellerid,offerid,"
              "sellingassettype,sellingassetcode,sellingissuer,"
              "buyingassettype,buyingassetcode,buyingissuer,"
              "amount,pricen,priced,price,flags,lastmodified) VALUES "
              "(:sid,:oid,:sat,:sac,:si,:bat,:bac,:bi,:a,:pn,:pd,:p,:f,:l)";
    }
    else
    {
        sql = "UPDATE offers SET sellingassettype=:sat "
              ",sellingassetcode=:sac,sellingissuer=:si,"
              "buyingassettype=:bat,buyingassetcode=:bac,buyingissuer=:bi,"
              "amount=:a,pricen=:pn,priced=:pd,price=:p,flags=:f,"
              "lastmodified=:l WHERE offerid=:oid";
    }

    auto prep = db.getPreparedStatement(sql);
    auto& st = prep.statement();

    if (insert)
    {
        st.exchange(use(actIDStrKey, "sid"));
    }
    st.exchange(use(mOffer.offerID, "oid"));
    st.exchange(use(sellingType, "sat"));
    st.exchange(use(sellingAssetCode, selling_ind, "sac"));
    st.exchange(use(sellingIssuerStrKey, selling_ind, "si"));
    st.exchange(use(buyingType, "bat"));
    st.exchange(use(buyingAssetCode, buying_ind, "bac"));
    st.exchange(use(buyingIssuerStrKey, buying_ind, "bi"));
    st.exchange(use(mOffer.amount, "a"));
    st.exchange(use(mOffer.price.n, "pn"));
    st.exchange(use(mOffer.price.d, "pd"));
    auto price = computePrice();
    st.exchange(use(price, "p"));
    st.exchange(use(mOffer.flags, "f"));
    st.exchange(use(getLastModified(), "l"));
    st.define_and_bind();

    auto timer =
        insert ? db.getInsertTimer("offer") : db.getUpdateTimer("offer");
    st.execute(true);

    if (st.get_affected_rows() != 1)
    {
        throw std::runtime_error("could not update SQL");
    }

    if (insert)
    {
        delta.addEntry(*this);
    }
    else
    {
        delta.modEntry(*this);
    }
}
void
AccountFrame::storeUpdate(LedgerDelta& delta, Database& db, bool insert) const
{
    flushCachedEntry(db);

    std::string actIDStrKey = PubKeyUtils::toStrKey(mAccountEntry.accountID);
    std::string sql;

    if (insert)
    {
        sql = std::string(
            "INSERT INTO accounts ( accountid, balance, seqnum, "
            "numsubentries, inflationdest, homedomain, thresholds, flags) "
            "VALUES ( :id, :v1, :v2, :v3, :v4, :v5, :v6, :v7 )");
    }
    else
    {
        sql = std::string(
            "UPDATE accounts SET balance = :v1, seqnum = :v2, "
            "numsubentries = :v3, "
            "inflationdest = :v4, homedomain = :v5, thresholds = :v6, "
            "flags = :v7 WHERE accountid = :id");
    }

    auto prep = db.getPreparedStatement(sql);

    soci::indicator inflation_ind = soci::i_null;
    string inflationDestStrKey;

    if (mAccountEntry.inflationDest)
    {
        inflationDestStrKey =
            PubKeyUtils::toStrKey(*mAccountEntry.inflationDest);
        inflation_ind = soci::i_ok;
    }

    string thresholds(bn::encode_b64(mAccountEntry.thresholds));

    {
        soci::statement& st = prep.statement();
        st.exchange(use(actIDStrKey, "id"));
        st.exchange(use(mAccountEntry.balance, "v1"));
        st.exchange(use(mAccountEntry.seqNum, "v2"));
        st.exchange(use(mAccountEntry.numSubEntries, "v3"));
        st.exchange(use(inflationDestStrKey, inflation_ind, "v4"));
        st.exchange(use(string(mAccountEntry.homeDomain), "v5"));
        st.exchange(use(thresholds, "v6"));
        st.exchange(use(mAccountEntry.flags, "v7"));
        st.define_and_bind();
        {
            auto timer = insert ? db.getInsertTimer("account")
                                : db.getUpdateTimer("account");
            st.execute(true);
        }

        if (st.get_affected_rows() != 1)
        {
            throw std::runtime_error("Could not update data in SQL");
        }
        if (insert)
        {
            delta.addEntry(*this);
        }
        else
        {
            delta.modEntry(*this);
        }
    }

    if (mUpdateSigners)
    {
        // instead separate signatures from account, just like offers are
        // separate entities
        AccountFrame::pointer startAccountFrame;
        startAccountFrame = loadAccount(getID(), db);
        if (!startAccountFrame)
        {
            throw runtime_error("could not load account!");
        }
        AccountEntry& startAccount = startAccountFrame->mAccountEntry;

        // deal with changes to Signers
        if (mAccountEntry.signers.size() < startAccount.signers.size())
        { // some signers were removed
            for (auto const& startSigner : startAccount.signers)
            {
                bool found = false;
                for (auto const& finalSigner : mAccountEntry.signers)
                {
                    if (finalSigner.pubKey == startSigner.pubKey)
                    {
                        if (finalSigner.weight != startSigner.weight)
                        {
                            std::string signerStrKey =
                                PubKeyUtils::toStrKey(finalSigner.pubKey);
                            {
                                auto timer = db.getUpdateTimer("signer");
                                db.getSession()
                                    << "UPDATE signers set weight=:v1 where "
                                       "accountid=:v2 and publickey=:v3",
                                    use(finalSigner.weight), use(actIDStrKey),
                                    use(signerStrKey);
                            }
                        }
                        found = true;
                        break;
                    }
                }
                if (!found)
                { // delete signer
                    std::string signerStrKey =
                        PubKeyUtils::toStrKey(startSigner.pubKey);

                    soci::statement st =
                        (db.getSession().prepare << "DELETE from signers where "
                                                    "accountid=:v2 and "
                                                    "publickey=:v3",
                         use(actIDStrKey), use(signerStrKey));

                    {
                        auto timer = db.getDeleteTimer("signer");
                        st.execute(true);
                    }

                    if (st.get_affected_rows() != 1)
                    {
                        throw std::runtime_error(
                            "Could not update data in SQL");
                    }
                }
            }
        }
        else
        { // signers added or the same
            for (auto const& finalSigner : mAccountEntry.signers)
            {
                bool found = false;
                for (auto const& startSigner : startAccount.signers)
                {
                    if (finalSigner.pubKey == startSigner.pubKey)
                    {
                        if (finalSigner.weight != startSigner.weight)
                        {
                            std::string signerStrKey =
                                PubKeyUtils::toStrKey(finalSigner.pubKey);

                            soci::statement st =
                                (db.getSession().prepare
                                     << "UPDATE signers set weight=:v1 where "
                                        "accountid=:v2 and publickey=:v3",
                                 use(finalSigner.weight), use(actIDStrKey),
                                 use(signerStrKey));

                            st.execute(true);

                            if (st.get_affected_rows() != 1)
                            {
                                throw std::runtime_error(
                                    "Could not update data in SQL");
                            }
                        }
                        found = true;
                        break;
                    }
                }
                if (!found)
                { // new signer
                    std::string signerStrKey =
                        PubKeyUtils::toStrKey(finalSigner.pubKey);

                    soci::statement st = (db.getSession().prepare
                                              << "INSERT INTO signers "
                                                 "(accountid,publickey,weight) "
                                                 "VALUES (:v1,:v2,:v3)",
                                          use(actIDStrKey), use(signerStrKey),
                                          use(finalSigner.weight));

                    st.execute(true);

                    if (st.get_affected_rows() != 1)
                    {
                        throw std::runtime_error(
                            "Could not update data in SQL");
                    }
                }
            }
        }

        // Flush again to ensure changed signers are reloaded.
        flushCachedEntry(db);
    }
}