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::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

View File

@@ -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(

View File

@@ -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 ||

View File

@@ -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);

View File

@@ -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);

View File

@@ -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));

View File

@@ -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);

View File

@@ -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())

View File

@@ -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);

View File

@@ -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;
} }

View File

@@ -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 ==