mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-21 12:15:54 +00:00
fix: account_objects returns error when filter does not make sense (#1579)
Fix #1488
This commit is contained in:
@@ -71,7 +71,7 @@ AccountObjectsHandler::process(AccountObjectsHandler::Input input, Context const
|
|||||||
|
|
||||||
if (input.deletionBlockersOnly) {
|
if (input.deletionBlockersOnly) {
|
||||||
typeFilter.emplace();
|
typeFilter.emplace();
|
||||||
auto const& deletionBlockers = util::getDeletionBlockerLedgerTypes();
|
auto const& deletionBlockers = util::LedgerTypes::GetDeletionBlockerLedgerTypes();
|
||||||
typeFilter->reserve(deletionBlockers.size());
|
typeFilter->reserve(deletionBlockers.size());
|
||||||
|
|
||||||
for (auto type : deletionBlockers) {
|
for (auto type : deletionBlockers) {
|
||||||
@@ -159,7 +159,7 @@ tag_invoke(boost::json::value_to_tag<AccountObjectsHandler::Input>, boost::json:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (jsonObject.contains(JS(type)))
|
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)))
|
if (jsonObject.contains(JS(limit)))
|
||||||
input.limit = jv.at(JS(limit)).as_int64();
|
input.limit = jv.at(JS(limit)).as_int64();
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public:
|
|||||||
static RpcSpecConstRef
|
static RpcSpecConstRef
|
||||||
spec([[maybe_unused]] uint32_t apiVersion)
|
spec([[maybe_unused]] uint32_t apiVersion)
|
||||||
{
|
{
|
||||||
auto const& ledgerTypeStrs = util::getLedgerEntryTypeStrs();
|
auto const& accountOwnedTypes = util::LedgerTypes::GetAccountOwnedLedgerTypeStrList();
|
||||||
static auto const rpcSpec = RpcSpec{
|
static auto const rpcSpec = RpcSpec{
|
||||||
{JS(account), validation::Required{}, validation::CustomValidators::AccountValidator},
|
{JS(account), validation::Required{}, validation::CustomValidators::AccountValidator},
|
||||||
{JS(ledger_hash), validation::CustomValidators::Uint256HexStringValidator},
|
{JS(ledger_hash), validation::CustomValidators::Uint256HexStringValidator},
|
||||||
@@ -122,7 +122,7 @@ public:
|
|||||||
modifiers::Clamp<int32_t>(LIMIT_MIN, LIMIT_MAX)},
|
modifiers::Clamp<int32_t>(LIMIT_MIN, LIMIT_MAX)},
|
||||||
{JS(type),
|
{JS(type),
|
||||||
validation::Type<std::string>{},
|
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(marker), validation::CustomValidators::AccountMarkerValidator},
|
||||||
{JS(deletion_blockers_only), validation::Type<bool>{}},
|
{JS(deletion_blockers_only), validation::Type<bool>{}},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <boost/json/value_to.hpp>
|
#include <boost/json/value_to.hpp>
|
||||||
#include <xrpl/basics/base_uint.h>
|
#include <xrpl/basics/base_uint.h>
|
||||||
#include <xrpl/basics/strHex.h>
|
#include <xrpl/basics/strHex.h>
|
||||||
|
#include <xrpl/protocol/ErrorCodes.h>
|
||||||
#include <xrpl/protocol/LedgerFormats.h>
|
#include <xrpl/protocol/LedgerFormats.h>
|
||||||
#include <xrpl/protocol/LedgerHeader.h>
|
#include <xrpl/protocol/LedgerHeader.h>
|
||||||
#include <xrpl/protocol/STLedgerEntry.h>
|
#include <xrpl/protocol/STLedgerEntry.h>
|
||||||
@@ -195,11 +196,11 @@ tag_invoke(boost::json::value_to_tag<LedgerDataHandler::Input>, boost::json::val
|
|||||||
if (jsonObject.contains("out_of_order"))
|
if (jsonObject.contains("out_of_order"))
|
||||||
input.outOfOrder = jsonObject.at("out_of_order").as_bool();
|
input.outOfOrder = jsonObject.at("out_of_order").as_bool();
|
||||||
|
|
||||||
if (jsonObject.contains("marker")) {
|
if (jsonObject.contains(JS(marker))) {
|
||||||
if (jsonObject.at("marker").is_string()) {
|
if (jsonObject.at(JS(marker)).is_string()) {
|
||||||
input.marker = ripple::uint256{boost::json::value_to<std::string>(jsonObject.at("marker")).data()};
|
input.marker = ripple::uint256{boost::json::value_to<std::string>(jsonObject.at(JS(marker))).data()};
|
||||||
} else {
|
} else {
|
||||||
input.diffMarker = jsonObject.at("marker").as_int64();
|
input.diffMarker = jsonObject.at(JS(marker)).as_int64();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +216,7 @@ tag_invoke(boost::json::value_to_tag<LedgerDataHandler::Input>, boost::json::val
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (jsonObject.contains(JS(type)))
|
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;
|
return input;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ public:
|
|||||||
static RpcSpecConstRef
|
static RpcSpecConstRef
|
||||||
spec([[maybe_unused]] uint32_t apiVersion)
|
spec([[maybe_unused]] uint32_t apiVersion)
|
||||||
{
|
{
|
||||||
auto const& ledgerTypeStrs = util::getLedgerEntryTypeStrs();
|
auto const& ledgerTypeStrs = util::LedgerTypes::GetLedgerEntryTypeStrList();
|
||||||
static auto const rpcSpec = RpcSpec{
|
static auto const rpcSpec = RpcSpec{
|
||||||
{JS(binary), validation::Type<bool>{}},
|
{JS(binary), validation::Type<bool>{}},
|
||||||
{"out_of_order", validation::Type<bool>{}},
|
{"out_of_order", validation::Type<bool>{}},
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
using namespace ripple;
|
using namespace ripple;
|
||||||
using namespace ::rpc;
|
|
||||||
|
|
||||||
namespace rpc {
|
namespace rpc {
|
||||||
|
|
||||||
@@ -91,11 +90,11 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, NFTInfoHandler::
|
|||||||
{JS(nft_id), output.nftID},
|
{JS(nft_id), output.nftID},
|
||||||
{JS(ledger_index), output.ledgerIndex},
|
{JS(ledger_index), output.ledgerIndex},
|
||||||
{JS(owner), output.owner},
|
{JS(owner), output.owner},
|
||||||
{"is_burned", output.isBurned},
|
{JS(is_burned), output.isBurned},
|
||||||
{JS(flags), output.flags},
|
{JS(flags), output.flags},
|
||||||
{"transfer_fee", output.transferFee},
|
{"transfer_fee", output.transferFee},
|
||||||
{JS(issuer), output.issuer},
|
{JS(issuer), output.issuer},
|
||||||
{"nft_taxon", output.taxon},
|
{JS(nft_taxon), output.taxon},
|
||||||
{JS(nft_serial), output.serial},
|
{JS(nft_serial), output.serial},
|
||||||
{JS(validated), output.validated},
|
{JS(validated), output.validated},
|
||||||
{JS(uri), output.uri},
|
{JS(uri), output.uri},
|
||||||
|
|||||||
@@ -85,13 +85,13 @@ NFTsByIssuerHandler::process(NFTsByIssuerHandler::Input input, Context const& ct
|
|||||||
nftJson[JS(nft_id)] = strHex(nft.tokenID);
|
nftJson[JS(nft_id)] = strHex(nft.tokenID);
|
||||||
nftJson[JS(ledger_index)] = nft.ledgerSequence;
|
nftJson[JS(ledger_index)] = nft.ledgerSequence;
|
||||||
nftJson[JS(owner)] = toBase58(nft.owner);
|
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(uri)] = strHex(nft.uri);
|
||||||
|
|
||||||
nftJson[JS(flags)] = nft::getFlags(nft.tokenID);
|
nftJson[JS(flags)] = nft::getFlags(nft.tokenID);
|
||||||
nftJson["transfer_fee"] = nft::getTransferFee(nft.tokenID);
|
nftJson["transfer_fee"] = nft::getTransferFee(nft.tokenID);
|
||||||
nftJson[JS(issuer)] = toBase58(nft::getIssuer(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);
|
nftJson[JS(nft_serial)] = nft::getSerial(nft.tokenID);
|
||||||
|
|
||||||
output.nfts.push_back(nftJson);
|
output.nfts.push_back(nftJson);
|
||||||
@@ -118,7 +118,7 @@ tag_invoke(boost::json::value_from_tag, boost::json::value& jv, NFTsByIssuerHand
|
|||||||
jv.as_object()[JS(marker)] = *(output.marker);
|
jv.as_object()[JS(marker)] = *(output.marker);
|
||||||
|
|
||||||
if (output.nftTaxon.has_value())
|
if (output.nftTaxon.has_value())
|
||||||
jv.as_object()["nft_taxon"] = *(output.nftTaxon);
|
jv.as_object()[JS(nft_taxon)] = *(output.nftTaxon);
|
||||||
}
|
}
|
||||||
|
|
||||||
NFTsByIssuerHandler::Input
|
NFTsByIssuerHandler::Input
|
||||||
@@ -143,8 +143,8 @@ tag_invoke(boost::json::value_to_tag<NFTsByIssuerHandler::Input>, boost::json::v
|
|||||||
if (jsonObject.contains(JS(limit)))
|
if (jsonObject.contains(JS(limit)))
|
||||||
input.limit = jsonObject.at(JS(limit)).as_int64();
|
input.limit = jsonObject.at(JS(limit)).as_int64();
|
||||||
|
|
||||||
if (jsonObject.contains("nft_taxon"))
|
if (jsonObject.contains(JS(nft_taxon)))
|
||||||
input.nftTaxon = jsonObject.at("nft_taxon").as_int64();
|
input.nftTaxon = jsonObject.at(JS(nft_taxon)).as_int64();
|
||||||
|
|
||||||
if (jsonObject.contains(JS(marker)))
|
if (jsonObject.contains(JS(marker)))
|
||||||
input.marker = boost::json::value_to<std::string>(jsonObject.at(JS(marker)));
|
input.marker = boost::json::value_to<std::string>(jsonObject.at(JS(marker)));
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public:
|
|||||||
{
|
{
|
||||||
static auto const rpcSpec = RpcSpec{
|
static auto const rpcSpec = RpcSpec{
|
||||||
{JS(issuer), validation::Required{}, validation::CustomValidators::AccountValidator},
|
{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_hash), validation::CustomValidators::Uint256HexStringValidator},
|
||||||
{JS(ledger_index), validation::CustomValidators::LedgerIndexValidator},
|
{JS(ledger_index), validation::CustomValidators::LedgerIndexValidator},
|
||||||
{JS(limit),
|
{JS(limit),
|
||||||
|
|||||||
@@ -19,99 +19,29 @@
|
|||||||
|
|
||||||
#include "util/LedgerUtils.hpp"
|
#include "util/LedgerUtils.hpp"
|
||||||
|
|
||||||
#include "rpc/JS.hpp"
|
|
||||||
|
|
||||||
#include <xrpl/protocol/LedgerFormats.h>
|
#include <xrpl/protocol/LedgerFormats.h>
|
||||||
#include <xrpl/protocol/jss.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace util {
|
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
|
ripple::LedgerEntryType
|
||||||
getLedgerEntryTypeFromStr(std::string const& entryName)
|
LedgerTypes::GetLedgerEntryTypeFromStr(std::string const& entryName)
|
||||||
{
|
{
|
||||||
if (impl::LEDGER_TYPES_MAP.find(entryName) == impl::LEDGER_TYPES_MAP.end())
|
static std::unordered_map<std::string, ripple::LedgerEntryType> typeMap = []() {
|
||||||
return ripple::ltANY;
|
std::unordered_map<std::string, ripple::LedgerEntryType> map;
|
||||||
|
std::for_each(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), [&map](auto const& item) {
|
||||||
return impl::LEDGER_TYPES_MAP.at(entryName).type;
|
map[item.name] = item.type;
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<ripple::LedgerEntryType> const&
|
|
||||||
getDeletionBlockerLedgerTypes()
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
return ret;
|
return map;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
return deletionBlockerLedgerTypes;
|
if (typeMap.find(entryName) == typeMap.end())
|
||||||
|
return ripple::ltANY;
|
||||||
|
|
||||||
|
return typeMap.at(entryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
|
|||||||
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "rpc/JS.hpp"
|
||||||
|
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <xrpl/basics/Slice.h>
|
#include <xrpl/basics/Slice.h>
|
||||||
#include <xrpl/basics/StringUtilities.h>
|
#include <xrpl/basics/StringUtilities.h>
|
||||||
@@ -27,36 +29,164 @@
|
|||||||
#include <xrpl/protocol/LedgerHeader.h>
|
#include <xrpl/protocol/LedgerHeader.h>
|
||||||
#include <xrpl/protocol/jss.h>
|
#include <xrpl/protocol/jss.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace util {
|
namespace util {
|
||||||
|
|
||||||
/**
|
class LedgerTypes;
|
||||||
* @brief Returns a string set of all supported ledger entry types
|
|
||||||
*
|
namespace impl {
|
||||||
* @return The set of ledger entry types
|
class LedgerTypeAttribute {
|
||||||
*/
|
enum class LedgerCategory {
|
||||||
std::unordered_set<std::string> const&
|
Invalid,
|
||||||
getLedgerEntryTypeStrs();
|
AccountOwned, // The ledger object is owned by account
|
||||||
|
Chain, // The ledger object is shared across the chain
|
||||||
|
DeletionBlocker // The ledger object is owned by account and it blocks deletion
|
||||||
|
};
|
||||||
|
ripple::LedgerEntryType type = ripple::ltANY;
|
||||||
|
char const* name = nullptr;
|
||||||
|
LedgerCategory category = LedgerCategory::Invalid;
|
||||||
|
|
||||||
|
constexpr LedgerTypeAttribute(char const* name, ripple::LedgerEntryType type, LedgerCategory category)
|
||||||
|
: type(type), name(name), category(category)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr LedgerTypeAttribute
|
||||||
|
ChainLedgerType(char const* name, ripple::LedgerEntryType type)
|
||||||
|
{
|
||||||
|
return LedgerTypeAttribute(name, type, LedgerCategory::Chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr LedgerTypeAttribute
|
||||||
|
AccountOwnedLedgerType(char const* name, ripple::LedgerEntryType type)
|
||||||
|
{
|
||||||
|
return LedgerTypeAttribute(name, type, LedgerCategory::AccountOwned);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr LedgerTypeAttribute
|
||||||
|
DeletionBlockerLedgerType(char const* name, ripple::LedgerEntryType type)
|
||||||
|
{
|
||||||
|
return LedgerTypeAttribute(name, type, LedgerCategory::DeletionBlocker);
|
||||||
|
}
|
||||||
|
friend class util::LedgerTypes;
|
||||||
|
};
|
||||||
|
} // namespace impl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the ledger type from a string representation
|
* @brief A helper class that provides lists of different ledger type catagory.
|
||||||
*
|
*
|
||||||
* @param entryName The string representation of the ledger entry type
|
|
||||||
* @return The ledger entry type
|
|
||||||
*/
|
*/
|
||||||
ripple::LedgerEntryType
|
class LedgerTypes {
|
||||||
getLedgerEntryTypeFromStr(std::string const& entryName);
|
using LedgerTypeAttribute = impl::LedgerTypeAttribute;
|
||||||
|
using LedgerTypeAttributeList = LedgerTypeAttribute[];
|
||||||
|
|
||||||
|
static constexpr LedgerTypeAttributeList const LEDGER_TYPES{
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(account), ripple::ltACCOUNT_ROOT),
|
||||||
|
LedgerTypeAttribute::ChainLedgerType(JS(amendments), ripple::ltAMENDMENTS),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(check), ripple::ltCHECK),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(deposit_preauth), ripple::ltDEPOSIT_PREAUTH),
|
||||||
|
// dir node belongs to account, but can not be filtered from account_objects
|
||||||
|
LedgerTypeAttribute::ChainLedgerType(JS(directory), ripple::ltDIR_NODE),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(escrow), ripple::ltESCROW),
|
||||||
|
LedgerTypeAttribute::ChainLedgerType(JS(fee), ripple::ltFEE_SETTINGS),
|
||||||
|
LedgerTypeAttribute::ChainLedgerType(JS(hashes), ripple::ltLEDGER_HASHES),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(offer), ripple::ltOFFER),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(payment_channel), ripple::ltPAYCHAN),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(signer_list), ripple::ltSIGNER_LIST),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(state), ripple::ltRIPPLE_STATE),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(ticket), ripple::ltTICKET),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(nft_offer), ripple::ltNFTOKEN_OFFER),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(nft_page), ripple::ltNFTOKEN_PAGE),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(amm), ripple::ltAMM),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(bridge), ripple::ltBRIDGE),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(JS(xchain_owned_claim_id), ripple::ltXCHAIN_OWNED_CLAIM_ID),
|
||||||
|
LedgerTypeAttribute::DeletionBlockerLedgerType(
|
||||||
|
JS(xchain_owned_create_account_claim_id),
|
||||||
|
ripple::ltXCHAIN_OWNED_CREATE_ACCOUNT_CLAIM_ID
|
||||||
|
),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(did), ripple::ltDID),
|
||||||
|
LedgerTypeAttribute::AccountOwnedLedgerType(JS(oracle), ripple::ltORACLE),
|
||||||
|
LedgerTypeAttribute::ChainLedgerType(JS(nunl), ripple::ltNEGATIVE_UNL),
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Returns a list of all ledger entry type as string.
|
||||||
|
* @return A list of all ledger entry type as string.
|
||||||
|
*/
|
||||||
|
static constexpr auto
|
||||||
|
GetLedgerEntryTypeStrList()
|
||||||
|
{
|
||||||
|
std::array<char const*, std::size(LEDGER_TYPES)> res{};
|
||||||
|
std::transform(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), std::begin(res), [](auto const& item) {
|
||||||
|
return item.name;
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the list of ledger entry types which will block the account deletion
|
* @brief Returns a list of all account owned ledger entry type as string.
|
||||||
*
|
*
|
||||||
* @return The list of ledger entry types
|
* @return A list of all account owned ledger entry type as string.
|
||||||
*/
|
*/
|
||||||
std::vector<ripple::LedgerEntryType> const&
|
static constexpr auto
|
||||||
getDeletionBlockerLedgerTypes();
|
GetAccountOwnedLedgerTypeStrList()
|
||||||
|
{
|
||||||
|
auto constexpr filter = [](auto const& item) {
|
||||||
|
return item.category != LedgerTypeAttribute::LedgerCategory::Chain;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto constexpr accountOwnedCount = std::count_if(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), filter);
|
||||||
|
std::array<char const*, accountOwnedCount> res{};
|
||||||
|
auto it = std::begin(res);
|
||||||
|
std::for_each(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), [&](auto const& item) {
|
||||||
|
if (filter(item)) {
|
||||||
|
*it = item.name;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a list of all account deletion blocker's type as string.
|
||||||
|
*
|
||||||
|
* @return A list of all account deletion blocker's type as string.
|
||||||
|
*/
|
||||||
|
static constexpr auto
|
||||||
|
GetDeletionBlockerLedgerTypes()
|
||||||
|
{
|
||||||
|
auto constexpr filter = [](auto const& item) {
|
||||||
|
return item.category == LedgerTypeAttribute::LedgerCategory::DeletionBlocker;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto constexpr deletionBlockersCount = std::count_if(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), filter);
|
||||||
|
std::array<ripple::LedgerEntryType, deletionBlockersCount> res{};
|
||||||
|
auto it = std::begin(res);
|
||||||
|
std::for_each(std::begin(LEDGER_TYPES), std::end(LEDGER_TYPES), [&](auto const& item) {
|
||||||
|
if (filter(item)) {
|
||||||
|
*it = item.type;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the ripple::LedgerEntryType from the given string.
|
||||||
|
*
|
||||||
|
* @param entryName The name of the ledger entry type
|
||||||
|
* @return The ripple::LedgerEntryType of the given string, returns ltANY if not found.
|
||||||
|
*/
|
||||||
|
static ripple::LedgerEntryType
|
||||||
|
GetLedgerEntryTypeFromStr(std::string const& entryName);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deserializes a ripple::LedgerHeader from ripple::Slice of data.
|
* @brief Deserializes a ripple::LedgerHeader from ripple::Slice of data.
|
||||||
|
|||||||
@@ -95,6 +95,12 @@ generateTestValuesForParametersTest()
|
|||||||
"invalidParams",
|
"invalidParams",
|
||||||
"Invalid field 'type'."
|
"Invalid field 'type'."
|
||||||
},
|
},
|
||||||
|
AccountObjectsParamTestCaseBundle{
|
||||||
|
"TypeNotAccountOwned",
|
||||||
|
R"({"account":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", "type":"amendments"})",
|
||||||
|
"invalidParams",
|
||||||
|
"Invalid field 'type'."
|
||||||
|
},
|
||||||
AccountObjectsParamTestCaseBundle{
|
AccountObjectsParamTestCaseBundle{
|
||||||
"LedgerHashInvalid",
|
"LedgerHashInvalid",
|
||||||
R"({"account":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", "ledger_hash":"1"})",
|
R"({"account":"rLEsXccBGNR3UPuPu2hUXPjziKC3qKSBun", "ledger_hash":"1"})",
|
||||||
|
|||||||
@@ -26,11 +26,12 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
TEST(LedgerUtilsTests, LedgerObjectTypeList)
|
TEST(LedgerUtilsTests, LedgerObjectTypeList)
|
||||||
{
|
{
|
||||||
auto const& types = util::getLedgerEntryTypeStrs();
|
auto constexpr types = util::LedgerTypes::GetLedgerEntryTypeStrList();
|
||||||
static char const* typesList[] = {
|
static constexpr char const* typesList[] = {
|
||||||
JS(account),
|
JS(account),
|
||||||
JS(amendments),
|
JS(amendments),
|
||||||
JS(check),
|
JS(check),
|
||||||
@@ -54,27 +55,63 @@ TEST(LedgerUtilsTests, LedgerObjectTypeList)
|
|||||||
JS(oracle),
|
JS(oracle),
|
||||||
JS(nunl)
|
JS(nunl)
|
||||||
};
|
};
|
||||||
ASSERT_TRUE(std::size(typesList) == types.size());
|
|
||||||
EXPECT_TRUE(std::all_of(std::cbegin(typesList), std::cend(typesList), [&types](auto const& type) {
|
static_assert(std::size(typesList) == types.size());
|
||||||
|
|
||||||
|
static_assert(std::all_of(std::cbegin(typesList), std::cend(typesList), [&types](std::string_view type) {
|
||||||
return std::find(std::cbegin(types), std::cend(types), type) != std::cend(types);
|
return std::find(std::cbegin(types), std::cend(types), type) != std::cend(types);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(LedgerUtilsTests, AccountOwnedTypeList)
|
||||||
|
{
|
||||||
|
auto constexpr accountOwned = util::LedgerTypes::GetAccountOwnedLedgerTypeStrList();
|
||||||
|
static constexpr char const* correctTypes[] = {
|
||||||
|
JS(account),
|
||||||
|
JS(check),
|
||||||
|
JS(deposit_preauth),
|
||||||
|
JS(escrow),
|
||||||
|
JS(offer),
|
||||||
|
JS(payment_channel),
|
||||||
|
JS(signer_list),
|
||||||
|
JS(state),
|
||||||
|
JS(ticket),
|
||||||
|
JS(nft_offer),
|
||||||
|
JS(nft_page),
|
||||||
|
JS(amm),
|
||||||
|
JS(bridge),
|
||||||
|
JS(xchain_owned_claim_id),
|
||||||
|
JS(xchain_owned_create_account_claim_id),
|
||||||
|
JS(did),
|
||||||
|
JS(oracle)
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(std::size(correctTypes) == accountOwned.size());
|
||||||
|
|
||||||
|
static_assert(std::all_of(
|
||||||
|
std::cbegin(correctTypes),
|
||||||
|
std::cend(correctTypes),
|
||||||
|
[&accountOwned](std::string_view type) {
|
||||||
|
return std::find(std::cbegin(accountOwned), std::cend(accountOwned), type) != std::cend(accountOwned);
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(LedgerUtilsTests, StrToType)
|
TEST(LedgerUtilsTests, StrToType)
|
||||||
{
|
{
|
||||||
EXPECT_EQ(util::getLedgerEntryTypeFromStr("mess"), ripple::ltANY);
|
EXPECT_EQ(util::LedgerTypes::GetLedgerEntryTypeFromStr("mess"), ripple::ltANY);
|
||||||
EXPECT_EQ(util::getLedgerEntryTypeFromStr("tomato"), ripple::ltANY);
|
EXPECT_EQ(util::LedgerTypes::GetLedgerEntryTypeFromStr("tomato"), ripple::ltANY);
|
||||||
EXPECT_EQ(util::getLedgerEntryTypeFromStr("account"), ripple::ltACCOUNT_ROOT);
|
EXPECT_EQ(util::LedgerTypes::GetLedgerEntryTypeFromStr("account"), ripple::ltACCOUNT_ROOT);
|
||||||
|
|
||||||
auto const& types = util::getLedgerEntryTypeStrs();
|
auto constexpr types = util::LedgerTypes::GetLedgerEntryTypeStrList();
|
||||||
std::for_each(types.cbegin(), types.cend(), [](auto const& typeStr) {
|
std::for_each(types.cbegin(), types.cend(), [](auto const& typeStr) {
|
||||||
EXPECT_NE(util::getLedgerEntryTypeFromStr(typeStr), ripple::ltANY);
|
EXPECT_NE(util::LedgerTypes::GetLedgerEntryTypeFromStr(typeStr), ripple::ltANY);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LedgerUtilsTests, DeletionBlockerTypes)
|
TEST(LedgerUtilsTests, DeletionBlockerTypes)
|
||||||
{
|
{
|
||||||
auto const& testedTypes = util::getDeletionBlockerLedgerTypes();
|
auto constexpr testedTypes = util::LedgerTypes::GetDeletionBlockerLedgerTypes();
|
||||||
|
|
||||||
static ripple::LedgerEntryType constexpr deletionBlockers[] = {
|
static ripple::LedgerEntryType constexpr deletionBlockers[] = {
|
||||||
ripple::ltCHECK,
|
ripple::ltCHECK,
|
||||||
@@ -87,8 +124,8 @@ TEST(LedgerUtilsTests, DeletionBlockerTypes)
|
|||||||
ripple::ltBRIDGE
|
ripple::ltBRIDGE
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSERT_TRUE(std::size(deletionBlockers) == testedTypes.size());
|
static_assert(std::size(deletionBlockers) == testedTypes.size());
|
||||||
EXPECT_TRUE(std::any_of(testedTypes.cbegin(), testedTypes.cend(), [](auto const& type) {
|
static_assert(std::any_of(testedTypes.cbegin(), testedTypes.cend(), [](auto const& type) {
|
||||||
return std::find(std::cbegin(deletionBlockers), std::cend(deletionBlockers), type) !=
|
return std::find(std::cbegin(deletionBlockers), std::cend(deletionBlockers), type) !=
|
||||||
std::cend(deletionBlockers);
|
std::cend(deletionBlockers);
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user