mirror of
https://github.com/XRPLF/clio.git
synced 2026-04-29 15:37:53 +00:00
139 lines
3.9 KiB
C++
139 lines
3.9 KiB
C++
#include <handlers/RPCHelpers.h>
|
|
#include <reporting/BackendInterface.h>
|
|
|
|
std::optional<ripple::AccountID>
|
|
accountFromStringStrict(std::string const& account)
|
|
{
|
|
boost::optional<ripple::AccountID> result;
|
|
|
|
auto const publicKey = ripple::parseBase58<ripple::PublicKey>(
|
|
ripple::TokenType::AccountPublic, account);
|
|
|
|
if (publicKey)
|
|
result = ripple::calcAccountID(*publicKey);
|
|
else
|
|
result = ripple::parseBase58<ripple::AccountID>(account);
|
|
|
|
if (result)
|
|
return result.value();
|
|
else
|
|
return {};
|
|
}
|
|
std::pair<
|
|
std::shared_ptr<ripple::STTx const>,
|
|
std::shared_ptr<ripple::STObject const>>
|
|
deserializeTxPlusMeta(Backend::TransactionAndMetadata const& blobs)
|
|
{
|
|
std::pair<
|
|
std::shared_ptr<ripple::STTx const>,
|
|
std::shared_ptr<ripple::STObject const>>
|
|
result;
|
|
{
|
|
ripple::SerialIter s{
|
|
blobs.transaction.data(), blobs.transaction.size()};
|
|
result.first = std::make_shared<ripple::STTx const>(s);
|
|
}
|
|
{
|
|
ripple::SerialIter s{blobs.metadata.data(), blobs.metadata.size()};
|
|
result.second =
|
|
std::make_shared<ripple::STObject const>(s, ripple::sfMetadata);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
boost::json::object
|
|
getJson(ripple::STBase const& obj)
|
|
{
|
|
auto start = std::chrono::system_clock::now();
|
|
boost::json::value value = boost::json::parse(
|
|
obj.getJson(ripple::JsonOptions::none).toStyledString());
|
|
auto end = std::chrono::system_clock::now();
|
|
value.as_object()["deserialization_time_microseconds"] =
|
|
std::chrono::duration_cast<std::chrono::microseconds>(end - start)
|
|
.count();
|
|
return value.as_object();
|
|
}
|
|
|
|
boost::json::object
|
|
getJson(ripple::SLE const& sle)
|
|
{
|
|
auto start = std::chrono::system_clock::now();
|
|
boost::json::value value = boost::json::parse(
|
|
sle.getJson(ripple::JsonOptions::none).toStyledString());
|
|
auto end = std::chrono::system_clock::now();
|
|
value.as_object()["deserialization_time_microseconds"] =
|
|
std::chrono::duration_cast<std::chrono::microseconds>(end - start)
|
|
.count();
|
|
return value.as_object();
|
|
}
|
|
std::optional<uint32_t>
|
|
ledgerSequenceFromRequest(
|
|
boost::json::object const& request,
|
|
BackendInterface const& backend)
|
|
{
|
|
if (not request.contains("ledger_index"))
|
|
{
|
|
return backend.fetchLatestLedgerSequence();
|
|
}
|
|
else
|
|
{
|
|
return request.at("ledger_index").as_int64();
|
|
}
|
|
}
|
|
|
|
std::optional<ripple::uint256>
|
|
traverseOwnedNodes(
|
|
BackendInterface const& backend,
|
|
ripple::AccountID const& accountID,
|
|
std::uint32_t sequence,
|
|
ripple::uint256 const& cursor,
|
|
std::function<bool(ripple::SLE)> atOwnedNode)
|
|
{
|
|
auto const rootIndex = ripple::keylet::ownerDir(accountID);
|
|
auto currentIndex = rootIndex;
|
|
|
|
std::vector<ripple::uint256> keys;
|
|
std::optional<ripple::uint256> nextCursor = {};
|
|
|
|
for (;;)
|
|
{
|
|
auto ownedNode =
|
|
backend.fetchLedgerObject(currentIndex.key, sequence);
|
|
|
|
if (!ownedNode)
|
|
{
|
|
throw std::runtime_error("Could not find owned node");
|
|
}
|
|
|
|
ripple::SerialIter it{ownedNode->data(), ownedNode->size()};
|
|
ripple::SLE dir{it, currentIndex.key};
|
|
|
|
for (auto const& key : dir.getFieldV256(ripple::sfIndexes))
|
|
{
|
|
if (key >= cursor)
|
|
keys.push_back(key);
|
|
}
|
|
|
|
auto const uNodeNext = dir.getFieldU64(ripple::sfIndexNext);
|
|
if (uNodeNext == 0)
|
|
break;
|
|
|
|
currentIndex = ripple::keylet::page(rootIndex, uNodeNext);
|
|
}
|
|
|
|
auto objects = backend.fetchLedgerObjects(keys, sequence);
|
|
|
|
for (auto i = 0; i < objects.size(); ++i)
|
|
{
|
|
ripple::SerialIter it{objects[i].data(), objects[i].size()};
|
|
ripple::SLE sle(it, keys[i]);
|
|
if (!atOwnedNode(sle))
|
|
{
|
|
nextCursor = keys[i+1];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return nextCursor;
|
|
}
|