diff --git a/src/ripple/module/app/book/Amount.h b/src/ripple/module/app/book/Amount.h index e5b91fc51..50e82dcbc 100644 --- a/src/ripple/module/app/book/Amount.h +++ b/src/ripple/module/app/book/Amount.h @@ -191,7 +191,7 @@ public: if (sig == 0) return os << "0"; - + if (sig < 0) os << "-"; if (m_integral) @@ -204,10 +204,11 @@ public: }; //------------------------------------------------------------------------------ +// TODO(tom): remove this typedef and have exactly one name for STAmount. typedef STAmount Amount; -} -} +} // core +} // ripple #endif diff --git a/src/ripple/module/app/book/Types.h b/src/ripple/module/app/book/Types.h index 8de49a275..4f40705b9 100644 --- a/src/ripple/module/app/book/Types.h +++ b/src/ripple/module/app/book/Types.h @@ -21,8 +21,7 @@ #define RIPPLE_CORE_TYPES_H_INCLUDED #include -#include -#include +#include #include #include @@ -33,14 +32,6 @@ namespace core { /** A mutable view that overlays an immutable ledger to track changes. */ typedef LedgerEntrySet LedgerView; -/** Asset identifiers. */ -typedef RippleAsset Asset; -typedef RippleAssetRef AssetRef; - -/** Uniquely identifies an order book. */ -typedef RippleBook Book; -typedef RippleBookRef BookRef; - /** A clock representing network time. This measures seconds since the Ripple epoch as seen by the ledger close clock. diff --git a/src/ripple/module/app/book/impl/BookTip.cpp b/src/ripple/module/app/book/impl/BookTip.cpp index 7fab2af9a..fe720f96e 100644 --- a/src/ripple/module/app/book/impl/BookTip.cpp +++ b/src/ripple/module/app/book/impl/BookTip.cpp @@ -26,8 +26,8 @@ BookTip::BookTip (LedgerView& view, BookRef book) : m_view (view) , m_valid (false) , m_book (Ledger::getBookBase ( - book.in.currency, book.in.issuer, - book.out.currency, book.out.issuer)) + book.in.currency, book.in.account, + book.out.currency, book.out.account)) , m_end (Ledger::getQualityNext (m_book)) { } @@ -65,7 +65,7 @@ BookTip::step () m_book = page; // The quality immediately before the next quality - --m_book; + --m_book; break; } diff --git a/src/ripple/module/app/book/impl/Taker.cpp b/src/ripple/module/app/book/impl/Taker.cpp index 227238f9e..aac931e3a 100644 --- a/src/ripple/module/app/book/impl/Taker.cpp +++ b/src/ripple/module/app/book/impl/Taker.cpp @@ -46,11 +46,7 @@ Taker::remaining_offer () const { // If the taker is done, then there's no offer to place. if (done ()) - { - return Amounts ( - Amount (m_amount.in.getCurrency (), m_amount.in.getIssuer ()), - Amount (m_amount.out.getCurrency (), m_amount.out.getIssuer ())); - } + return Amounts (m_amount.in.zeroed(), m_amount.out.zeroed()); // Avoid math altogether if we didn't cross. if (m_amount == m_remain) @@ -272,7 +268,7 @@ Taker::cross (Offer const& leg1, Offer const& leg2) Amounts flow1 (flow (amount1, leg1, m_account)); amount2 = leg2.quality().ceil_in (amount2, flow1.out); - + Amounts flow2 (flow (amount2, leg2, m_account)); m_remain.out -= amount2.out; diff --git a/src/ripple/module/app/book/tests/Quality.test.cpp b/src/ripple/module/app/book/tests/Quality.test.cpp index 7970537de..ffda37347 100644 --- a/src/ripple/module/app/book/tests/Quality.test.cpp +++ b/src/ripple/module/app/book/tests/Quality.test.cpp @@ -32,7 +32,7 @@ public: Amount static raw (std::uint64_t mantissa, int exponent) { - return Amount (Currency(3), Account(3), mantissa, exponent); + return Amount ({Currency(3), Account(3)}, mantissa, exponent); } template @@ -241,9 +241,9 @@ public: { testcase ("comparisons"); - Amount const amount1 (noCurrency (), noAccount (), 231); - Amount const amount2 (noCurrency (), noAccount (), 462); - Amount const amount3 (noCurrency (), noAccount (), 924); + Amount const amount1 (noIssue(), 231); + Amount const amount2 (noIssue(), 462); + Amount const amount3 (noIssue(), 924); Quality const q11 (core::Amounts (amount1, amount1)); Quality const q12 (core::Amounts (amount1, amount2)); @@ -264,9 +264,9 @@ public: { testcase ("composition"); - Amount const amount1 (noCurrency (), noAccount (), 231); - Amount const amount2 (noCurrency (), noAccount (), 462); - Amount const amount3 (noCurrency (), noAccount (), 924); + Amount const amount1 (noIssue(), 231); + Amount const amount2 (noIssue(), 462); + Amount const amount3 (noIssue(), 924); Quality const q11 (core::Amounts (amount1, amount1)); Quality const q12 (core::Amounts (amount1, amount2)); @@ -289,8 +289,8 @@ public: testcase ("operations"); Quality const q11 (core::Amounts ( - Amount (noCurrency (), noAccount (), 731), - Amount (noCurrency (), noAccount (), 731))); + Amount (noIssue(), 731), + Amount (noIssue(), 731))); Quality qa (q11); Quality qb (q11); diff --git a/src/ripple/module/app/ledger/LedgerEntrySet.cpp b/src/ripple/module/app/ledger/LedgerEntrySet.cpp index 5630c0610..099fa1961 100644 --- a/src/ripple/module/app/ledger/LedgerEntrySet.cpp +++ b/src/ripple/module/app/ledger/LedgerEntrySet.cpp @@ -1114,7 +1114,7 @@ STAmount LedgerEntrySet::rippleOwed ( } else { - saBalance.clear (currency, uToAccountID); + saBalance.clear ({currency, uToAccountID}); WriteLog (lsDEBUG, LedgerEntrySet) << "rippleOwed:" << " No credit line between " << @@ -1146,7 +1146,7 @@ STAmount LedgerEntrySet::rippleLimit ( } else { - saLimit.clear (currency, uToAccountID); + saLimit.clear ({currency, uToAccountID}); } return saLimit; @@ -1237,7 +1237,7 @@ STAmount LedgerEntrySet::rippleHolds ( if (!sleRippleState) { - saBalance.clear (currency, issuer); + saBalance.clear ({currency, issuer}); } else if (account > issuer) { @@ -1351,12 +1351,10 @@ STAmount LedgerEntrySet::rippleTransferFee ( { // NIKB use STAmount::saFromRate STAmount saTransitRate ( - noCurrency(), noAccount(), - static_cast (uTransitRate), -9); + noIssue(), static_cast (uTransitRate), -9); STAmount saTransferTotal = STAmount::multiply ( - saAmount, saTransitRate, - saAmount.getCurrency (), saAmount.getIssuer ()); + saAmount, saTransitRate, saAmount.issue ()); STAmount saTransferFee = saTransferTotal - saAmount; WriteLog (lsDEBUG, LedgerEntrySet) << "rippleTransferFee:" << @@ -1366,7 +1364,7 @@ STAmount LedgerEntrySet::rippleTransferFee ( } } - return STAmount (saAmount.getCurrency (), saAmount.getIssuer ()); + return saAmount.zeroed(); } TER LedgerEntrySet::trustCreate ( @@ -1413,42 +1411,42 @@ TER LedgerEntrySet::trustCreate ( if (tesSUCCESS == terResult) { - const bool bSetDst = saLimit.getIssuer () == uDstAccountID; - const bool bSetHigh = bSrcHigh ^ bSetDst; + const bool bSetDst = saLimit.getIssuer () == uDstAccountID; + const bool bSetHigh = bSrcHigh ^ bSetDst; // Remember deletion hints. sleRippleState->setFieldU64 (sfLowNode, uLowNode); sleRippleState->setFieldU64 (sfHighNode, uHighNode); sleRippleState->setFieldAmount ( - !bSetHigh ? sfLowLimit : sfHighLimit, saLimit); + bSetHigh ? sfHighLimit : sfLowLimit, saLimit); sleRippleState->setFieldAmount ( bSetHigh ? sfLowLimit : sfHighLimit, - STAmount (saBalance.getCurrency (), - bSetDst ? uSrcAccountID : uDstAccountID)); + STAmount ({saBalance.getCurrency (), + bSetDst ? uSrcAccountID : uDstAccountID})); if (uQualityIn) sleRippleState->setFieldU32 ( - !bSetHigh ? sfLowQualityIn : sfHighQualityIn, uQualityIn); + bSetHigh ? sfHighQualityIn : sfLowQualityIn, uQualityIn); if (uQualityOut) sleRippleState->setFieldU32 ( - !bSetHigh ? sfLowQualityOut : sfHighQualityOut, uQualityOut); + bSetHigh ? sfHighQualityOut : sfLowQualityOut, uQualityOut); - std::uint32_t uFlags = !bSetHigh ? lsfLowReserve : lsfHighReserve; + std::uint32_t uFlags = bSetHigh ? lsfHighReserve : lsfLowReserve; if (bAuth) { - uFlags |= (!bSetHigh ? lsfLowAuth : lsfHighAuth); + uFlags |= (bSetHigh ? lsfHighAuth : lsfLowAuth); } if (bNoRipple) { - uFlags |= (!bSetHigh ? lsfLowNoRipple : lsfHighNoRipple); + uFlags |= (bSetHigh ? lsfHighNoRipple : lsfLowNoRipple); } sleRippleState->setFieldU32 (sfFlags, uFlags); ownerCountAdjust ( - !bSetDst ? uSrcAccountID : uDstAccountID, 1, sleAccount); + bSetDst ? uDstAccountID : uSrcAccountID, 1, sleAccount); // ONLY: Create ripple balance. sleRippleState->setFieldAmount ( @@ -1528,8 +1526,8 @@ TER LedgerEntrySet::rippleCredit ( if (!sleRippleState) { - STAmount saReceiverLimit = STAmount (currency, uReceiverID); - STAmount saBalance = saAmount; + STAmount saReceiverLimit({currency, uReceiverID}); + STAmount saBalance = saAmount; saBalance.setIssuer (noAccount()); diff --git a/src/ripple/module/app/ledger/OrderBookDB.cpp b/src/ripple/module/app/ledger/OrderBookDB.cpp index f6e1424a3..79742101f 100644 --- a/src/ripple/module/app/ledger/OrderBookDB.cpp +++ b/src/ripple/module/app/ledger/OrderBookDB.cpp @@ -61,9 +61,9 @@ void OrderBookDB::setup (Ledger::ref ledger) static void updateHelper (SLE::ref entry, ripple::unordered_set< uint256 >& seen, - ripple::unordered_map< RippleAsset, std::vector >& destMap, - ripple::unordered_map< RippleAsset, std::vector >& sourceMap, - ripple::unordered_set< RippleAsset >& XRPBooks, + ripple::unordered_map< Issue, std::vector >& destMap, + ripple::unordered_map< Issue, std::vector >& sourceMap, + ripple::unordered_set< Issue >& XRPBooks, int& books) { if ((entry->getType () == ltDIR_NODE) && (entry->isFieldPresent (sfExchangeRate)) && @@ -85,10 +85,10 @@ static void updateHelper (SLE::ref entry, OrderBook::pointer book = std::make_shared (std::cref (index), std::cref (ci), std::cref (co), std::cref (ii), std::cref (io)); - sourceMap[RippleAssetRef (ci, ii)].push_back (book); - destMap[RippleAssetRef (co, io)].push_back (book); + sourceMap[IssueRef (ci, ii)].push_back (book); + destMap[IssueRef (co, io)].push_back (book); if (co.isZero()) - XRPBooks.insert(RippleAssetRef (ci, ii)); + XRPBooks.insert(IssueRef (ci, ii)); ++books; } } @@ -97,9 +97,9 @@ static void updateHelper (SLE::ref entry, void OrderBookDB::update (Ledger::pointer ledger) { ripple::unordered_set< uint256 > seen; - ripple::unordered_map< RippleAsset, std::vector > destMap; - ripple::unordered_map< RippleAsset, std::vector > sourceMap; - ripple::unordered_set< RippleAsset > XRPBooks; + ripple::unordered_map< Issue, std::vector > destMap; + ripple::unordered_map< Issue, std::vector > sourceMap; + ripple::unordered_set< Issue > XRPBooks; WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB::update>"; @@ -139,7 +139,7 @@ void OrderBookDB::addOrderBook(Currency const& ci, Currency const& co, if (toXRP) { // We don't want to search through all the to-XRP or from-XRP order books! - for (auto ob : mSourceMap[RippleAssetRef(ci, ii)]) + for (auto ob : mSourceMap[{ci, ii}]) { if (ob->getCurrencyOut().isZero ()) // also to XRP return; @@ -147,7 +147,7 @@ void OrderBookDB::addOrderBook(Currency const& ci, Currency const& co, } else { - for (auto ob : mDestMap[RippleAssetRef(co, io)]) + for (auto ob : mDestMap[{co, io}]) { if ((ob->getCurrencyIn() == ci) && (ob->getIssuerIn() == ii)) return; @@ -157,10 +157,10 @@ void OrderBookDB::addOrderBook(Currency const& ci, Currency const& co, uint256 index = Ledger::getBookBase(ci, ii, co, io); auto book = std::make_shared (index, ci, co, ii, io); - mSourceMap[RippleAssetRef (ci, ii)].push_back (book); - mDestMap[RippleAssetRef (co, io)].push_back (book); + mSourceMap[{ci, ii}].push_back (book); + mDestMap[{co, io}].push_back (book); if (toXRP) - mXRPBooks.insert(RippleAssetRef (ci, ii)); + mXRPBooks.insert({ci, ii}); } // return list of all orderbooks that want this issuerID and currencyID @@ -168,8 +168,7 @@ void OrderBookDB::getBooksByTakerPays (Account const& issuerID, Currency const& std::vector& bookRet) { ScopedLockType sl (mLock); - auto it = mSourceMap.find (RippleAssetRef (currencyID, issuerID)); - + auto it = mSourceMap.find ({currencyID, issuerID}); if (it != mSourceMap.end ()) bookRet = it->second; else @@ -180,7 +179,7 @@ bool OrderBookDB::isBookToXRP(Account const& issuerID, Currency const& currencyI { ScopedLockType sl (mLock); - return mXRPBooks.count(RippleAssetRef(currencyID, issuerID)) > 0; + return mXRPBooks.count({currencyID, issuerID}) > 0; } // return list of all orderbooks that give this issuerID and currencyID @@ -188,7 +187,7 @@ void OrderBookDB::getBooksByTakerGets (Account const& issuerID, Currency const& std::vector& bookRet) { ScopedLockType sl (mLock); - auto it = mDestMap.find (RippleAssetRef (currencyID, issuerID)); + auto it = mDestMap.find ({currencyID, issuerID}); if (it != mDestMap.end ()) bookRet = it->second; @@ -206,9 +205,8 @@ BookListeners::pointer OrderBookDB::makeBookListeners (Currency const& currencyP { ret = std::make_shared (); - mListeners [RippleBookRef ( - RippleAssetRef (currencyPays, issuerPays), - RippleAssetRef (currencyGets, issuerGets))] = ret; + mListeners [BookRef ({currencyPays, issuerPays}, + {currencyGets, issuerGets})] = ret; assert (getBookListeners (currencyPays, currencyGets, issuerPays, issuerGets) == ret); } @@ -221,9 +219,8 @@ BookListeners::pointer OrderBookDB::getBookListeners (Currency const& currencyPa BookListeners::pointer ret; ScopedLockType sl (mLock); - auto it0 (mListeners.find (RippleBookRef ( - RippleAssetRef (currencyPays, issuerPays), - RippleAssetRef (currencyGets, issuerGets)))); + auto it0 (mListeners.find (BookRef ( + {currencyPays, issuerPays}, {currencyGets, issuerGets}))); if (it0 != mListeners.end ()) ret = it0->second; diff --git a/src/ripple/module/app/ledger/OrderBookDB.h b/src/ripple/module/app/ledger/OrderBookDB.h index 8b274f018..66e58e9a8 100644 --- a/src/ripple/module/app/ledger/OrderBookDB.h +++ b/src/ripple/module/app/ledger/OrderBookDB.h @@ -79,7 +79,7 @@ public: void processTxn (Ledger::ref ledger, const AcceptedLedgerTx& alTx, Json::Value const& jvObj); private: - typedef ripple::unordered_map > + typedef ripple::unordered_map > AssetToOrderBook; // by ci/ii @@ -89,13 +89,13 @@ private: AssetToOrderBook mDestMap; // does an order book to XRP exist - ripple::unordered_set mXRPBooks; + ripple::unordered_set mXRPBooks; typedef RippleRecursiveMutex LockType; typedef std::lock_guard ScopedLockType; LockType mLock; - typedef ripple::unordered_map + typedef ripple::unordered_map BookToListenersMap; BookToListenersMap mListeners; diff --git a/src/ripple/module/app/misc/NetworkOPs.cpp b/src/ripple/module/app/misc/NetworkOPs.cpp index 08e575dca..e821c19cb 100644 --- a/src/ripple/module/app/misc/NetworkOPs.cpp +++ b/src/ripple/module/app/misc/NetworkOPs.cpp @@ -3004,8 +3004,7 @@ void NetworkOPsImp::getBookPage ( // Need to charge a transfer fee to offer owner. uOfferRate = uTransferRate; saOwnerFundsLimit = STAmount::divide ( - saOwnerFunds, STAmount (noCurrency(), noAccount(), - uOfferRate, -9)); + saOwnerFunds, STAmount (noIssue(), uOfferRate, -9)); // TODO(tom): why -9? } else @@ -3038,7 +3037,7 @@ void NetworkOPsImp::getBookPage ( saOwnerFunds, STAmount::multiply ( saTakerGetsFunded, - STAmount (noCurrency(), noAccount(), + STAmount (noIssue(), uOfferRate, -9))); umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays; @@ -3165,7 +3164,7 @@ void NetworkOPsImp::getBookPage ( // Need to charge a transfer fee to offer owner. uOfferRate = uTransferRate; // TODO(tom): where does -9 come from?! - STAmount amount (noCurrency(), noAccount(), uOfferRate, -9); + STAmount amount (noIssue(), uOfferRate, -9); saOwnerFundsLimit = STAmount::divide (saOwnerFunds, amount); } else @@ -3198,7 +3197,7 @@ void NetworkOPsImp::getBookPage ( : std::min (saOwnerFunds, STAmount::multiply ( saTakerGetsFunded, STAmount ( - noCurrency(), noAccount(), uOfferRate, + noIssue(), uOfferRate, -9))); umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays; diff --git a/src/ripple/module/app/misc/OrderBook.h b/src/ripple/module/app/misc/OrderBook.h index 1c381ce4d..062e4f54e 100644 --- a/src/ripple/module/app/misc/OrderBook.h +++ b/src/ripple/module/app/misc/OrderBook.h @@ -39,7 +39,7 @@ public: @param issuerOut The destination issuer. */ // VFALCO NOTE what is the meaning of the index parameter? - // VFALCO TODO Replace with RippleAsset + // VFALCO TODO Replace with Issue OrderBook (uint256 const& index, Currency const& currencyIn, Currency const& currencyOut, diff --git a/src/ripple/module/app/paths/CalcNodeDeliverFwd.cpp b/src/ripple/module/app/paths/CalcNodeDeliverFwd.cpp index 8e0fa40ca..7a028eb1c 100644 --- a/src/ripple/module/app/paths/CalcNodeDeliverFwd.cpp +++ b/src/ripple/module/app/paths/CalcNodeDeliverFwd.cpp @@ -264,7 +264,7 @@ TER nodeDeliverFwd ( // Do outbound debiting. // Send to issuer/limbo total amount including fees (issuer gets // fees). - auto id = !!node.currency_ ? Account(node.issuer_) : xrpIssuer(); + auto id = !!node.currency_ ? Account(node.issuer_) : xrpAccount(); auto outPassTotal = saOutPassAct + saOutPassFees; rippleCalc.mActiveLedger.accountSend (node.offerOwnerAccount_, id, outPassTotal); @@ -296,7 +296,7 @@ TER nodeDeliverFwd ( || uInAccountID != node.offerOwnerAccount_) { auto id = !isXRP(previousNode.currency_) ? - uInAccountID : xrpIssuer(); + uInAccountID : xrpAccount(); resultCode = rippleCalc.mActiveLedger.accountSend ( id, node.offerOwnerAccount_, saInPassAct); diff --git a/src/ripple/module/app/paths/ComputeAccountLiquidityForward.cpp b/src/ripple/module/app/paths/ComputeAccountLiquidityForward.cpp index 9d859ad4f..449ec0a4c 100644 --- a/src/ripple/module/app/paths/ComputeAccountLiquidityForward.cpp +++ b/src/ripple/module/app/paths/ComputeAccountLiquidityForward.cpp @@ -78,18 +78,11 @@ TER computeForwardLiquidityForAccount ( // rev. // For nextNodeIsAccount - STAmount saPrvRedeemAct ( - previousNode.saFwdRedeem.getCurrency (), - previousNode.saFwdRedeem.getIssuer ()); - - STAmount saPrvIssueAct ( - previousNode.saFwdIssue.getCurrency (), - previousNode.saFwdIssue.getIssuer ()); + auto saPrvRedeemAct = previousNode.saFwdRedeem.zeroed(); + auto saPrvIssueAct = previousNode.saFwdIssue.zeroed(); // For !previousNodeIsAccount - STAmount saPrvDeliverAct ( - previousNode.saFwdDeliver.getCurrency (), - previousNode.saFwdDeliver.getIssuer ()); + auto saPrvDeliverAct = previousNode.saFwdDeliver.zeroed (); WriteLog (lsTRACE, RippleCalc) << "computeForwardLiquidityForAccount> " @@ -167,7 +160,7 @@ TER computeForwardLiquidityForAccount ( ? previousNode.saFwdIssue // No fee. : STAmount::mulRound ( previousNode.saFwdIssue, - STAmount (noCurrency(), noAccount(), uQualityIn, -9), + STAmount (noIssue(), uQualityIn, -9), true); // Amount to credit. // Amount to credit. Credit for less than received as a surcharge. @@ -329,7 +322,7 @@ TER computeForwardLiquidityForAccount ( node.saFwdDeliver = std::min ( node.saFwdDeliver, rippleCalc.mActiveLedger.accountHolds ( - node.account_, xrpCurrency(), xrpIssuer())); + node.account_, xrpCurrency(), xrpAccount())); } @@ -360,7 +353,7 @@ TER computeForwardLiquidityForAccount ( // Deliver XRP to limbo. resultCode = rippleCalc.mActiveLedger.accountSend ( - node.account_, xrpIssuer(), node.saFwdDeliver); + node.account_, xrpAccount(), node.saFwdDeliver); } } } diff --git a/src/ripple/module/app/paths/ComputeAccountLiquidityReverse.cpp b/src/ripple/module/app/paths/ComputeAccountLiquidityReverse.cpp index 46ec8dfec..56c32c39b 100644 --- a/src/ripple/module/app/paths/ComputeAccountLiquidityReverse.cpp +++ b/src/ripple/module/app/paths/ComputeAccountLiquidityReverse.cpp @@ -84,19 +84,19 @@ TER computeReverseLiquidityForAccount ( const STAmount saPrvOwed = (previousNodeIsAccount && nodeIndex != 0) ? rippleCalc.mActiveLedger.rippleOwed ( node.account_, previousAccountID, node.currency_) - : STAmount (node.currency_, node.account_); + : STAmount ({node.currency_, node.account_}); // The limit amount that the previous account may owe. const STAmount saPrvLimit = (previousNodeIsAccount && nodeIndex != 0) ? rippleCalc.mActiveLedger.rippleLimit ( node.account_, previousAccountID, node.currency_) - : STAmount (node.currency_, node.account_); + : STAmount ({node.currency_, node.account_}); // Next account is owed. const STAmount saNxtOwed = (nextNodeIsAccount && nodeIndex != lastNodeIndex) ? rippleCalc.mActiveLedger.rippleOwed ( node.account_, nextAccountID, node.currency_) - : STAmount (node.currency_, node.account_); + : STAmount ({node.currency_, node.account_}); WriteLog (lsTRACE, RippleCalc) << "computeReverseLiquidityForAccount>" @@ -114,7 +114,7 @@ TER computeReverseLiquidityForAccount ( // Previous can redeem the owed IOUs it holds. const STAmount saPrvRedeemReq = (saPrvOwed > zero) ? saPrvOwed - : STAmount (saPrvOwed.getCurrency (), saPrvOwed.getIssuer ()); + : STAmount (saPrvOwed.issue ()); // This is the amount we're actually going to be setting for the previous // node. @@ -129,27 +129,25 @@ TER computeReverseLiquidityForAccount ( // Precompute these values in case we have an order book. auto deliverCurrency = previousNode.saRevDeliver.getCurrency (); const STAmount saPrvDeliverReq ( - deliverCurrency, previousNode.saRevDeliver.getIssuer (), -1); + {deliverCurrency, previousNode.saRevDeliver.getIssuer ()}, -1); // Unlimited delivery. - STAmount& saPrvDeliverAct = previousNode.saRevDeliver; + STAmount& saPrvDeliverAct = previousNode.saRevDeliver; // For nextNodeIsAccount const STAmount& saCurRedeemReq = node.saRevRedeem; // Set to zero, because we're trying to hit the previous node. - STAmount saCurRedeemAct ( - saCurRedeemReq.getCurrency (), saCurRedeemReq.getIssuer ()); + auto saCurRedeemAct = saCurRedeemReq.zeroed(); const STAmount& saCurIssueReq = node.saRevIssue; + // Track the amount we actually redeem. - STAmount saCurIssueAct ( - saCurIssueReq.getCurrency (), saCurIssueReq.getIssuer ()); + auto saCurIssueAct = saCurIssueReq.zeroed(); // For !nextNodeIsAccount const STAmount& saCurDeliverReq = node.saRevDeliver; - STAmount saCurDeliverAct ( - saCurDeliverReq.getCurrency (), saCurDeliverReq.getIssuer ()); + auto saCurDeliverAct = saCurDeliverReq.zeroed(); WriteLog (lsTRACE, RippleCalc) << "computeReverseLiquidityForAccount:" @@ -192,8 +190,7 @@ TER computeReverseLiquidityForAccount ( const STAmount saCurWantedReq = std::min ( pathState.outReq() - pathState.outAct(), saPrvLimit + saPrvOwed); - STAmount saCurWantedAct ( - saCurWantedReq.getCurrency (), saCurWantedReq.getIssuer ()); + auto saCurWantedAct = saCurWantedReq.zeroed (); WriteLog (lsTRACE, RippleCalc) << "computeReverseLiquidityForAccount: account --> ACCOUNT --> $ :" diff --git a/src/ripple/module/app/paths/ComputeRippleLiquidity.cpp b/src/ripple/module/app/paths/ComputeRippleLiquidity.cpp index a620a68b5..e3e3ad9ac 100644 --- a/src/ripple/module/app/paths/ComputeRippleLiquidity.cpp +++ b/src/ripple/module/app/paths/ComputeRippleLiquidity.cpp @@ -139,11 +139,11 @@ void computeRippleLiquidity ( // current actual = current request * (quality out / quality in). auto numerator = STAmount::mulRound ( - saCur, uQualityOut, currency, uCurIssuerID, true); + saCur, uQualityOut, {currency, uCurIssuerID}, true); // True means "round up" to get best flow. STAmount saCurIn = STAmount::divRound ( - numerator, uQualityIn, currency, uCurIssuerID, true); + numerator, uQualityIn, {currency, uCurIssuerID}, true); WriteLog (lsTRACE, RippleCalc) << "computeRippleLiquidity:" @@ -170,12 +170,13 @@ void computeRippleLiquidity ( // This is inverted compared to the code above because we're // going the other way + Issue issue{currency, uCurIssuerID}; auto numerator = STAmount::mulRound ( - saPrv, uQualityIn, currency, uCurIssuerID, true); + saPrv, uQualityIn, issue, true); // A part of current. All of previous. (Cur is the driver // variable.) STAmount saCurOut = STAmount::divRound ( - numerator, uQualityOut, currency, uCurIssuerID, true); + numerator, uQualityOut, issue, true); WriteLog (lsTRACE, RippleCalc) << "computeRippleLiquidity:4: saCurReq=" << saCurReq; diff --git a/src/ripple/module/app/paths/PathRequest.cpp b/src/ripple/module/app/paths/PathRequest.cpp index a675a2e6e..763a2df55 100644 --- a/src/ripple/module/app/paths/PathRequest.cpp +++ b/src/ripple/module/app/paths/PathRequest.cpp @@ -361,7 +361,7 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast) if (!sameAccount || (c != saDstAmount.getCurrency ())) { if (c.isZero ()) - sourceCurrencies.insert (std::make_pair (c, xrpIssuer())); + sourceCurrencies.insert (std::make_pair (c, xrpAccount())); else sourceCurrencies.insert (std::make_pair (c, raSrcAccount.getAccountID ())); } @@ -414,7 +414,7 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast) for (auto const& currIssuer: sourceCurrencies) { { - STAmount test (currIssuer.first, currIssuer.second, 1); + STAmount test ({currIssuer.first, currIssuer.second}, 1); if (m_journal.debug) { m_journal.debug @@ -436,11 +436,12 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast) PathState::List pathStateList; STAmount saMaxAmountAct; STAmount saDstAmountAct; - STAmount saMaxAmount ( - currIssuer.first, - currIssuer.second.isNonZero () ? Account(currIssuer.second) : - (currIssuer.first.isZero () ? xrpIssuer() : - raSrcAccount.getAccountID ()), 1); + auto& account = currIssuer.second.isNonZero () + ? Account(currIssuer.second) + : isXRP (currIssuer.first) + ? xrpAccount() + : raSrcAccount.getAccountID (); + STAmount saMaxAmount ({currIssuer.first, account}, 1); saMaxAmount.negate (); m_journal.debug << iIdentifier << " Paths found, calling rippleCalc"; diff --git a/src/ripple/module/app/paths/PathRequest.h b/src/ripple/module/app/paths/PathRequest.h index bd79fde67..c68158e5c 100644 --- a/src/ripple/module/app/paths/PathRequest.h +++ b/src/ripple/module/app/paths/PathRequest.h @@ -45,7 +45,7 @@ public: typedef const pointer& ref; typedef const wptr& wref; - // TODO(tom): Use RippleAsset instead! + // TODO(tom): Use Issue instead! typedef std::pair CurrencyIssuer; public: diff --git a/src/ripple/module/app/paths/PathState.cpp b/src/ripple/module/app/paths/PathState.cpp index 5d92a9e5f..a1945312b 100644 --- a/src/ripple/module/app/paths/PathState.cpp +++ b/src/ripple/module/app/paths/PathState.cpp @@ -78,7 +78,7 @@ TER PathState::pushImpliedNodes ( if (nodes_.back ().currency_ != currency) { // Currency is different, need to convert via an offer from an order - // book. xrpIssuer() does double duty as signaling "this is an order + // book. xrpAccount() does double duty as signaling "this is an order // book". // Corresponds to "Implies an offer directory" in the diagram, currently @@ -88,8 +88,8 @@ TER PathState::pushImpliedNodes ( : STPathElement::typeCurrency | STPathElement::typeIssuer; // The offer's output is what is now wanted. - // xrpIssuer() is a placeholder for offers. - resultCode = pushNode (type, xrpIssuer(), currency, issuer); + // xrpAccount() is a placeholder for offers. + resultCode = pushNode (type, xrpAccount(), currency, issuer); } @@ -193,13 +193,13 @@ TER PathState::pushNode ( ? issuer : !!node.currency_ // Not XRP. ? account - : xrpIssuer(); + : xrpAccount(); // Zero value - for accounts. - node.saRevRedeem = STAmount (node.currency_, account); + node.saRevRedeem = STAmount ({node.currency_, account}); node.saRevIssue = node.saRevRedeem; // For order books only - zero currency with the issuer ID. - node.saRevDeliver = STAmount (node.currency_, node.issuer_); + node.saRevDeliver = STAmount ({node.currency_, node.issuer_}); node.saFwdDeliver = node.saRevDeliver; if (pathIsEmpty) @@ -220,7 +220,7 @@ TER PathState::pushNode ( resultCode = pushImpliedNodes ( node.account_, node.currency_, - isXRP(node.currency_) ? xrpIssuer() : account); + isXRP(node.currency_) ? xrpAccount() : account); // Note: previousNode may no longer be the immediately previous node. } @@ -322,9 +322,9 @@ TER PathState::pushNode ( ? Account(previousNode.issuer_) // Default to previous issuer : Account(previousNode.account_) // Or previous account if no previous issuer. - : xrpIssuer(); + : xrpAccount(); node.saRateMax = saZero; - node.saRevDeliver = STAmount (node.currency_, node.issuer_); + node.saRevDeliver = STAmount({node.currency_, node.issuer_}); node.saFwdDeliver = node.saRevDeliver; if (node.currency_.isZero() != node.issuer_.isZero()) @@ -345,7 +345,7 @@ TER PathState::pushNode ( // Insert intermediary issuer account if needed. resultCode = pushImpliedNodes ( - xrpIssuer(), // Rippling, but offers don't have an account. + xrpAccount(), // Rippling, but offers don't have an account. previousNode.currency_, previousNode.issuer_); } @@ -389,7 +389,7 @@ void PathState::expandPath ( const Currency currencyOutID = saOutReq.getCurrency (); const Account issuerOutID = saOutReq.getIssuer (); const Account uSenderIssuerID - = isXRP(uMaxCurrencyID) ? xrpIssuer() : uSenderID; + = isXRP(uMaxCurrencyID) ? xrpAccount() : uSenderID; // Sender is always issuer for non-XRP. WriteLog (lsTRACE, RippleCalc) @@ -450,7 +450,7 @@ void PathState::expandPath ( ? (issuerOutID == uReceiverID) ? Account(uReceiverID) : Account(issuerOutID) // Use implied node. - : xrpIssuer(); + : xrpAccount(); WriteLog (lsDEBUG, RippleCalc) << "expandPath: implied check:" diff --git a/src/ripple/module/app/paths/Pathfinder.cpp b/src/ripple/module/app/paths/Pathfinder.cpp index f9ac5870f..23724cf13 100644 --- a/src/ripple/module/app/paths/Pathfinder.cpp +++ b/src/ripple/module/app/paths/Pathfinder.cpp @@ -111,7 +111,7 @@ Pathfinder::Pathfinder ( mDstAmount (saDstAmount), mSrcCurrencyID (uSrcCurrencyID), mSrcIssuerID (uSrcIssuerID), - mSrcAmount (uSrcCurrencyID, uSrcIssuerID, 1u, 0, true), + mSrcAmount ({uSrcCurrencyID, uSrcIssuerID}, 1u, 0, true), mLedger (cache->getLedger ()), mRLCache (cache) { @@ -502,7 +502,7 @@ int Pathfinder::getPathsOut ( Currency const& currencyID, Account const& accountID, bool isDstCurrency, Account const& dstAccount) { - // VFALCO TODO Use RippleAsset here + // VFALCO TODO Use Issue here auto currencyAccount = std::make_pair(currencyID, accountID); auto it = mPOMap.find (currencyAccount); @@ -791,7 +791,7 @@ void Pathfinder::addLink( { STPathElement pathElement( STPathElement::typeCurrency, - xrpIssuer(), xrpCurrency(), xrpIssuer()); + xrpAccount(), xrpCurrency(), xrpAccount()); incompletePaths.assembleAdd(currentPath, pathElement); } } @@ -804,7 +804,7 @@ void Pathfinder::addLink( BOOST_FOREACH(OrderBook::ref book, books) { if (!currentPath.hasSeen ( - xrpIssuer(), + xrpAccount(), book->getCurrencyOut(), book->getIssuerOut()) && !matchesOrigin( @@ -821,7 +821,7 @@ void Pathfinder::addLink( // add the order book itself newPath.addElement(STPathElement( STPathElement::typeCurrency, - xrpIssuer(), xrpCurrency(), xrpIssuer())); + xrpAccount(), xrpCurrency(), xrpAccount())); if (mDstAmount.getCurrency().isZero()) { // destination is XRP, add account and path is complete @@ -835,7 +835,7 @@ void Pathfinder::addLink( { // Don't want the book if we've already seen the issuer // add the order book itself newPath.addElement(STPathElement(STPathElement::typeCurrency | STPathElement::typeIssuer, - xrpIssuer(), book->getCurrencyOut(), book->getIssuerOut())); + xrpAccount(), book->getCurrencyOut(), book->getIssuerOut())); if ((book->getIssuerOut() == mDstAccountID) && book->getCurrencyOut() == mDstAmount.getCurrency()) { // with the destination account, this path is complete diff --git a/src/ripple/module/app/paths/RippleCalc.cpp b/src/ripple/module/app/paths/RippleCalc.cpp index 3af788397..4c6342900 100644 --- a/src/ripple/module/app/paths/RippleCalc.cpp +++ b/src/ripple/module/app/paths/RippleCalc.cpp @@ -55,13 +55,13 @@ TER rippleCalculate ( PathState::List& pathStateList, // Issuer: - // XRP: xrpIssuer() + // XRP: xrpAccount() // non-XRP: uSrcAccountID (for any issuer) or another account with trust // node. STAmount const& saMaxAmountReq, // --> -1 = no limit. // Issuer: - // XRP: xrpIssuer() + // XRP: xrpAccount() // non-XRP: uDstAccountID (for any issuer) or another account with trust // node. STAmount const& saDstAmountReq, diff --git a/src/ripple/module/app/transactors/CreateOffer.cpp b/src/ripple/module/app/transactors/CreateOffer.cpp index 05d64ab65..d07e152ee 100644 --- a/src/ripple/module/app/transactors/CreateOffer.cpp +++ b/src/ripple/module/app/transactors/CreateOffer.cpp @@ -40,19 +40,19 @@ CreateOffer::CreateOffer ( } TER -CreateOffer::checkAcceptAsset(core::AssetRef asset) const +CreateOffer::checkAcceptAsset(IssueRef issue) const { /* Only valid for custom currencies */ - assert (!asset.is_xrp ()); + assert (!isXRP (issue.currency)); SLE::pointer const issuerAccount = mEngine->entryCache ( - ltACCOUNT_ROOT, Ledger::getAccountRootIndex (asset.issuer)); + ltACCOUNT_ROOT, Ledger::getAccountRootIndex (issue.account)); if (!issuerAccount) { if (m_journal.warning) m_journal.warning << "delay: can't receive IOUs from non-existent issuer: " << - to_string (asset.issuer); + to_string (issue.account); return (mParams & tapRETRY) ? terNO_ACCOUNT @@ -63,7 +63,7 @@ CreateOffer::checkAcceptAsset(core::AssetRef asset) const { SLE::pointer const trustLine (mEngine->entryCache ( ltRIPPLE_STATE, Ledger::getRippleStateIndex ( - mTxnAccountID, asset.issuer, asset.currency))); + mTxnAccountID, issue.account, issue.currency))); if (!trustLine) { @@ -75,7 +75,7 @@ CreateOffer::checkAcceptAsset(core::AssetRef asset) const // Entries have a canonical representation, determined by a // lexicographical "greater than" comparison employing strict weak // ordering. Determine which entry we need to access. - bool const canonical_gt (mTxnAccountID > asset.issuer); + bool const canonical_gt (mTxnAccountID > issue.account); bool const need_auth (trustLine->getFieldU32 (sfFlags) & (canonical_gt ? lsfLowAuth : lsfHighAuth)); @@ -279,7 +279,7 @@ CreateOffer::doApply () // Make sure that we are authorized to hold what the taker will pay us. if (terResult == tesSUCCESS && !saTakerPays.isNative ()) - terResult = checkAcceptAsset (core::Asset (uPaysCurrency, uPaysIssuerID)); + terResult = checkAcceptAsset (Issue (uPaysCurrency, uPaysIssuerID)); bool crossed = false; bool const bOpenLedger (mParams & tapOPEN_LEDGER); @@ -358,7 +358,7 @@ CreateOffer::doApply () // Earlier, we verified that the amounts, as specified in the offer, // were not negative. That they are now suggests that something went // very wrong with offer crossing. - m_journal.fatal << (crossed ? "Partially consumed" : "Full") << + m_journal.fatal << (crossed ? "Partially consumed" : "Full") << " offer has negative component:" << " pays=" << saTakerPays.getFullText () << " gets=" << saTakerGets.getFullText (); diff --git a/src/ripple/module/app/transactors/CreateOffer.h b/src/ripple/module/app/transactors/CreateOffer.h index 24a51ac64..7c88f32ab 100644 --- a/src/ripple/module/app/transactors/CreateOffer.h +++ b/src/ripple/module/app/transactors/CreateOffer.h @@ -32,7 +32,7 @@ class CreateOffer { protected: /** Determine if we are authorized to hold the asset we want to get */ - TER checkAcceptAsset(core::AssetRef asset) const; + TER checkAcceptAsset(IssueRef asset) const; /** Fill offer as much as possible by consuming offers already on the books. We adjusts account balances and charges fees on top to taker. @@ -65,4 +65,3 @@ std::unique_ptr make_CreateOffer ( } #endif - diff --git a/src/ripple/module/app/transactors/CreateOfferBridged.cpp b/src/ripple/module/app/transactors/CreateOfferBridged.cpp index dc1a5be09..96e93e156 100644 --- a/src/ripple/module/app/transactors/CreateOfferBridged.cpp +++ b/src/ripple/module/app/transactors/CreateOfferBridged.cpp @@ -41,20 +41,17 @@ CreateOfferBridged::crossOffers ( core::LedgerView view_cancel (view.duplicate()); - core::AssetRef const asset_in ( - taker_amount.in.getCurrency(), taker_amount.in.getIssuer()); - - core::AssetRef const asset_out ( - taker_amount.out.getCurrency(), taker_amount.out.getIssuer()); + auto& asset_in = taker_amount.in.issue(); + auto& asset_out = taker_amount.out.issue(); core::OfferStream offers_direct (view, view_cancel, - core::Book (asset_in, asset_out), when, m_journal); + Book (asset_in, asset_out), when, m_journal); core::OfferStream offers_leg1 (view, view_cancel, - core::Book (asset_in, xrp_asset ()), when, m_journal); + Book (asset_in, xrpIssue ()), when, m_journal); core::OfferStream offers_leg2 (view, view_cancel, - core::Book (xrp_asset (), asset_out), when, m_journal); + Book (xrpIssue (), asset_out), when, m_journal); core::Taker taker (view, mTxnAccountID, taker_amount, options); diff --git a/src/ripple/module/app/transactors/CreateOfferDirect.cpp b/src/ripple/module/app/transactors/CreateOfferDirect.cpp index 069486f1d..0dfe2eced 100644 --- a/src/ripple/module/app/transactors/CreateOfferDirect.cpp +++ b/src/ripple/module/app/transactors/CreateOfferDirect.cpp @@ -45,16 +45,11 @@ CreateOfferDirect::crossOffers ( mEngine->getLedger ()->getParentCloseTimeNC ()); core::LedgerView view_cancel (view.duplicate()); - core::OfferStream offers (view, view_cancel, - core::Book ( - core::AssetRef ( - taker_amount.in.getCurrency(), taker_amount.in.getIssuer()), - core::AssetRef ( - taker_amount.out.getCurrency(), taker_amount.out.getIssuer())), + core::OfferStream offers ( + view, view_cancel, + Book (taker_amount.in.issue(), taker_amount.out.issue()), when, m_journal); - Account& account = mTxnAccountID; - // TODO(tom): why is that last line needed? - core::Taker taker (offers.view(), account, taker_amount, options); + core::Taker taker (offers.view(), mTxnAccountID, taker_amount, options); TER cross_result (tesSUCCESS); diff --git a/src/ripple/module/app/transactors/Payment.cpp b/src/ripple/module/app/transactors/Payment.cpp index 6e505b36e..21809d88b 100644 --- a/src/ripple/module/app/transactors/Payment.cpp +++ b/src/ripple/module/app/transactors/Payment.cpp @@ -39,8 +39,9 @@ TER Payment::doApply () maxSourceAmount = saDstAmount; else maxSourceAmount = STAmount ( - saDstAmount.getCurrency (), mTxnAccountID, saDstAmount.getMantissa (), - saDstAmount.getExponent (), saDstAmount < zero); + {saDstAmount.getCurrency (), mTxnAccountID}, + saDstAmount.getMantissa (), saDstAmount.getExponent (), + saDstAmount < zero); auto const& uSrcCurrency = maxSourceAmount.getCurrency (); auto const& uDstCurrency = saDstAmount.getCurrency (); diff --git a/src/ripple/module/app/transactors/SetTrust.cpp b/src/ripple/module/app/transactors/SetTrust.cpp index 49a940012..3544bde6b 100644 --- a/src/ripple/module/app/transactors/SetTrust.cpp +++ b/src/ripple/module/app/transactors/SetTrust.cpp @@ -352,12 +352,12 @@ TER SetTrust::doApply () } else if (badCurrency() == currency) { - terResult = temBAD_CURRENCY; + terResult = temBAD_CURRENCY; } else { // Zero balance in currency. - STAmount saBalance (STAmount (currency, noAccount())); + STAmount saBalance ({currency, noAccount()}); uint256 index (Ledger::getRippleStateIndex ( mTxnAccountID, uDstAccountID, currency)); diff --git a/src/ripple/module/data/protocol/STAmount.cpp b/src/ripple/module/data/protocol/STAmount.cpp index 171479a9b..6a7d541b0 100644 --- a/src/ripple/module/data/protocol/STAmount.cpp +++ b/src/ripple/module/data/protocol/STAmount.cpp @@ -28,7 +28,7 @@ std::uint64_t STAmount::uRateOne = std::string STAmount::getHumanCurrency () const { - return to_string (mCurrency); + return to_string (mIssue.currency); } bool STAmount::bSetJson (const Json::Value& jvSource) @@ -101,14 +101,14 @@ STAmount::STAmount (SField::ref n, const Json::Value& v) else { // non-XRP - if (!to_currency (mCurrency, currency.asString ())) + if (!to_currency (mIssue.currency, currency.asString ())) throw std::runtime_error ("invalid currency"); if (!issuer.isString () - || !to_issuer (mIssuer, issuer.asString ())) + || !to_issuer (mIssue.account, issuer.asString ())) throw std::runtime_error ("invalid issuer"); - if (mIssuer.isZero ()) + if (isXRP (*this)) throw std::runtime_error ("invalid issuer"); } @@ -157,7 +157,7 @@ STAmount::STAmount (SField::ref n, const Json::Value& v) bool STAmount::setValue (const std::string& sAmount) { - // Note: mIsNative and mCurrency must be set already! + // Note: mIsNative and mIssue.currency must be set already! static boost::regex reNumber ( "\\`([+-]?)(\\d*)(\\.(\\d*))?([eE]([+-]?)(\\d+))?\\'"); @@ -253,14 +253,14 @@ bool STAmount::setFullValue (const std::string& sAmount, const std::string& sCur // // Figure out the currency. // - if (!to_currency (mCurrency, sCurrency)) + if (!to_currency (mIssue.currency, sCurrency)) { WriteLog (lsINFO, STAmount) << "Currency malformed: " << sCurrency; return false; } - mIsNative = !mCurrency; + mIsNative = !mIssue.currency; // // Figure out the issuer. @@ -275,10 +275,10 @@ bool STAmount::setFullValue (const std::string& sAmount, const std::string& sCur return false; } - mIssuer = naIssuerID.getAccountID (); + mIssue.account = naIssuerID.getAccountID (); // Stamps not must have an issuer. - if (mIsNative && !mIssuer.isZero ()) + if (mIsNative && !isXRP (*this)) { WriteLog (lsINFO, STAmount) << "Issuer specified for XRP: " << sIssuer; @@ -289,13 +289,15 @@ bool STAmount::setFullValue (const std::string& sAmount, const std::string& sCur } // amount = value * [10 ^ offset] -// representation range is 10^80 - 10^(-80) -// on the wire, high 8 bits are (offset+142), low 56 bits are value -// value is zero if amount is zero, otherwise value is 10^15 to (10^16 - 1) inclusive +// Representation range is 10^80 - 10^(-80). +// On the wire, high 8 bits are (offset+142), low 56 bits are value. +// +// Value is zero if amount is zero, otherwise value is 10^15 to (10^16 - 1) +// inclusive. void STAmount::canonicalize () { - if (mCurrency.isZero ()) + if (isXRP (*this)) { // native currency amounts should always have an offset of zero mIsNative = true; @@ -384,8 +386,8 @@ void STAmount::add (Serializer& s) const else // 256 = positive s.add64 (mValue | (static_cast (mOffset + 512 + 256 + 97) << (64 - 10))); - s.add160 (mCurrency); - s.add160 (mIssuer); + s.add160 (mIssue.currency); + s.add160 (mIssue.account); } } @@ -398,18 +400,23 @@ STAmount STAmount::createFromInt64 (SField::ref name, std::int64_t value) void STAmount::setValue (const STAmount& a) { - mCurrency = a.mCurrency; - mIssuer = a.mIssuer; + mIssue = a.mIssue; mValue = a.mValue; mOffset = a.mOffset; mIsNative = a.mIsNative; mIsNegative = a.mIsNegative; } +void STAmount::setIssue (Issue const& issue) { + mIssue = std::move(issue); + mIsNative = isXRP (*this); +} + int STAmount::compare (const STAmount& a) const { // Compares the value of a to the value of this STAmount, amounts must be comparable - if (mIsNegative != a.mIsNegative) return mIsNegative ? -1 : 1; + if (mIsNegative != a.mIsNegative) + return mIsNegative ? -1 : 1; if (!mValue) { @@ -446,14 +453,16 @@ STAmount* STAmount::construct (SerializerIterator& sit, SField::ref name) return new STAmount (name, value, true); // negative } - Currency currency; - currency.copyFrom (sit.get160 ()); + Issue issue; + issue.currency.copyFrom (sit.get160 ()); - if (!currency) - throw std::runtime_error ("invalid non-native currency"); + if (isXRP (issue.currency)) + throw std::runtime_error ("invalid native currency"); - Account issuer; - issuer.copyFrom (sit.get160 ()); + issue.account.copyFrom (sit.get160 ()); + + if (isXRP (issue.account)) + throw std::runtime_error ("invalid native account"); // 10 bits for the offset, sign and "not native" flag int offset = static_cast (value >> (64 - 10)); @@ -473,21 +482,23 @@ STAmount* STAmount::construct (SerializerIterator& sit, SField::ref name) throw std::runtime_error ("invalid currency value"); } - return new STAmount (name, currency, issuer, value, offset, isNegative); + return new STAmount (name, issue, value, offset, isNegative); } if (offset != 512) throw std::runtime_error ("invalid currency value"); - return new STAmount (name, currency, issuer); + return new STAmount (name, issue); } std::int64_t STAmount::getSNValue () const { // signed native value - if (!mIsNative) throw std::runtime_error ("not native"); + if (!mIsNative) + throw std::runtime_error ("not native"); - if (mIsNegative) return - static_cast (mValue); + if (mIsNegative) + return - static_cast (mValue); return static_cast (mValue); } @@ -526,7 +537,7 @@ std::string STAmount::getText () const { ret.append (raw_value); - if(scientific) + if (scientific) { ret.append (1, 'e'); ret.append (std::to_string (mOffset)); @@ -604,16 +615,13 @@ bool STAmount::isComparable (const STAmount& t) const if (t.mIsNative) return false; - return mCurrency == t.mCurrency; + return mIssue.currency == t.mIssue.currency; } bool STAmount::isEquivalent (const SerializedType& t) const { const STAmount* v = dynamic_cast (&t); - - if (!v) return false; - - return isComparable (*v) && (mIsNegative == v->mIsNegative) && (mValue == v->mValue) && (mOffset == v->mOffset); + return v && (*v == *this); } void STAmount::throwComparable (const STAmount& t) const @@ -625,12 +633,18 @@ void STAmount::throwComparable (const STAmount& t) const bool STAmount::operator== (const STAmount& a) const { - return isComparable (a) && (mIsNegative == a.mIsNegative) && (mOffset == a.mOffset) && (mValue == a.mValue); + return isComparable (a) && + mIsNegative == a.mIsNegative && + mOffset == a.mOffset && + mValue == a.mValue; } bool STAmount::operator!= (const STAmount& a) const { - return (mOffset != a.mOffset) || (mValue != a.mValue) || (mIsNegative != a.mIsNegative) || !isComparable (a); + return mOffset != a.mOffset || + mValue != a.mValue || + mIsNegative != a.mIsNegative || + !isComparable (a); } bool STAmount::operator< (const STAmount& a) const @@ -673,17 +687,19 @@ STAmount STAmount::operator- (void) const { if (mValue == 0) return *this; - return STAmount (getFName (), mCurrency, mIssuer, mValue, mOffset, mIsNative, !mIsNegative); + return STAmount ( + getFName (), mIssue, mValue, mOffset, mIsNative, !mIsNegative); } STAmount& STAmount::operator= (std::uint64_t v) { - // does not copy name, does not change currency type + // Does not copy name, does not change currency type. mOffset = 0; mValue = v; mIsNegative = false; - if (!mIsNative) canonicalize (); + if (!mIsNative) + canonicalize (); return *this; } @@ -732,12 +748,14 @@ bool STAmount::operator>= (std::uint64_t v) const STAmount STAmount::operator+ (std::uint64_t v) const { - return STAmount (getFName (), getSNValue () + static_cast (v)); + return STAmount ( + getFName (), getSNValue () + static_cast (v)); } STAmount STAmount::operator- (std::uint64_t v) const { - return STAmount (getFName (), getSNValue () - static_cast (v)); + return STAmount ( + getFName (), getSNValue () - static_cast (v)); } STAmount::operator double () const @@ -746,7 +764,8 @@ STAmount::operator double () const if (!mValue) return 0.0; - if (mIsNegative) return -1.0 * static_cast (mValue) * pow (10.0, mOffset); + if (mIsNegative) + return -1.0 * static_cast (mValue) * pow (10.0, mOffset); return static_cast (mValue) * pow (10.0, mOffset); } @@ -761,18 +780,22 @@ STAmount operator+ (const STAmount& v1, const STAmount& v2) if (v1 == zero) { // Result must be in terms of v1 currency and issuer. - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, v2.mIsNegative); + return STAmount (v1.getFName (), v1.mIssue, + v2.mValue, v2.mOffset, v2.mIsNegative); } if (v1.mIsNative) return STAmount (v1.getFName (), v1.getSNValue () + v2.getSNValue ()); int ov1 = v1.mOffset, ov2 = v2.mOffset; - std::int64_t vv1 = static_cast (v1.mValue), vv2 = static_cast (v2.mValue); + std::int64_t vv1 = static_cast (v1.mValue); + std::int64_t vv2 = static_cast (v2.mValue); - if (v1.mIsNegative) vv1 = -vv1; + if (v1.mIsNegative) + vv1 = -vv1; - if (v2.mIsNegative) vv2 = -vv2; + if (v2.mIsNegative) + vv2 = -vv2; while (ov1 < ov2) { @@ -786,16 +809,17 @@ STAmount operator+ (const STAmount& v1, const STAmount& v2) ++ov2; } - // this addition cannot overflow an std::int64_t, it can overflow an STAmount and the constructor will throw + // This addition cannot overflow an std::int64_t. It can overflow an + // STAmount and the constructor will throw. std::int64_t fv = vv1 + vv2; if ((fv >= -10) && (fv <= 10)) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer); - else if (fv >= 0) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, fv, ov1, false); + return STAmount (v1.getFName (), v1.mIssue); + if (fv >= 0) + return STAmount (v1.getFName (), v1.mIssue, fv, ov1, false); else - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, -fv, ov1, true); + return STAmount (v1.getFName (), v1.mIssue, -fv, ov1, true); } STAmount operator- (const STAmount& v1, const STAmount& v2) @@ -807,16 +831,21 @@ STAmount operator- (const STAmount& v1, const STAmount& v2) if (v2.mIsNative) { - // XXX This could be better, check for overflow and that maximum range is covered. - return STAmount::createFromInt64 (v1.getFName (), v1.getSNValue () - v2.getSNValue ()); + // XXX This could be better, check for overflow and that maximum range + // is covered. + return STAmount::createFromInt64 ( + v1.getFName (), v1.getSNValue () - v2.getSNValue ()); } int ov1 = v1.mOffset, ov2 = v2.mOffset; - std::int64_t vv1 = static_cast (v1.mValue), vv2 = static_cast (v2.mValue); + auto vv1 = static_cast (v1.mValue); + auto vv2 = static_cast (v2.mValue); - if (v1.mIsNegative) vv1 = -vv1; + if (v1.mIsNegative) + vv1 = -vv1; - if (v2.mIsNegative) vv2 = -vv2; + if (v2.mIsNegative) + vv2 = -vv2; while (ov1 < ov2) { @@ -835,23 +864,22 @@ STAmount operator- (const STAmount& v1, const STAmount& v2) std::int64_t fv = vv1 - vv2; if ((fv >= -10) && (fv <= 10)) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer); - else if (fv >= 0) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, fv, ov1, false); + return STAmount (v1.getFName (), v1.mIssue); + if (fv >= 0) + return STAmount (v1.getFName (), v1.mIssue, fv, ov1, false); else - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, -fv, ov1, true); + return STAmount (v1.getFName (), v1.mIssue, -fv, ov1, true); } // NIKB TODO Make Amount::divide skip math if den == QUALITY_ONE STAmount STAmount::divide ( - const STAmount& num, const STAmount& den, Currency const& currency, - Account const& issuer) + const STAmount& num, const STAmount& den, Issue const& issue) { if (den == zero) throw std::runtime_error ("division by zero"); if (num == zero) - return STAmount (currency, issuer); + return {issue}; std::uint64_t numVal = num.mValue, denVal = den.mValue; int numOffset = num.mOffset, denOffset = den.mOffset; @@ -884,21 +912,24 @@ STAmount STAmount::divide ( // 10^16 <= quotient <= 10^18 assert (BN_num_bytes (&v) <= 64); - return STAmount (currency, issuer, v.getuint64 () + 5, - numOffset - denOffset - 17, num.mIsNegative != den.mIsNegative); + // TODO(tom): where do 5 and 17 come from? + return STAmount (issue, v.getuint64 () + 5, + numOffset - denOffset - 17, + num.mIsNegative != den.mIsNegative); } STAmount STAmount::multiply ( - const STAmount& v1, const STAmount& v2, Currency const& currency, - Account const& issuer) + const STAmount& v1, const STAmount& v2, Issue const& issue) { if (v1 == zero || v2 == zero) - return STAmount (currency, issuer); + return STAmount (issue); - if (v1.mIsNative && v2.mIsNative && currency.isZero ()) + if (v1.mIsNative && v2.mIsNative && isXRP (issue) ) { - std::uint64_t minV = (v1.getSNValue () < v2.getSNValue ()) ? v1.getSNValue () : v2.getSNValue (); - std::uint64_t maxV = (v1.getSNValue () < v2.getSNValue ()) ? v2.getSNValue () : v1.getSNValue (); + std::uint64_t minV = v1.getSNValue () < v2.getSNValue () + ? v1.getSNValue () : v2.getSNValue (); + std::uint64_t maxV = v1.getSNValue () < v2.getSNValue () + ? v2.getSNValue () : v1.getSNValue (); if (minV > 3000000000ull) // sqrt(cMaxNative) throw std::runtime_error ("Native value overflow"); @@ -944,8 +975,9 @@ STAmount STAmount::multiply ( // 10^16 <= product <= 10^18 assert (BN_num_bytes (&v) <= 64); - return STAmount (currency, issuer, v.getuint64 () + 7, offset1 + offset2 + 14, - v1.mIsNegative != v2.mIsNegative); + // TODO(tom): where do 7 and 14 come from? + return STAmount (issue, v.getuint64 () + 7, + offset1 + offset2 + 14, v1.mIsNegative != v2.mIsNegative); } // Convert an offer into an index amount so they sort by rate. @@ -964,7 +996,7 @@ std::uint64_t STAmount::getRate (const STAmount& offerOut, const STAmount& offer try { - STAmount r = divide (offerIn, offerOut, noCurrency(), noAccount()); + STAmount r = divide (offerIn, offerOut, noIssue()); if (r == zero) // offer is too good return 0; @@ -985,34 +1017,39 @@ std::uint64_t STAmount::getRate (const STAmount& offerOut, const STAmount& offer STAmount STAmount::setRate (std::uint64_t rate) { if (rate == 0) - return STAmount (noCurrency(), noAccount()); + return STAmount (noIssue()); std::uint64_t mantissa = rate & ~ (255ull << (64 - 8)); int exponent = static_cast (rate >> (64 - 8)) - 100; - return STAmount (noCurrency(), noAccount(), mantissa, exponent); + return STAmount (noIssue(), mantissa, exponent); } -STAmount STAmount::getPay (const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed) +STAmount STAmount::getPay ( + const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed) { - // Someone wants to get (needed) out of the offer, how much should they pay in? + // Someone wants to get (needed) out of the offer, how much should they pay + // in? if (offerOut == zero) - return STAmount (offerIn.getCurrency (), offerIn.getIssuer ()); + return STAmount (offerIn.issue ()); if (needed >= offerOut) - { // They need more than offered, pay full amount. return needed; - } - STAmount ret = divide (multiply (needed, offerIn, noCurrency(), noAccount()), offerOut, offerIn.getCurrency (), offerIn.getIssuer ()); + + STAmount ret = divide (multiply (needed, offerIn, noIssue()), + offerOut, offerIn.issue()); return (ret > offerIn) ? offerIn : ret; } STAmount STAmount::deserialize (SerializerIterator& it) { - std::unique_ptr s (dynamic_cast (construct (it, sfGeneric))); + auto s = dynamic_cast (construct (it, sfGeneric)); + if (!s) + throw std::runtime_error("Deserialization error"); + STAmount ret (*s); return ret; } @@ -1028,12 +1065,12 @@ std::string STAmount::getFullText () const { ret += "/"; - if (!mIssuer) + if (isXRP (*this)) ret += "0"; - else if (mIssuer == noAccount()) + else if (mIssue.account == noAccount()) ret += "1"; else - ret += to_string (mIssuer); + ret += to_string (mIssue.account); } return ret; @@ -1047,9 +1084,9 @@ STAmount STAmount::getRound () const std::uint64_t valueDigits = mValue % 1000000000ull; if (valueDigits == 1) - return STAmount (mCurrency, mIssuer, mValue - 1, mOffset, mIsNegative); + return STAmount (mIssue, mValue - 1, mOffset, mIsNegative); else if (valueDigits == 999999999ull) - return STAmount (mCurrency, mIssuer, mValue + 1, mOffset, mIsNegative); + return STAmount (mIssue, mValue + 1, mOffset, mIsNegative); return *this; } @@ -1083,11 +1120,11 @@ void STAmount::setJson (Json::Value& elem) const if (!mIsNative) { - // It is an error for currency or issuer not to be specified for valid json. - + // It is an error for currency or issuer not to be specified for valid + // json. elem[jss::value] = getText (); elem[jss::currency] = getHumanCurrency (); - elem[jss::issuer] = to_string (mIssuer); + elem[jss::issuer] = to_string (mIssue.account); } else { @@ -1110,11 +1147,9 @@ public: static STAmount serializeAndDeserialize (const STAmount& s) { Serializer ser; - s.add (ser); SerializerIterator sit (ser); - return STAmount::deserialize (sit); } @@ -1123,17 +1158,17 @@ public: bool roundTest (int n, int d, int m) { // check STAmount rounding - STAmount num (noCurrency(), noAccount(), n); - STAmount den (noCurrency(), noAccount(), d); - STAmount mul (noCurrency(), noAccount(), m); - STAmount quot = STAmount::divide (n, d, noCurrency(), noAccount()); - STAmount res = STAmount::multiply (quot, mul, noCurrency(), noAccount()); + STAmount num (noIssue(), n); + STAmount den (noIssue(), d); + STAmount mul (noIssue(), m); + STAmount quot = STAmount::divide (n, d, noIssue()); + STAmount res = STAmount::multiply (quot, mul, noIssue()); expect (! res.isNative (), "Product should not be native"); res.roundSelf (); - STAmount cmp (noCurrency(), noAccount(), (n * m) / d); + STAmount cmp (noIssue(), (n * m) / d); expect (! cmp.isNative (), "Comparison amount should not be native"); @@ -1158,13 +1193,13 @@ public: void mulTest (int a, int b) { - STAmount aa (noCurrency(), noAccount(), a); - STAmount bb (noCurrency(), noAccount(), b); - STAmount prod1 (STAmount::multiply (aa, bb, noCurrency(), noAccount())); + STAmount aa (noIssue(), a); + STAmount bb (noIssue(), b); + STAmount prod1 (STAmount::multiply (aa, bb, noIssue())); expect (! prod1.isNative ()); - STAmount prod2 (noCurrency(), noAccount(), static_cast (a) * static_cast (b)); + STAmount prod2 (noIssue(), static_cast (a) * static_cast (b)); if (prod1 != prod2) { @@ -1179,7 +1214,7 @@ public: } aa = a; - prod1 = STAmount::multiply (aa, bb, noCurrency(), noAccount()); + prod1 = STAmount::multiply (aa, bb, noIssue()); if (prod1 != prod2) { @@ -1374,7 +1409,7 @@ public: { testcase ("custom currency"); - STAmount zeroSt (noCurrency(), noAccount()), one (noCurrency(), noAccount(), 1), hundred (noCurrency(), noAccount(), 100); + STAmount zeroSt (noIssue()), one (noIssue(), 1), hundred (noIssue(), 100); unexpected (serializeAndDeserialize (zeroSt) != zeroSt, "STAmount fail"); @@ -1500,33 +1535,33 @@ public: unexpected ((hundred != hundred), "STAmount fail"); - unexpected (STAmount (noCurrency(), noAccount()).getText () != "0", "STAmount fail"); + unexpected (STAmount (noIssue()).getText () != "0", "STAmount fail"); - unexpected (STAmount (noCurrency(), noAccount(), 31).getText () != "31", "STAmount fail"); + unexpected (STAmount (noIssue(), 31).getText () != "31", "STAmount fail"); - unexpected (STAmount (noCurrency(), noAccount(), 31, 1).getText () != "310", "STAmount fail"); + unexpected (STAmount (noIssue(), 31, 1).getText () != "310", "STAmount fail"); - unexpected (STAmount (noCurrency(), noAccount(), 31, -1).getText () != "3.1", "STAmount fail"); + unexpected (STAmount (noIssue(), 31, -1).getText () != "3.1", "STAmount fail"); - unexpected (STAmount (noCurrency(), noAccount(), 31, -2).getText () != "0.31", "STAmount fail"); + unexpected (STAmount (noIssue(), 31, -2).getText () != "0.31", "STAmount fail"); - unexpected (STAmount::multiply (STAmount (noCurrency(), noAccount(), 20), STAmount (3), noCurrency(), noAccount()).getText () != "60", + unexpected (STAmount::multiply (STAmount (noIssue(), 20), STAmount (3), noIssue()).getText () != "60", "STAmount multiply fail 1"); - unexpected (STAmount::multiply (STAmount (noCurrency(), noAccount(), 20), STAmount (3), xrpCurrency (), xrpIssuer()).getText () != "60", + unexpected (STAmount::multiply (STAmount (noIssue(), 20), STAmount (3), xrpIssue ()).getText () != "60", "STAmount multiply fail 2"); - unexpected (STAmount::multiply (STAmount (20), STAmount (3), noCurrency(), noAccount()).getText () != "60", + unexpected (STAmount::multiply (STAmount (20), STAmount (3), noIssue()).getText () != "60", "STAmount multiply fail 3"); - unexpected (STAmount::multiply (STAmount (20), STAmount (3), xrpCurrency (), xrpIssuer()).getText () != "60", + unexpected (STAmount::multiply (STAmount (20), STAmount (3), xrpIssue ()).getText () != "60", "STAmount multiply fail 4"); - if (STAmount::divide (STAmount (noCurrency(), noAccount(), 60), STAmount (3), noCurrency(), noAccount()).getText () != "20") + if (STAmount::divide (STAmount (noIssue(), 60), STAmount (3), noIssue()).getText () != "20") { WriteLog (lsFATAL, STAmount) << "60/3 = " << - STAmount::divide (STAmount (noCurrency(), noAccount(), 60), - STAmount (3), noCurrency(), noAccount()).getText (); + STAmount::divide (STAmount (noIssue(), 60), + STAmount (3), noIssue()).getText (); fail ("STAmount divide fail"); } else @@ -1534,21 +1569,21 @@ public: pass (); } - unexpected (STAmount::divide (STAmount (noCurrency(), noAccount(), 60), STAmount (3), xrpCurrency (), xrpIssuer()).getText () != "20", + unexpected (STAmount::divide (STAmount (noIssue(), 60), STAmount (3), xrpIssue ()).getText () != "20", "STAmount divide fail"); - unexpected (STAmount::divide (STAmount (noCurrency(), noAccount(), 60), STAmount (noCurrency(), noAccount(), 3), noCurrency(), noAccount()).getText () != "20", + unexpected (STAmount::divide (STAmount (noIssue(), 60), STAmount (noIssue(), 3), noIssue()).getText () != "20", "STAmount divide fail"); - unexpected (STAmount::divide (STAmount (noCurrency(), noAccount(), 60), STAmount (noCurrency(), noAccount(), 3), xrpCurrency (), xrpIssuer()).getText () != "20", + unexpected (STAmount::divide (STAmount (noIssue(), 60), STAmount (noIssue(), 3), xrpIssue ()).getText () != "20", "STAmount divide fail"); - STAmount a1 (noCurrency(), noAccount(), 60), a2 (noCurrency(), noAccount(), 10, -1); + STAmount a1 (noIssue(), 60), a2 (noIssue(), 10, -1); - unexpected (STAmount::divide (a2, a1, noCurrency(), noAccount()) != STAmount::setRate (STAmount::getRate (a1, a2)), + unexpected (STAmount::divide (a2, a1, noIssue()) != STAmount::setRate (STAmount::getRate (a1, a2)), "STAmount setRate(getRate) fail"); - unexpected (STAmount::divide (a1, a2, noCurrency(), noAccount()) != STAmount::setRate (STAmount::getRate (a2, a1)), + unexpected (STAmount::divide (a1, a2, noIssue()) != STAmount::setRate (STAmount::getRate (a2, a1)), "STAmount setRate(getRate) fail"); } @@ -1587,22 +1622,22 @@ public: unexpected (STAmount::getRate (STAmount (10), STAmount (1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 2"); - unexpected (STAmount::getRate (STAmount (noCurrency(), noAccount(), 1), STAmount (noCurrency(), noAccount(), 10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull), + unexpected (STAmount::getRate (STAmount (noIssue(), 1), STAmount (noIssue(), 10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 3"); - unexpected (STAmount::getRate (STAmount (noCurrency(), noAccount(), 10), STAmount (noCurrency(), noAccount(), 1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), + unexpected (STAmount::getRate (STAmount (noIssue(), 10), STAmount (noIssue(), 1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 4"); - unexpected (STAmount::getRate (STAmount (noCurrency(), noAccount(), 1), STAmount (10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull), + unexpected (STAmount::getRate (STAmount (noIssue(), 1), STAmount (10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 5"); - unexpected (STAmount::getRate (STAmount (noCurrency(), noAccount(), 10), STAmount (1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), + unexpected (STAmount::getRate (STAmount (noIssue(), 10), STAmount (1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 6"); - unexpected (STAmount::getRate (STAmount (1), STAmount (noCurrency(), noAccount(), 10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull), + unexpected (STAmount::getRate (STAmount (1), STAmount (noIssue(), 10)) != (((100ull - 14) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 7"); - unexpected (STAmount::getRate (STAmount (10), STAmount (noCurrency(), noAccount(), 1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), + unexpected (STAmount::getRate (STAmount (10), STAmount (noIssue(), 1)) != (((100ull - 16) << (64 - 8)) | 1000000000000000ull), "STAmount getRate fail 8"); roundTest (1, 3, 3); @@ -1637,29 +1672,33 @@ public: testcase ("underflow"); STAmount bigNative (STAmount::cMaxNative / 2); - STAmount bigValue (noCurrency(), noAccount(), + STAmount bigValue (noIssue(), (STAmount::cMinValue + STAmount::cMaxValue) / 2, STAmount::cMaxOffset - 1); - STAmount smallValue (noCurrency(), noAccount(), + STAmount smallValue (noIssue(), (STAmount::cMinValue + STAmount::cMaxValue) / 2, STAmount::cMinOffset + 1); - STAmount zeroSt (noCurrency(), noAccount(), 0); + STAmount zeroSt (noIssue(), 0); - STAmount smallXsmall = STAmount::multiply (smallValue, smallValue, noCurrency(), noAccount()); + STAmount smallXsmall = STAmount::multiply (smallValue, smallValue, noIssue()); expect (smallXsmall == zero, "smallXsmall != 0"); - STAmount bigDsmall = STAmount::divide (smallValue, bigValue, noCurrency(), noAccount()); + STAmount bigDsmall = STAmount::divide (smallValue, bigValue, noIssue()); expect (bigDsmall == zero, beast::String ("small/big != 0: ") + bigDsmall.getText ()); - bigDsmall = STAmount::divide (smallValue, bigNative, noCurrency(), xrpIssuer ()); +#if 0 + // TODO(tom): this test makes no sense - we should have no way to have + // the currency not be XRP while the account is XRP. + bigDsmall = STAmount::divide (smallValue, bigNative, noCurrency(), xrpAccount ()); +#endif expect (bigDsmall == zero, beast::String ("small/bigNative != 0: ") + bigDsmall.getText ()); - bigDsmall = STAmount::divide (smallValue, bigValue, xrpCurrency (), xrpIssuer ()); + bigDsmall = STAmount::divide (smallValue, bigValue, xrpIssue ()); expect (bigDsmall == zero, beast::String ("(small/big)->N != 0: ") + bigDsmall.getText ()); - bigDsmall = STAmount::divide (smallValue, bigNative, xrpCurrency (), xrpIssuer ()); + bigDsmall = STAmount::divide (smallValue, bigNative, xrpIssue ()); expect (bigDsmall == zero, beast::String ("(small/bigNative)->N != 0: ") + bigDsmall.getText ()); @@ -1688,27 +1727,27 @@ public: int offset = -14; STAmount::canonicalizeRound (false, value, offset, true); - STAmount one (noCurrency(), noAccount(), 1); - STAmount two (noCurrency(), noAccount(), 2); - STAmount three (noCurrency(), noAccount(), 3); + STAmount one (noIssue(), 1); + STAmount two (noIssue(), 2); + STAmount three (noIssue(), 3); - STAmount oneThird1 = STAmount::divRound (one, three, noCurrency(), noAccount(), false); - STAmount oneThird2 = STAmount::divide (one, three, noCurrency(), noAccount()); - STAmount oneThird3 = STAmount::divRound (one, three, noCurrency(), noAccount(), true); + STAmount oneThird1 = STAmount::divRound (one, three, noIssue(), false); + STAmount oneThird2 = STAmount::divide (one, three, noIssue()); + STAmount oneThird3 = STAmount::divRound (one, three, noIssue(), true); WriteLog (lsINFO, STAmount) << oneThird1; WriteLog (lsINFO, STAmount) << oneThird2; WriteLog (lsINFO, STAmount) << oneThird3; - STAmount twoThird1 = STAmount::divRound (two, three, noCurrency(), noAccount(), false); - STAmount twoThird2 = STAmount::divide (two, three, noCurrency(), noAccount()); - STAmount twoThird3 = STAmount::divRound (two, three, noCurrency(), noAccount(), true); + STAmount twoThird1 = STAmount::divRound (two, three, noIssue(), false); + STAmount twoThird2 = STAmount::divide (two, three, noIssue()); + STAmount twoThird3 = STAmount::divRound (two, three, noIssue(), true); WriteLog (lsINFO, STAmount) << twoThird1; WriteLog (lsINFO, STAmount) << twoThird2; WriteLog (lsINFO, STAmount) << twoThird3; - STAmount oneA = STAmount::mulRound (oneThird1, three, noCurrency(), noAccount(), false); - STAmount oneB = STAmount::multiply (oneThird2, three, noCurrency(), noAccount()); - STAmount oneC = STAmount::mulRound (oneThird3, three, noCurrency(), noAccount(), true); + STAmount oneA = STAmount::mulRound (oneThird1, three, noIssue(), false); + STAmount oneB = STAmount::multiply (oneThird2, three, noIssue()); + STAmount oneC = STAmount::mulRound (oneThird3, three, noIssue(), true); WriteLog (lsINFO, STAmount) << oneA; WriteLog (lsINFO, STAmount) << oneB; WriteLog (lsINFO, STAmount) << oneC; @@ -1720,9 +1759,9 @@ public: WriteLog (lsINFO, STAmount) << fourThirdsB; WriteLog (lsINFO, STAmount) << fourThirdsC; - STAmount dripTest1 = STAmount::mulRound (twoThird2, two, xrpCurrency (), xrpIssuer (), false); - STAmount dripTest2 = STAmount::multiply (twoThird2, two, xrpCurrency (), xrpIssuer ()); - STAmount dripTest3 = STAmount::mulRound (twoThird2, two, xrpCurrency (), xrpIssuer (), true); + STAmount dripTest1 = STAmount::mulRound (twoThird2, two, xrpIssue (), false); + STAmount dripTest2 = STAmount::multiply (twoThird2, two, xrpIssue ()); + STAmount dripTest3 = STAmount::mulRound (twoThird2, two, xrpIssue (), true); WriteLog (lsINFO, STAmount) << dripTest1; WriteLog (lsINFO, STAmount) << dripTest2; WriteLog (lsINFO, STAmount) << dripTest3; diff --git a/src/ripple/module/data/protocol/STAmount.h b/src/ripple/module/data/protocol/STAmount.h new file mode 100644 index 000000000..6ff39e308 --- /dev/null +++ b/src/ripple/module/data/protocol/STAmount.h @@ -0,0 +1,458 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_STAMOUNT_H +#define RIPPLE_STAMOUNT_H + +#include +#include +#include + +namespace ripple { + +// Internal form: +// 1: If amount is zero, then value is zero and offset is -100 +// 2: Otherwise: +// legal offset range is -96 to +80 inclusive +// value range is 10^15 to (10^16 - 1) inclusive +// amount = value * [10 ^ offset] + +// Wire form: +// High 8 bits are (offset+142), legal range is, 80 to 22 inclusive +// Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive +class STAmount : public SerializedType +{ +public: + static const int cMinOffset = -96; + static const int cMaxOffset = 80; + + static const std::uint64_t cMinValue = 1000000000000000ull; + static const std::uint64_t cMaxValue = 9999999999999999ull; + static const std::uint64_t cMaxNative = 9000000000000000000ull; + + // Max native value on network. + static const std::uint64_t cMaxNativeN = 100000000000000000ull; + static const std::uint64_t cNotNative = 0x8000000000000000ull; + static const std::uint64_t cPosNative = 0x4000000000000000ull; + + static std::uint64_t uRateOne; + + STAmount (std::uint64_t v = 0, bool negative = false) + : mValue (v), mOffset (0), mIsNative (true), mIsNegative (negative) + { + if (v == 0) mIsNegative = false; + } + + STAmount (SField::ref n, std::uint64_t v = 0, bool negative = false) + : SerializedType (n), mValue (v), mOffset (0), mIsNative (true), + mIsNegative (negative) + { + } + + STAmount (SField::ref n, std::int64_t v) + : SerializedType (n), mOffset (0), mIsNative (true) + { + set (v); + } + + STAmount (Issue const& issue, + std::uint64_t uV = 0, int iOff = 0, bool negative = false) + : mIssue(issue), mValue (uV), mOffset (iOff), mIsNegative (negative) + { + canonicalize (); + } + + STAmount (Issue const& issue, + std::uint32_t uV, int iOff = 0, bool negative = false) + : mIssue(issue), mValue (uV), mOffset (iOff), mIsNegative (negative) + { + canonicalize (); + } + + STAmount (SField::ref n, Issue const& issue, + std::uint64_t v = 0, int off = 0, bool negative = false) : + SerializedType (n), mIssue(issue), mValue (v), mOffset (off), + mIsNegative (negative) + { + canonicalize (); + } + + STAmount (Issue const& issue, std::int64_t v, int iOff = 0) + : mIssue(issue), mOffset (iOff) + { + set (v); + canonicalize (); + } + + STAmount (SField::ref n, Issue const& issue, std::int64_t v, int off = 0) + : SerializedType (n), mIssue(issue), mOffset (off) + { + set (v); + canonicalize (); + } + + STAmount (Issue const& issue, int v, int iOff = 0) + : mIssue(issue), mOffset (iOff) + { + set (v); + canonicalize (); + } + + STAmount (SField::ref n, Issue const& issue, int v, int off = 0) + : SerializedType (n), mIssue(issue), mOffset (off) + { + set (v); + canonicalize (); + } + + STAmount (SField::ref, const Json::Value&); + + static STAmount createFromInt64 (SField::ref n, std::int64_t v); + + static std::unique_ptr deserialize ( + SerializerIterator& sit, SField::ref name) + { + return std::unique_ptr (construct (sit, name)); + } + + bool bSetJson (const Json::Value& jvSource); + + static STAmount saFromRate (std::uint64_t uRate = 0) + { + return STAmount (noIssue(), uRate, -9, false); + } + + SerializedTypeID getSType () const + { + return STI_AMOUNT; + } + std::string getText () const; + std::string getFullText () const; + void add (Serializer& s) const; + + int getExponent () const + { + return mOffset; + } + std::uint64_t getMantissa () const + { + return mValue; + } + + int signum () const + { + return mValue ? (mIsNegative ? -1 : 1) : 0; + } + + // When the currency is XRP, the value in raw units. S=signed + std::uint64_t getNValue () const + { + if (!mIsNative) + throw std::runtime_error ("not native"); + + return mValue; + } + void setNValue (std::uint64_t v) + { + if (!mIsNative) + throw std::runtime_error ("not native"); + + mValue = v; + } + std::int64_t getSNValue () const; + void setSNValue (std::int64_t); + + std::string getHumanCurrency () const; + + bool isNative () const + { + return mIsNative; + } + bool isLegalNet () const + { + return !mIsNative || (mValue <= cMaxNativeN); + } + + explicit + operator bool () const noexcept + { + return *this != zero; + } + + void negate () + { + if (*this != zero) + mIsNegative = !mIsNegative; + } + + /** @return a copy of amount with the same Issuer and Currency but zero + value. */ + STAmount zeroed() const + { + // TODO(tom): what does this next comment mean here? + // See https://ripplelabs.atlassian.net/browse/WC-1847?jql= + return STAmount (mIssue); + } + + void clear () + { + // VFALCO: Why -100? + mOffset = mIsNative ? 0 : -100; + mValue = 0; + mIsNegative = false; + } + + // Zero while copying currency and issuer. + void clear (const STAmount& saTmpl) + { + clear(saTmpl.mIssue); + } + + void clear (Issue const& issue) + { + setIssue(issue); + clear (); + } + + STAmount& operator=(beast::Zero) + { + clear (); + return *this; + } + + int compare (const STAmount&) const; + + Account const& getIssuer () const + { + return mIssue.account; + } + + void setIssuer (Account const& uIssuer) + { + mIssue.account = uIssuer; + setIssue(mIssue); + } + + /** Set the Issue for this amount and update mIsNative. */ + void setIssue (Issue const& issue); + + Currency const& getCurrency () const + { + return mIssue.currency; + } + + Issue const& issue () const + { + return mIssue; + } + + bool setValue (const std::string& sAmount); + bool setFullValue ( + const std::string& sAmount, const std::string& sCurrency = "", + const std::string& sIssuer = ""); + void setValue (const STAmount&); + + virtual bool isEquivalent (const SerializedType& t) const; + virtual bool isDefault () const + { + return (mValue == 0) && mIsNative; + } + + bool operator== (const STAmount&) const; + bool operator!= (const STAmount&) const; + bool operator< (const STAmount&) const; + bool operator> (const STAmount&) const; + bool operator<= (const STAmount&) const; + bool operator>= (const STAmount&) const; + bool isComparable (const STAmount&) const; + void throwComparable (const STAmount&) const; + + // native currency only + bool operator< (std::uint64_t) const; + bool operator> (std::uint64_t) const; + bool operator<= (std::uint64_t) const; + bool operator>= (std::uint64_t) const; + STAmount operator+ (std::uint64_t) const; + STAmount operator- (std::uint64_t) const; + STAmount operator- (void) const; + + STAmount& operator+= (const STAmount&); + STAmount& operator-= (const STAmount&); + STAmount& operator+= (std::uint64_t); + STAmount& operator-= (std::uint64_t); + STAmount& operator= (std::uint64_t); + + operator double () const; + + friend STAmount operator+ (const STAmount& v1, const STAmount& v2); + friend STAmount operator- (const STAmount& v1, const STAmount& v2); + + static STAmount divide ( + const STAmount& v1, const STAmount& v2, Issue const& issue); + + static STAmount divide ( + const STAmount& v1, const STAmount& v2, const STAmount& saUnit) + { + return divide (v1, v2, saUnit.issue ()); + } + static STAmount divide (const STAmount& v1, const STAmount& v2) + { + return divide (v1, v2, v1); + } + + static STAmount multiply ( + const STAmount& v1, const STAmount& v2, Issue const& issue); + + static STAmount multiply ( + const STAmount& v1, const STAmount& v2, const STAmount& saUnit) + { + return multiply (v1, v2, saUnit.issue()); + } + static STAmount multiply (const STAmount& v1, const STAmount& v2) + { + return multiply (v1, v2, v1); + } + + /* addRound, subRound can end up rounding if the amount subtracted is too small + to make a change. Consder (X-d) where d is very small relative to X. + If you ask to round down, then (X-d) should not be X unless d is zero. + If you ask to round up, (X+d) should never be X unless d is zero. (Assuming X and d are positive). + */ + // Add, subtract, multiply, or divide rounding result in specified direction + static STAmount addRound ( + const STAmount& v1, const STAmount& v2, bool roundUp); + static STAmount subRound ( + const STAmount& v1, const STAmount& v2, bool roundUp); + static STAmount mulRound ( + const STAmount& v1, const STAmount& v2, Issue const& issue, + bool roundUp); + static STAmount divRound ( + const STAmount& v1, const STAmount& v2, Issue const& issue, + bool roundUp); + + static STAmount mulRound ( + const STAmount& v1, const STAmount& v2, const STAmount& saUnit, + bool roundUp) + { + return mulRound (v1, v2, saUnit.issue (), roundUp); + } + static STAmount mulRound ( + const STAmount& v1, const STAmount& v2, bool roundUp) + { + return mulRound (v1, v2, v1.issue (), roundUp); + } + static STAmount divRound ( + const STAmount& v1, const STAmount& v2, const STAmount& saUnit, + bool roundUp) + { + return divRound (v1, v2, saUnit.issue (), roundUp); + } + static STAmount divRound ( + const STAmount& v1, const STAmount& v2, bool roundUp) + { + return divRound (v1, v2, v1.issue (), roundUp); + } + + // Someone is offering X for Y, what is the rate? + // Rate: smaller is better, the taker wants the most out: in/out + static std::uint64_t getRate ( + const STAmount& offerOut, const STAmount& offerIn); + static STAmount setRate (std::uint64_t rate); + + // Someone is offering X for Y, I need Z, how much do I pay + + // WARNING: most methods in rippled have parameters ordered "in, out" - this + // one is ordered "out, in". + static STAmount getPay ( + const STAmount& out, const STAmount& in, const STAmount& needed); + + static STAmount deserialize (SerializerIterator&); + + Json::Value getJson (int) const; + void setJson (Json::Value&) const; + + STAmount getRound () const; + void roundSelf (); + + static void canonicalizeRound ( + bool isNative, std::uint64_t& value, int& offset, bool roundUp); + +private: + Issue mIssue; + + std::uint64_t mValue; + int mOffset; + bool mIsNative; // A shorthand for isXRP(mIssue). + bool mIsNegative; + + void canonicalize (); + STAmount* duplicate () const + { + return new STAmount (*this); + } + static STAmount* construct (SerializerIterator&, SField::ref name); + + STAmount (SField::ref name, Issue const& issue, + std::uint64_t val, int off, bool isNat, bool negative) + : SerializedType (name), mIssue(issue), mValue (val), + mOffset (off), mIsNative (isNat), mIsNegative (negative) + { + } + + void set (std::int64_t v) + { + if (v < 0) + { + mIsNegative = true; + mValue = static_cast (-v); + } + else + { + mIsNegative = false; + mValue = static_cast (v); + } + } + + void set (int v) + { + if (v < 0) + { + mIsNegative = true; + mValue = static_cast (-v); + } + else + { + mIsNegative = false; + mValue = static_cast (v); + } + } +}; + +inline bool isXRP(STAmount const& amount) +{ + return isXRP (amount.issue().currency); +} + +// VFALCO TODO Make static member accessors for these in STAmount +extern const STAmount saZero; +extern const STAmount saOne; + +} // ripple + +#endif diff --git a/src/ripple/module/data/protocol/STAmountRound.cpp b/src/ripple/module/data/protocol/STAmountRound.cpp index 27cc79102..6a3147421 100644 --- a/src/ripple/module/data/protocol/STAmountRound.cpp +++ b/src/ripple/module/data/protocol/STAmountRound.cpp @@ -73,7 +73,7 @@ STAmount STAmount::addRound (const STAmount& v1, const STAmount& v2, bool roundU return v1; if (v1.mValue == 0) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, + return STAmount (v1.getFName (), v1.mIssue, v2.mValue, v2.mOffset, v2.mIsNegative); if (v1.mIsNative) @@ -122,18 +122,18 @@ STAmount STAmount::addRound (const STAmount& v1, const STAmount& v2, bool roundU std::int64_t fv = vv1 + vv2; if ((fv >= -10) && (fv <= 10)) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer); + return STAmount (v1.getFName (), v1.mIssue); else if (fv >= 0) { std::uint64_t v = static_cast (fv); canonicalizeRound (false, v, ov1, roundUp); - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, false); + return STAmount (v1.getFName (), v1.mIssue, v, ov1, false); } else { std::uint64_t v = static_cast (-fv); canonicalizeRound (false, v, ov1, !roundUp); - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, true); + return STAmount (v1.getFName (), v1.mIssue, v, ov1, true); } } @@ -145,7 +145,7 @@ STAmount STAmount::subRound (const STAmount& v1, const STAmount& v2, bool roundU return v1; if (v1.mValue == 0) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, + return STAmount (v1.getFName (), v1.mIssue, v2.mValue, v2.mOffset, !v2.mIsNegative); if (v1.mIsNative) @@ -194,30 +194,29 @@ STAmount STAmount::subRound (const STAmount& v1, const STAmount& v2, bool roundU std::int64_t fv = vv1 + vv2; if ((fv >= -10) && (fv <= 10)) - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer); + return STAmount (v1.getFName (), v1.mIssue); if (fv >= 0) { std::uint64_t v = static_cast (fv); canonicalizeRound (false, v, ov1, roundUp); - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, false); + return STAmount (v1.getFName (), v1.mIssue, v, ov1, false); } else { std::uint64_t v = static_cast (-fv); canonicalizeRound (false, v, ov1, !roundUp); - return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v, ov1, true); + return STAmount (v1.getFName (), v1.mIssue, v, ov1, true); } } STAmount STAmount::mulRound ( - const STAmount& v1, const STAmount& v2, Currency const& currency, - Account const& issuer, bool roundUp) + const STAmount& v1, const STAmount& v2, Issue const& issue, bool roundUp) { if (v1 == zero || v2 == zero) - return STAmount (currency, issuer); + return {issue}; - if (v1.mIsNative && v2.mIsNative && currency.isZero ()) + if (v1.mIsNative && v2.mIsNative && isXRP (issue)) { std::uint64_t minV = (v1.getSNValue () < v2.getSNValue ()) ? v1.getSNValue () : v2.getSNValue (); @@ -274,19 +273,19 @@ STAmount STAmount::mulRound ( std::uint64_t amount = v.getuint64 (); int offset = offset1 + offset2 + 14; canonicalizeRound ( - currency.isZero (), amount, offset, resultNegative != roundUp); - return STAmount (currency, issuer, amount, offset, resultNegative); + isXRP (issue), amount, offset, resultNegative != roundUp); + return STAmount (issue, amount, offset, resultNegative); } STAmount STAmount::divRound ( const STAmount& num, const STAmount& den, - Currency const& currency, Account const& issuer, bool roundUp) + Issue const& issue, bool roundUp) { if (den == zero) throw std::runtime_error ("division by zero"); if (num == zero) - return STAmount (currency, issuer); + return {issue}; std::uint64_t numVal = num.mValue, denVal = den.mValue; int numOffset = num.mOffset, denOffset = den.mOffset; @@ -325,8 +324,8 @@ STAmount STAmount::divRound ( std::uint64_t amount = v.getuint64 (); int offset = numOffset - denOffset - 17; canonicalizeRound ( - currency.isZero (), amount, offset, resultNegative != roundUp); - return STAmount (currency, issuer, amount, offset, resultNegative); + isXRP (issue), amount, offset, resultNegative != roundUp); + return STAmount (issue, amount, offset, resultNegative); } } // ripple diff --git a/src/ripple/module/data/protocol/SerializedType.h b/src/ripple/module/data/protocol/SerializedType.h new file mode 100644 index 000000000..3057fc282 --- /dev/null +++ b/src/ripple/module/data/protocol/SerializedType.h @@ -0,0 +1,203 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_SERIALIZEDTYPE_H +#define RIPPLE_SERIALIZEDTYPE_H + +#include +#include + +namespace ripple { + +// VFALCO TODO fix this restriction on copy assignment. +// +// CAUTION: Do not create a vector (or similar container) of any object derived +// from SerializedType. Use Boost ptr_* containers. The copy assignment operator +// of SerializedType has semantics that will cause contained types to change +// their names when an object is deleted because copy assignment is used to +// "slide down" the remaining types and this will not copy the field +// name. Changing the copy assignment operator to copy the field name breaks the +// use of copy assignment just to copy values, which is used in the transaction +// engine code. + +// VFALCO TODO Remove this unused enum +/* +enum PathFlags +{ + PF_END = 0x00, // End of current path & path list. + PF_BOUNDARY = 0xFF, // End of current path & new path follows. + + PF_ACCOUNT = 0x01, + PF_OFFER = 0x02, + + PF_WANTED_CURRENCY = 0x10, + PF_WANTED_ISSUER = 0x20, + PF_REDEEM = 0x40, + PF_ISSUE = 0x80, +}; +*/ + +//------------------------------------------------------------------------------ + +/** A type which can be exported to a well known binary format. + + A SerializedType: + - Always a field + - Can always go inside an eligible enclosing SerializedType + (such as STArray) + - Has a field name + + + Like JSON, a SerializedObject is a basket which has rules + on what it can hold. +*/ +// VFALCO TODO Document this as it looks like a central class. +// STObject is derived from it +// +class SerializedType +{ +public: + SerializedType () : fName (&sfGeneric) + { + ; + } + + explicit SerializedType (SField::ref n) : fName (&n) + { + assert (fName); + } + + virtual ~SerializedType () { } + + static std::unique_ptr deserialize (SField::ref name) + { + return std::unique_ptr (new SerializedType (name)); + } + + /** A SerializeType is a field. + This sets the name. + */ + void setFName (SField::ref n) + { + fName = &n; + assert (fName); + } + SField::ref getFName () const + { + return *fName; + } + virtual SerializedTypeID getSType () const + { + return STI_NOTPRESENT; + } + std::unique_ptr clone () const + { + return std::unique_ptr (duplicate ()); + } + + virtual std::string getFullText () const; + virtual std::string getText () const // just the value + { + return std::string (); + } + virtual Json::Value getJson (int /*options*/) const + { + return getText (); + } + + virtual void add (Serializer& s) const + { + assert (false); + } + + virtual bool isEquivalent (const SerializedType& t) const; + + void addFieldID (Serializer& s) const + { + assert (fName->isBinary ()); + s.addFieldID (fName->fieldType, fName->fieldValue); + } + + SerializedType& operator= (const SerializedType& t); + + bool operator== (const SerializedType& t) const + { + return (getSType () == t.getSType ()) && isEquivalent (t); + } + bool operator!= (const SerializedType& t) const + { + return (getSType () != t.getSType ()) || !isEquivalent (t); + } + + virtual bool isDefault () const + { + return true; + } + + template + D& downcast() + { + D* ptr = dynamic_cast (this); + if (ptr == nullptr) + throw std::runtime_error ("type mismatch"); + return *ptr; + } + + template + D const& downcast() const + { + D const * ptr = dynamic_cast (this); + if (ptr == nullptr) + throw std::runtime_error ("type mismatch"); + return *ptr; + } + +protected: + // VFALCO TODO make accessors for this + SField::ptr fName; + +private: + virtual SerializedType* duplicate () const + { + return new SerializedType (*fName); + } +}; + +//------------------------------------------------------------------------------ + +inline SerializedType* new_clone (const SerializedType& s) +{ + SerializedType* const copy (s.clone ().release ()); + assert (typeid (*copy) == typeid (s)); + return copy; +} + +inline void delete_clone (const SerializedType* s) +{ + boost::checked_delete (s); +} + +inline std::ostream& operator<< (std::ostream& out, const SerializedType& t) +{ + return out << t.getFullText (); +} + +} // ripple + +#endif diff --git a/src/ripple/module/data/protocol/SerializedTypes.cpp b/src/ripple/module/data/protocol/SerializedTypes.cpp index 4f1965f94..10cb3a55f 100644 --- a/src/ripple/module/data/protocol/SerializedTypes.cpp +++ b/src/ripple/module/data/protocol/SerializedTypes.cpp @@ -19,8 +19,8 @@ namespace ripple { -const STAmount saZero (noCurrency(), noAccount(), 0); -const STAmount saOne (noCurrency(), noAccount(), 1); +const STAmount saZero (noIssue(), 0); +const STAmount saOne (noIssue(), 1); SerializedType& SerializedType::operator= (const SerializedType& t) { @@ -522,26 +522,6 @@ std::string STPath::getText () const } #endif -#if 0 -std::string STPathSet::getText () const -{ - std::string ret ("{"); - bool firstPath = true; - - BOOST_FOREACH (std::vector::const_iterator::value_type it, value) - { - if (!firstPath) - { - ret += ", "; - firstPath = false; - } - - ret += it.getText (); - } - return ret + "}"; -} -#endif - void STPathSet::add (Serializer& s) const { assert (fName->isBinary ()); diff --git a/src/ripple/module/data/protocol/SerializedTypes.h b/src/ripple/module/data/protocol/SerializedTypes.h index 1372efee2..d3bf282ce 100644 --- a/src/ripple/module/data/protocol/SerializedTypes.h +++ b/src/ripple/module/data/protocol/SerializedTypes.h @@ -22,183 +22,14 @@ #include #include +#include +#include namespace ripple { -// VFALCO TODO fix this restriction on copy assignment. -// -// CAUTION: Do not create a vector (or similar container) of any object derived -// from SerializedType. Use Boost ptr_* containers. The copy assignment operator -// of SerializedType has semantics that will cause contained types to change -// their names when an object is deleted because copy assignment is used to -// "slide down" the remaining types and this will not copy the field -// name. Changing the copy assignment operator to copy the field name breaks the -// use of copy assignment just to copy values, which is used in the transaction -// engine code. - -// VFALCO TODO Remove this unused enum -/* -enum PathFlags -{ - PF_END = 0x00, // End of current path & path list. - PF_BOUNDARY = 0xFF, // End of current path & new path follows. - - PF_ACCOUNT = 0x01, - PF_OFFER = 0x02, - - PF_WANTED_CURRENCY = 0x10, - PF_WANTED_ISSUER = 0x20, - PF_REDEEM = 0x40, - PF_ISSUE = 0x80, -}; -*/ - -//------------------------------------------------------------------------------ - -/** A type which can be exported to a well known binary format. - - A SerializedType: - - Always a field - - Can always go inside an eligible enclosing SerializedType - (such as STArray) - - Has a field name - - - Like JSON, a SerializedObject is a basket which has rules - on what it can hold. -*/ -// VFALCO TODO Document this as it looks like a central class. -// STObject is derived from it -// -class SerializedType -{ -public: - SerializedType () : fName (&sfGeneric) - { - ; - } - - explicit SerializedType (SField::ref n) : fName (&n) - { - assert (fName); - } - - virtual ~SerializedType () { } - - static std::unique_ptr deserialize (SField::ref name) - { - return std::unique_ptr (new SerializedType (name)); - } - - /** A SerializeType is a field. - This sets the name. - */ - void setFName (SField::ref n) - { - fName = &n; - assert (fName); - } - SField::ref getFName () const - { - return *fName; - } - virtual SerializedTypeID getSType () const - { - return STI_NOTPRESENT; - } - std::unique_ptr clone () const - { - return std::unique_ptr (duplicate ()); - } - - virtual std::string getFullText () const; - virtual std::string getText () const // just the value - { - return std::string (); - } - virtual Json::Value getJson (int /*options*/) const - { - return getText (); - } - - virtual void add (Serializer& s) const - { - assert (false); - } - - virtual bool isEquivalent (const SerializedType& t) const; - - void addFieldID (Serializer& s) const - { - assert (fName->isBinary ()); - s.addFieldID (fName->fieldType, fName->fieldValue); - } - - SerializedType& operator= (const SerializedType& t); - - bool operator== (const SerializedType& t) const - { - return (getSType () == t.getSType ()) && isEquivalent (t); - } - bool operator!= (const SerializedType& t) const - { - return (getSType () != t.getSType ()) || !isEquivalent (t); - } - - virtual bool isDefault () const - { - return true; - } - - template - D& downcast() - { - D* ptr = dynamic_cast (this); - if (ptr == nullptr) - throw std::runtime_error ("type mismatch"); - return *ptr; - } - - template - D const& downcast() const - { - D const * ptr = dynamic_cast (this); - if (ptr == nullptr) - throw std::runtime_error ("type mismatch"); - return *ptr; - } - -protected: - // VFALCO TODO make accessors for this - SField::ptr fName; - -private: - virtual SerializedType* duplicate () const - { - return new SerializedType (*fName); - } -}; - -//------------------------------------------------------------------------------ - -inline SerializedType* new_clone (const SerializedType& s) -{ - SerializedType* const copy (s.clone ().release ()); - assert (typeid (*copy) == typeid (s)); - return copy; -} - -inline void delete_clone (const SerializedType* s) -{ - boost::checked_delete (s); -} - -inline std::ostream& operator<< (std::ostream& out, const SerializedType& t) -{ - return out << t.getFullText (); -} - -//------------------------------------------------------------------------------ +// TODO(tom): make STUInt8, STUInt16, STUInt32, STUInt64 a single templated +// class to reduce the quadruple redundancy we have all over the rippled code +// regarding uint-like types. class STUInt8 : public SerializedType { @@ -443,406 +274,10 @@ private: //------------------------------------------------------------------------------ -// Internal form: -// 1: If amount is zero, then value is zero and offset is -100 -// 2: Otherwise: -// legal offset range is -96 to +80 inclusive -// value range is 10^15 to (10^16 - 1) inclusive -// amount = value * [10 ^ offset] - -// Wire form: -// High 8 bits are (offset+142), legal range is, 80 to 22 inclusive -// Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive -class STAmount : public SerializedType -{ -public: - static const int cMinOffset = -96, cMaxOffset = 80; - static const std::uint64_t cMinValue = 1000000000000000ull, cMaxValue = 9999999999999999ull; - static const std::uint64_t cMaxNative = 9000000000000000000ull; - static const std::uint64_t cMaxNativeN = 100000000000000000ull; // max native value on network - static const std::uint64_t cNotNative = 0x8000000000000000ull; - static const std::uint64_t cPosNative = 0x4000000000000000ull; - - static std::uint64_t uRateOne; - - STAmount (std::uint64_t v = 0, bool isNeg = false) - : mValue (v), mOffset (0), mIsNative (true), mIsNegative (isNeg) - { - if (v == 0) mIsNegative = false; - } - - STAmount (SField::ref n, std::uint64_t v = 0, bool isNeg = false) - : SerializedType (n), mValue (v), mOffset (0), mIsNative (true), mIsNegative (isNeg) - { - ; - } - - STAmount (SField::ref n, std::int64_t v) : SerializedType (n), mOffset (0), mIsNative (true) - { - set (v); - } - - STAmount (Currency const& currency, Account const& issuer, - std::uint64_t uV = 0, int iOff = 0, bool bNegative = false) - : mCurrency (currency), mIssuer (issuer), mValue (uV), mOffset (iOff), mIsNegative (bNegative) - { - canonicalize (); - } - - STAmount (Currency const& currency, Account const& issuer, - std::uint32_t uV, int iOff = 0, bool bNegative = false) - : mCurrency (currency), mIssuer (issuer), mValue (uV), mOffset (iOff), mIsNegative (bNegative) - { - canonicalize (); - } - - STAmount (SField::ref n, Currency const& currency, Account const& issuer, - std::uint64_t v = 0, int off = 0, bool isNeg = false) : - SerializedType (n), mCurrency (currency), mIssuer (issuer), mValue (v), mOffset (off), mIsNegative (isNeg) - { - canonicalize (); - } - - STAmount (Currency const& currency, Account const& issuer, std::int64_t v, int iOff = 0) - : mCurrency (currency), mIssuer (issuer), mOffset (iOff) - { - set (v); - canonicalize (); - } - - STAmount (SField::ref n, Currency const& currency, Account const& issuer, std::int64_t v, int off = 0) - : SerializedType (n), mCurrency (currency), mIssuer (issuer), mOffset (off) - { - set (v); - canonicalize (); - } - - STAmount (Currency const& currency, Account const& issuer, int v, int iOff = 0) - : mCurrency (currency), mIssuer (issuer), mOffset (iOff) - { - set (v); - canonicalize (); - } - - STAmount (SField::ref n, Currency const& currency, Account const& issuer, int v, int off = 0) - : SerializedType (n), mCurrency (currency), mIssuer (issuer), mOffset (off) - { - set (v); - canonicalize (); - } - - STAmount (SField::ref, const Json::Value&); - - static STAmount createFromInt64 (SField::ref n, std::int64_t v); - - static std::unique_ptr deserialize (SerializerIterator& sit, SField::ref name) - { - return std::unique_ptr (construct (sit, name)); - } - - bool bSetJson (const Json::Value& jvSource); - - static STAmount saFromRate (std::uint64_t uRate = 0) - { - return STAmount (noCurrency(), noAccount(), uRate, -9, false); - } - - SerializedTypeID getSType () const - { - return STI_AMOUNT; - } - std::string getText () const; - std::string getFullText () const; - void add (Serializer& s) const; - - int getExponent () const - { - return mOffset; - } - std::uint64_t getMantissa () const - { - return mValue; - } - - int signum () const - { - return mValue ? (mIsNegative ? -1 : 1) : 0; - } - - // When the currency is XRP, the value in raw units. S=signed - std::uint64_t getNValue () const - { - if (!mIsNative) throw std::runtime_error ("not native"); - - return mValue; - } - void setNValue (std::uint64_t v) - { - if (!mIsNative) throw std::runtime_error ("not native"); - - mValue = v; - } - std::int64_t getSNValue () const; - void setSNValue (std::int64_t); - - std::string getHumanCurrency () const; - - bool isNative () const - { - return mIsNative; - } - bool isLegalNet () const - { - return !mIsNative || (mValue <= cMaxNativeN); - } - - explicit - operator bool () const noexcept - { - return *this != zero; - } - - void negate () - { - if (*this != zero) - mIsNegative = !mIsNegative; - } - - // Return a copy of amount with the same Issuer and Currency but zero value. - STAmount zeroed() const - { - STAmount c(mCurrency, mIssuer); - c = zero; - // See https://ripplelabs.atlassian.net/browse/WC-1847?jql= - return c; - } - - void clear () - { - // VFALCO: Why -100? - mOffset = mIsNative ? 0 : -100; - mValue = 0; - mIsNegative = false; - } - - // Zero while copying currency and issuer. - void clear (const STAmount& saTmpl) - { - mCurrency = saTmpl.mCurrency; - mIssuer = saTmpl.mIssuer; - mIsNative = saTmpl.mIsNative; - clear (); - } - void clear (Currency const& currency, Account const& issuer) - { - mCurrency = currency; - mIssuer = issuer; - mIsNative = !currency; - clear (); - } - - STAmount& operator=(beast::Zero) - { - clear (); - return *this; - } - - int compare (const STAmount&) const; - - Account const& getIssuer () const - { - return mIssuer; - } - STAmount* setIssuer (Account const& uIssuer) - { - mIssuer = uIssuer; - return this; - } - - Currency const& getCurrency () const - { - return mCurrency; - } - bool setValue (const std::string& sAmount); - bool setFullValue ( - const std::string& sAmount, const std::string& sCurrency = "", - const std::string& sIssuer = ""); - void setValue (const STAmount&); - - virtual bool isEquivalent (const SerializedType& t) const; - virtual bool isDefault () const - { - return (mValue == 0) && mIssuer.isZero () && mCurrency.isZero (); - } - - bool operator== (const STAmount&) const; - bool operator!= (const STAmount&) const; - bool operator< (const STAmount&) const; - bool operator> (const STAmount&) const; - bool operator<= (const STAmount&) const; - bool operator>= (const STAmount&) const; - bool isComparable (const STAmount&) const; - void throwComparable (const STAmount&) const; - - // native currency only - bool operator< (std::uint64_t) const; - bool operator> (std::uint64_t) const; - bool operator<= (std::uint64_t) const; - bool operator>= (std::uint64_t) const; - STAmount operator+ (std::uint64_t) const; - STAmount operator- (std::uint64_t) const; - STAmount operator- (void) const; - - STAmount& operator+= (const STAmount&); - STAmount& operator-= (const STAmount&); - STAmount& operator+= (std::uint64_t); - STAmount& operator-= (std::uint64_t); - STAmount& operator= (std::uint64_t); - - operator double () const; - - friend STAmount operator+ (const STAmount& v1, const STAmount& v2); - friend STAmount operator- (const STAmount& v1, const STAmount& v2); - - static STAmount divide ( - const STAmount& v1, const STAmount& v2, - Currency const& currency, Account const& issuer); - - static STAmount divide ( - const STAmount& v1, const STAmount& v2, const STAmount& saUnit) - { - return divide (v1, v2, saUnit.getCurrency (), saUnit.getIssuer ()); - } - static STAmount divide (const STAmount& v1, const STAmount& v2) - { - return divide (v1, v2, v1); - } - - static STAmount multiply ( - const STAmount& v1, const STAmount& v2, - Currency const& currency, Account const& issuer); - - static STAmount multiply ( - const STAmount& v1, const STAmount& v2, const STAmount& saUnit) - { - return multiply (v1, v2, saUnit.getCurrency (), saUnit.getIssuer ()); - } - static STAmount multiply (const STAmount& v1, const STAmount& v2) - { - return multiply (v1, v2, v1); - } - - /* addRound, subRound can end up rounding if the amount subtracted is too small - to make a change. Consder (X-d) where d is very small relative to X. - If you ask to round down, then (X-d) should not be X unless d is zero. - If you ask to round up, (X+d) should never be X unless d is zero. (Assuming X and d are positive). - */ - // Add, subtract, multiply, or divide rounding result in specified direction - static STAmount addRound (const STAmount& v1, const STAmount& v2, bool roundUp); - static STAmount subRound (const STAmount& v1, const STAmount& v2, bool roundUp); - static STAmount mulRound (const STAmount& v1, const STAmount& v2, - Currency const& currency, Account const& issuer, bool roundUp); - static STAmount divRound (const STAmount& v1, const STAmount& v2, - Currency const& currency, Account const& issuer, bool roundUp); - - static STAmount mulRound (const STAmount& v1, const STAmount& v2, const STAmount& saUnit, bool roundUp) - { - return mulRound (v1, v2, saUnit.getCurrency (), saUnit.getIssuer (), roundUp); - } - static STAmount mulRound (const STAmount& v1, const STAmount& v2, bool roundUp) - { - return mulRound (v1, v2, v1.getCurrency (), v1.getIssuer (), roundUp); - } - static STAmount divRound (const STAmount& v1, const STAmount& v2, const STAmount& saUnit, bool roundUp) - { - return divRound (v1, v2, saUnit.getCurrency (), saUnit.getIssuer (), roundUp); - } - static STAmount divRound (const STAmount& v1, const STAmount& v2, bool roundUp) - { - return divRound (v1, v2, v1.getCurrency (), v1.getIssuer (), roundUp); - } - - // Someone is offering X for Y, what is the rate? - // Rate: smaller is better, the taker wants the most out: in/out - static std::uint64_t getRate (const STAmount& offerOut, const STAmount& offerIn); - static STAmount setRate (std::uint64_t rate); - - // Someone is offering X for Y, I need Z, how much do I pay - static STAmount getPay ( - const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed); - - static STAmount deserialize (SerializerIterator&); - - Json::Value getJson (int) const; - void setJson (Json::Value&) const; - - STAmount getRound () const; - void roundSelf (); - - static void canonicalizeRound ( - bool isNative, std::uint64_t& value, int& offset, bool roundUp); - -private: - Currency mCurrency; // Compared by ==. Always update mIsNative. - Account mIssuer; // Not compared by ==. 0 for XRP. - - std::uint64_t mValue; - int mOffset; - bool mIsNative; // Always !mCurrency. Native is XRP. - bool mIsNegative; - - void canonicalize (); - STAmount* duplicate () const - { - return new STAmount (*this); - } - static STAmount* construct (SerializerIterator&, SField::ref name); - - STAmount (SField::ref name, Currency const& cur, Account const& iss, - std::uint64_t val, int off, bool isNat, bool isNeg) - : SerializedType (name), mCurrency (cur), mIssuer (iss), mValue (val), - mOffset (off), mIsNative (isNat), mIsNegative (isNeg) - { - ; - } - - void set (std::int64_t v) - { - if (v < 0) - { - mIsNegative = true; - mValue = static_cast (-v); - } - else - { - mIsNegative = false; - mValue = static_cast (v); - } - } - - void set (int v) - { - if (v < 0) - { - mIsNegative = true; - mValue = static_cast (-v); - } - else - { - mIsNegative = false; - mValue = static_cast (v); - } - } -}; - -// VFALCO TODO Make static member accessors for these in STAmount -extern const STAmount saZero; -extern const STAmount saOne; - -//------------------------------------------------------------------------------ - // TODO(tom): make STHash128, STHash160 and STHash256 a single templated class -// to reduce the triple redundancy we have all over the rippled code. +// to reduce the triple redundancy we have all over the rippled code regarding +// hash-like classes. + class STHash128 : public SerializedType { public: @@ -1497,7 +932,6 @@ public: return true; } - virtual bool isEquivalent (const SerializedType& t) const; virtual bool isDefault () const { diff --git a/src/ripple/module/rpc/handlers/BookOffers.cpp b/src/ripple/module/rpc/handlers/BookOffers.cpp index bf7be746c..b96a2289d 100644 --- a/src/ripple/module/rpc/handlers/BookOffers.cpp +++ b/src/ripple/module/rpc/handlers/BookOffers.cpp @@ -99,7 +99,7 @@ Json::Value doBookOffers (RPC::Context& context) } else { - pay_issuer = xrpIssuer (); + pay_issuer = xrpAccount (); } if (isXRP (pay_currency) && ! isXRP (pay_issuer)) @@ -128,7 +128,7 @@ Json::Value doBookOffers (RPC::Context& context) } else { - get_issuer = xrpIssuer (); + get_issuer = xrpAccount (); } diff --git a/src/ripple/module/rpc/handlers/RipplePathFind.cpp b/src/ripple/module/rpc/handlers/RipplePathFind.cpp index 8401d5754..80faf8b69 100644 --- a/src/ripple/module/rpc/handlers/RipplePathFind.cpp +++ b/src/ripple/module/rpc/handlers/RipplePathFind.cpp @@ -204,12 +204,12 @@ Json::Value doRipplePathFind (RPC::Context& context) STAmount saMaxAmountAct; STAmount saDstAmountAct; STAmount saMaxAmount ( - uSrcCurrencyID, - !!uSrcIssuerID - ? uSrcIssuerID // Use specifed issuer. - : !!uSrcCurrencyID // Default to source account. - ? Account(raSrc.getAccountID ()) - : xrpIssuer(), + {uSrcCurrencyID, + !!uSrcIssuerID + ? uSrcIssuerID // Use specifed issuer. + : !!uSrcCurrencyID // Default to source account. + ? Account(raSrc.getAccountID ()) + : xrpAccount()}, 1); saMaxAmount.negate (); diff --git a/src/ripple/module/rpc/handlers/Subscribe.cpp b/src/ripple/module/rpc/handlers/Subscribe.cpp index ea4852746..d0a957b61 100644 --- a/src/ripple/module/rpc/handlers/Subscribe.cpp +++ b/src/ripple/module/rpc/handlers/Subscribe.cpp @@ -198,7 +198,7 @@ Json::Value doSubscribe (RPC::Context& context) || !jvSubRequest[jss::taker_gets].isObject ()) return rpcError (rpcINVALID_PARAMS); - // VFALCO TODO Use RippleAsset here + // VFALCO TODO Use Issue here Currency pay_currency; Account pay_issuer; Currency get_currency; diff --git a/src/ripple/types/api/Book.h b/src/ripple/types/api/Book.h new file mode 100644 index 000000000..554f1feaa --- /dev/null +++ b/src/ripple/types/api/Book.h @@ -0,0 +1,237 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_BOOK_H_INCLUDED +#define RIPPLE_TYPES_BOOK_H_INCLUDED + +#include + +namespace ripple { + +/** Specifies an order book. + The order book is a pair of Issues called in and out. + @see Issue. +*/ +template +class BookType +{ +public: + typedef IssueType Issue; + + Issue in; + Issue out; + + BookType () + { + } + + BookType (Issue const& in_, Issue const& out_) + : in (in_) + , out (out_) + { + } + + template + BookType (BookType const& other) + : in (other.in) + , out (other.out) + { + } + + /** Assignment. + This is only valid when ByValue == `true` + */ + template + BookType& operator= (BookType const& other) + { + in = other.in; + out = other.out; + return *this; + } +}; + +template +std::string to_string (BookType const& book) +{ + return to_string(book.in) + "->" + to_string(book.out); +} + +template +std::ostream& operator<<(std::ostream& os, BookType const& x) +{ + os << to_string (x); + return os; +} + +template +void hash_append (Hasher& h, BookType const& b) +{ + using beast::hash_append; + hash_append (h, b.in, b.out); +} + +/** Ordered comparison. */ +template +int compare (BookType const& lhs, + BookType const& rhs) +{ + int const diff (compare (lhs.in, rhs.in)); + if (diff != 0) + return diff; + return compare (lhs.out, rhs.out); +} + +/** Equality comparison. */ +/** @{ */ +template +bool operator== (BookType const& lhs, + BookType const& rhs) +{ + return (lhs.in == rhs.in) && + (lhs.out == rhs.out); +} + +template +bool operator!= (BookType const& lhs, + BookType const& rhs) +{ + return (lhs.in != rhs.in) || + (lhs.out != rhs.out); +} +/** @} */ + +/** Strict weak ordering. */ +/** @{ */ +template +bool operator< (BookType const& lhs, + BookType const& rhs) +{ + int const diff (compare (lhs.in, rhs.in)); + if (diff != 0) + return diff < 0; + return lhs.out < rhs.out; +} + +template +bool operator> (BookType const& lhs, + BookType const& rhs) +{ + return rhs < lhs; +} + +template +bool operator>= (BookType const& lhs, + BookType const& rhs) +{ + return ! (lhs < rhs); +} + +template +bool operator<= (BookType const& lhs, + BookType const& rhs) +{ + return ! (rhs < lhs); +} +/** @} */ + +//------------------------------------------------------------------------------ + +typedef BookType Book; +typedef BookType BookRef; + +} + +//------------------------------------------------------------------------------ + +namespace std { + +template +struct hash > + : private boost::base_from_member , 0> + , private boost::base_from_member , 1> +{ +private: + typedef boost::base_from_member < + std::hash , 0> currency_hash_type; + typedef boost::base_from_member < + std::hash , 1> issuer_hash_type; + +public: + typedef std::size_t value_type; + typedef ripple::IssueType argument_type; + + value_type operator() (argument_type const& value) const + { + value_type result (currency_hash_type::member (value.currency)); + if (!isXRP (value.currency)) + boost::hash_combine (result, + issuer_hash_type::member (value.account)); + return result; + } +}; + +//------------------------------------------------------------------------------ + +template +struct hash > +{ +private: + typedef std::hash > hasher; + + hasher m_hasher; + +public: + typedef std::size_t value_type; + typedef ripple::BookType argument_type; + + value_type operator() (argument_type const& value) const + { + value_type result (m_hasher (value.in)); + boost::hash_combine (result, m_hasher (value.out)); + return result; + } +}; + +} + +//------------------------------------------------------------------------------ + +namespace boost { + +template +struct hash > + : std::hash > +{ + typedef std::hash > Base; + // VFALCO NOTE broken in vs2012 + //using Base::Base; // inherit ctors +}; + +template +struct hash > + : std::hash > +{ + typedef std::hash > Base; + // VFALCO NOTE broken in vs2012 + //using Base::Base; // inherit ctors +}; + +} + +#endif diff --git a/src/ripple/types/api/Issue.h b/src/ripple/types/api/Issue.h new file mode 100644 index 000000000..caaf40285 --- /dev/null +++ b/src/ripple/types/api/Issue.h @@ -0,0 +1,194 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_TYPES_ISSUE_INCLUDED +#define RIPPLE_TYPES_ISSUE_INCLUDED + +#include +#include +#include + +#include + +namespace ripple { + +/** A currency issued by an account. + + When ByValue is `false`, this only stores references, and the caller + is responsible for managing object lifetime. + + @see Currency, Account, Issue, IssueRef, Book +*/ +template +class IssueType +{ +public: + typedef typename + std::conditional ::type + IssueCurrency; + + typedef typename + std::conditional ::type + IssueAccount; + + IssueCurrency currency; + IssueAccount account; + + IssueType () + { + } + + IssueType (Currency const& c, Account const& a) + : currency (c), account (a) + { + } + + template + IssueType (IssueType const& other) + : currency (other.currency) + , account (other.account) + { + } + + /** Assignment. */ + template + std::enable_if_t + operator= (IssueType const& other) + { + currency = other.currency; + account = other.account; + return *this; + } +}; + +template +bool isConsistent(IssueType const& ac) +{ + return isXRP (ac.currency) == isXRP (ac.account); +} + +template +std::string to_string (IssueType const& ac) +{ + return to_string(ac.account) + "/" + to_string(ac.currency); +} + +template +std::ostream& operator<< ( + std::ostream& os, IssueType const& x) +{ + os << to_string (x); + return os; +} + +template +void hash_append (Hasher& h, IssueType const& r) +{ + using beast::hash_append; + hash_append (h, r.currency, r.account); +} + +/** Ordered comparison. + The assets are ordered first by currency and then by account, + if the currency is not XRP. +*/ +template +int compare (IssueType const& lhs, + IssueType const& rhs) +{ + int diff = compare (lhs.currency, rhs.currency); + if (diff != 0) + return diff; + if (isXRP (lhs.currency)) + return 0; + return compare (lhs.account, rhs.account); +} + +/** Equality comparison. */ +/** @{ */ +template +bool operator== (IssueType const& lhs, + IssueType const& rhs) +{ + return compare (lhs, rhs) == 0; +} + +template +bool operator!= (IssueType const& lhs, + IssueType const& rhs) +{ + return ! (lhs == rhs); +} +/** @} */ + +/** Strict weak ordering. */ +/** @{ */ +template +bool operator< (IssueType const& lhs, + IssueType const& rhs) +{ + return compare (lhs, rhs) < 0; +} + +template +bool operator> (IssueType const& lhs, + IssueType const& rhs) +{ + return rhs < lhs; +} + +template +bool operator>= (IssueType const& lhs, + IssueType const& rhs) +{ + return ! (lhs < rhs); +} + +template +bool operator<= (IssueType const& lhs, + IssueType const& rhs) +{ + return ! (rhs < lhs); +} +/** @} */ + +//------------------------------------------------------------------------------ + +typedef IssueType Issue; +typedef IssueType IssueRef; + +//------------------------------------------------------------------------------ + +/** Returns an asset specifier that represents XRP. */ +inline Issue const& xrpIssue () +{ + static Issue issue {xrpCurrency(), xrpAccount()}; + return issue; +} + +/** Returns an asset specifier that represents no account and currency. */ +inline Issue const& noIssue () +{ + static Issue issue {noCurrency(), noAccount()}; + return issue; +} + +} + +#endif diff --git a/src/ripple/types/api/RippleAssets.h b/src/ripple/types/api/RippleAssets.h deleted file mode 100644 index 3c10c04aa..000000000 --- a/src/ripple/types/api/RippleAssets.h +++ /dev/null @@ -1,391 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef RIPPLE_TYPES_RIPPLEASSETS_H_INCLUDED -#define RIPPLE_TYPES_RIPPLEASSETS_H_INCLUDED - -#include -#include -#include - -#include - -namespace ripple { - -//------------------------------------------------------------------------------ - -/** Ripple asset specifier, expressed as a currency issuer pair. - When ByValue is `false`, this only stores references, and the caller - is responsible for managing object lifetime. - @see Currency, Account, RippleAssset, RippleAssetRef -*/ -template -class RippleAssetType -{ -public: - typedef typename - std::conditional ::type - AssetCurrency; - - typedef typename - std::conditional ::type - AssetIssuer; - - AssetCurrency currency; - AssetIssuer issuer; - - RippleAssetType () - { - } - - RippleAssetType (Currency const& currency_, Account const& issuer_) - : currency (currency_), issuer (issuer_) - { - // Either XRP and (currency == zero && issuer == zero) or some custom - // currency and (currency != 0 && issuer != 0) - assert (currency.isZero () == issuer.isZero ()); - } - - template - RippleAssetType (RippleAssetType const& other) - : currency (other.currency) - , issuer (other.issuer) - { - } - - /** Assignment. */ - template - std::enable_if_t - operator= (RippleAssetType const& other) - { - currency = other.currency; - issuer = other.issuer; - return *this; - } - - bool is_xrp () const - { - assert (currency.isZero () == issuer.isZero ()); - if (currency.isZero ()) - return true; - return false; - } - - template - friend - void - hash_append (Hasher& h, RippleAssetType const& r) - { - using beast::hash_append; - hash_append (h, r.currency, r.issuer); - } -}; - -/** Ordered comparison. - The assets are ordered first by currency and then by issuer, - if the currency is not XRP. -*/ -template -int compare (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - int const diff (compare (lhs.currency, rhs.currency)); - if (diff != 0) - return diff; - if (lhs.is_xrp ()) - return 0; - return compare (lhs.issuer, rhs.issuer); -} - -/** Equality comparison. */ -/** @{ */ -template -bool operator== (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - return compare (lhs, rhs) == 0; -} - -template -bool operator!= (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - return ! (lhs == rhs); -} -/** @} */ - -/** Strict weak ordering. */ -/** @{ */ -template -bool operator< (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - return compare (lhs, rhs) < 0; -} - -template -bool operator> (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - return rhs < lhs; -} - -template -bool operator>= (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - return ! (lhs < rhs); -} - -template -bool operator<= (RippleAssetType const& lhs, - RippleAssetType const& rhs) -{ - return ! (rhs < lhs); -} -/** @} */ - -//------------------------------------------------------------------------------ - -typedef RippleAssetType RippleAsset; -typedef RippleAssetType RippleAssetRef; - -/** Create an asset specifier by parsing the given JSON. - Errors, if any, will be returned or injected into the specified result - JSON object using the JSON-RPC error specification interface. - @param currency_field The JSON field name of the currency specifier - @param issuer_field The JSON field name of the issuer specifier - @param result The JSON in which to store any errors. - #return An asset representing the parsed JSON if no errors occurred. -*/ -RippleAsset make_asset (Json::Value json, - std::string const& currency_field, std::string const& issuer_field, - Json::Value* result); - -//------------------------------------------------------------------------------ - -/** Returns an asset specifier that represents XRP. */ -inline RippleAssetRef xrp_asset () -{ - static RippleAsset asset (Currency (0), Account (0)); - return asset; -} - -//------------------------------------------------------------------------------ - -/** Specifies an order book. - The order book is defined by the input asset ('in') and output - asset ('out'). -*/ -template -class RippleBookType -{ -public: - typedef RippleAssetType AssetType; - - AssetType in; - AssetType out; - - RippleBookType () - { - } - - RippleBookType (AssetType const& in_, AssetType const& out_) - : in (in_) - , out (out_) - { - } - - template - RippleBookType (RippleBookType const& other) - : in (other.in) - , out (other.out) - { - } - - /** Assignment. - This is only valid when ByValue == `true` - */ - template - RippleBookType& operator= (RippleBookType const& other) - { - in = other.in; - out = other.out; - return *this; - } - - template - friend - void - hash_append (Hasher& h, RippleBookType const& b) - { - using beast::hash_append; - hash_append (h, b.in, b.out); - } -}; - -/** Ordered comparison. */ -template -int compare (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - int const diff (compare (lhs.in, rhs.in)); - if (diff != 0) - return diff; - return compare (lhs.out, rhs.out); -} - -/** Equality comparison. */ -/** @{ */ -template -bool operator== (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - return (lhs.in == rhs.in) && - (lhs.out == rhs.out); -} - -template -bool operator!= (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - return (lhs.in != rhs.in) || - (lhs.out != rhs.out); -} -/** @} */ - -/** Strict weak ordering. */ -/** @{ */ -template -bool operator< (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - int const diff (compare (lhs.in, rhs.in)); - if (diff != 0) - return diff < 0; - return lhs.out < rhs.out; -} - -template -bool operator> (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - return rhs < lhs; -} - -template -bool operator>= (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - return ! (lhs < rhs); -} - -template -bool operator<= (RippleBookType const& lhs, - RippleBookType const& rhs) -{ - return ! (rhs < lhs); -} -/** @} */ - -//------------------------------------------------------------------------------ - -typedef RippleBookType RippleBook; -typedef RippleBookType RippleBookRef; - -} - -//------------------------------------------------------------------------------ - -namespace std { - -template -struct hash > - : private boost::base_from_member , 0> - , private boost::base_from_member , 1> -{ -private: - typedef boost::base_from_member < - std::hash , 0> currency_hash_type; - typedef boost::base_from_member < - std::hash , 1> issuer_hash_type; - -public: - typedef std::size_t value_type; - typedef ripple::RippleAssetType argument_type; - - value_type operator() (argument_type const& value) const - { - value_type result (currency_hash_type::member (value.currency)); - if (! value.is_xrp ()) - boost::hash_combine (result, - issuer_hash_type::member (value.issuer)); - return result; - } -}; - -//------------------------------------------------------------------------------ - -template -struct hash > -{ -private: - typedef std::hash > hasher; - - hasher m_hasher; - -public: - typedef std::size_t value_type; - typedef ripple::RippleBookType argument_type; - - value_type operator() (argument_type const& value) const - { - value_type result (m_hasher (value.in)); - boost::hash_combine (result, m_hasher (value.out)); - return result; - } -}; - -} - -//------------------------------------------------------------------------------ - -namespace boost { - -template -struct hash > - : std::hash > -{ - typedef std::hash > Base; - // VFALCO NOTE broken in vs2012 - //using Base::Base; // inherit ctors -}; - -template -struct hash > - : std::hash > -{ - typedef std::hash > Base; - // VFALCO NOTE broken in vs2012 - //using Base::Base; // inherit ctors -}; - -} - -#endif diff --git a/src/ripple/types/api/UintTypes.h b/src/ripple/types/api/UintTypes.h index 1e50fe3fe..2409c82de 100644 --- a/src/ripple/types/api/UintTypes.h +++ b/src/ripple/types/api/UintTypes.h @@ -51,7 +51,7 @@ typedef std::unordered_set CurrencySet; typedef std::unordered_set NodeIDSet; /** A special account that's used as the "issuer" for XRP. */ -Account const& xrpIssuer(); +Account const& xrpAccount(); /** XRP currency. */ Currency const& xrpCurrency(); @@ -64,6 +64,8 @@ Currency const& noCurrency(); /** We deliberately disallow the currency that looks like "XRP" because too many people were using it instead of the correct XRP currency. */ + + Currency const& badCurrency(); inline bool isXRP(Currency const& c) diff --git a/src/ripple/types/impl/RippleAssets.cpp b/src/ripple/types/impl/Issue.cpp similarity index 52% rename from src/ripple/types/impl/RippleAssets.cpp rename to src/ripple/types/impl/Issue.cpp index 667f533f4..b727fc54d 100644 --- a/src/ripple/types/impl/RippleAssets.cpp +++ b/src/ripple/types/impl/Issue.cpp @@ -43,7 +43,7 @@ namespace ripple { -class RippleAsset_test : public beast::unit_test::suite +class Issue_test : public beast::unit_test::suite { public: // Comparison, hash tests for uint60 (via base_uint) @@ -75,61 +75,61 @@ public: //-------------------------------------------------------------------------- - // Comparison, hash tests for RippleAssetType - template - void testAssetType () + // Comparison, hash tests for IssueType + template + void testIssueType () { Currency const c1 (1); Account const i1 (1); Currency const c2 (2); Account const i2 (2); Currency const c3 (3); Account const i3 (3); - expect (Asset (c1, i1) != Asset (c2, i1)); - expect (Asset (c1, i1) < Asset (c2, i1)); - expect (Asset (c1, i1) <= Asset (c2, i1)); - expect (Asset (c2, i1) <= Asset (c2, i1)); - expect (Asset (c2, i1) == Asset (c2, i1)); - expect (Asset (c2, i1) >= Asset (c2, i1)); - expect (Asset (c3, i1) >= Asset (c2, i1)); - expect (Asset (c3, i1) > Asset (c2, i1)); - expect (Asset (c1, i1) != Asset (c1, i2)); - expect (Asset (c1, i1) < Asset (c1, i2)); - expect (Asset (c1, i1) <= Asset (c1, i2)); - expect (Asset (c1, i2) <= Asset (c1, i2)); - expect (Asset (c1, i2) == Asset (c1, i2)); - expect (Asset (c1, i2) >= Asset (c1, i2)); - expect (Asset (c1, i3) >= Asset (c1, i2)); - expect (Asset (c1, i3) > Asset (c1, i2)); + expect (Issue (c1, i1) != Issue (c2, i1)); + expect (Issue (c1, i1) < Issue (c2, i1)); + expect (Issue (c1, i1) <= Issue (c2, i1)); + expect (Issue (c2, i1) <= Issue (c2, i1)); + expect (Issue (c2, i1) == Issue (c2, i1)); + expect (Issue (c2, i1) >= Issue (c2, i1)); + expect (Issue (c3, i1) >= Issue (c2, i1)); + expect (Issue (c3, i1) > Issue (c2, i1)); + expect (Issue (c1, i1) != Issue (c1, i2)); + expect (Issue (c1, i1) < Issue (c1, i2)); + expect (Issue (c1, i1) <= Issue (c1, i2)); + expect (Issue (c1, i2) <= Issue (c1, i2)); + expect (Issue (c1, i2) == Issue (c1, i2)); + expect (Issue (c1, i2) >= Issue (c1, i2)); + expect (Issue (c1, i3) >= Issue (c1, i2)); + expect (Issue (c1, i3) > Issue (c1, i2)); - std::hash hash; + std::hash hash; - expect (hash (Asset (c1, i1)) == hash (Asset (c1, i1))); - expect (hash (Asset (c1, i2)) == hash (Asset (c1, i2))); - expect (hash (Asset (c1, i3)) == hash (Asset (c1, i3))); - expect (hash (Asset (c2, i1)) == hash (Asset (c2, i1))); - expect (hash (Asset (c2, i2)) == hash (Asset (c2, i2))); - expect (hash (Asset (c2, i3)) == hash (Asset (c2, i3))); - expect (hash (Asset (c3, i1)) == hash (Asset (c3, i1))); - expect (hash (Asset (c3, i2)) == hash (Asset (c3, i2))); - expect (hash (Asset (c3, i3)) == hash (Asset (c3, i3))); - expect (hash (Asset (c1, i1)) != hash (Asset (c1, i2))); - expect (hash (Asset (c1, i1)) != hash (Asset (c1, i3))); - expect (hash (Asset (c1, i1)) != hash (Asset (c2, i1))); - expect (hash (Asset (c1, i1)) != hash (Asset (c2, i2))); - expect (hash (Asset (c1, i1)) != hash (Asset (c2, i3))); - expect (hash (Asset (c1, i1)) != hash (Asset (c3, i1))); - expect (hash (Asset (c1, i1)) != hash (Asset (c3, i2))); - expect (hash (Asset (c1, i1)) != hash (Asset (c3, i3))); + expect (hash (Issue (c1, i1)) == hash (Issue (c1, i1))); + expect (hash (Issue (c1, i2)) == hash (Issue (c1, i2))); + expect (hash (Issue (c1, i3)) == hash (Issue (c1, i3))); + expect (hash (Issue (c2, i1)) == hash (Issue (c2, i1))); + expect (hash (Issue (c2, i2)) == hash (Issue (c2, i2))); + expect (hash (Issue (c2, i3)) == hash (Issue (c2, i3))); + expect (hash (Issue (c3, i1)) == hash (Issue (c3, i1))); + expect (hash (Issue (c3, i2)) == hash (Issue (c3, i2))); + expect (hash (Issue (c3, i3)) == hash (Issue (c3, i3))); + expect (hash (Issue (c1, i1)) != hash (Issue (c1, i2))); + expect (hash (Issue (c1, i1)) != hash (Issue (c1, i3))); + expect (hash (Issue (c1, i1)) != hash (Issue (c2, i1))); + expect (hash (Issue (c1, i1)) != hash (Issue (c2, i2))); + expect (hash (Issue (c1, i1)) != hash (Issue (c2, i3))); + expect (hash (Issue (c1, i1)) != hash (Issue (c3, i1))); + expect (hash (Issue (c1, i1)) != hash (Issue (c3, i2))); + expect (hash (Issue (c1, i1)) != hash (Issue (c3, i3))); } template - void testAssetSet () + void testIssueSet () { Currency const c1 (1); Account const i1 (1); Currency const c2 (2); Account const i2 (2); - RippleAssetRef const a1 (c1, i1); - RippleAssetRef const a2 (c2, i2); + IssueRef const a1 (c1, i1); + IssueRef const a2 (c2, i2); { Set c; @@ -139,9 +139,9 @@ public: c.insert (a2); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleAsset (c1, i2)) == 0)) return; - if (! expect (c.erase (RippleAsset (c1, i1)) == 1)) return; - if (! expect (c.erase (RippleAsset (c2, i2)) == 1)) return; + if (! expect (c.erase (Issue (c1, i2)) == 0)) return; + if (! expect (c.erase (Issue (c1, i1)) == 1)) return; + if (! expect (c.erase (Issue (c2, i2)) == 1)) return; if (! expect (c.empty ())) return; } @@ -153,9 +153,9 @@ public: c.insert (a2); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleAssetRef (c1, i2)) == 0)) return; - if (! expect (c.erase (RippleAssetRef (c1, i1)) == 1)) return; - if (! expect (c.erase (RippleAssetRef (c2, i2)) == 1)) return; + if (! expect (c.erase (IssueRef (c1, i2)) == 0)) return; + if (! expect (c.erase (IssueRef (c1, i1)) == 1)) return; + if (! expect (c.erase (IssueRef (c2, i2)) == 1)) return; if (! expect (c.empty ())) return; #if STL_SET_HAS_EMPLACE @@ -168,14 +168,14 @@ public: } template - void testAssetMap () + void testIssueMap () { Currency const c1 (1); Account const i1 (1); Currency const c2 (2); Account const i2 (2); - RippleAssetRef const a1 (c1, i1); - RippleAssetRef const a2 (c2, i2); + IssueRef const a1 (c1, i1); + IssueRef const a2 (c2, i2); { Map c; @@ -185,9 +185,9 @@ public: c.insert (std::make_pair (a2, 2)); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleAsset (c1, i2)) == 0)) return; - if (! expect (c.erase (RippleAsset (c1, i1)) == 1)) return; - if (! expect (c.erase (RippleAsset (c2, i2)) == 1)) return; + if (! expect (c.erase (Issue (c1, i2)) == 0)) return; + if (! expect (c.erase (Issue (c1, i1)) == 1)) return; + if (! expect (c.erase (Issue (c2, i2)) == 1)) return; if (! expect (c.empty ())) return; } @@ -199,63 +199,63 @@ public: c.insert (std::make_pair (a2, 2)); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleAssetRef (c1, i2)) == 0)) return; - if (! expect (c.erase (RippleAssetRef (c1, i1)) == 1)) return; - if (! expect (c.erase (RippleAssetRef (c2, i2)) == 1)) return; + if (! expect (c.erase (IssueRef (c1, i2)) == 0)) return; + if (! expect (c.erase (IssueRef (c1, i1)) == 1)) return; + if (! expect (c.erase (IssueRef (c2, i2)) == 1)) return; if (! expect (c.empty ())) return; } } - void testAssetSets () + void testIssueSets () { - testcase ("std::set "); - testAssetSet > (); + testcase ("std::set "); + testIssueSet > (); - testcase ("std::set "); - testAssetSet > (); + testcase ("std::set "); + testIssueSet > (); #if RIPPLE_ASSETS_ENABLE_STD_HASH - testcase ("std::unordered_set "); - testAssetSet > (); + testcase ("std::unordered_set "); + testIssueSet > (); - testcase ("std::unordered_set "); - testAssetSet > (); + testcase ("std::unordered_set "); + testIssueSet > (); #endif - testcase ("ripple::unordered_set "); - testAssetSet > (); + testcase ("ripple::unordered_set "); + testIssueSet > (); - testcase ("ripple::unordered_set "); - testAssetSet > (); + testcase ("ripple::unordered_set "); + testIssueSet > (); } - void testAssetMaps () + void testIssueMaps () { - testcase ("std::map "); - testAssetMap > (); + testcase ("std::map "); + testIssueMap > (); - testcase ("std::map "); - testAssetMap > (); + testcase ("std::map "); + testIssueMap > (); #if RIPPLE_ASSETS_ENABLE_STD_HASH - testcase ("std::unordered_map "); - testAssetMap > (); + testcase ("std::unordered_map "); + testIssueMap > (); - testcase ("std::unordered_map "); - testAssetMap > (); + testcase ("std::unordered_map "); + testIssueMap > (); - testcase ("ripple::unordered_map "); - testAssetMap > (); + testcase ("ripple::unordered_map "); + testIssueMap > (); - testcase ("ripple::unordered_map "); - testAssetMap > (); + testcase ("ripple::unordered_map "); + testIssueMap > (); #endif } //-------------------------------------------------------------------------- - // Comparison, hash tests for RippleBookType + // Comparison, hash tests for BookType template void testBook () { @@ -263,10 +263,10 @@ public: Currency const c2 (2); Account const i2 (2); Currency const c3 (3); Account const i3 (3); - RippleAsset a1 (c1, i1); - RippleAsset a2 (c1, i2); - RippleAsset a3 (c2, i2); - RippleAsset a4 (c3, i2); + Issue a1 (c1, i1); + Issue a2 (c1, i2); + Issue a3 (c2, i2); + Issue a4 (c3, i2); expect (Book (a1, a2) != Book (a2, a3)); expect (Book (a1, a2) < Book (a2, a3)); @@ -320,10 +320,10 @@ public: Account const i1 (1); Currency const c2 (2); Account const i2 (2); - RippleAssetRef const a1 (c1, i1); - RippleAssetRef const a2 (c2, i2); - RippleBookRef const b1 (a1, a2); - RippleBookRef const b2 (a2, a1); + IssueRef const a1 (c1, i1); + IssueRef const a2 (c2, i2); + BookRef const b1 (a1, a2); + BookRef const b2 (a2, a1); { Set c; @@ -333,9 +333,9 @@ public: c.insert (b2); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleBook (a1, a1)) == 0)) return; - if (! expect (c.erase (RippleBook (a1, a2)) == 1)) return; - if (! expect (c.erase (RippleBook (a2, a1)) == 1)) return; + if (! expect (c.erase (Book (a1, a1)) == 0)) return; + if (! expect (c.erase (Book (a1, a2)) == 1)) return; + if (! expect (c.erase (Book (a2, a1)) == 1)) return; if (! expect (c.empty ())) return; } @@ -347,9 +347,9 @@ public: c.insert (b2); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleBookRef (a1, a1)) == 0)) return; - if (! expect (c.erase (RippleBookRef (a1, a2)) == 1)) return; - if (! expect (c.erase (RippleBookRef (a2, a1)) == 1)) return; + if (! expect (c.erase (BookRef (a1, a1)) == 0)) return; + if (! expect (c.erase (BookRef (a1, a2)) == 1)) return; + if (! expect (c.erase (BookRef (a2, a1)) == 1)) return; if (! expect (c.empty ())) return; #if STL_SET_HAS_EMPLACE @@ -368,13 +368,13 @@ public: Account const i1 (1); Currency const c2 (2); Account const i2 (2); - RippleAssetRef const a1 (c1, i1); - RippleAssetRef const a2 (c2, i2); - RippleBookRef const b1 (a1, a2); - RippleBookRef const b2 (a2, a1); + IssueRef const a1 (c1, i1); + IssueRef const a2 (c2, i2); + BookRef const b1 (a1, a2); + BookRef const b2 (a2, a1); //typename Map::value_type value_type; - //std::pair value_type; + //std::pair value_type; { Map c; @@ -386,9 +386,9 @@ public: c.insert (std::make_pair (b2, 1)); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleBook (a1, a1)) == 0)) return; - if (! expect (c.erase (RippleBook (a1, a2)) == 1)) return; - if (! expect (c.erase (RippleBook (a2, a1)) == 1)) return; + if (! expect (c.erase (Book (a1, a1)) == 0)) return; + if (! expect (c.erase (Book (a1, a2)) == 1)) return; + if (! expect (c.erase (Book (a2, a1)) == 1)) return; if (! expect (c.empty ())) return; } @@ -402,56 +402,56 @@ public: c.insert (std::make_pair (b2, 1)); if (! expect (c.size () == 2)) return; - if (! expect (c.erase (RippleBookRef (a1, a1)) == 0)) return; - if (! expect (c.erase (RippleBookRef (a1, a2)) == 1)) return; - if (! expect (c.erase (RippleBookRef (a2, a1)) == 1)) return; + if (! expect (c.erase (BookRef (a1, a1)) == 0)) return; + if (! expect (c.erase (BookRef (a1, a2)) == 1)) return; + if (! expect (c.erase (BookRef (a2, a1)) == 1)) return; if (! expect (c.empty ())) return; } } void testBookSets () { - testcase ("std::set "); - testBookSet > (); + testcase ("std::set "); + testBookSet > (); - testcase ("std::set "); - testBookSet > (); + testcase ("std::set "); + testBookSet > (); #if RIPPLE_ASSETS_ENABLE_STD_HASH - testcase ("std::unordered_set "); - testBookSet > (); + testcase ("std::unordered_set "); + testBookSet > (); - testcase ("std::unordered_set "); - testBookSet > (); + testcase ("std::unordered_set "); + testBookSet > (); #endif - testcase ("ripple::unordered_set "); - testBookSet > (); + testcase ("ripple::unordered_set "); + testBookSet > (); - testcase ("ripple::unordered_set "); - testBookSet > (); + testcase ("ripple::unordered_set "); + testBookSet > (); } void testBookMaps () { - testcase ("std::map "); - testBookMap > (); + testcase ("std::map "); + testBookMap > (); - testcase ("std::map "); - testBookMap > (); + testcase ("std::map "); + testBookMap > (); #if RIPPLE_ASSETS_ENABLE_STD_HASH - testcase ("std::unordered_map "); - testBookMap > (); + testcase ("std::unordered_map "); + testBookMap > (); - testcase ("std::unordered_map "); - testBookMap > (); + testcase ("std::unordered_map "); + testBookMap > (); - testcase ("ripple::unordered_map "); - testBookMap > (); + testcase ("ripple::unordered_map "); + testBookMap > (); - testcase ("ripple::unordered_map "); - testBookMap > (); + testcase ("ripple::unordered_map "); + testBookMap > (); #endif } @@ -467,28 +467,28 @@ public: // --- - testcase ("RippleAsset"); - testAssetType (); + testcase ("Issue"); + testIssueType (); - testcase ("RippleAssetRef"); - testAssetType (); + testcase ("IssueRef"); + testIssueType (); - testAssetSets (); - testAssetMaps (); + testIssueSets (); + testIssueMaps (); // --- - testcase ("RippleBook"); - testBook (); + testcase ("Book"); + testBook (); - testcase ("RippleBookRef"); - testBook (); + testcase ("BookRef"); + testBook (); testBookSets (); testBookMaps (); } }; -BEAST_DEFINE_TESTSUITE(RippleAsset,types,ripple); +BEAST_DEFINE_TESTSUITE(Issue,types,ripple); } diff --git a/src/ripple/types/impl/UintTypes.cpp b/src/ripple/types/impl/UintTypes.cpp index b492441fa..6fc22736e 100644 --- a/src/ripple/types/impl/UintTypes.cpp +++ b/src/ripple/types/impl/UintTypes.cpp @@ -129,7 +129,7 @@ const char* systemCurrencyCode() { return "XRP"; } -Account const& xrpIssuer() +Account const& xrpAccount() { static const Account account(0); return account; diff --git a/src/ripple/unity/types.cpp b/src/ripple/unity/types.cpp index ace5e7bcc..9f5cd07cc 100644 --- a/src/ripple/unity/types.cpp +++ b/src/ripple/unity/types.cpp @@ -45,6 +45,6 @@ #include #include #include -#include +#include #include diff --git a/src/ripple/unity/types.h b/src/ripple/unity/types.h index 7a2e148ee..ee11faae5 100644 --- a/src/ripple/unity/types.h +++ b/src/ripple/unity/types.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,6 @@ #include #include #include -#include #include #include #include