mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
Fix nft_sell_offers/nft_buy_offers limit and marker correctness (#342)
Fixes #335
This commit is contained in:
@@ -661,7 +661,7 @@ traverseOwnedNodes(
|
|||||||
std::uint32_t limit,
|
std::uint32_t limit,
|
||||||
std::optional<std::string> jsonCursor,
|
std::optional<std::string> jsonCursor,
|
||||||
boost::asio::yield_context& yield,
|
boost::asio::yield_context& yield,
|
||||||
std::function<void(ripple::SLE)> atOwnedNode)
|
std::function<void(ripple::SLE&&)> atOwnedNode)
|
||||||
{
|
{
|
||||||
auto parsedCursor =
|
auto parsedCursor =
|
||||||
parseAccountCursor(backend, sequence, jsonCursor, accountID, yield);
|
parseAccountCursor(backend, sequence, jsonCursor, accountID, yield);
|
||||||
@@ -693,7 +693,7 @@ traverseOwnedNodes(
|
|||||||
std::uint32_t limit,
|
std::uint32_t limit,
|
||||||
std::optional<std::string> jsonCursor,
|
std::optional<std::string> jsonCursor,
|
||||||
boost::asio::yield_context& yield,
|
boost::asio::yield_context& yield,
|
||||||
std::function<void(ripple::SLE)> atOwnedNode)
|
std::function<void(ripple::SLE&&)> atOwnedNode)
|
||||||
{
|
{
|
||||||
auto cursor = AccountCursor({beast::zero, 0});
|
auto cursor = AccountCursor({beast::zero, 0});
|
||||||
|
|
||||||
@@ -832,9 +832,7 @@ traverseOwnedNodes(
|
|||||||
for (auto i = 0; i < objects.size(); ++i)
|
for (auto i = 0; i < objects.size(); ++i)
|
||||||
{
|
{
|
||||||
ripple::SerialIter it{objects[i].data(), objects[i].size()};
|
ripple::SerialIter it{objects[i].data(), objects[i].size()};
|
||||||
ripple::SLE sle(it, keys[i]);
|
atOwnedNode(ripple::SLE{it, keys[i]});
|
||||||
|
|
||||||
atOwnedNode(sle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (limit == 0)
|
if (limit == 0)
|
||||||
@@ -1701,4 +1699,4 @@ traverseTransactions(
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RPC
|
} // namespace RPC
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ traverseOwnedNodes(
|
|||||||
std::uint32_t limit,
|
std::uint32_t limit,
|
||||||
std::optional<std::string> jsonCursor,
|
std::optional<std::string> jsonCursor,
|
||||||
boost::asio::yield_context& yield,
|
boost::asio::yield_context& yield,
|
||||||
std::function<void(ripple::SLE)> atOwnedNode);
|
std::function<void(ripple::SLE&&)> atOwnedNode);
|
||||||
|
|
||||||
std::variant<Status, AccountCursor>
|
std::variant<Status, AccountCursor>
|
||||||
traverseOwnedNodes(
|
traverseOwnedNodes(
|
||||||
@@ -112,7 +112,7 @@ traverseOwnedNodes(
|
|||||||
std::uint32_t limit,
|
std::uint32_t limit,
|
||||||
std::optional<std::string> jsonCursor,
|
std::optional<std::string> jsonCursor,
|
||||||
boost::asio::yield_context& yield,
|
boost::asio::yield_context& yield,
|
||||||
std::function<void(ripple::SLE)> atOwnedNode);
|
std::function<void(ripple::SLE&&)> atOwnedNode);
|
||||||
|
|
||||||
std::shared_ptr<ripple::SLE const>
|
std::shared_ptr<ripple::SLE const>
|
||||||
read(
|
read(
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ doAccountChannels(Context const& context)
|
|||||||
response[JS(channels)] = boost::json::value(boost::json::array_kind);
|
response[JS(channels)] = boost::json::value(boost::json::array_kind);
|
||||||
boost::json::array& jsonChannels = response.at(JS(channels)).as_array();
|
boost::json::array& jsonChannels = response.at(JS(channels)).as_array();
|
||||||
|
|
||||||
auto const addToResponse = [&](ripple::SLE const& sle) {
|
auto const addToResponse = [&](ripple::SLE&& sle) {
|
||||||
if (sle.getType() == ripple::ltPAYCHAN &&
|
if (sle.getType() == ripple::ltPAYCHAN &&
|
||||||
sle.getAccountID(ripple::sfAccount) == accountID &&
|
sle.getAccountID(ripple::sfAccount) == accountID &&
|
||||||
(!destAccount ||
|
(!destAccount ||
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ doAccountCurrencies(Context const& context)
|
|||||||
return Status{Error::rpcACT_NOT_FOUND, "accountNotFound"};
|
return Status{Error::rpcACT_NOT_FOUND, "accountNotFound"};
|
||||||
|
|
||||||
std::set<std::string> send, receive;
|
std::set<std::string> send, receive;
|
||||||
auto const addToResponse = [&](ripple::SLE const& sle) {
|
auto const addToResponse = [&](ripple::SLE&& sle) {
|
||||||
if (sle.getType() == ripple::ltRIPPLE_STATE)
|
if (sle.getType() == ripple::ltRIPPLE_STATE)
|
||||||
{
|
{
|
||||||
ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance);
|
ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ doAccountLines(Context const& context)
|
|||||||
response[JS(lines)] = boost::json::value(boost::json::array_kind);
|
response[JS(lines)] = boost::json::value(boost::json::array_kind);
|
||||||
boost::json::array& jsonLines = response.at(JS(lines)).as_array();
|
boost::json::array& jsonLines = response.at(JS(lines)).as_array();
|
||||||
|
|
||||||
auto const addToResponse = [&](ripple::SLE const& sle) -> void {
|
auto const addToResponse = [&](ripple::SLE&& sle) -> void {
|
||||||
if (sle.getType() == ripple::ltRIPPLE_STATE)
|
if (sle.getType() == ripple::ltRIPPLE_STATE)
|
||||||
{
|
{
|
||||||
addLine(jsonLines, sle, accountID, peerAccount);
|
addLine(jsonLines, sle, accountID, peerAccount);
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ doAccountObjects(Context const& context)
|
|||||||
boost::json::array& jsonObjects =
|
boost::json::array& jsonObjects =
|
||||||
response.at(JS(account_objects)).as_array();
|
response.at(JS(account_objects)).as_array();
|
||||||
|
|
||||||
auto const addToResponse = [&](ripple::SLE const& sle) {
|
auto const addToResponse = [&](ripple::SLE&& sle) {
|
||||||
if (!objectType || objectType == sle.getType())
|
if (!objectType || objectType == sle.getType())
|
||||||
{
|
{
|
||||||
jsonObjects.push_back(toJson(sle));
|
jsonObjects.push_back(toJson(sle));
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ doAccountOffers(Context const& context)
|
|||||||
response[JS(offers)] = boost::json::value(boost::json::array_kind);
|
response[JS(offers)] = boost::json::value(boost::json::array_kind);
|
||||||
boost::json::array& jsonLines = response.at(JS(offers)).as_array();
|
boost::json::array& jsonLines = response.at(JS(offers)).as_array();
|
||||||
|
|
||||||
auto const addToResponse = [&](ripple::SLE const& sle) {
|
auto const addToResponse = [&](ripple::SLE&& sle) {
|
||||||
if (sle.getType() == ripple::ltOFFER)
|
if (sle.getType() == ripple::ltOFFER)
|
||||||
{
|
{
|
||||||
addOffer(jsonLines, sle);
|
addOffer(jsonLines, sle);
|
||||||
|
|||||||
@@ -202,10 +202,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
tag_invoke(
|
tag_invoke(json::value_from_tag, json::value& jv, BookChange const& change)
|
||||||
const json::value_from_tag&,
|
|
||||||
json::value& jv,
|
|
||||||
BookChange const& change)
|
|
||||||
{
|
{
|
||||||
auto amountStr = [](STAmount const& amount) -> std::string {
|
auto amountStr = [](STAmount const& amount) -> std::string {
|
||||||
return isXRP(amount) ? to_string(amount.xrp())
|
return isXRP(amount) ? to_string(amount.xrp())
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ doGatewayBalances(Context const& context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Traverse the cold wallet's trust lines
|
// Traverse the cold wallet's trust lines
|
||||||
auto const addToResponse = [&](ripple::SLE const& sle) {
|
auto const addToResponse = [&](ripple::SLE&& sle) {
|
||||||
if (sle.getType() == ripple::ltRIPPLE_STATE)
|
if (sle.getType() == ripple::ltRIPPLE_STATE)
|
||||||
{
|
{
|
||||||
ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance);
|
ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance);
|
||||||
|
|||||||
@@ -8,30 +8,38 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <rpc/RPCHelpers.h>
|
#include <rpc/RPCHelpers.h>
|
||||||
|
|
||||||
namespace RPC {
|
namespace json = boost::json;
|
||||||
|
|
||||||
static void
|
namespace ripple {
|
||||||
appendNftOfferJson(ripple::SLE const& offer, boost::json::array& offers)
|
|
||||||
|
void
|
||||||
|
tag_invoke(json::value_from_tag, json::value& jv, SLE const& offer)
|
||||||
{
|
{
|
||||||
offers.push_back(boost::json::object_kind);
|
auto amount = ::RPC::toBoostJson(
|
||||||
boost::json::object& obj(offers.back().as_object());
|
offer.getFieldAmount(sfAmount).getJson(JsonOptions::none));
|
||||||
|
|
||||||
obj[JS(nft_offer_index)] = ripple::to_string(offer.key());
|
json::object obj = {
|
||||||
obj[JS(flags)] = (offer)[ripple::sfFlags];
|
{JS(nft_offer_index), to_string(offer.key())},
|
||||||
obj[JS(owner)] = ripple::toBase58(offer.getAccountID(ripple::sfOwner));
|
{JS(flags), offer[sfFlags]},
|
||||||
|
{JS(owner), toBase58(offer.getAccountID(sfOwner))},
|
||||||
|
{JS(amount), std::move(amount)},
|
||||||
|
};
|
||||||
|
|
||||||
if (offer.isFieldPresent(ripple::sfDestination))
|
if (offer.isFieldPresent(sfDestination))
|
||||||
obj[JS(destination)] =
|
obj.insert_or_assign(
|
||||||
ripple::toBase58(offer.getAccountID(ripple::sfDestination));
|
JS(destination), toBase58(offer.getAccountID(sfDestination)));
|
||||||
|
|
||||||
if (offer.isFieldPresent(ripple::sfExpiration))
|
if (offer.isFieldPresent(sfExpiration))
|
||||||
obj[JS(expiration)] = offer.getFieldU32(ripple::sfExpiration);
|
obj.insert_or_assign(JS(expiration), offer.getFieldU32(sfExpiration));
|
||||||
|
|
||||||
obj[JS(amount)] = toBoostJson(offer.getFieldAmount(ripple::sfAmount)
|
jv = std::move(obj);
|
||||||
.getJson(ripple::JsonOptions::none));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result
|
} // namespace ripple
|
||||||
|
|
||||||
|
namespace RPC {
|
||||||
|
|
||||||
|
Result
|
||||||
enumerateNFTOffers(
|
enumerateNFTOffers(
|
||||||
Context const& context,
|
Context const& context,
|
||||||
ripple::uint256 const& tokenid,
|
ripple::uint256 const& tokenid,
|
||||||
@@ -55,13 +63,11 @@ enumerateNFTOffers(
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
boost::json::object response = {};
|
boost::json::object response = {};
|
||||||
|
boost::json::array jsonOffers = {};
|
||||||
response[JS(nft_id)] = ripple::to_string(tokenid);
|
response[JS(nft_id)] = ripple::to_string(tokenid);
|
||||||
response[JS(offers)] = boost::json::value(boost::json::array_kind);
|
|
||||||
|
|
||||||
auto& jsonOffers = response[JS(offers)].as_array();
|
|
||||||
|
|
||||||
std::vector<ripple::SLE> offers;
|
std::vector<ripple::SLE> offers;
|
||||||
std::uint64_t reserve(limit);
|
auto reserve = limit;
|
||||||
ripple::uint256 cursor;
|
ripple::uint256 cursor;
|
||||||
|
|
||||||
if (request.contains(JS(marker)))
|
if (request.contains(JS(marker)))
|
||||||
@@ -85,7 +91,7 @@ enumerateNFTOffers(
|
|||||||
if (tokenid != sle->getFieldH256(ripple::sfNFTokenID))
|
if (tokenid != sle->getFieldH256(ripple::sfNFTokenID))
|
||||||
return Status{Error::rpcINVALID_PARAMS, "invalidTokenid"};
|
return Status{Error::rpcINVALID_PARAMS, "invalidTokenid"};
|
||||||
|
|
||||||
appendNftOfferJson(*sle, jsonOffers);
|
jsonOffers.push_back(json::value_from(*sle));
|
||||||
offers.reserve(reserve);
|
offers.reserve(reserve);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -100,13 +106,13 @@ enumerateNFTOffers(
|
|||||||
cursor,
|
cursor,
|
||||||
0,
|
0,
|
||||||
lgrInfo.seq,
|
lgrInfo.seq,
|
||||||
limit,
|
reserve,
|
||||||
{},
|
{},
|
||||||
context.yield,
|
context.yield,
|
||||||
[&offers](ripple::SLE const& offer) {
|
[&offers](ripple::SLE&& offer) {
|
||||||
if (offer.getType() == ripple::ltNFTOKEN_OFFER)
|
if (offer.getType() == ripple::ltNFTOKEN_OFFER)
|
||||||
{
|
{
|
||||||
offers.emplace_back(offer);
|
offers.push_back(std::move(offer));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +129,16 @@ enumerateNFTOffers(
|
|||||||
offers.pop_back();
|
offers.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& offer : offers)
|
std::transform(
|
||||||
appendNftOfferJson(offer, jsonOffers);
|
std::cbegin(offers),
|
||||||
|
std::cend(offers),
|
||||||
|
std::back_inserter(jsonOffers),
|
||||||
|
[](auto const& offer) {
|
||||||
|
// uses tag_invoke at the top of this file
|
||||||
|
return json::value_from(offer);
|
||||||
|
});
|
||||||
|
|
||||||
|
response.insert_or_assign(JS(offers), std::move(jsonOffers));
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ doNoRippleCheck(Context const& context)
|
|||||||
&accountSeq,
|
&accountSeq,
|
||||||
&limit,
|
&limit,
|
||||||
&accountID,
|
&accountID,
|
||||||
&problems](auto const& ownedItem) {
|
&problems](ripple::SLE&& ownedItem) {
|
||||||
if (ownedItem.getType() == ripple::ltRIPPLE_STATE)
|
if (ownedItem.getType() == ripple::ltRIPPLE_STATE)
|
||||||
{
|
{
|
||||||
bool const bLow = accountID ==
|
bool const bLow = accountID ==
|
||||||
|
|||||||
Reference in New Issue
Block a user