mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 01:07:54 +00:00
Add 'type' param to ledger_data and ledger rpc commands (RIPD-1446):
The 'type' field allows the rpc client to specify what type of ledger
entries to retrieve. The available types are:
"account"
"amendments"
"directory"
"fee"
"hashes"
"offer"
"signer_list"
"state"
"ticket"
This commit is contained in:
committed by
Nik Bougalis
parent
fab3ec0b56
commit
1a7a6f22e2
@@ -31,17 +31,12 @@ namespace ripple {
|
|||||||
|
|
||||||
struct LedgerFill
|
struct LedgerFill
|
||||||
{
|
{
|
||||||
LedgerFill (ReadView const& l, int o = 0)
|
LedgerFill (ReadView const& l, int o = 0, std::vector<TxQ::TxDetails> q = {},
|
||||||
|
LedgerEntryType t = ltINVALID)
|
||||||
: ledger (l)
|
: ledger (l)
|
||||||
, options (o)
|
, options (o)
|
||||||
{
|
, txQueue(std::move(q))
|
||||||
}
|
, type (t)
|
||||||
|
|
||||||
LedgerFill(ReadView const& l, int o,
|
|
||||||
std::vector<TxQ::TxDetails> q)
|
|
||||||
: ledger(l)
|
|
||||||
, options(o)
|
|
||||||
, txQueue(q)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,6 +53,7 @@ struct LedgerFill
|
|||||||
ReadView const& ledger;
|
ReadView const& ledger;
|
||||||
int options;
|
int options;
|
||||||
std::vector<TxQ::TxDetails> txQueue;
|
std::vector<TxQ::TxDetails> txQueue;
|
||||||
|
LedgerEntryType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Given a Ledger and options, fill a Json::Object or Json::Value with a
|
/** Given a Ledger and options, fill a Json::Object or Json::Value with a
|
||||||
|
|||||||
@@ -170,16 +170,19 @@ void fillJsonState(Object& json, LedgerFill const& fill)
|
|||||||
|
|
||||||
for(auto const& sle : ledger.sles)
|
for(auto const& sle : ledger.sles)
|
||||||
{
|
{
|
||||||
if (binary)
|
if (fill.type == ltINVALID || sle->getType () == fill.type)
|
||||||
{
|
{
|
||||||
auto&& obj = appendObject(array);
|
if (binary)
|
||||||
obj[jss::hash] = to_string(sle->key());
|
{
|
||||||
obj[jss::tx_blob] = serializeHex(*sle);
|
auto&& obj = appendObject(array);
|
||||||
|
obj[jss::hash] = to_string(sle->key());
|
||||||
|
obj[jss::tx_blob] = serializeHex(*sle);
|
||||||
|
}
|
||||||
|
else if (expanded)
|
||||||
|
array.append(sle->getJson(0));
|
||||||
|
else
|
||||||
|
array.append(to_string(sle->key()));
|
||||||
}
|
}
|
||||||
else if (expanded)
|
|
||||||
array.append(sle->getJson(0));
|
|
||||||
else
|
|
||||||
array.append(to_string(sle->key()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#define RIPPLE_PROTOCOL_LEDGERFORMATS_H_INCLUDED
|
#define RIPPLE_PROTOCOL_LEDGERFORMATS_H_INCLUDED
|
||||||
|
|
||||||
#include <ripple/protocol/KnownFormats.h>
|
#include <ripple/protocol/KnownFormats.h>
|
||||||
|
#include <ripple/rpc/Status.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -163,6 +164,9 @@ private:
|
|||||||
void addCommonFields (Item& item);
|
void addCommonFields (Item& item);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::pair<RPC::Status, LedgerEntryType>
|
||||||
|
chooseLedgerEntryType(Json::Value const& params);
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,12 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include <BeastConfig.h>
|
#include <BeastConfig.h>
|
||||||
|
#include <ripple/protocol/ErrorCodes.h>
|
||||||
|
#include <ripple/protocol/JsonFields.h>
|
||||||
#include <ripple/protocol/LedgerFormats.h>
|
#include <ripple/protocol/LedgerFormats.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -165,4 +170,49 @@ LedgerFormats::getInstance ()
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<RPC::Status, LedgerEntryType>
|
||||||
|
chooseLedgerEntryType(Json::Value const& params)
|
||||||
|
{
|
||||||
|
std::pair<RPC::Status, LedgerEntryType> result{RPC::Status::OK, ltINVALID};
|
||||||
|
if (params.isMember(jss::type))
|
||||||
|
{
|
||||||
|
static
|
||||||
|
std::array<std::pair<char const *, LedgerEntryType>, 9> const types
|
||||||
|
{{
|
||||||
|
{ jss::account, ltACCOUNT_ROOT },
|
||||||
|
{ jss::amendments, ltAMENDMENTS },
|
||||||
|
{ jss::directory, ltDIR_NODE },
|
||||||
|
{ jss::fee, ltFEE_SETTINGS },
|
||||||
|
{ jss::hashes, ltLEDGER_HASHES },
|
||||||
|
{ jss::offer, ltOFFER },
|
||||||
|
{ jss::signer_list, ltSIGNER_LIST },
|
||||||
|
{ jss::state, ltRIPPLE_STATE },
|
||||||
|
{ jss::ticket, ltTICKET }
|
||||||
|
}};
|
||||||
|
|
||||||
|
auto const& p = params[jss::type];
|
||||||
|
if (!p.isString())
|
||||||
|
{
|
||||||
|
result.first = RPC::Status{rpcINVALID_PARAMS,
|
||||||
|
"Invalid field 'type', not string."};
|
||||||
|
assert(result.first.type() == RPC::Status::Type::error_code_i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const filter = p.asString ();
|
||||||
|
auto iter = std::find_if (types.begin (), types.end (),
|
||||||
|
[&filter](decltype (types.front ())& t)
|
||||||
|
{ return t.first == filter; });
|
||||||
|
if (iter == types.end ())
|
||||||
|
{
|
||||||
|
result.first = RPC::Status{rpcINVALID_PARAMS,
|
||||||
|
"Invalid field 'type'."};
|
||||||
|
assert(result.first.type() == RPC::Status::Type::error_code_i);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.second = iter->second;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
using Code = int;
|
using Code = int;
|
||||||
using Strings = std::vector <std::string>;
|
using Strings = std::vector <std::string>;
|
||||||
|
|
||||||
static const Code OK = 0;
|
static constexpr Code OK = 0;
|
||||||
|
|
||||||
Status () = default;
|
Status () = default;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <ripple/protocol/ErrorCodes.h>
|
#include <ripple/protocol/ErrorCodes.h>
|
||||||
#include <ripple/protocol/Indexes.h>
|
#include <ripple/protocol/Indexes.h>
|
||||||
#include <ripple/protocol/JsonFields.h>
|
#include <ripple/protocol/JsonFields.h>
|
||||||
|
#include <ripple/protocol/LedgerFormats.h>
|
||||||
#include <ripple/resource/Fees.h>
|
#include <ripple/resource/Fees.h>
|
||||||
#include <ripple/rpc/Context.h>
|
#include <ripple/rpc/Context.h>
|
||||||
#include <ripple/rpc/impl/RPCHelpers.h>
|
#include <ripple/rpc/impl/RPCHelpers.h>
|
||||||
@@ -72,36 +73,12 @@ Json::Value doAccountObjects (RPC::Context& context)
|
|||||||
if (! ledger->exists(keylet::account (accountID)))
|
if (! ledger->exists(keylet::account (accountID)))
|
||||||
return rpcError (rpcACT_NOT_FOUND);
|
return rpcError (rpcACT_NOT_FOUND);
|
||||||
|
|
||||||
auto type = ltINVALID;
|
auto type = chooseLedgerEntryType(params);
|
||||||
if (params.isMember (jss::type))
|
if (type.first)
|
||||||
{
|
{
|
||||||
static
|
result.clear();
|
||||||
std::array<std::pair<char const *, LedgerEntryType>, 9> const
|
type.first.inject(result);
|
||||||
types
|
return result;
|
||||||
{{
|
|
||||||
{ jss::account, ltACCOUNT_ROOT },
|
|
||||||
{ jss::amendments, ltAMENDMENTS },
|
|
||||||
{ jss::directory, ltDIR_NODE },
|
|
||||||
{ jss::fee, ltFEE_SETTINGS },
|
|
||||||
{ jss::hashes, ltLEDGER_HASHES },
|
|
||||||
{ jss::offer, ltOFFER },
|
|
||||||
{ jss::signer_list, ltSIGNER_LIST },
|
|
||||||
{ jss::state, ltRIPPLE_STATE },
|
|
||||||
{ jss::ticket, ltTICKET }
|
|
||||||
}};
|
|
||||||
|
|
||||||
auto const& p = params[jss::type];
|
|
||||||
if (! p.isString ())
|
|
||||||
return RPC::expected_field_error (jss::type, "string");
|
|
||||||
|
|
||||||
auto const filter = p.asString ();
|
|
||||||
auto iter = std::find_if (types.begin (), types.end (),
|
|
||||||
[&filter](decltype (types.front ())& t)
|
|
||||||
{ return t.first == filter; });
|
|
||||||
if (iter == types.end ())
|
|
||||||
return RPC::invalid_field_error (jss::type);
|
|
||||||
|
|
||||||
type = iter->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int limit;
|
unsigned int limit;
|
||||||
@@ -131,7 +108,7 @@ Json::Value doAccountObjects (RPC::Context& context)
|
|||||||
return RPC::invalid_field_error (jss::marker);
|
return RPC::invalid_field_error (jss::marker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! RPC::getAccountObjects (*ledger, accountID, type,
|
if (! RPC::getAccountObjects (*ledger, accountID, type.second,
|
||||||
dirIndex, entryIndex, limit, result))
|
dirIndex, entryIndex, limit, result))
|
||||||
{
|
{
|
||||||
result[jss::account_objects] = Json::arrayValue;
|
result[jss::account_objects] = Json::arrayValue;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <ripple/ledger/ReadView.h>
|
#include <ripple/ledger/ReadView.h>
|
||||||
#include <ripple/protocol/ErrorCodes.h>
|
#include <ripple/protocol/ErrorCodes.h>
|
||||||
#include <ripple/protocol/JsonFields.h>
|
#include <ripple/protocol/JsonFields.h>
|
||||||
|
#include <ripple/protocol/LedgerFormats.h>
|
||||||
#include <ripple/rpc/impl/RPCHelpers.h>
|
#include <ripple/rpc/impl/RPCHelpers.h>
|
||||||
#include <ripple/rpc/impl/Tuning.h>
|
#include <ripple/rpc/impl/Tuning.h>
|
||||||
#include <ripple/rpc/Context.h>
|
#include <ripple/rpc/Context.h>
|
||||||
@@ -34,6 +35,7 @@ namespace ripple {
|
|||||||
// limit: integer, maximum number of entries
|
// limit: integer, maximum number of entries
|
||||||
// marker: opaque, resume point
|
// marker: opaque, resume point
|
||||||
// binary: boolean, format
|
// binary: boolean, format
|
||||||
|
// type: string // optional, defaults to all ledger node types
|
||||||
// Outputs:
|
// Outputs:
|
||||||
// ledger_hash: chosen ledger's hash
|
// ledger_hash: chosen ledger's hash
|
||||||
// ledger_index: chosen ledger's index
|
// ledger_index: chosen ledger's index
|
||||||
@@ -84,6 +86,13 @@ Json::Value doLedgerData (RPC::Context& context)
|
|||||||
LedgerFill::Options::binary : 0));
|
LedgerFill::Options::binary : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto type = chooseLedgerEntryType(params);
|
||||||
|
if (type.first)
|
||||||
|
{
|
||||||
|
jvResult.clear();
|
||||||
|
type.first.inject(jvResult);
|
||||||
|
return jvResult;
|
||||||
|
}
|
||||||
Json::Value& nodes = jvResult[jss::state];
|
Json::Value& nodes = jvResult[jss::state];
|
||||||
|
|
||||||
auto e = lpLedger->sles.end();
|
auto e = lpLedger->sles.end();
|
||||||
@@ -98,16 +107,19 @@ Json::Value doLedgerData (RPC::Context& context)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBinary)
|
if (type.second == ltINVALID || sle->getType () == type.second)
|
||||||
{
|
{
|
||||||
Json::Value& entry = nodes.append (Json::objectValue);
|
if (isBinary)
|
||||||
entry[jss::data] = serializeHex(*sle);
|
{
|
||||||
entry[jss::index] = to_string(sle->key());
|
Json::Value& entry = nodes.append (Json::objectValue);
|
||||||
}
|
entry[jss::data] = serializeHex(*sle);
|
||||||
else
|
entry[jss::index] = to_string(sle->key());
|
||||||
{
|
}
|
||||||
Json::Value& entry = nodes.append (sle->getJson (0));
|
else
|
||||||
entry[jss::index] = to_string(sle->key());
|
{
|
||||||
|
Json::Value& entry = nodes.append (sle->getJson (0));
|
||||||
|
entry[jss::index] = to_string(sle->key());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ Status LedgerHandler::check()
|
|||||||
bool const binary = params[jss::binary].asBool();
|
bool const binary = params[jss::binary].asBool();
|
||||||
bool const owner_funds = params[jss::owner_funds].asBool();
|
bool const owner_funds = params[jss::owner_funds].asBool();
|
||||||
bool const queue = params[jss::queue].asBool();
|
bool const queue = params[jss::queue].asBool();
|
||||||
|
auto type = chooseLedgerEntryType(params);
|
||||||
|
if (type.first)
|
||||||
|
return type.first;
|
||||||
|
type_ = type.second;
|
||||||
|
|
||||||
options_ = (full ? LedgerFill::full : 0)
|
options_ = (full ? LedgerFill::full : 0)
|
||||||
| (expand ? LedgerFill::expand : 0)
|
| (expand ? LedgerFill::expand : 0)
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ private:
|
|||||||
std::vector<TxQ::TxDetails> queueTxs_;
|
std::vector<TxQ::TxDetails> queueTxs_;
|
||||||
Json::Value result_;
|
Json::Value result_;
|
||||||
int options_ = 0;
|
int options_ = 0;
|
||||||
|
LedgerEntryType type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -89,7 +90,7 @@ void LedgerHandler::writeResult (Object& value)
|
|||||||
if (ledger_)
|
if (ledger_)
|
||||||
{
|
{
|
||||||
Json::copyFrom (value, result_);
|
Json::copyFrom (value, result_);
|
||||||
addJson (value, {*ledger_, options_, queueTxs_});
|
addJson (value, {*ledger_, options_, queueTxs_, type_});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ error_code_i fillHandler (Context& context,
|
|||||||
|
|
||||||
JLOG (context.j.trace()) << "COMMAND:" << strCommand;
|
JLOG (context.j.trace()) << "COMMAND:" << strCommand;
|
||||||
JLOG (context.j.trace()) << "REQUEST:" << context.params;
|
JLOG (context.j.trace()) << "REQUEST:" << context.params;
|
||||||
|
|
||||||
auto handler = getHandler(strCommand);
|
auto handler = getHandler(strCommand);
|
||||||
|
|
||||||
if (!handler)
|
if (!handler)
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
namespace ripple {
|
namespace ripple {
|
||||||
namespace RPC {
|
namespace RPC {
|
||||||
|
|
||||||
|
constexpr Status::Code Status::OK;
|
||||||
|
|
||||||
std::string Status::codeString () const
|
std::string Status::codeString () const
|
||||||
{
|
{
|
||||||
if (!*this)
|
if (!*this)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include <ripple/basics/StringUtilities.h>
|
#include <ripple/basics/StringUtilities.h>
|
||||||
|
#include <ripple/protocol/Feature.h>
|
||||||
#include <ripple/protocol/JsonFields.h>
|
#include <ripple/protocol/JsonFields.h>
|
||||||
#include <test/jtx.h>
|
#include <test/jtx.h>
|
||||||
|
|
||||||
@@ -58,7 +59,6 @@ public:
|
|||||||
}
|
}
|
||||||
env.close();
|
env.close();
|
||||||
|
|
||||||
// no limit specified
|
|
||||||
// with no limit specified, we get the max_limit if the total number of
|
// with no limit specified, we get the max_limit if the total number of
|
||||||
// accounts is greater than max, which it is here
|
// accounts is greater than max, which it is here
|
||||||
Json::Value jvParams;
|
Json::Value jvParams;
|
||||||
@@ -101,7 +101,6 @@ public:
|
|||||||
}
|
}
|
||||||
env.close();
|
env.close();
|
||||||
|
|
||||||
// no limit specified
|
|
||||||
// with no limit specified, we should get all of our fund entries
|
// with no limit specified, we should get all of our fund entries
|
||||||
// plus three more related to the gateway setup
|
// plus three more related to the gateway setup
|
||||||
Json::Value jvParams;
|
Json::Value jvParams;
|
||||||
@@ -189,7 +188,6 @@ public:
|
|||||||
}
|
}
|
||||||
env.close();
|
env.close();
|
||||||
|
|
||||||
// no limit specified
|
|
||||||
// with no limit specified, we should get all of our fund entries
|
// with no limit specified, we should get all of our fund entries
|
||||||
// plus three more related to the gateway setup
|
// plus three more related to the gateway setup
|
||||||
Json::Value jvParams;
|
Json::Value jvParams;
|
||||||
@@ -264,6 +262,151 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testLedgerType()
|
||||||
|
{
|
||||||
|
// Put a bunch of different LedgerEntryTypes into a ledger
|
||||||
|
using namespace test::jtx;
|
||||||
|
Env env { *this, envconfig(validator, ""),
|
||||||
|
features(featureMultiSign, featureTickets) };
|
||||||
|
Account const gw { "gateway" };
|
||||||
|
auto const USD = gw["USD"];
|
||||||
|
env.fund(XRP(100000), gw);
|
||||||
|
|
||||||
|
int const num_accounts = 10;
|
||||||
|
|
||||||
|
for (auto i = 0; i < num_accounts; i++)
|
||||||
|
{
|
||||||
|
Account const bob { std::string("bob") + std::to_string(i) };
|
||||||
|
env.fund(XRP(1000), bob);
|
||||||
|
}
|
||||||
|
env(offer(Account{"bob0"}, USD(100), XRP(100)));
|
||||||
|
env.trust(Account{"bob2"}["USD"](100), Account{"bob3"});
|
||||||
|
|
||||||
|
auto majorities = getMajorityAmendments(*env.closed());
|
||||||
|
for (int i = 0; i <= 256; ++i)
|
||||||
|
{
|
||||||
|
env.close();
|
||||||
|
majorities = getMajorityAmendments(*env.closed());
|
||||||
|
if (!majorities.empty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
env(signers(Account{"bob0"}, 1, {{Account{"bob1"}, 1}, {Account{"bob2"}, 1}}));
|
||||||
|
env(ticket::create(env.master));
|
||||||
|
env.close();
|
||||||
|
|
||||||
|
// Now fetch each type
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "account";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "account";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 12) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "AccountRoot" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "amendments";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "amendments";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 1) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "Amendments" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "directory";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "directory";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 5) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "DirectoryNode" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "fee";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "fee";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 1) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "FeeSettings" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "hashes";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "hashes";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 2) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "LedgerHashes" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "offer";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "offer";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 1) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "Offer" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "signer_list";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "signer_list";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 1) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "SignerList" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "state";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "state";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 1) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "RippleState" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "ticket";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "ticket";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( checkArraySize(jrr[jss::state], 1) );
|
||||||
|
for (auto const& j : jrr[jss::state])
|
||||||
|
BEAST_EXPECT( j["LedgerEntryType"] == "Ticket" );
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // jvParams[jss::type] = "misspelling";
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = "current";
|
||||||
|
jvParams[jss::type] = "misspelling";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger_data",
|
||||||
|
boost::lexical_cast<std::string>(jvParams)) [jss::result];
|
||||||
|
BEAST_EXPECT( jrr.isMember("error") );
|
||||||
|
BEAST_EXPECT( jrr["error"] == "invalidParams" );
|
||||||
|
BEAST_EXPECT( jrr["error_message"] == "Invalid field 'type'." );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
testCurrentLedgerToLimits(true);
|
testCurrentLedgerToLimits(true);
|
||||||
@@ -272,6 +415,7 @@ public:
|
|||||||
testBadInput();
|
testBadInput();
|
||||||
testMarkerFollow();
|
testMarkerFollow();
|
||||||
testLedgerHeader();
|
testLedgerHeader();
|
||||||
|
testLedgerType();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -652,6 +652,44 @@ class LedgerRPC_test : public beast::unit_test::suite
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testLedgerAccountsType()
|
||||||
|
{
|
||||||
|
testcase("Ledger Request, Accounts Option");
|
||||||
|
using namespace test::jtx;
|
||||||
|
|
||||||
|
Env env {*this};
|
||||||
|
|
||||||
|
env.close();
|
||||||
|
|
||||||
|
std::string index;
|
||||||
|
{
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = 3u;
|
||||||
|
jvParams[jss::accounts] = true;
|
||||||
|
jvParams[jss::expand] = true;
|
||||||
|
jvParams[jss::type] = "hashes";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger", to_string(jvParams) ) [jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u]["LedgerEntryType"]
|
||||||
|
== "LedgerHashes");
|
||||||
|
index = jrr[jss::ledger][jss::accountState][0u]["index"].asString();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Json::Value jvParams;
|
||||||
|
jvParams[jss::ledger_index] = 3u;
|
||||||
|
jvParams[jss::accounts] = true;
|
||||||
|
jvParams[jss::expand] = false;
|
||||||
|
jvParams[jss::type] = "hashes";
|
||||||
|
auto const jrr = env.rpc ( "json", "ledger", to_string(jvParams) ) [jss::result];
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger].isMember(jss::accountState));
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger][jss::accountState].isArray());
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger][jss::accountState].size() == 1u);
|
||||||
|
BEAST_EXPECT(jrr[jss::ledger][jss::accountState][0u] == index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void run ()
|
void run ()
|
||||||
{
|
{
|
||||||
@@ -668,6 +706,7 @@ public:
|
|||||||
testLookupLedger();
|
testLookupLedger();
|
||||||
testNoQueue();
|
testNoQueue();
|
||||||
testQueue();
|
testQueue();
|
||||||
|
testLedgerAccountsType();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user