mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Add account_offers paging (RIPD-344)
This commit is contained in:
committed by
Nik Bougalis
parent
cd1bd18a49
commit
d78f740250
@@ -801,7 +801,7 @@ public:
|
|||||||
{ "account_currencies", &RPCParser::parseAccountCurrencies, 1, 2 },
|
{ "account_currencies", &RPCParser::parseAccountCurrencies, 1, 2 },
|
||||||
{ "account_info", &RPCParser::parseAccountItems, 1, 2 },
|
{ "account_info", &RPCParser::parseAccountItems, 1, 2 },
|
||||||
{ "account_lines", &RPCParser::parseAccountLines, 1, 5 },
|
{ "account_lines", &RPCParser::parseAccountLines, 1, 5 },
|
||||||
{ "account_offers", &RPCParser::parseAccountItems, 1, 2 },
|
{ "account_offers", &RPCParser::parseAccountItems, 1, 4 },
|
||||||
{ "account_tx", &RPCParser::parseAccountTransactions, 1, 8 },
|
{ "account_tx", &RPCParser::parseAccountTransactions, 1, 8 },
|
||||||
{ "book_offers", &RPCParser::parseBookOffers, 2, 7 },
|
{ "book_offers", &RPCParser::parseBookOffers, 2, 7 },
|
||||||
{ "connect", &RPCParser::parseConnect, 1, 2 },
|
{ "connect", &RPCParser::parseConnect, 1, 2 },
|
||||||
|
|||||||
@@ -17,49 +17,41 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <ripple/rpc/impl/Tuning.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
static void offerAdder (Json::Value& jvLines, SLE::ref offer)
|
|
||||||
{
|
|
||||||
if (offer->getType () == ltOFFER)
|
|
||||||
{
|
|
||||||
Json::Value& obj = jvLines.append (Json::objectValue);
|
|
||||||
offer->getFieldAmount (sfTakerPays).setJson (obj[jss::taker_pays]);
|
|
||||||
offer->getFieldAmount (sfTakerGets).setJson (obj[jss::taker_gets]);
|
|
||||||
obj[jss::seq] = offer->getFieldU32 (sfSequence);
|
|
||||||
obj[jss::flags] = offer->getFieldU32 (sfFlags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// {
|
// {
|
||||||
// account: <account>|<account_public_key>
|
// account: <account>|<account_public_key>
|
||||||
// account_index: <number> // optional, defaults to 0.
|
// account_index: <number> // optional, defaults to 0.
|
||||||
// ledger_hash : <ledger>
|
// ledger_hash : <ledger>
|
||||||
// ledger_index : <ledger_index>
|
// ledger_index : <ledger_index>
|
||||||
|
// limit: integer // optional
|
||||||
|
// marker: opaque // optional, resume previous query
|
||||||
// }
|
// }
|
||||||
Json::Value doAccountOffers (RPC::Context& context)
|
Json::Value doAccountOffers (RPC::Context& context)
|
||||||
{
|
{
|
||||||
Ledger::pointer ledger;
|
auto const& params (context.params_);
|
||||||
Json::Value result
|
|
||||||
= RPC::lookupLedger (context.params_, ledger, context.netOps_);
|
|
||||||
|
|
||||||
if (!ledger)
|
Ledger::pointer ledger;
|
||||||
|
Json::Value result (RPC::lookupLedger (params, ledger, context.netOps_));
|
||||||
|
|
||||||
|
if (! ledger)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (!context.params_.isMember (jss::account))
|
if (! params.isMember (jss::account))
|
||||||
return RPC::missing_field_error ("account");
|
return RPC::missing_field_error ("account");
|
||||||
|
|
||||||
std::string strIdent = context.params_[jss::account].asString ();
|
std::string strIdent (params[jss::account].asString ());
|
||||||
bool bIndex = context.params_.isMember (jss::account_index);
|
bool bIndex (params.isMember (jss::account_index));
|
||||||
int iIndex = bIndex ? context.params_[jss::account_index].asUInt () : 0;
|
int iIndex (bIndex ? params[jss::account_index].asUInt () : 0);
|
||||||
|
|
||||||
RippleAddress raAccount;
|
RippleAddress raAccount;
|
||||||
|
|
||||||
result = RPC::accountFromString (
|
result = RPC::accountFromString (
|
||||||
ledger, raAccount, bIndex, strIdent, iIndex, false, context.netOps_);
|
ledger, raAccount, bIndex, strIdent, iIndex, false, context.netOps_);
|
||||||
|
|
||||||
if (!result.empty ())
|
if (! result.empty ())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
// Get info on account.
|
// Get info on account.
|
||||||
@@ -69,17 +61,116 @@ Json::Value doAccountOffers (RPC::Context& context)
|
|||||||
if (bIndex)
|
if (bIndex)
|
||||||
result[jss::account_index] = iIndex;
|
result[jss::account_index] = iIndex;
|
||||||
|
|
||||||
if (!ledger->hasAccount (raAccount))
|
if (! ledger->hasAccount (raAccount))
|
||||||
return rpcError (rpcACT_NOT_FOUND);
|
return rpcError (rpcACT_NOT_FOUND);
|
||||||
|
|
||||||
|
unsigned int limit;
|
||||||
|
if (params.isMember (jss::limit))
|
||||||
|
{
|
||||||
|
limit = std::max (RPC::Tuning::minOffersPerRequest,
|
||||||
|
std::min (params[jss::limit].asUInt (),
|
||||||
|
RPC::Tuning::maxOffersPerRequest));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
limit = RPC::Tuning::defaultOffersPerRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint256 const rootIndex (Ledger::getOwnerDirIndex (raAccount.getAccountID ()));
|
||||||
|
std::uint32_t resumeSeq;
|
||||||
|
uint256 currentIndex;
|
||||||
|
bool resume (true);
|
||||||
|
|
||||||
|
if (params.isMember (jss::marker))
|
||||||
|
{
|
||||||
|
Json::Value const& marker (params[jss::marker]);
|
||||||
|
|
||||||
|
if (! marker.isObject () || marker.size () != 2 ||
|
||||||
|
! marker.isMember (jss::seq) || ! marker[jss::seq].isIntegral () ||
|
||||||
|
! marker.isMember (jss::account_index) ||
|
||||||
|
! marker[jss::account_index].isString ())
|
||||||
|
{
|
||||||
|
return rpcError (rpcACT_MALFORMED);
|
||||||
|
}
|
||||||
|
|
||||||
|
resumeSeq = marker[jss::seq].asUInt ();
|
||||||
|
currentIndex = Ledger::getDirNodeIndex (rootIndex,
|
||||||
|
uintFromHex (marker[jss::account_index].asString ()));
|
||||||
|
|
||||||
|
resume = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentIndex = rootIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value& jvsOffers(result[jss::offers] = Json::arrayValue);
|
||||||
|
unsigned int i (0);
|
||||||
|
bool process (true);
|
||||||
|
|
||||||
|
while (process)
|
||||||
|
{
|
||||||
|
SLE::pointer ownerDir (ledger->getSLEi (currentIndex));
|
||||||
|
|
||||||
|
if (!ownerDir || ownerDir->getType () != ltDIR_NODE)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (auto const& node : ownerDir->getFieldV256 (sfIndexes).peekValue ())
|
||||||
|
{
|
||||||
|
SLE::ref offer (ledger->getSLEi (node));
|
||||||
|
|
||||||
|
if (offer->getType () == ltOFFER)
|
||||||
|
{
|
||||||
|
std::uint32_t const seq (offer->getFieldU32 (sfSequence));
|
||||||
|
|
||||||
|
if (!resume && resumeSeq == seq)
|
||||||
|
resume = true;
|
||||||
|
|
||||||
|
if (resume)
|
||||||
|
{
|
||||||
|
if (i < limit)
|
||||||
|
{
|
||||||
|
Json::Value& obj (jvsOffers.append (Json::objectValue));
|
||||||
|
offer->getFieldAmount (sfTakerPays).setJson (
|
||||||
|
obj[jss::taker_pays]);
|
||||||
|
offer->getFieldAmount (sfTakerGets).setJson (
|
||||||
|
obj[jss::taker_gets]);
|
||||||
|
obj[jss::seq] = seq;
|
||||||
|
obj[jss::flags] = offer->getFieldU32 (sfFlags);
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result[jss::limit] = limit;
|
||||||
|
|
||||||
|
Json::Value& marker (result[jss::marker] = Json::objectValue);
|
||||||
|
marker[jss::seq] = seq;
|
||||||
|
marker[jss::account_index] = strHex(
|
||||||
|
ownerDir->getFieldU64 (sfIndexPrevious));
|
||||||
|
|
||||||
|
process = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process)
|
||||||
|
{
|
||||||
|
std::uint64_t const uNodeNext(ownerDir->getFieldU64(sfIndexNext));
|
||||||
|
|
||||||
|
if (!uNodeNext)
|
||||||
|
break;
|
||||||
|
|
||||||
|
currentIndex = Ledger::getDirNodeIndex(rootIndex, uNodeNext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resume)
|
||||||
|
return rpcError (rpcACT_MALFORMED);
|
||||||
|
|
||||||
Json::Value& jvsOffers = (result[jss::offers] = Json::arrayValue);
|
|
||||||
auto adder = std::bind (
|
|
||||||
&offerAdder,
|
|
||||||
std::ref (jvsOffers),
|
|
||||||
std::placeholders::_1);
|
|
||||||
ledger->visitAccountItems (raAccount.getAccountID (), adder);
|
|
||||||
context.loadType_ = Resource::feeMediumBurdenRPC;
|
context.loadType_ = Resource::feeMediumBurdenRPC;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user