Skip to content

Commit

Permalink
fix: account_objects returns error when filter does not make sense (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
cindyyan317 authored Aug 5, 2024
1 parent 2a74a65 commit a7f3449
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 130 deletions.
4 changes: 2 additions & 2 deletions src/rpc/handlers/AccountObjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const

if (input.deletionBlockersOnly) {
typeFilter.emplace();
auto const& deletionBlockers = util::getDeletionBlockerLedgerTypes();
auto const& deletionBlockers = util::LedgerTypes::GetDeletionBlockerLedgerTypes();
typeFilter->reserve(deletionBlockers.size());

for (auto type : deletionBlockers) {
Expand Down Expand Up @@ -159,7 +159,7 @@ tag_invoke(boost::json::value_to_tag<AccountObjectsHandler::Input>, boost::json:
}

if (jsonObject.contains(JS(type)))
input.type = util::getLedgerEntryTypeFromStr(boost::json::value_to<std::string>(jv.at(JS(type))));
input.type = util::LedgerTypes::GetLedgerEntryTypeFromStr(boost::json::value_to<std::string>(jv.at(JS(type))));

if (jsonObject.contains(JS(limit)))
input.limit = jv.at(JS(limit)).as_int64();
Expand Down
4 changes: 2 additions & 2 deletions src/rpc/handlers/AccountObjects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class AccountObjectsHandler {
static RpcSpecConstRef
spec([[maybe_unused]] uint32_t apiVersion)
{
auto const& ledgerTypeStrs = util::getLedgerEntryTypeStrs();
auto const& accountOwnedTypes = util::LedgerTypes::GetAccountOwnedLedgerTypeStrList();
static auto const rpcSpec = RpcSpec{
{JS(account), validation::Required{}, validation::CustomValidators::AccountValidator},
{JS(ledger_hash), validation::CustomValidators::Uint256HexStringValidator},
Expand All @@ -122,7 +122,7 @@ class AccountObjectsHandler {
modifiers::Clamp<int32_t>(LIMIT_MIN, LIMIT_MAX)},
{JS(type),
validation::Type<std::string>{},
validation::OneOf<std::string>(ledgerTypeStrs.cbegin(), ledgerTypeStrs.cend())},
validation::OneOf<std::string>(accountOwnedTypes.cbegin(), accountOwnedTypes.cend())},
{JS(marker), validation::CustomValidators::AccountMarkerValidator},
{JS(deletion_blockers_only), validation::Type<bool>{}},
};
Expand Down
11 changes: 6 additions & 5 deletions src/rpc/handlers/LedgerData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <boost/json/value_to.hpp>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/strHex.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/LedgerHeader.h>
#include <xrpl/protocol/STLedgerEntry.h>
Expand Down Expand Up @@ -195,11 +196,11 @@ tag_invoke(boost::json::value_to_tag<LedgerDataHandler::Input>, boost::json::val
if (jsonObject.contains("out_of_order"))
input.outOfOrder = jsonObject.at("out_of_order").as_bool();

if (jsonObject.contains("marker")) {
if (jsonObject.at("marker").is_string()) {
input.marker = ripple::uint256{boost::json::value_to<std::string>(jsonObject.at("marker")).data()};
if (jsonObject.contains(JS(marker))) {
if (jsonObject.at(JS(marker)).is_string()) {
input.marker = ripple::uint256{boost::json::value_to<std::string>(jsonObject.at(JS(marker))).data()};
} else {
input.diffMarker = jsonObject.at("marker").as_int64();
input.diffMarker = jsonObject.at(JS(marker)).as_int64();
}
}

Expand All @@ -215,7 +216,7 @@ tag_invoke(boost::json::value_to_tag<LedgerDataHandler::Input>, boost::json::val
}

if (jsonObject.contains(JS(type)))
input.type = util::getLedgerEntryTypeFromStr(boost::json::value_to<std::string>(jsonObject.at(JS(type))));
input.type = util::LedgerTypes::GetLedgerEntryTypeFromStr(boost::json::value_to<std::string>(jv.at(JS(type))));

return input;
}
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/handlers/LedgerData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class LedgerDataHandler {
static RpcSpecConstRef
spec([[maybe_unused]] uint32_t apiVersion)
{
auto const& ledgerTypeStrs = util::getLedgerEntryTypeStrs();
auto const& ledgerTypeStrs = util::LedgerTypes::GetLedgerEntryTypeStrList();
static auto const rpcSpec = RpcSpec{
{JS(binary), validation::Type<bool>{}},
{"out_of_order", validation::Type<bool>{}},
Expand Down
5 changes: 2 additions & 3 deletions src/rpc/handlers/NFTInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
#include <variant>

using namespace ripple;
using namespace ::rpc;

namespace rpc {

Expand Down Expand Up @@ -91,11 +90,11 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, NFTInfoHandler::
{JS(nft_id), output.nftID},
{JS(ledger_index), output.ledgerIndex},
{JS(owner), output.owner},
{"is_burned", output.isBurned},
{JS(is_burned), output.isBurned},
{JS(flags), output.flags},
{"transfer_fee", output.transferFee},
{JS(issuer), output.issuer},
{"nft_taxon", output.taxon},
{JS(nft_taxon), output.taxon},
{JS(nft_serial), output.serial},
{JS(validated), output.validated},
{JS(uri), output.uri},
Expand Down
10 changes: 5 additions & 5 deletions src/rpc/handlers/NFTsByIssuer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ NFTsByIssuerHandler::process(NFTsByIssuerHandler::Input input, Context const& ct
nftJson[JS(nft_id)] = strHex(nft.tokenID);
nftJson[JS(ledger_index)] = nft.ledgerSequence;
nftJson[JS(owner)] = toBase58(nft.owner);
nftJson["is_burned"] = nft.isBurned;
nftJson[JS(is_burned)] = nft.isBurned;
nftJson[JS(uri)] = strHex(nft.uri);

nftJson[JS(flags)] = nft::getFlags(nft.tokenID);
nftJson["transfer_fee"] = nft::getTransferFee(nft.tokenID);
nftJson[JS(issuer)] = toBase58(nft::getIssuer(nft.tokenID));
nftJson["nft_taxon"] = nft::toUInt32(nft::getTaxon(nft.tokenID));
nftJson[JS(nft_taxon)] = nft::toUInt32(nft::getTaxon(nft.tokenID));
nftJson[JS(nft_serial)] = nft::getSerial(nft.tokenID);

output.nfts.push_back(nftJson);
Expand All @@ -118,7 +118,7 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, NFTsByIssuerHand
jv.as_object()[JS(marker)] = *(output.marker);

if (output.nftTaxon.has_value())
jv.as_object()["nft_taxon"] = *(output.nftTaxon);
jv.as_object()[JS(nft_taxon)] = *(output.nftTaxon);
}

NFTsByIssuerHandler::Input
Expand All @@ -143,8 +143,8 @@ tag_invoke(boost::json::value_to_tag<NFTsByIssuerHandler::Input>, boost::json::v
if (jsonObject.contains(JS(limit)))
input.limit = jsonObject.at(JS(limit)).as_int64();

if (jsonObject.contains("nft_taxon"))
input.nftTaxon = jsonObject.at("nft_taxon").as_int64();
if (jsonObject.contains(JS(nft_taxon)))
input.nftTaxon = jsonObject.at(JS(nft_taxon)).as_int64();

if (jsonObject.contains(JS(marker)))
input.marker = boost::json::value_to<std::string>(jsonObject.at(JS(marker)));
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/handlers/NFTsByIssuer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class NFTsByIssuerHandler {
{
static auto const rpcSpec = RpcSpec{
{JS(issuer), validation::Required{}, validation::CustomValidators::AccountValidator},
{"nft_taxon", validation::Type<uint32_t>{}},
{JS(nft_taxon), validation::Type<uint32_t>{}},
{JS(ledger_hash), validation::CustomValidators::Uint256HexStringValidator},
{JS(ledger_index), validation::CustomValidators::LedgerIndexValidator},
{JS(limit),
Expand Down
90 changes: 10 additions & 80 deletions src/util/LedgerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,99 +19,29 @@

#include "util/LedgerUtils.hpp"

#include "rpc/JS.hpp"

#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/jss.h>

#include <algorithm>
#include <iterator>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace util {
namespace impl {

struct LedgerTypeAttributes {
ripple::LedgerEntryType type = ripple::ltANY;
bool deletionBlocker = false;

LedgerTypeAttributes(ripple::LedgerEntryType type, bool blocker = false) : type(type), deletionBlocker(blocker)
{
}
};

// Ledger entry type filter list, add new types here to support filtering for ledger_data and
// account_objects
static std::unordered_map<std::string, LedgerTypeAttributes> const LEDGER_TYPES_MAP{{
{JS(account), LedgerTypeAttributes(ripple::ltACCOUNT_ROOT)},
{JS(amendments), LedgerTypeAttributes(ripple::ltAMENDMENTS)},
{JS(check), LedgerTypeAttributes(ripple::ltCHECK, true)},
{JS(deposit_preauth), LedgerTypeAttributes(ripple::ltDEPOSIT_PREAUTH)},
{JS(directory), LedgerTypeAttributes(ripple::ltDIR_NODE)},
{JS(escrow), LedgerTypeAttributes(ripple::ltESCROW, true)},
{JS(fee), LedgerTypeAttributes(ripple::ltFEE_SETTINGS)},
{JS(hashes), LedgerTypeAttributes(ripple::ltLEDGER_HASHES)},
{JS(offer), LedgerTypeAttributes(ripple::ltOFFER)},
{JS(payment_channel), LedgerTypeAttributes(ripple::ltPAYCHAN, true)},
{JS(signer_list), LedgerTypeAttributes(ripple::ltSIGNER_LIST)},
{JS(state), LedgerTypeAttributes(ripple::ltRIPPLE_STATE, true)},
{JS(ticket), LedgerTypeAttributes(ripple::ltTICKET)},
{JS(nft_offer), LedgerTypeAttributes(ripple::ltNFTOKEN_OFFER)},
{JS(nft_page), LedgerTypeAttributes(ripple::ltNFTOKEN_PAGE, true)},
{JS(amm), LedgerTypeAttributes(ripple::ltAMM)},
{JS(bridge), LedgerTypeAttributes(ripple::ltBRIDGE, true)},
{JS(xchain_owned_claim_id), LedgerTypeAttributes(ripple::ltXCHAIN_OWNED_CLAIM_ID, true)},
{JS(xchain_owned_create_account_claim_id),
LedgerTypeAttributes(ripple::ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID, true)},
{JS(did), LedgerTypeAttributes(ripple::ltDID)},
{JS(oracle), LedgerTypeAttributes(ripple::ltORACLE)},
{JS(nunl), LedgerTypeAttributes(ripple::ltNEGATIVE_UNL)},
}};
} // namespace impl

std::unordered_set<std::string> const&
getLedgerEntryTypeStrs()
{
static std::unordered_set<std::string> const typesKeys = []() {
std::unordered_set<std::string> keys;
std::transform(
impl::LEDGER_TYPES_MAP.begin(),
impl::LEDGER_TYPES_MAP.end(),
std::inserter(keys, keys.begin()),
[](auto const& item) { return item.first; }
);
return keys;
}();

return typesKeys;
}

ripple::LedgerEntryType
getLedgerEntryTypeFromStr(std::string const& entryName)
{
if (impl::LEDGER_TYPES_MAP.find(entryName) == impl::LEDGER_TYPES_MAP.end())
return ripple::ltANY;

return impl::LEDGER_TYPES_MAP.at(entryName).type;
}

std::vector<ripple::LedgerEntryType> const&
getDeletionBlockerLedgerTypes()
LedgerTypes::GetLedgerEntryTypeFromStr(std::string const& entryName)
{
static std::vector<ripple::LedgerEntryType> const deletionBlockerLedgerTypes = []() {
// TODO: Move to std::ranges::views::filter when move to higher clang
auto ret = std::vector<ripple::LedgerEntryType>{};
std::for_each(impl::LEDGER_TYPES_MAP.cbegin(), impl::LEDGER_TYPES_MAP.cend(), [&ret](auto const& item) {
if (item.second.deletionBlocker)
ret.push_back(item.second.type);
static std::unordered_map<std::string, ripple::LedgerEntryType> typeMap = []() {
std::unordered_map<std::string, ripple::LedgerEntryType> map;
std::for_each(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), [&map](auto const& item) {
map[item.name] = item.type;
});
return ret;
return map;
}();

return deletionBlockerLedgerTypes;
if (typeMap.find(entryName) == typeMap.end())
return ripple::ltANY;

return typeMap.at(entryName);
}

} // namespace util
Loading

0 comments on commit a7f3449

Please sign in to comment.