diff --git a/src/ripple/app/ledger/Ledger.h b/src/ripple/app/ledger/Ledger.h index db2bf9d93..5a68e3461 100644 --- a/src/ripple/app/ledger/Ledger.h +++ b/src/ripple/app/ledger/Ledger.h @@ -91,7 +91,7 @@ public: // Used for ledgers loaded from JSON files Ledger (uint256 const& parentHash, uint256 const& transHash, uint256 const& accountHash, - std::uint64_t totCoins, std::uint32_t closeTime, + std::uint64_t totDrops, std::uint32_t closeTime, std::uint32_t parentCloseTime, int closeFlags, int closeResolution, std::uint32_t ledgerSeq, bool & loaded); @@ -242,7 +242,7 @@ public: uint256 const& getHash(); - void setTotalCoins (std::uint64_t totDrops) + void setTotalDrops (std::uint64_t totDrops) { info_.drops = totDrops; } diff --git a/src/ripple/app/ledger/LedgerMaster.h b/src/ripple/app/ledger/LedgerMaster.h index 4661024a5..39eb37925 100644 --- a/src/ripple/app/ledger/LedgerMaster.h +++ b/src/ripple/app/ledger/LedgerMaster.h @@ -81,6 +81,8 @@ public: // This is the last ledger we published to clients and can lag the validated ledger virtual Ledger::ref getPublishedLedger () = 0; + virtual bool isValidLedger(LedgerInfo const&) = 0; + virtual int getPublishedLedgerAge () = 0; virtual int getValidatedLedgerAge () = 0; virtual bool isCaughtUp(std::string& reason) = 0; diff --git a/src/ripple/app/ledger/LedgerToJson.h b/src/ripple/app/ledger/LedgerToJson.h index ada83984f..4ef4314ab 100644 --- a/src/ripple/app/ledger/LedgerToJson.h +++ b/src/ripple/app/ledger/LedgerToJson.h @@ -73,8 +73,8 @@ Blob serializeBlob(Object const& o) } /** Serialize an object to a hex string. */ -template -std::string serializeHex(Object const& o) +inline +std::string serializeHex(STObject const& o) { return strHex(serializeBlob(o)); } diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp index b93d7c857..e1d4ab68b 100644 --- a/src/ripple/app/ledger/impl/LedgerMaster.cpp +++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp @@ -1264,6 +1264,36 @@ public: return mPubLedger; } + bool isValidLedger(LedgerInfo const& info) override + { + if (info.validated) + return true; + + if (info.open) + return false; + + auto seq = info.seq; + try + { + // Use the skip list in the last validated ledger to see if ledger + // comes before the last validated ledger (and thus has been + // validated). + auto hash = walkHashBySeq (seq); + if (info.hash != hash) + return false; + } + catch (SHAMapMissingNode const&) + { + WriteLog (lsWARNING, RPCHandler) + << "Missing SHANode " << std::to_string (seq); + return false; + } + + // Mark ledger as validated to save time if we see it again. + info.validated = true; + return true; + } + int getMinValidations () { return mMinValidations; diff --git a/src/ripple/app/ledger/impl/LedgerToJson.cpp b/src/ripple/app/ledger/impl/LedgerToJson.cpp index aec34cdde..725ec4da6 100644 --- a/src/ripple/app/ledger/impl/LedgerToJson.cpp +++ b/src/ripple/app/ledger/impl/LedgerToJson.cpp @@ -90,32 +90,29 @@ void fillJsonTx (Object& json, LedgerFill const& fill) try { - using value_type = ReadView::txs_type::value_type; - forEachTx(fill.ledger, [&] (value_type const& i) { + for (auto& i: fill.ledger.txs) + { count.yield(); if (! bExpanded) { txns.append(to_string(i.first->getTransactionID())); - return true; } - - auto&& txJson = appendObject (txns); - - if (bBinary) + else if (bBinary) { + auto&& txJson = appendObject (txns); txJson[jss::tx_blob] = serializeHex(*i.first); if (i.second) txJson[jss::meta] = serializeHex(*i.second); } else { + auto&& txJson = appendObject (txns); copyFrom(txJson, i.first->getJson(0)); if (i.second) txJson[jss::metaData] = i.second->getJson(0); } - return true; - }); + } } catch (...) { diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp index 365a5b2d5..cbb6824f8 100644 --- a/src/ripple/app/main/Application.cpp +++ b/src/ripple/app/main/Application.cpp @@ -1164,7 +1164,7 @@ bool ApplicationImp::loadOldLedger ( std::uint32_t closeTime = getApp().getOPs().getCloseTimeNC (); std::uint32_t closeTimeResolution = 30; bool closeTimeEstimated = false; - std::uint64_t totalCoins = 0; + std::uint64_t totalDrops = 0; if (ledger.get().isMember ("accountState")) { @@ -1188,7 +1188,7 @@ bool ApplicationImp::loadOldLedger ( } if (ledger.get().isMember ("total_coins")) { - totalCoins = + totalDrops = beast::lexicalCastThrow (ledger.get()["total_coins"].asString()); } @@ -1201,7 +1201,7 @@ bool ApplicationImp::loadOldLedger ( else { loadLedger = std::make_shared (seq, closeTime); - loadLedger->setTotalCoins(totalCoins); + loadLedger->setTotalDrops(totalDrops); for (Json::UInt index = 0; index < ledger.get().size(); ++index) { diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp index b53317d4e..6edb0d2ac 100644 --- a/src/ripple/app/misc/NetworkOPs.cpp +++ b/src/ripple/app/misc/NetworkOPs.cpp @@ -217,9 +217,11 @@ public: // Book functions. // - void getBookPage (bool bAdmin, Ledger::pointer lpLedger, Book const&, - AccountID const& uTakerID, const bool bProof, const unsigned int iLimit, - Json::Value const& jvMarker, Json::Value& jvResult) override; + void getBookPage (bool bAdmin, std::shared_ptr& lpLedger, + Book const&, AccountID const& uTakerID, const bool bProof, + const unsigned int iLimit, + Json::Value const& jvMarker, Json::Value& jvResult) + override; // Ledger proposal/close functions. void processTrustedProposal ( @@ -2640,7 +2642,7 @@ InfoSub::pointer NetworkOPsImp::addRpcSub ( // FIXME : support iLimit. void NetworkOPsImp::getBookPage ( bool bAdmin, - Ledger::pointer lpLedger, + std::shared_ptr& lpLedger, Book const& book, AccountID const& uTakerID, bool const bProof, @@ -2864,7 +2866,7 @@ void NetworkOPsImp::getBookPage ( // FIXME : support iLimit. void NetworkOPsImp::getBookPage ( bool bAdmin, - Ledger::pointer lpLedger, + std::shared_ptr lpLedger, Book const& book, AccountID const& uTakerID, bool const bProof, diff --git a/src/ripple/app/misc/NetworkOPs.h b/src/ripple/app/misc/NetworkOPs.h index e4054e595..52dde31d4 100644 --- a/src/ripple/app/misc/NetworkOPs.h +++ b/src/ripple/app/misc/NetworkOPs.h @@ -145,7 +145,7 @@ public: virtual void getBookPage ( bool bAdmin, - Ledger::pointer lpLedger, + std::shared_ptr& lpLedger, Book const& book, AccountID const& uTakerID, bool const bProof, diff --git a/src/ripple/ledger/ReadView.h b/src/ripple/ledger/ReadView.h index 639ff41e5..b75566f7e 100644 --- a/src/ripple/ledger/ReadView.h +++ b/src/ripple/ledger/ReadView.h @@ -322,17 +322,6 @@ void forEachSLE(ReadView const& view, Functor func, uint256 const& start = {}) break; } -/** Run a functor on each transaction in a ReadView, as long as the functor - returns true. Might throw an exception if the ledger is corrupt. */ -template -void forEachTx(ReadView const& view, Functor func) -{ - for (auto i = view.txs.begin(); i != view.txs.begin(); ++i) - if (i->first) - if (! func(*i)) - break; -} - } // ripple #include diff --git a/src/ripple/rpc/handlers/AccountCurrenciesHandler.cpp b/src/ripple/rpc/handlers/AccountCurrenciesHandler.cpp index db0782156..b4ceeac13 100644 --- a/src/ripple/rpc/handlers/AccountCurrenciesHandler.cpp +++ b/src/ripple/rpc/handlers/AccountCurrenciesHandler.cpp @@ -29,7 +29,7 @@ Json::Value doAccountCurrencies (RPC::Context& context) auto& params = context.params; // Get the current ledger - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (!ledger) return result; diff --git a/src/ripple/rpc/handlers/AccountInfo.cpp b/src/ripple/rpc/handlers/AccountInfo.cpp index 96a67845f..7406bc9cd 100644 --- a/src/ripple/rpc/handlers/AccountInfo.cpp +++ b/src/ripple/rpc/handlers/AccountInfo.cpp @@ -37,7 +37,7 @@ Json::Value doAccountInfo (RPC::Context& context) { auto& params = context.params; - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (!ledger) @@ -58,16 +58,13 @@ Json::Value doAccountInfo (RPC::Context& context) if (jvAccepted) return jvAccepted; - auto const sleAccepted = cachedRead(*ledger, - keylet::account(accountID).key, ltACCOUNT_ROOT); - + auto const sleAccepted = ledger->read(keylet::account(accountID)); if (sleAccepted) { injectSLE(jvAccepted, *sleAccepted); // See if there's a SignerEntries for this account. - uint256 const signerListIndex = getSignerListIndex (accountID); - auto const signerList = cachedRead(*ledger, signerListIndex); + auto const signerList = ledger->read (keylet::signers(accountID)); if (signerList) { diff --git a/src/ripple/rpc/handlers/AccountLines.cpp b/src/ripple/rpc/handlers/AccountLines.cpp index 6dd7406d3..0c3670d31 100644 --- a/src/ripple/rpc/handlers/AccountLines.cpp +++ b/src/ripple/rpc/handlers/AccountLines.cpp @@ -81,7 +81,7 @@ Json::Value doAccountLines (RPC::Context& context) if (! params.isMember (jss::account)) return RPC::missing_field_error (jss::account); - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (! ledger) return result; @@ -152,9 +152,9 @@ Json::Value doAccountLines (RPC::Context& context) return RPC::expected_field_error (jss::marker, "string"); startAfter.SetHex (marker.asString ()); - auto const sleLine = cachedRead(*ledger, startAfter); + auto const sleLine = ledger->read({ltRIPPLE_STATE, startAfter}); - if (sleLine == nullptr || sleLine->getType () != ltRIPPLE_STATE) + if (! sleLine) return rpcError (rpcINVALID_PARAMS); if (sleLine->getFieldAmount (sfLowLimit).getIssuer () == accountID) @@ -180,7 +180,6 @@ Json::Value doAccountLines (RPC::Context& context) } { - // VFALCO Needs a caching view here if (! forEachItemAfter(*ledger, accountID, startAfter, startHint, reserve, [&visitData](std::shared_ptr const& sleCur) diff --git a/src/ripple/rpc/handlers/AccountObjects.cpp b/src/ripple/rpc/handlers/AccountObjects.cpp index 7610f4ab2..8e56a3511 100644 --- a/src/ripple/rpc/handlers/AccountObjects.cpp +++ b/src/ripple/rpc/handlers/AccountObjects.cpp @@ -46,7 +46,7 @@ Json::Value doAccountObjects (RPC::Context& context) if (! params.isMember (jss::account)) return RPC::missing_field_error (jss::account); - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (ledger == nullptr) return result; diff --git a/src/ripple/rpc/handlers/AccountOffers.cpp b/src/ripple/rpc/handlers/AccountOffers.cpp index 37120eab2..ca6e5ba28 100644 --- a/src/ripple/rpc/handlers/AccountOffers.cpp +++ b/src/ripple/rpc/handlers/AccountOffers.cpp @@ -49,7 +49,7 @@ Json::Value doAccountOffers (RPC::Context& context) if (! params.isMember (jss::account)) return RPC::missing_field_error (jss::account); - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (! ledger) return result; @@ -108,11 +108,9 @@ Json::Value doAccountOffers (RPC::Context& context) return RPC::expected_field_error (jss::marker, "string"); startAfter.SetHex (marker.asString ()); - auto const sleOffer = cachedRead (*ledger, startAfter); + auto const sleOffer = ledger->read({ltOFFER, startAfter}); - if (sleOffer == nullptr || - sleOffer->getType () != ltOFFER || - accountID != sleOffer->getAccountID (sfAccount)) + if (! sleOffer || accountID != sleOffer->getAccountID (sfAccount)) { return rpcError (rpcINVALID_PARAMS); } diff --git a/src/ripple/rpc/handlers/AccountTx.cpp b/src/ripple/rpc/handlers/AccountTx.cpp index e687ffe59..76fd99522 100644 --- a/src/ripple/rpc/handlers/AccountTx.cpp +++ b/src/ripple/rpc/handlers/AccountTx.cpp @@ -83,7 +83,7 @@ Json::Value doAccountTx (RPC::Context& context) } else { - Ledger::pointer ledger; + std::shared_ptr ledger; auto ret = RPC::lookupLedger (ledger, context); if (! ledger) diff --git a/src/ripple/rpc/handlers/AccountTxOld.cpp b/src/ripple/rpc/handlers/AccountTxOld.cpp index 317383cf3..8c21d253e 100644 --- a/src/ripple/rpc/handlers/AccountTxOld.cpp +++ b/src/ripple/rpc/handlers/AccountTxOld.cpp @@ -103,7 +103,7 @@ Json::Value doAccountTxOld (RPC::Context& context) } else { - Ledger::pointer ledger; + std::shared_ptr ledger; auto ret = RPC::lookupLedger (ledger, context); if (!ledger) diff --git a/src/ripple/rpc/handlers/BookOffers.cpp b/src/ripple/rpc/handlers/BookOffers.cpp index f69b3f0ad..5c338f8d6 100644 --- a/src/ripple/rpc/handlers/BookOffers.cpp +++ b/src/ripple/rpc/handlers/BookOffers.cpp @@ -30,7 +30,7 @@ Json::Value doBookOffers (RPC::Context& context) if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200) return rpcError (rpcTOO_BUSY); - Ledger::pointer lpLedger; + std::shared_ptr lpLedger; auto jvResult = RPC::lookupLedger (lpLedger, context); if (!lpLedger) diff --git a/src/ripple/rpc/handlers/CanDelete.cpp b/src/ripple/rpc/handlers/CanDelete.cpp index 4e1514120..1d1017b65 100644 --- a/src/ripple/rpc/handlers/CanDelete.cpp +++ b/src/ripple/rpc/handlers/CanDelete.cpp @@ -70,7 +70,7 @@ Json::Value doCanDelete (RPC::Context& context) canDeleteStr.find_first_not_of("0123456789abcdef") == std::string::npos) { - Ledger::pointer ledger = context.ledgerMaster.getLedgerByHash ( + auto ledger = context.ledgerMaster.getLedgerByHash ( from_hex_text(canDeleteStr)); if (!ledger) diff --git a/src/ripple/rpc/handlers/GatewayBalances.cpp b/src/ripple/rpc/handlers/GatewayBalances.cpp index 6bebf7a54..87768a146 100644 --- a/src/ripple/rpc/handlers/GatewayBalances.cpp +++ b/src/ripple/rpc/handlers/GatewayBalances.cpp @@ -49,7 +49,7 @@ Json::Value doGatewayBalances (RPC::Context& context) auto& params = context.params; // Get the current ledger - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (!ledger) diff --git a/src/ripple/rpc/handlers/Ledger.cpp b/src/ripple/rpc/handlers/Ledger.cpp index 8df222916..8b62fe6fb 100644 --- a/src/ripple/rpc/handlers/Ledger.cpp +++ b/src/ripple/rpc/handlers/Ledger.cpp @@ -41,7 +41,7 @@ Status LedgerHandler::check () if (!needsLedger) return Status::OK; - if (auto s = RPC::lookupLedger (ledger_, context_, result_)) + if (auto s = lookupLedger (ledger_, context_, result_)) return s; bool bFull = params[jss::full].asBool(); diff --git a/src/ripple/rpc/handlers/Ledger.h b/src/ripple/rpc/handlers/Ledger.h index 4dfddc0b6..60e4e7476 100644 --- a/src/ripple/rpc/handlers/Ledger.h +++ b/src/ripple/rpc/handlers/Ledger.h @@ -64,7 +64,7 @@ public: private: Context& context_; - Ledger::pointer ledger_; + std::shared_ptr ledger_; Json::Value result_; int options_ = 0; }; diff --git a/src/ripple/rpc/handlers/LedgerData.cpp b/src/ripple/rpc/handlers/LedgerData.cpp index 1d00d4794..c2daf9fd9 100644 --- a/src/ripple/rpc/handlers/LedgerData.cpp +++ b/src/ripple/rpc/handlers/LedgerData.cpp @@ -34,13 +34,13 @@ namespace ripple { // marker: resume point, if any Json::Value doLedgerData (RPC::Context& context) { - int const BINARY_PAGE_LENGTH = 2048; - int const JSON_PAGE_LENGTH = 256; + static int const BINARY_PAGE_LENGTH = 2048; + static int const JSON_PAGE_LENGTH = 256; - Ledger::pointer lpLedger; + std::shared_ptr lpLedger; auto const& params = context.params; - auto jvResult = RPC::lookupLedger (lpLedger, context); + auto jvResult = RPC::lookupLedger(lpLedger, context); if (!lpLedger) return jvResult; @@ -48,9 +48,7 @@ Json::Value doLedgerData (RPC::Context& context) if (params.isMember (jss::marker)) { Json::Value const& jMarker = params[jss::marker]; - if (!jMarker.isString ()) - return RPC::expected_field_error (jss::marker, "valid"); - if (!resumePoint.SetHex (jMarker.asString ())) + if (! (jMarker.isString () && resumePoint.SetHex (jMarker.asString ()))) return RPC::expected_field_error (jss::marker, "valid"); } @@ -71,40 +69,33 @@ Json::Value doLedgerData (RPC::Context& context) if ((limit < 0) || ((limit > maxLimit) && (context.role != Role::ADMIN))) limit = maxLimit; - jvResult[jss::ledger_hash] = to_string (lpLedger->getHash()); - jvResult[jss::ledger_index] = std::to_string( lpLedger->info().seq); + jvResult[jss::ledger_hash] = to_string (lpLedger->info().hash); + jvResult[jss::ledger_index] = std::to_string(lpLedger->info().seq); Json::Value& nodes = (jvResult[jss::state] = Json::arrayValue); - auto& map = lpLedger->stateMap(); - - for (;;) - { - auto item = map.peekNextItem (resumePoint); - if (!item) - break; - resumePoint = item->key(); + forEachSLE(*lpLedger, [&] (SLE const& sle) { if (limit-- <= 0) { - --resumePoint; - jvResult[jss::marker] = to_string (resumePoint); - break; + auto marker = sle.key(); + jvResult[jss::marker] = to_string (--marker); + return false; } if (isBinary) { Json::Value& entry = nodes.append (Json::objectValue); - entry[jss::data] = strHex ( - item->peekData().begin(), item->peekData().size()); - entry[jss::index] = to_string (item->key()); + entry[jss::data] = serializeHex(sle); + entry[jss::index] = to_string (sle.key()); } else { - SLE sle (SerialIter{item->data(), item->size()}, item->key()); Json::Value& entry = nodes.append (sle.getJson (0)); - entry[jss::index] = to_string (item->key()); + entry[jss::index] = to_string (sle.key()); } - } + + return true; + }); return jvResult; } diff --git a/src/ripple/rpc/handlers/LedgerEntry.cpp b/src/ripple/rpc/handlers/LedgerEntry.cpp index 4808474dc..5fc38a782 100644 --- a/src/ripple/rpc/handlers/LedgerEntry.cpp +++ b/src/ripple/rpc/handlers/LedgerEntry.cpp @@ -30,7 +30,7 @@ namespace ripple { // } Json::Value doLedgerEntry (RPC::Context& context) { - Ledger::pointer lpLedger; + std::shared_ptr lpLedger; auto jvResult = RPC::lookupLedger (lpLedger, context); if (!lpLedger) @@ -201,8 +201,7 @@ Json::Value doLedgerEntry (RPC::Context& context) if (uNodeIndex.isNonZero ()) { - auto const sleNode = cachedRead(*lpLedger, uNodeIndex); - + auto const sleNode = lpLedger->read(keylet::unchecked(uNodeIndex)); if (context.params.isMember(jss::binary)) bNodeBinary = context.params[jss::binary].asBool(); diff --git a/src/ripple/rpc/handlers/LedgerHeader.cpp b/src/ripple/rpc/handlers/LedgerHeader.cpp index 3c9f4565e..49e2d0ee0 100644 --- a/src/ripple/rpc/handlers/LedgerHeader.cpp +++ b/src/ripple/rpc/handlers/LedgerHeader.cpp @@ -28,16 +28,14 @@ namespace ripple { // } Json::Value doLedgerHeader (RPC::Context& context) { - Ledger::pointer lpLedger; + std::shared_ptr lpLedger; auto jvResult = RPC::lookupLedger (lpLedger, context); if (!lpLedger) return jvResult; Serializer s; - - lpLedger->addRaw (s); - + addRaw (lpLedger->info(), s); jvResult[jss::ledger_data] = strHex (s.peekData ()); // This information isn't verified: they should only use it if they trust diff --git a/src/ripple/rpc/handlers/NoRippleCheck.cpp b/src/ripple/rpc/handlers/NoRippleCheck.cpp index 1e4295ccc..7ba096d26 100644 --- a/src/ripple/rpc/handlers/NoRippleCheck.cpp +++ b/src/ripple/rpc/handlers/NoRippleCheck.cpp @@ -29,14 +29,15 @@ static void fillTransaction ( Json::Value& txArray, AccountID const& accountID, std::uint32_t& sequence, - Ledger::ref ledger) + ReadView const& ledger) { txArray["Sequence"] = Json::UInt (sequence++); txArray["Account"] = getApp().accountIDCache().toBase58 (accountID); // VFALCO Needs audit // Why are we hard-coding 10? + auto& fees = ledger.fees(); txArray["Fee"] = Json::UInt (getApp().getFeeTrack().scaleFeeLoad( - 10, ledger->fees().base, ledger->fees().units, false)); + 10, fees.base, fees.units, false)); } // { @@ -83,7 +84,7 @@ Json::Value doNoRippleCheck (RPC::Context& context) if (params.isMember (jss::transactions)) transactions = params["transactions"].asBool(); - Ledger::pointer ledger; + std::shared_ptr ledger; auto result = RPC::lookupLedger (ledger, context); if (! ledger) return result; @@ -103,8 +104,7 @@ Json::Value doNoRippleCheck (RPC::Context& context) return result; } - auto const sle = cachedRead(*ledger, - keylet::account(accountID).key, ltACCOUNT_ROOT); + auto const sle = ledger->read(keylet::account(accountID)); if (! sle) return rpcError (rpcACT_NOT_FOUND); @@ -127,7 +127,7 @@ Json::Value doNoRippleCheck (RPC::Context& context) Json::Value& tx = jvTransactions.append (Json::objectValue); tx["TransactionType"] = "AccountSet"; tx["SetFlag"] = 8; - fillTransaction (tx, accountID, seq, ledger); + fillTransaction (tx, accountID, seq, *ledger); } } @@ -171,7 +171,7 @@ Json::Value doNoRippleCheck (RPC::Context& context) tx["TransactionType"] = "TrustSet"; tx["LimitAmount"] = limitAmount.getJson (0); tx["Flags"] = bNoRipple ? tfClearNoRipple : tfSetNoRipple; - fillTransaction(tx, accountID, seq, ledger); + fillTransaction(tx, accountID, seq, *ledger); return true; } diff --git a/src/ripple/rpc/handlers/PathFind.cpp b/src/ripple/rpc/handlers/PathFind.cpp index 4442b0a40..a21268495 100644 --- a/src/ripple/rpc/handlers/PathFind.cpp +++ b/src/ripple/rpc/handlers/PathFind.cpp @@ -24,7 +24,7 @@ namespace ripple { Json::Value doPathFind (RPC::Context& context) { - Ledger::pointer lpLedger = context.ledgerMaster.getClosedLedger(); + auto lpLedger = context.ledgerMaster.getClosedLedger(); if (!context.params.isMember (jss::subcommand) || !context.params[jss::subcommand].isString ()) @@ -35,7 +35,7 @@ Json::Value doPathFind (RPC::Context& context) if (!context.infoSub) return rpcError (rpcNO_EVENTS); - std::string sSubCommand = context.params[jss::subcommand].asString (); + auto sSubCommand = context.params[jss::subcommand].asString (); if (sSubCommand == "create") { diff --git a/src/ripple/rpc/handlers/RipplePathFind.cpp b/src/ripple/rpc/handlers/RipplePathFind.cpp index 016b51156..d6ae45d21 100644 --- a/src/ripple/rpc/handlers/RipplePathFind.cpp +++ b/src/ripple/rpc/handlers/RipplePathFind.cpp @@ -73,7 +73,7 @@ Json::Value doRipplePathFind (RPC::Context& context) context.params.isMember(jss::ledger_hash)) { // The caller specified a ledger - jvResult = RPC::lookupLedger (lpLedger, context); + jvResult = RPC::lookupLedgerDeprecated (lpLedger, context); if (!lpLedger) return jvResult; } diff --git a/src/ripple/rpc/handlers/Subscribe.cpp b/src/ripple/rpc/handlers/Subscribe.cpp index d16d244c2..5ab0710e5 100644 --- a/src/ripple/rpc/handlers/Subscribe.cpp +++ b/src/ripple/rpc/handlers/Subscribe.cpp @@ -292,8 +292,8 @@ Json::Value doSubscribe (RPC::Context& context) if (bSnapshot) { context.loadType = Resource::feeMediumBurdenRPC; - auto lpLedger = getApp().getLedgerMaster (). - getPublishedLedger (); + std::shared_ptr lpLedger + = getApp().getLedgerMaster().getPublishedLedger(); if (lpLedger) { const Json::Value jvMarker = Json::Value (Json::nullValue); diff --git a/src/ripple/rpc/handlers/TransactionEntry.cpp b/src/ripple/rpc/handlers/TransactionEntry.cpp index f466d5255..cae318352 100644 --- a/src/ripple/rpc/handlers/TransactionEntry.cpp +++ b/src/ripple/rpc/handlers/TransactionEntry.cpp @@ -31,7 +31,7 @@ namespace ripple { Json::Value doTransactionEntry (RPC::Context& context) { Ledger::pointer lpLedger; - Json::Value jvResult = RPC::lookupLedger (lpLedger, context); + Json::Value jvResult = RPC::lookupLedgerDeprecated (lpLedger, context); if (!lpLedger) return jvResult; diff --git a/src/ripple/rpc/impl/GetAccountObjects.cpp b/src/ripple/rpc/impl/GetAccountObjects.cpp index 6f2ceed54..a8a798e6b 100644 --- a/src/ripple/rpc/impl/GetAccountObjects.cpp +++ b/src/ripple/rpc/impl/GetAccountObjects.cpp @@ -26,7 +26,7 @@ namespace ripple { namespace RPC { bool -getAccountObjects (Ledger const& ledger, AccountID const& account, +getAccountObjects (ReadView const& ledger, AccountID const& account, LedgerEntryType const type, uint256 dirIndex, uint256 const& entryIndex, std::uint32_t const limit, Json::Value& jvResult) { @@ -39,7 +39,7 @@ getAccountObjects (Ledger const& ledger, AccountID const& account, found = true; } - auto dir = cachedRead(ledger, dirIndex, ltDIR_NODE); + auto dir = ledger.read({ltDIR_NODE, dirIndex}); if (! dir) return false; @@ -55,17 +55,17 @@ getAccountObjects (Ledger const& ledger, AccountID const& account, iter = std::find (iter, entries.end (), entryIndex); if (iter == entries.end ()) return false; - + found = true; } for (; iter != entries.end (); ++iter) { - auto const sleNode = cachedRead(ledger, *iter ); + auto const sleNode = ledger.read(keylet::child(*iter)); if (type == ltINVALID || sleNode->getType () == type) { jvObjects.append (sleNode->getJson (0)); - + if (++i == limit) { if (++iter != entries.end ()) @@ -86,7 +86,7 @@ getAccountObjects (Ledger const& ledger, AccountID const& account, return true; dirIndex = getDirNodeIndex (rootDirIndex, nodeIndex); - dir = cachedRead(ledger, dirIndex, ltDIR_NODE); + dir = ledger.read({ltDIR_NODE, dirIndex}); if (! dir) return true; @@ -99,7 +99,7 @@ getAccountObjects (Ledger const& ledger, AccountID const& account, jvResult[jss::marker] = to_string (dirIndex) + ',' + to_string (*e.begin ()); } - + return true; } } @@ -107,4 +107,3 @@ getAccountObjects (Ledger const& ledger, AccountID const& account, } // RPC } // ripple - diff --git a/src/ripple/rpc/impl/GetAccountObjects.h b/src/ripple/rpc/impl/GetAccountObjects.h index 1630d41f5..354b88067 100644 --- a/src/ripple/rpc/impl/GetAccountObjects.h +++ b/src/ripple/rpc/impl/GetAccountObjects.h @@ -35,7 +35,7 @@ namespace RPC { @param jvResult A JSON result that holds the request objects. */ bool -getAccountObjects (Ledger const& ledger, AccountID const& account, +getAccountObjects (ReadView const& ledger, AccountID const& account, LedgerEntryType const type, uint256 dirIndex, uint256 const& entryIndex, std::uint32_t const limit, Json::Value& jvResult); diff --git a/src/ripple/rpc/impl/LookupLedger.cpp b/src/ripple/rpc/impl/LookupLedger.cpp index 0eb723a12..19bcdf222 100644 --- a/src/ripple/rpc/impl/LookupLedger.cpp +++ b/src/ripple/rpc/impl/LookupLedger.cpp @@ -19,6 +19,7 @@ #include #include +#include namespace ripple { namespace RPC { @@ -34,14 +35,14 @@ bool isValidatedOld (LedgerMaster& ledgerMaster) Tuning::maxValidatedLedgerAge; } -Status ledgerFromRequest (Ledger::pointer& ledger, Context& context) +template +Status ledgerFromRequest (T& ledger, Context& context) { static auto const minSequenceGap = 10; ledger.reset(); auto& params = context.params; - auto& netOps = context.netOps; auto& ledgerMaster = context.ledgerMaster; auto indexValue = params[jss::ledger_index]; @@ -124,14 +125,12 @@ Status ledgerFromRequest (Ledger::pointer& ledger, Context& context) return {rpcNO_NETWORK, "InsufficientNetworkMode"}; } } - - assert (ledger->isImmutable ()); } return Status::OK; } -bool isValidated (LedgerMaster& ledgerMaster, Ledger& ledger) +bool isValidated (LedgerMaster& ledgerMaster, ReadView const& ledger) { if (ledger.info().validated) return true; @@ -146,7 +145,7 @@ bool isValidated (LedgerMaster& ledgerMaster, Ledger& ledger) // comes before the last validated ledger (and thus has been // validated). auto hash = ledgerMaster.walkHashBySeq (seq); - if (ledger.getHash() != hash) + if (ledger.info().hash != hash) return false; } catch (SHAMapMissingNode const&) @@ -157,7 +156,7 @@ bool isValidated (LedgerMaster& ledgerMaster, Ledger& ledger) } // Mark ledger as validated to save time if we see it again. - ledger.setValidated(); + ledger.info().validated = true; return true; } @@ -182,27 +181,62 @@ bool isValidated (LedgerMaster& ledgerMaster, Ledger& ledger) // return value. Otherwise, the object contains the field "validated" and // optionally the fields "ledger_hash", "ledger_index" and // "ledger_current_index", if they are defined. -Status lookupLedger ( +Status lookupLedgerDeprecated ( Ledger::pointer& ledger, Context& context, Json::Value& result) { if (auto status = ledgerFromRequest (ledger, context)) return status; - if (! ledger->info().open) + auto& info = ledger->info(); + + if (!info.open) { - result[jss::ledger_hash] = to_string (ledger->getHash()); - result[jss::ledger_index] = ledger->info().seq; + result[jss::ledger_hash] = to_string (info.hash); + result[jss::ledger_index] = info.seq; } else { - result[jss::ledger_current_index] = ledger->info().seq; + result[jss::ledger_current_index] = info.seq; + } + + result[jss::validated] = getApp().getLedgerMaster().isValidLedger(info); + return Status::OK; +} + +Status lookupLedger ( + std::shared_ptr& ledger, Context& context, + Json::Value& result) +{ + if (auto status = ledgerFromRequest (ledger, context)) + return status; + + auto& info = ledger->info(); + + if (!info.open) + { + result[jss::ledger_hash] = to_string (info.hash); + result[jss::ledger_index] = info.seq; + } + else + { + result[jss::ledger_current_index] = info.seq; } result[jss::validated] = isValidated (context.ledgerMaster, *ledger); return Status::OK; } -Json::Value lookupLedger (Ledger::pointer& ledger, Context& context) +Json::Value lookupLedgerDeprecated (Ledger::pointer& ledger, Context& context) +{ + Json::Value result; + if (auto status = lookupLedgerDeprecated (ledger, context, result)) + status.inject (result); + + return result; +} + +Json::Value lookupLedger ( + std::shared_ptr& ledger, Context& context) { Json::Value result; if (auto status = lookupLedger (ledger, context, result)) diff --git a/src/ripple/rpc/impl/LookupLedger.h b/src/ripple/rpc/impl/LookupLedger.h index 712ce3bd6..0c0caac98 100644 --- a/src/ripple/rpc/impl/LookupLedger.h +++ b/src/ripple/rpc/impl/LookupLedger.h @@ -23,6 +23,9 @@ #include namespace ripple { + +class ReadView; + namespace RPC { class Context; @@ -33,14 +36,15 @@ class Context; If there is no error in the return value, then the ledger pointer will have been filled. */ -Json::Value lookupLedger (Ledger::pointer&, Context&); +Json::Value lookupLedgerDeprecated (Ledger::pointer&, Context&); +Json::Value lookupLedger (std::shared_ptr&, Context&); /** Look up a ledger from a request and fill a Json::Result with the data representing a ledger. If the returned Status is OK, the ledger pointer will have been filled. */ Status lookupLedger ( - Ledger::pointer&, Context&, Json::Value& result); + std::shared_ptr&, Context&, Json::Value& result); } // RPC } // ripple