diff --git a/src/cpp/ripple/AcceptedLedger.cpp b/src/cpp/ripple/AcceptedLedger.cpp index 6226c3ebcb..2e2f69f085 100644 --- a/src/cpp/ripple/AcceptedLedger.cpp +++ b/src/cpp/ripple/AcceptedLedger.cpp @@ -49,12 +49,11 @@ void ALTransaction::buildJson() if (!mAffected.empty()) { - Json::Value affected(Json::arrayValue); + Json::Value& affected = (mJson["affected"] = Json::arrayValue); BOOST_FOREACH(const RippleAddress& ra, mAffected) { affected.append(ra.humanAccountID()); } - mJson["affected"] = affected; } } @@ -64,7 +63,7 @@ AcceptedLedger::AcceptedLedger(Ledger::ref ledger) : mLedger(ledger) for (SHAMapItem::pointer item = txSet.peekFirstItem(); !!item; item = txSet.peekNextItem(item->getTag())) { SerializerIterator sit(item->peekSerializer()); - insert(ALTransaction(ledger->getLedgerSeq(), sit)); + insert(boost::make_shared(ledger->getLedgerSeq(), sit)); } } @@ -78,16 +77,16 @@ AcceptedLedger::pointer AcceptedLedger::makeAcceptedLedger(Ledger::ref ledger) return ret; } -void AcceptedLedger::insert(const ALTransaction& at) +void AcceptedLedger::insert(ALTransaction::ref at) { - assert(mMap.find(at.getIndex()) == mMap.end()); - mMap.insert(std::make_pair(at.getIndex(), at)); + assert(mMap.find(at->getIndex()) == mMap.end()); + mMap.insert(std::make_pair(at->getIndex(), at)); } -const ALTransaction* AcceptedLedger::getTxn(int i) const +ALTransaction::pointer AcceptedLedger::getTxn(int i) const { map_t::const_iterator it = mMap.find(i); if (it == mMap.end()) - return NULL; - return &it->second; + return ALTransaction::pointer(); + return it->second; } diff --git a/src/cpp/ripple/AcceptedLedger.h b/src/cpp/ripple/AcceptedLedger.h index 04f917a788..f8de687399 100644 --- a/src/cpp/ripple/AcceptedLedger.h +++ b/src/cpp/ripple/AcceptedLedger.h @@ -19,6 +19,8 @@ protected: void buildJson(); public: + typedef boost::shared_ptr pointer; + typedef const pointer& ref; ALTransaction(uint32 ledgerSeq, SerializerIterator& sit); ALTransaction(SerializedTransaction::ref, TransactionMetaSet::ref); @@ -42,17 +44,17 @@ public: class AcceptedLedger { public: - typedef boost::shared_ptr pointer; - typedef const pointer& ret; - typedef std::map map_t; // Must be an ordered map! - typedef map_t::value_type value_type; - typedef map_t::const_iterator const_iterator; + typedef boost::shared_ptr pointer; + typedef const pointer& ret; + typedef std::map map_t; // Must be an ordered map! + typedef map_t::value_type value_type; + typedef map_t::const_iterator const_iterator; protected: Ledger::pointer mLedger; map_t mMap; - void insert(const ALTransaction&); + void insert(ALTransaction::ref); static TaggedCache ALCache; AcceptedLedger(Ledger::ref ledger); @@ -68,7 +70,7 @@ public: int getLedgerSeq() const { return mLedger->getLedgerSeq(); } int getTxnCount() const { return mMap.size(); } - const ALTransaction* getTxn(int) const; + ALTransaction::pointer getTxn(int) const; }; #endif diff --git a/src/cpp/ripple/Amount.cpp b/src/cpp/ripple/Amount.cpp index c65067afb9..9c1775c711 100644 --- a/src/cpp/ripple/Amount.cpp +++ b/src/cpp/ripple/Amount.cpp @@ -1223,9 +1223,9 @@ void STAmount::roundSelf() } } -Json::Value STAmount::getJson(int) const +void STAmount::setJson(Json::Value& elem) const { - Json::Value elem(Json::objectValue); + elem = Json::objectValue; if (!mIsNative) { @@ -1237,9 +1237,14 @@ Json::Value STAmount::getJson(int) const } else { - elem=getText(); + elem = getText(); } +} +Json::Value STAmount::getJson(int) const +{ + Json::Value elem; + setJson(elem); return elem; } diff --git a/src/cpp/ripple/Ledger.cpp b/src/cpp/ripple/Ledger.cpp index 4f2bb44056..8bb7709e2e 100644 --- a/src/cpp/ripple/Ledger.cpp +++ b/src/cpp/ripple/Ledger.cpp @@ -471,12 +471,12 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) BOOST_FOREACH(const AcceptedLedger::value_type& vt, aLedger->getMap()) { - uint256 txID = vt.second.getTransactionID(); + uint256 txID = vt.second->getTransactionID(); theApp->getMasterTransaction().inLedger(txID, mLedgerSeq); db->executeSQL(boost::str(deleteAcctTrans % txID.GetHex())); - const std::vector& accts = vt.second.getAffected(); + const std::vector& accts = vt.second->getAffected(); if (!accts.empty()) { std::string sql = "INSERT INTO AccountTransactions (TransID, Account, LedgerSeq, TxnSeq) VALUES "; @@ -496,7 +496,7 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) sql += "',"; sql += boost::lexical_cast(getLedgerSeq()); sql += ","; - sql += boost::lexical_cast(vt.second.getTxnSeq()); + sql += boost::lexical_cast(vt.second->getTxnSeq()); sql += ")"; } sql += ";"; @@ -507,7 +507,7 @@ void Ledger::saveAcceptedLedger(Job&, bool fromConsensus) cLog(lsWARNING) << "Transaction in ledger " << mLedgerSeq << " affects no accounts"; db->executeSQL(SerializedTransaction::getMetaSQLInsertReplaceHeader() + - vt.second.getTxn()->getMetaSQL(getLedgerSeq(), vt.second.getEscMeta()) + ";"); + vt.second->getTxn()->getMetaSQL(getLedgerSeq(), vt.second->getEscMeta()) + ";"); } db->executeSQL("COMMIT TRANSACTION;"); } diff --git a/src/cpp/ripple/NetworkOPs.cpp b/src/cpp/ripple/NetworkOPs.cpp index b7208a606b..0a500b2f50 100644 --- a/src/cpp/ripple/NetworkOPs.cpp +++ b/src/cpp/ripple/NetworkOPs.cpp @@ -1439,8 +1439,8 @@ void NetworkOPs::pubLedger(Ledger::ref accepted) { BOOST_FOREACH(const AcceptedLedger::value_type& vt, alpAccepted->getMap()) { - cLog(lsTRACE) << "pubAccepted: " << vt.second.getJson(); - pubValidatedTransaction(lpAccepted, vt.second); + cLog(lsTRACE) << "pubAccepted: " << vt.second->getJson(); + pubValidatedTransaction(lpAccepted, *vt.second); } } } @@ -1841,8 +1841,9 @@ InfoSub::pointer NetworkOPs::addRpcSub(const std::string& strUrl, InfoSub::ref r // FIXME : support iLimit. void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPaysCurrencyID, const uint160& uTakerPaysIssuerID, const uint160& uTakerGetsCurrencyID, const uint160& uTakerGetsIssuerID, const uint160& uTakerID, const bool bProof, const unsigned int iLimit, const Json::Value& jvMarker, Json::Value& jvResult) { - boost::unordered_map umBalance; - Json::Value jvOffers = Json::Value(Json::arrayValue); + Json::Value& jvOffers = (jvResult["offers"] = Json::Value(Json::arrayValue)); + + std::map umBalance; const uint256 uBookBase = Ledger::getBookBase(uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); const uint256 uBookEnd = Ledger::getQualityNext(uBookBase); uint256 uTipIndex = uBookBase; @@ -1863,20 +1864,22 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays unsigned int uBookEntry; STAmount saDirRate; -// unsigned int iLeft = iLimit; + unsigned int iLeft = iLimit; + if ((iLeft == 0) || (iLeft > 300)) + iLeft = 300; uint32 uTransferRate = lesActive.rippleTransferRate(uTakerGetsIssuerID); - while (!bDone) { + while (!bDone && (iLeft > 0)) { if (bDirectAdvance) { bDirectAdvance = false; - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDirectAdvance")); + cLog(lsTRACE) << "getBookPage: bDirectAdvance"; sleOfferDir = lesActive.entryCache(ltDIR_NODE, lpLedger->getNextLedgerIndex(uTipIndex, uBookEnd)); if (!sleOfferDir) { - cLog(lsTRACE) << boost::str(boost::format("getBookPage: bDone")); + cLog(lsTRACE) << "getBookPage: bDone"; bDone = true; } else @@ -1895,9 +1898,9 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays if (!bDone) { SLE::pointer sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); - const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); - STAmount saTakerGets = sleOffer->getFieldAmount(sfTakerGets); - STAmount saTakerPays = sleOffer->getFieldAmount(sfTakerPays); + const uint160 uOfferOwnerID = sleOffer->getFieldAccount160(sfAccount); + const STAmount& saTakerGets = sleOffer->getFieldAmount(sfTakerGets); + const STAmount& saTakerPays = sleOffer->getFieldAmount(sfTakerPays); STAmount saOwnerFunds; if (uTakerGetsIssuerID == uOfferOwnerID) @@ -1907,7 +1910,7 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays } else { - boost::unordered_map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); + std::map::const_iterator umBalanceEntry = umBalance.find(uOfferOwnerID); if (umBalanceEntry != umBalance.end()) { @@ -1964,30 +1967,27 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays // cLog(lsINFO) << boost::str(boost::format("getBookPage: saDirRate=%s") % saDirRate.getText()); // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate).getFullText()); // cLog(lsINFO) << boost::str(boost::format("getBookPage: multiply=%s") % STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays).getFullText()); - STAmount saTakerPaysFunded; - - saTakerGetsFunded = saOwnerFundsLimit; - saTakerPaysFunded = std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)); // Only provide, if not fully funded. - jvOffer["taker_gets_funded"] = saTakerGetsFunded.getJson(0); - jvOffer["taker_pays_funded"] = saTakerPaysFunded.getJson(0); + + saTakerGetsFunded = saOwnerFundsLimit; + + saTakerGetsFunded.setJson(jvOffer["taker_gets_funded"]); + std::min(saTakerPays, STAmount::multiply(saTakerGetsFunded, saDirRate, saTakerPays)).setJson(jvOffer["taker_pays_funded"]); } - STAmount saOwnerPays = QUALITY_ONE == uOfferRate + STAmount saOwnerPays = (QUALITY_ONE == uOfferRate) ? saTakerGetsFunded : std::min(saOwnerFunds, STAmount::multiply(saTakerGetsFunded, STAmount(CURRENCY_ONE, ACCOUNT_ONE, uOfferRate, -9))); - STAmount saOwnerBalance = saOwnerFunds-saOwnerPays; - - umBalance[uOfferOwnerID] = saOwnerBalance; + umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays; if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID) { // Only provide funded offers and offers of the taker. - jvOffer["quality"] = saDirRate.getText(); - - jvOffers.append(jvOffer); + Json::Value& jvOf = jvOffers.append(jvOffer); + jvOf["quality"] = saDirRate.getText(); + --iLeft; } if (!lesActive.dirNext(uTipIndex, sleOfferDir, uBookEntry, uOfferIndex)) @@ -2001,7 +2001,6 @@ void NetworkOPs::getBookPage(Ledger::pointer lpLedger, const uint160& uTakerPays } } - jvResult["offers"] = jvOffers; // jvResult["marker"] = Json::Value(Json::arrayValue); // jvResult["nodes"] = Json::Value(Json::arrayValue); } diff --git a/src/cpp/ripple/OfferCreateTransactor.cpp b/src/cpp/ripple/OfferCreateTransactor.cpp index c7ce3e0ac1..5abb874d48 100644 --- a/src/cpp/ripple/OfferCreateTransactor.cpp +++ b/src/cpp/ripple/OfferCreateTransactor.cpp @@ -212,7 +212,7 @@ TER OfferCreateTransactor::takeOffers( cLog(lsDEBUG) << "takeOffers: considering offer : " << sleOffer->getJson(0); - const uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + const uint160 uOfferOwnerID = sleOffer->getFieldAccount160(sfAccount); STAmount saOfferPays = sleOffer->getFieldAmount(sfTakerGets); STAmount saOfferGets = sleOffer->getFieldAmount(sfTakerPays); diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 4f46ba3cbf..92b066f8f6 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -1064,12 +1064,12 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL } AccountState::pointer as = mNetOps->getAccountState(lpLedger, raAccount); - MasterLockHolder.unlock(); + + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); if (as) { - Json::Value jsonLines(Json::arrayValue); - jvResult["account"] = raAccount.humanAccountID(); // XXX This is wrong, we do access the current ledger and do need to worry about changes. @@ -1077,6 +1077,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL AccountItems rippleLines(raAccount.getAccountID(), lpLedger, AccountItem::pointer(new RippleState())); + Json::Value& jsonLines = (jvResult["lines"] = Json::arrayValue); BOOST_FOREACH(AccountItem::ref item, rippleLines.getItems()) { RippleState* line=(RippleState*)item.get(); @@ -1087,7 +1088,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL STAmount saLimit = line->getLimit(); STAmount saLimitPeer = line->getLimitPeer(); - Json::Value jPeer = Json::Value(Json::objectValue); + Json::Value& jPeer = jsonLines.append(Json::objectValue); jPeer["account"] = RippleAddress::createHumanAccountID(line->getAccountIDPeer()); // Amount reported is positive if current account holds other account's IOUs. @@ -1098,11 +1099,8 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost, ScopedL jPeer["limit_peer"] = saLimitPeer.getText(); jPeer["quality_in"] = static_cast(line->getQualityIn()); jPeer["quality_out"] = static_cast(line->getQualityOut()); - - jsonLines.append(jPeer); } } - jvResult["lines"] = jsonLines; } else { @@ -1147,11 +1145,14 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped jvResult["account_index"] = iIndex; AccountState::pointer as = mNetOps->getAccountState(lpLedger, raAccount); - MasterLockHolder.unlock(); + + if (lpLedger->isImmutable()) + MasterLockHolder.unlock(); if (as) { - Json::Value jsonLines(Json::arrayValue); + Json::Value& jsonLines = jvResult["offers"]; + jsonLines = Json::arrayValue; AccountItems offers(raAccount.getAccountID(), lpLedger, AccountItem::pointer(new Offer())); BOOST_FOREACH(AccountItem::ref item, offers.getItems()) @@ -1162,16 +1163,15 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost, Scoped STAmount takerGets = offer->getTakerGets(); //RippleAddress account = offer->getAccount(); - Json::Value obj = Json::Value(Json::objectValue); + Json::Value& obj = jsonLines.append(obj); + obj = Json::Value(Json::objectValue); //obj["account"] = account.humanAccountID(); - obj["taker_pays"] = takerPays.getJson(0); - obj["taker_gets"] = takerGets.getJson(0); + takerPays.setJson(obj["taker_pays"]); + takerGets.setJson(obj["taker_gets"]); obj["seq"] = offer->getSeq(); - jsonLines.append(obj); } - jvResult["offers"] = jsonLines; } else { @@ -1868,10 +1868,16 @@ Json::Value RPCHandler::doLedger(Json::Value jvRequest, int& cost, ScopedLock& M | (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0) | (bAccounts ? LEDGER_JSON_DUMP_STATE : 0); - Json::Value ret(Json::objectValue); + if ((bFull || bAccounts) && !lpLedger->isImmutable()) + { // For full or accounts, it's cheaper to snapshot + lpLedger = boost::make_shared(*lpLedger, false); + assert(lpLedger->isImmutable()); + } - if (lpLedger->isClosed()) + if (lpLedger->isImmutable()) MasterLockHolder.unlock(); + + Json::Value ret(Json::objectValue); lpLedger->addJson(ret, iOptions); return ret; @@ -1957,7 +1963,7 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, Json::Value ret(Json::objectValue); ret["account"] = raAccount.humanAccountID(); - ret["transactions"] = Json::arrayValue; + Json::Value& jvTxns = (ret["transactions"] = Json::arrayValue); if (bBinary) { @@ -1967,15 +1973,14 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, for (std::vector::const_iterator it = txns.begin(), end = txns.end(); it != end; ++it) { - Json::Value jvObj(Json::objectValue); - uint32 uLedgerIndex = it->get<2>(); + Json::Value& jvObj = jvTxns.append(Json::objectValue); + uint32 uLedgerIndex = it->get<2>(); jvObj["tx_blob"] = it->get<0>(); jvObj["meta"] = it->get<1>(); jvObj["ledger_index"] = uLedgerIndex; jvObj["validated"] = bValidated && uValidatedMin <= uLedgerIndex && uValidatedMax >= uLedgerIndex; - ret["transactions"].append(jvObj); } } else @@ -1984,7 +1989,7 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, for (std::vector< std::pair >::iterator it = txns.begin(), end = txns.end(); it != end; ++it) { - Json::Value jvObj(Json::objectValue); + Json::Value& jvObj = jvTxns.append(Json::objectValue); if (it->first) jvObj["tx"] = it->first->getJson(1); @@ -1997,7 +2002,6 @@ Json::Value RPCHandler::doAccountTransactions(Json::Value jvRequest, int& cost, jvObj["validated"] = bValidated && uValidatedMin <= uLedgerIndex && uValidatedMax >= uLedgerIndex; } - ret["transactions"].append(jvObj); } } @@ -2174,6 +2178,8 @@ Json::Value RPCHandler::doLogRotate(Json::Value, int& cost, ScopedLock& MasterLo // } Json::Value RPCHandler::doWalletPropose(Json::Value jvRequest, int& cost, ScopedLock& MasterLockHolder) { + MasterLockHolder.unlock(); + RippleAddress naSeed; RippleAddress naAccount; @@ -2672,7 +2678,8 @@ Json::Value RPCHandler::doLedgerEntry(Json::Value jvRequest, int& cost, ScopedLo if (!lpLedger) return jvResult; - if (lpLedger->isClosed()) + + if (lpLedger->isImmutable()) MasterLockHolder.unlock(); uint256 uNodeIndex; @@ -2840,7 +2847,7 @@ Json::Value RPCHandler::doLedgerEntry(Json::Value jvRequest, int& cost, ScopedLo jvResult["error"] = "unknownOption"; } - if (!!uNodeIndex) + if (uNodeIndex.isNonZero()) { SLE::pointer sleNode = mNetOps->getSLEi(lpLedger, uNodeIndex); diff --git a/src/cpp/ripple/RippleCalc.cpp b/src/cpp/ripple/RippleCalc.cpp index 22da827e0f..8741d1d585 100644 --- a/src/cpp/ripple/RippleCalc.cpp +++ b/src/cpp/ripple/RippleCalc.cpp @@ -978,7 +978,7 @@ TER RippleCalc::calcNodeAdvance( { // Got a new offer. sleOffer = lesActive.entryCache(ltOFFER, uOfferIndex); - uOfrOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + uOfrOwnerID = sleOffer->getFieldAccount160(sfAccount); saTakerPays = sleOffer->getFieldAmount(sfTakerPays); saTakerGets = sleOffer->getFieldAmount(sfTakerGets); @@ -3136,7 +3136,7 @@ void TransactionEngine::calcOfferBridgeNext( SLE::pointer sleOffer = entryCache(ltOFFER, uOfferIndex); - uint160 uOfferOwnerID = sleOffer->getFieldAccount(sfAccount).getAccountID(); + uint160 uOfferOwnerID = sleOffer->getFieldAccount160(sfAccount); STAmount saOfferPays = sleOffer->getFieldAmount(sfTakerGets); STAmount saOfferGets = sleOffer->getFieldAmount(sfTakerPays); diff --git a/src/cpp/ripple/SerializedTypes.h b/src/cpp/ripple/SerializedTypes.h index c599c2d73c..7320fa9172 100644 --- a/src/cpp/ripple/SerializedTypes.h +++ b/src/cpp/ripple/SerializedTypes.h @@ -473,6 +473,7 @@ public: static bool issuerFromString(uint160& uDstIssuer, const std::string& sIssuer); Json::Value getJson(int) const; + void setJson(Json::Value&) const; STAmount getRound() const; void roundSelf(); diff --git a/src/cpp/ripple/TransactionCheck.cpp b/src/cpp/ripple/TransactionCheck.cpp index 3ef97b9dd6..0b4f5c1f5f 100644 --- a/src/cpp/ripple/TransactionCheck.cpp +++ b/src/cpp/ripple/TransactionCheck.cpp @@ -9,12 +9,11 @@ SETUP_LOG(); bool TransactionEngine::checkInvariants(TER result, const SerializedTransaction& txn, TransactionEngineParams params) { #if 0 - RippleAddress srcAccount = txn.getFieldAccount(sfAccount); uint32 txnSeq = txn.getFieldU32(sfSequence); LedgerEntryAction leaAction; - uint256 srcActId = Ledger::getAccountRootIndex(srcAccount.getAccountID()); + uint256 srcActId = Ledger::getAccountRootIndex(txn.getFieldAccount(sfAccount)); SLE::pointer origSrcAct = mLedger->getSLE(srcActId); SLE::pointer newSrcAct = mNodes.getEntry(srcActId, leaAction); diff --git a/src/cpp/ripple/Transactor.cpp b/src/cpp/ripple/Transactor.cpp index b9068e5047..82b8ab9bce 100644 --- a/src/cpp/ripple/Transactor.cpp +++ b/src/cpp/ripple/Transactor.cpp @@ -97,7 +97,7 @@ TER Transactor::checkSig() { // Consistency: Check signature // Verify the transaction's signing public key is the key authorized for signing. - if (mHasAuthKey && mSigningPubKey.getAccountID() == mTxnAccount->getFieldAccount(sfRegularKey).getAccountID()) + if (mHasAuthKey && mSigningPubKey.getAccountID() == mTxnAccount->getFieldAccount160(sfRegularKey)) { // Authorized to continue. nothing();