mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-30 08:35:52 +00:00
Make database reads async
* yield on db read using asio * PostgresBackend fetches multiple transactions or objects in parallel
This commit is contained in:
@@ -32,7 +32,8 @@ getRequiredBool(boost::json::object const& request, std::string const& field)
|
||||
else
|
||||
throw InvalidParamsError("Missing field " + field);
|
||||
}
|
||||
std::optional<uint32_t>
|
||||
|
||||
std::optional<std::uint32_t>
|
||||
getUInt(boost::json::object const& request, std::string const& field)
|
||||
{
|
||||
if (!request.contains(field))
|
||||
@@ -44,18 +45,20 @@ getUInt(boost::json::object const& request, std::string const& field)
|
||||
else
|
||||
throw InvalidParamsError("Invalid field " + field + ", not uint.");
|
||||
}
|
||||
uint32_t
|
||||
|
||||
std::uint32_t
|
||||
getUInt(
|
||||
boost::json::object const& request,
|
||||
std::string const& field,
|
||||
uint32_t dfault)
|
||||
std::uint32_t const dfault)
|
||||
{
|
||||
if (auto res = getUInt(request, field))
|
||||
return *res;
|
||||
else
|
||||
return dfault;
|
||||
}
|
||||
uint32_t
|
||||
|
||||
std::uint32_t
|
||||
getRequiredUInt(boost::json::object const& request, std::string const& field)
|
||||
{
|
||||
if (auto res = getUInt(request, field))
|
||||
@@ -63,6 +66,7 @@ getRequiredUInt(boost::json::object const& request, std::string const& field)
|
||||
else
|
||||
throw InvalidParamsError("Missing field " + field);
|
||||
}
|
||||
|
||||
std::optional<std::string>
|
||||
getString(boost::json::object const& request, std::string const& field)
|
||||
{
|
||||
@@ -97,7 +101,7 @@ std::optional<ripple::STAmount>
|
||||
getDeliveredAmount(
|
||||
std::shared_ptr<ripple::STTx const> const& txn,
|
||||
std::shared_ptr<ripple::TxMeta const> const& meta,
|
||||
uint32_t ledgerSequence)
|
||||
std::uint32_t const ledgerSequence)
|
||||
{
|
||||
if (meta->hasDeliveredAmount())
|
||||
return meta->getDeliveredAmount();
|
||||
@@ -358,7 +362,7 @@ ledgerInfoFromRequest(Context const& ctx)
|
||||
if (!ledgerHash.parseHex(hashValue.as_string().c_str()))
|
||||
return Status{Error::rpcINVALID_PARAMS, "ledgerHashMalformed"};
|
||||
|
||||
lgrInfo = ctx.backend->fetchLedgerByHash(ledgerHash);
|
||||
lgrInfo = ctx.backend->fetchLedgerByHash(ledgerHash, ctx.yield);
|
||||
}
|
||||
else if (!indexValue.is_null())
|
||||
{
|
||||
@@ -370,11 +374,12 @@ ledgerInfoFromRequest(Context const& ctx)
|
||||
else
|
||||
return Status{Error::rpcINVALID_PARAMS, "ledgerIndexMalformed"};
|
||||
|
||||
lgrInfo = ctx.backend->fetchLedgerBySequence(ledgerSequence);
|
||||
lgrInfo = ctx.backend->fetchLedgerBySequence(ledgerSequence, ctx.yield);
|
||||
}
|
||||
else
|
||||
{
|
||||
lgrInfo = ctx.backend->fetchLedgerBySequence(ctx.range.maxSequence);
|
||||
lgrInfo = ctx.backend->fetchLedgerBySequence(
|
||||
ctx.range.maxSequence, ctx.yield);
|
||||
}
|
||||
|
||||
if (!lgrInfo)
|
||||
@@ -407,10 +412,11 @@ traverseOwnedNodes(
|
||||
ripple::AccountID const& accountID,
|
||||
std::uint32_t sequence,
|
||||
ripple::uint256 const& cursor,
|
||||
boost::asio::yield_context& yield,
|
||||
std::function<bool(ripple::SLE)> atOwnedNode)
|
||||
{
|
||||
if (!backend.fetchLedgerObject(
|
||||
ripple::keylet::account(accountID).key, sequence))
|
||||
ripple::keylet::account(accountID).key, sequence, yield))
|
||||
throw AccountNotFoundError(ripple::toBase58(accountID));
|
||||
auto const rootIndex = ripple::keylet::ownerDir(accountID);
|
||||
auto currentIndex = rootIndex;
|
||||
@@ -421,7 +427,8 @@ traverseOwnedNodes(
|
||||
auto start = std::chrono::system_clock::now();
|
||||
for (;;)
|
||||
{
|
||||
auto ownedNode = backend.fetchLedgerObject(currentIndex.key, sequence);
|
||||
auto ownedNode =
|
||||
backend.fetchLedgerObject(currentIndex.key, sequence, yield);
|
||||
|
||||
if (!ownedNode)
|
||||
{
|
||||
@@ -449,7 +456,7 @@ traverseOwnedNodes(
|
||||
<< ((end - start).count() / 1000000000.0);
|
||||
|
||||
start = std::chrono::system_clock::now();
|
||||
auto objects = backend.fetchLedgerObjects(keys, sequence);
|
||||
auto objects = backend.fetchLedgerObjects(keys, sequence, yield);
|
||||
end = std::chrono::system_clock::now();
|
||||
|
||||
BOOST_LOG_TRIVIAL(debug) << "Time loading owned entries: "
|
||||
@@ -639,13 +646,14 @@ bool
|
||||
isGlobalFrozen(
|
||||
BackendInterface const& backend,
|
||||
std::uint32_t sequence,
|
||||
ripple::AccountID const& issuer)
|
||||
ripple::AccountID const& issuer,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
if (ripple::isXRP(issuer))
|
||||
return false;
|
||||
|
||||
auto key = ripple::keylet::account(issuer).key;
|
||||
auto blob = backend.fetchLedgerObject(key, sequence);
|
||||
auto blob = backend.fetchLedgerObject(key, sequence, yield);
|
||||
|
||||
if (!blob)
|
||||
return false;
|
||||
@@ -662,13 +670,14 @@ isFrozen(
|
||||
std::uint32_t sequence,
|
||||
ripple::AccountID const& account,
|
||||
ripple::Currency const& currency,
|
||||
ripple::AccountID const& issuer)
|
||||
ripple::AccountID const& issuer,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
if (ripple::isXRP(currency))
|
||||
return false;
|
||||
|
||||
auto key = ripple::keylet::account(issuer).key;
|
||||
auto blob = backend.fetchLedgerObject(key, sequence);
|
||||
auto blob = backend.fetchLedgerObject(key, sequence, yield);
|
||||
|
||||
if (!blob)
|
||||
return false;
|
||||
@@ -682,7 +691,7 @@ isFrozen(
|
||||
if (issuer != account)
|
||||
{
|
||||
key = ripple::keylet::line(account, issuer, currency).key;
|
||||
blob = backend.fetchLedgerObject(key, sequence);
|
||||
blob = backend.fetchLedgerObject(key, sequence, yield);
|
||||
|
||||
if (!blob)
|
||||
return false;
|
||||
@@ -704,10 +713,11 @@ ripple::XRPAmount
|
||||
xrpLiquid(
|
||||
BackendInterface const& backend,
|
||||
std::uint32_t sequence,
|
||||
ripple::AccountID const& id)
|
||||
ripple::AccountID const& id,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
auto key = ripple::keylet::account(id).key;
|
||||
auto blob = backend.fetchLedgerObject(key, sequence);
|
||||
auto blob = backend.fetchLedgerObject(key, sequence, yield);
|
||||
|
||||
if (!blob)
|
||||
return beast::zero;
|
||||
@@ -718,7 +728,7 @@ xrpLiquid(
|
||||
std::uint32_t const ownerCount = sle.getFieldU32(ripple::sfOwnerCount);
|
||||
|
||||
auto const reserve =
|
||||
backend.fetchFees(sequence)->accountReserve(ownerCount);
|
||||
backend.fetchFees(sequence, yield)->accountReserve(ownerCount);
|
||||
|
||||
auto const balance = sle.getFieldAmount(ripple::sfBalance);
|
||||
|
||||
@@ -732,9 +742,10 @@ xrpLiquid(
|
||||
ripple::STAmount
|
||||
accountFunds(
|
||||
BackendInterface const& backend,
|
||||
uint32_t sequence,
|
||||
std::uint32_t const sequence,
|
||||
ripple::STAmount const& amount,
|
||||
ripple::AccountID const& id)
|
||||
ripple::AccountID const& id,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
if (!amount.native() && amount.getIssuer() == id)
|
||||
{
|
||||
@@ -743,7 +754,13 @@ accountFunds(
|
||||
else
|
||||
{
|
||||
return accountHolds(
|
||||
backend, sequence, id, amount.getCurrency(), amount.getIssuer());
|
||||
backend,
|
||||
sequence,
|
||||
id,
|
||||
amount.getCurrency(),
|
||||
amount.getIssuer(),
|
||||
true,
|
||||
yield);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,16 +771,17 @@ accountHolds(
|
||||
ripple::AccountID const& account,
|
||||
ripple::Currency const& currency,
|
||||
ripple::AccountID const& issuer,
|
||||
bool zeroIfFrozen)
|
||||
bool const zeroIfFrozen,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
ripple::STAmount amount;
|
||||
if (ripple::isXRP(currency))
|
||||
{
|
||||
return {xrpLiquid(backend, sequence, account)};
|
||||
return {xrpLiquid(backend, sequence, account, yield)};
|
||||
}
|
||||
auto key = ripple::keylet::line(account, issuer, currency).key;
|
||||
|
||||
auto const blob = backend.fetchLedgerObject(key, sequence);
|
||||
auto const blob = backend.fetchLedgerObject(key, sequence, yield);
|
||||
|
||||
if (!blob)
|
||||
{
|
||||
@@ -774,7 +792,8 @@ accountHolds(
|
||||
ripple::SerialIter it{blob->data(), blob->size()};
|
||||
ripple::SLE sle{it, key};
|
||||
|
||||
if (zeroIfFrozen && isFrozen(backend, sequence, account, currency, issuer))
|
||||
if (zeroIfFrozen &&
|
||||
isFrozen(backend, sequence, account, currency, issuer, yield))
|
||||
{
|
||||
amount.clear(ripple::Issue(currency, issuer));
|
||||
}
|
||||
@@ -796,10 +815,11 @@ ripple::Rate
|
||||
transferRate(
|
||||
BackendInterface const& backend,
|
||||
std::uint32_t sequence,
|
||||
ripple::AccountID const& issuer)
|
||||
ripple::AccountID const& issuer,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
auto key = ripple::keylet::account(issuer).key;
|
||||
auto blob = backend.fetchLedgerObject(key, sequence);
|
||||
auto blob = backend.fetchLedgerObject(key, sequence, yield);
|
||||
|
||||
if (blob)
|
||||
{
|
||||
@@ -819,17 +839,18 @@ postProcessOrderBook(
|
||||
ripple::Book const& book,
|
||||
ripple::AccountID const& takerID,
|
||||
Backend::BackendInterface const& backend,
|
||||
uint32_t ledgerSequence)
|
||||
std::uint32_t const ledgerSequence,
|
||||
boost::asio::yield_context& yield)
|
||||
{
|
||||
boost::json::array jsonOffers;
|
||||
|
||||
std::map<ripple::AccountID, ripple::STAmount> umBalance;
|
||||
|
||||
bool globalFreeze =
|
||||
isGlobalFrozen(backend, ledgerSequence, book.out.account) ||
|
||||
isGlobalFrozen(backend, ledgerSequence, book.out.account);
|
||||
isGlobalFrozen(backend, ledgerSequence, book.out.account, yield) ||
|
||||
isGlobalFrozen(backend, ledgerSequence, book.out.account, yield);
|
||||
|
||||
auto rate = transferRate(backend, ledgerSequence, book.out.account);
|
||||
auto rate = transferRate(backend, ledgerSequence, book.out.account, yield);
|
||||
|
||||
for (auto const& obj : offers)
|
||||
{
|
||||
@@ -877,7 +898,8 @@ postProcessOrderBook(
|
||||
uOfferOwnerID,
|
||||
book.out.currency,
|
||||
book.out.account,
|
||||
zeroIfFrozen);
|
||||
zeroIfFrozen,
|
||||
yield);
|
||||
|
||||
if (saOwnerFunds < beast::zero)
|
||||
saOwnerFunds.clear();
|
||||
|
||||
Reference in New Issue
Block a user