Fix nft_sell_offers/nft_buy_offers limit and marker correctness (#342)

Fixes #335
This commit is contained in:
Alex Kremer
2022-11-02 20:20:48 +01:00
committed by GitHub
parent 9b74b3f898
commit 8cc2de5643
11 changed files with 53 additions and 45 deletions

View File

@@ -661,7 +661,7 @@ traverseOwnedNodes(
std::uint32_t limit,
std::optional<std::string> jsonCursor,
boost::asio::yield_context& yield,
std::function<void(ripple::SLE)> atOwnedNode)
std::function<void(ripple::SLE&&)> atOwnedNode)
{
auto parsedCursor =
parseAccountCursor(backend, sequence, jsonCursor, accountID, yield);
@@ -693,7 +693,7 @@ traverseOwnedNodes(
std::uint32_t limit,
std::optional<std::string> jsonCursor,
boost::asio::yield_context& yield,
std::function<void(ripple::SLE)> atOwnedNode)
std::function<void(ripple::SLE&&)> atOwnedNode)
{
auto cursor = AccountCursor({beast::zero, 0});
@@ -832,9 +832,7 @@ traverseOwnedNodes(
for (auto i = 0; i < objects.size(); ++i)
{
ripple::SerialIter it{objects[i].data(), objects[i].size()};
ripple::SLE sle(it, keys[i]);
atOwnedNode(sle);
atOwnedNode(ripple::SLE{it, keys[i]});
}
if (limit == 0)

View File

@@ -100,7 +100,7 @@ traverseOwnedNodes(
std::uint32_t limit,
std::optional<std::string> jsonCursor,
boost::asio::yield_context& yield,
std::function<void(ripple::SLE)> atOwnedNode);
std::function<void(ripple::SLE&&)> atOwnedNode);
std::variant<Status, AccountCursor>
traverseOwnedNodes(
@@ -112,7 +112,7 @@ traverseOwnedNodes(
std::uint32_t limit,
std::optional<std::string> jsonCursor,
boost::asio::yield_context& yield,
std::function<void(ripple::SLE)> atOwnedNode);
std::function<void(ripple::SLE&&)> atOwnedNode);
std::shared_ptr<ripple::SLE const>
read(

View File

@@ -87,7 +87,7 @@ doAccountChannels(Context const& context)
response[JS(channels)] = boost::json::value(boost::json::array_kind);
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 &&
sle.getAccountID(ripple::sfAccount) == accountID &&
(!destAccount ||

View File

@@ -35,7 +35,7 @@ doAccountCurrencies(Context const& context)
return Status{Error::rpcACT_NOT_FOUND, "accountNotFound"};
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)
{
ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance);

View File

@@ -133,7 +133,7 @@ doAccountLines(Context const& context)
response[JS(lines)] = boost::json::value(boost::json::array_kind);
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)
{
addLine(jsonLines, sle, accountID, peerAccount);

View File

@@ -179,7 +179,7 @@ doAccountObjects(Context const& context)
boost::json::array& jsonObjects =
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())
{
jsonObjects.push_back(toJson(sle));

View File

@@ -105,7 +105,7 @@ doAccountOffers(Context const& context)
response[JS(offers)] = boost::json::value(boost::json::array_kind);
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)
{
addOffer(jsonLines, sle);

View File

@@ -202,10 +202,7 @@ private:
};
void
tag_invoke(
const json::value_from_tag&,
json::value& jv,
BookChange const& change)
tag_invoke(json::value_from_tag, json::value& jv, BookChange const& change)
{
auto amountStr = [](STAmount const& amount) -> std::string {
return isXRP(amount) ? to_string(amount.xrp())

View File

@@ -79,7 +79,7 @@ doGatewayBalances(Context const& context)
}
// 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)
{
ripple::STAmount balance = sle.getFieldAmount(ripple::sfBalance);

View File

@@ -8,30 +8,38 @@
#include <algorithm>
#include <rpc/RPCHelpers.h>
namespace RPC {
namespace json = boost::json;
static void
appendNftOfferJson(ripple::SLE const& offer, boost::json::array& offers)
namespace ripple {
void
tag_invoke(json::value_from_tag, json::value& jv, SLE const& offer)
{
offers.push_back(boost::json::object_kind);
boost::json::object& obj(offers.back().as_object());
auto amount = ::RPC::toBoostJson(
offer.getFieldAmount(sfAmount).getJson(JsonOptions::none));
obj[JS(nft_offer_index)] = ripple::to_string(offer.key());
obj[JS(flags)] = (offer)[ripple::sfFlags];
obj[JS(owner)] = ripple::toBase58(offer.getAccountID(ripple::sfOwner));
json::object obj = {
{JS(nft_offer_index), to_string(offer.key())},
{JS(flags), offer[sfFlags]},
{JS(owner), toBase58(offer.getAccountID(sfOwner))},
{JS(amount), std::move(amount)},
};
if (offer.isFieldPresent(ripple::sfDestination))
obj[JS(destination)] =
ripple::toBase58(offer.getAccountID(ripple::sfDestination));
if (offer.isFieldPresent(sfDestination))
obj.insert_or_assign(
JS(destination), toBase58(offer.getAccountID(sfDestination)));
if (offer.isFieldPresent(ripple::sfExpiration))
obj[JS(expiration)] = offer.getFieldU32(ripple::sfExpiration);
if (offer.isFieldPresent(sfExpiration))
obj.insert_or_assign(JS(expiration), offer.getFieldU32(sfExpiration));
obj[JS(amount)] = toBoostJson(offer.getFieldAmount(ripple::sfAmount)
.getJson(ripple::JsonOptions::none));
jv = std::move(obj);
}
static Result
} // namespace ripple
namespace RPC {
Result
enumerateNFTOffers(
Context const& context,
ripple::uint256 const& tokenid,
@@ -55,13 +63,11 @@ enumerateNFTOffers(
return status;
boost::json::object response = {};
boost::json::array jsonOffers = {};
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::uint64_t reserve(limit);
auto reserve = limit;
ripple::uint256 cursor;
if (request.contains(JS(marker)))
@@ -85,7 +91,7 @@ enumerateNFTOffers(
if (tokenid != sle->getFieldH256(ripple::sfNFTokenID))
return Status{Error::rpcINVALID_PARAMS, "invalidTokenid"};
appendNftOfferJson(*sle, jsonOffers);
jsonOffers.push_back(json::value_from(*sle));
offers.reserve(reserve);
}
else
@@ -100,13 +106,13 @@ enumerateNFTOffers(
cursor,
0,
lgrInfo.seq,
limit,
reserve,
{},
context.yield,
[&offers](ripple::SLE const& offer) {
[&offers](ripple::SLE&& offer) {
if (offer.getType() == ripple::ltNFTOKEN_OFFER)
{
offers.emplace_back(offer);
offers.push_back(std::move(offer));
return true;
}
@@ -123,9 +129,16 @@ enumerateNFTOffers(
offers.pop_back();
}
for (auto const& offer : offers)
appendNftOfferJson(offer, jsonOffers);
std::transform(
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;
}

View File

@@ -100,7 +100,7 @@ doNoRippleCheck(Context const& context)
&accountSeq,
&limit,
&accountID,
&problems](auto const& ownedItem) {
&problems](ripple::SLE&& ownedItem) {
if (ownedItem.getType() == ripple::ltRIPPLE_STATE)
{
bool const bLow = accountID ==