mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-13 07:05:50 +00:00
Server Definitions Cleanup (#174)
* update server-definitions + test * Update ServerDefinitions.cpp * clang-format
This commit is contained in:
@@ -637,6 +637,7 @@ target_sources (rippled PRIVATE
|
|||||||
src/ripple/rpc/handlers/Random.cpp
|
src/ripple/rpc/handlers/Random.cpp
|
||||||
src/ripple/rpc/handlers/Reservations.cpp
|
src/ripple/rpc/handlers/Reservations.cpp
|
||||||
src/ripple/rpc/handlers/RipplePathFind.cpp
|
src/ripple/rpc/handlers/RipplePathFind.cpp
|
||||||
|
src/ripple/rpc/handlers/ServerDefinitions.cpp
|
||||||
src/ripple/rpc/handlers/ServerInfo.cpp
|
src/ripple/rpc/handlers/ServerInfo.cpp
|
||||||
src/ripple/rpc/handlers/ServerState.cpp
|
src/ripple/rpc/handlers/ServerState.cpp
|
||||||
src/ripple/rpc/handlers/SignFor.cpp
|
src/ripple/rpc/handlers/SignFor.cpp
|
||||||
@@ -993,6 +994,7 @@ if (tests)
|
|||||||
src/test/rpc/RPCCall_test.cpp
|
src/test/rpc/RPCCall_test.cpp
|
||||||
src/test/rpc/RPCOverload_test.cpp
|
src/test/rpc/RPCOverload_test.cpp
|
||||||
src/test/rpc/RobustTransaction_test.cpp
|
src/test/rpc/RobustTransaction_test.cpp
|
||||||
|
src/test/rpc/ServerDefinitions_test.cpp
|
||||||
src/test/rpc/ServerInfo_test.cpp
|
src/test/rpc/ServerInfo_test.cpp
|
||||||
src/test/rpc/ShardArchiveHandler_test.cpp
|
src/test/rpc/ShardArchiveHandler_test.cpp
|
||||||
src/test/rpc/Status_test.cpp
|
src/test/rpc/Status_test.cpp
|
||||||
|
|||||||
425
src/ripple/rpc/handlers/ServerDefinitions.cpp
Normal file
425
src/ripple/rpc/handlers/ServerDefinitions.cpp
Normal file
@@ -0,0 +1,425 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012-2014 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <ripple/app/main/Application.h>
|
||||||
|
#include <ripple/app/misc/NetworkOPs.h>
|
||||||
|
#include <ripple/app/reporting/P2pProxy.h>
|
||||||
|
#include <ripple/json/json_value.h>
|
||||||
|
#include <ripple/json/json_writer.h>
|
||||||
|
#include <ripple/net/RPCErr.h>
|
||||||
|
#include <ripple/protocol/LedgerFormats.h>
|
||||||
|
#include <ripple/protocol/SField.h>
|
||||||
|
#include <ripple/protocol/digest.h>
|
||||||
|
#include <ripple/protocol/jss.h>
|
||||||
|
#include <ripple/rpc/impl/TransactionSign.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <magic/magic_enum.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#define MAGIC_ENUM(x) \
|
||||||
|
template <> \
|
||||||
|
struct magic_enum::customize::enum_range<x> \
|
||||||
|
{ \
|
||||||
|
static constexpr int min = -20000; \
|
||||||
|
static constexpr int max = 20000; \
|
||||||
|
};
|
||||||
|
|
||||||
|
MAGIC_ENUM(ripple::SerializedTypeID);
|
||||||
|
MAGIC_ENUM(ripple::LedgerEntryType);
|
||||||
|
MAGIC_ENUM(ripple::TELcodes);
|
||||||
|
MAGIC_ENUM(ripple::TEMcodes);
|
||||||
|
MAGIC_ENUM(ripple::TEFcodes);
|
||||||
|
MAGIC_ENUM(ripple::TERcodes);
|
||||||
|
MAGIC_ENUM(ripple::TEScodes);
|
||||||
|
MAGIC_ENUM(ripple::TECcodes);
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
class Definitions
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Json::Value
|
||||||
|
generate()
|
||||||
|
{
|
||||||
|
// RH TODO: probably a better way to do this?
|
||||||
|
#define STR(x) \
|
||||||
|
([&] { \
|
||||||
|
std::ostringstream ss; \
|
||||||
|
return ss << (x), ss.str(); \
|
||||||
|
}())
|
||||||
|
|
||||||
|
Json::Value ret{Json::objectValue};
|
||||||
|
ret[jss::TYPES] = Json::objectValue;
|
||||||
|
|
||||||
|
auto const translate = [](std::string inp) -> std::string {
|
||||||
|
auto replace = [&](const char* f, const char* r) -> std::string {
|
||||||
|
std::string out = inp;
|
||||||
|
boost::replace_all(out, f, r);
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto find = [&](const char* s) -> bool {
|
||||||
|
return inp.find(s) != std::string::npos;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (find("UINT"))
|
||||||
|
{
|
||||||
|
if (find("256") || find("160") || find("128"))
|
||||||
|
return replace("UINT", "Hash");
|
||||||
|
else
|
||||||
|
return replace("UINT", "UInt");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inp == "OBJECT")
|
||||||
|
return "STObject";
|
||||||
|
if (inp == "ARRAY")
|
||||||
|
return "STArray";
|
||||||
|
if (inp == "AMM")
|
||||||
|
return "AMM";
|
||||||
|
if (inp == "ACCOUNT")
|
||||||
|
return "AccountID";
|
||||||
|
if (inp == "LEDGERENTRY")
|
||||||
|
return "LedgerEntry";
|
||||||
|
if (inp == "NOTPRESENT")
|
||||||
|
return "NotPresent";
|
||||||
|
if (inp == "PATHSET")
|
||||||
|
return "PathSet";
|
||||||
|
if (inp == "VL")
|
||||||
|
return "Blob";
|
||||||
|
if (inp == "DIR_NODE")
|
||||||
|
return "DirectoryNode";
|
||||||
|
if (inp == "PAYCHAN")
|
||||||
|
return "PayChannel";
|
||||||
|
if (inp == "IMPORT_VLSEQ")
|
||||||
|
return "ImportVLSequence";
|
||||||
|
|
||||||
|
static const std::map<std::string, std::string>
|
||||||
|
capitalization_exceptions = {
|
||||||
|
{"NFTOKEN", "NFToken"},
|
||||||
|
{"UNL", "UNL"},
|
||||||
|
{"XCHAIN", "XChain"},
|
||||||
|
{"ID", "ID"},
|
||||||
|
{"AMM", "AMM"},
|
||||||
|
{"URITOKEN", "URIToken"},
|
||||||
|
{"URI", "URI"}};
|
||||||
|
|
||||||
|
std::string out;
|
||||||
|
size_t pos = 0;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
pos = inp.find("_");
|
||||||
|
if (pos == std::string::npos)
|
||||||
|
pos = inp.size();
|
||||||
|
std::string token = inp.substr(0, pos);
|
||||||
|
if (auto const e = capitalization_exceptions.find(token);
|
||||||
|
e != capitalization_exceptions.end())
|
||||||
|
out += e->second;
|
||||||
|
else if (token.size() > 1)
|
||||||
|
{
|
||||||
|
boost::algorithm::to_lower(token);
|
||||||
|
token.data()[0] -= ('a' - 'A');
|
||||||
|
out += token;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
out += token;
|
||||||
|
if (pos == inp.size())
|
||||||
|
break;
|
||||||
|
inp = inp.substr(pos + 1);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
ret[jss::TYPES]["Done"] = -1;
|
||||||
|
std::map<int32_t, std::string> type_map{{-1, "Done"}};
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<SerializedTypeID>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
std::string type_name =
|
||||||
|
translate(name.data() + 4 /* remove STI_ */);
|
||||||
|
int32_t type_value = static_cast<int32_t>(entry.first);
|
||||||
|
ret[jss::TYPES][type_name] = type_value;
|
||||||
|
type_map[type_value] = type_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[jss::LEDGER_ENTRY_TYPES] = Json::objectValue;
|
||||||
|
ret[jss::LEDGER_ENTRY_TYPES][jss::Invalid] = -1;
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<LedgerEntryType>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
std::string type_name = translate(name.data() + 2 /* remove lt_ */);
|
||||||
|
int32_t type_value = static_cast<int32_t>(entry.first);
|
||||||
|
ret[jss::LEDGER_ENTRY_TYPES][type_name] = type_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[jss::FIELDS] = Json::arrayValue;
|
||||||
|
|
||||||
|
uint32_t i = 0;
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "Generic";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 0;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = false;
|
||||||
|
v[jss::type] = "Unknown";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "Invalid";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = -1;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = false;
|
||||||
|
v[jss::type] = "Unknown";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "ObjectEndMarker";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 1;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = true;
|
||||||
|
v[jss::type] = "STObject";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "ArrayEndMarker";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 1;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = true;
|
||||||
|
v[jss::type] = "STArray";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "hash";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 257;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = false;
|
||||||
|
v[jss::type] = "Hash256";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "index";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 258;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = false;
|
||||||
|
v[jss::type] = "Hash256";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "taker_gets_funded";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 258;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = false;
|
||||||
|
v[jss::type] = "Amount";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Json::Value a = Json::arrayValue;
|
||||||
|
a[0U] = "taker_pays_funded";
|
||||||
|
Json::Value v = Json::objectValue;
|
||||||
|
v[jss::nth] = 259;
|
||||||
|
v[jss::isVLEncoded] = false;
|
||||||
|
v[jss::isSerialized] = false;
|
||||||
|
v[jss::isSigningField] = false;
|
||||||
|
v[jss::type] = "Amount";
|
||||||
|
a[1U] = v;
|
||||||
|
ret[jss::FIELDS][i++] = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& [code, f] : ripple::SField::knownCodeToField)
|
||||||
|
{
|
||||||
|
if (f->fieldName == "")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Json::Value innerObj = Json::objectValue;
|
||||||
|
|
||||||
|
uint32_t fc = code & 0xFFU;
|
||||||
|
uint32_t tc = code >> 16U;
|
||||||
|
|
||||||
|
innerObj[jss::nth] = fc;
|
||||||
|
|
||||||
|
innerObj[jss::isVLEncoded] =
|
||||||
|
(tc == 7U /* Blob */ || tc == 8U /* AccountID */ ||
|
||||||
|
tc == 19U /* Vector256 */);
|
||||||
|
|
||||||
|
innerObj[jss::isSerialized] =
|
||||||
|
(tc <
|
||||||
|
10000); /* TRANSACTION, LEDGER_ENTRY, VALIDATION, METADATA */
|
||||||
|
|
||||||
|
innerObj[jss::isSigningField] = f->shouldInclude(false);
|
||||||
|
|
||||||
|
innerObj[jss::type] = type_map[tc];
|
||||||
|
|
||||||
|
Json::Value innerArray = Json::arrayValue;
|
||||||
|
innerArray[0U] = f->fieldName;
|
||||||
|
innerArray[1U] = innerObj;
|
||||||
|
|
||||||
|
ret[jss::FIELDS][i++] = innerArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[jss::TRANSACTION_RESULTS] = Json::objectValue;
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TELcodes>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||||
|
static_cast<int32_t>(entry.first);
|
||||||
|
}
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TEMcodes>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||||
|
static_cast<int32_t>(entry.first);
|
||||||
|
}
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TEFcodes>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||||
|
static_cast<int32_t>(entry.first);
|
||||||
|
}
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TERcodes>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||||
|
static_cast<int32_t>(entry.first);
|
||||||
|
}
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TEScodes>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||||
|
static_cast<int32_t>(entry.first);
|
||||||
|
}
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TECcodes>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
||||||
|
static_cast<int32_t>(entry.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const translate_tt = [](std::string inp) -> std::string {
|
||||||
|
if (inp == "PaychanClaim")
|
||||||
|
return "PaymentChannelClaim";
|
||||||
|
if (inp == "PaychanCreate")
|
||||||
|
return "PaymentChannelCreate";
|
||||||
|
if (inp == "PaychanFund")
|
||||||
|
return "PaymentChannelFund";
|
||||||
|
if (inp == "RegularKeySet")
|
||||||
|
return "SetRegularKey";
|
||||||
|
if (inp == "HookSet")
|
||||||
|
return "SetHook";
|
||||||
|
return inp;
|
||||||
|
};
|
||||||
|
|
||||||
|
ret[jss::TRANSACTION_TYPES] = Json::objectValue;
|
||||||
|
ret[jss::TRANSACTION_TYPES][jss::Invalid] = -1;
|
||||||
|
for (auto const& entry : magic_enum::enum_entries<TxType>())
|
||||||
|
{
|
||||||
|
const auto name = entry.second;
|
||||||
|
std::string type_name = translate_tt(translate(name.data() + 2));
|
||||||
|
int32_t type_value = static_cast<int32_t>(entry.first);
|
||||||
|
ret[jss::TRANSACTION_TYPES][type_name] = type_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret[jss::native_currency_code] = systemCurrencyCode();
|
||||||
|
// generate hash
|
||||||
|
{
|
||||||
|
const std::string out = Json::FastWriter().write(ret);
|
||||||
|
defsHash =
|
||||||
|
ripple::sha512Half(ripple::Slice{out.data(), out.size()});
|
||||||
|
ret[jss::hash] = to_string(*defsHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<uint256> defsHash;
|
||||||
|
Json::Value defs;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Definitions() : defs(generate()){};
|
||||||
|
|
||||||
|
bool
|
||||||
|
hashMatches(uint256 hash) const
|
||||||
|
{
|
||||||
|
return defsHash && *defsHash == hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value const&
|
||||||
|
operator()(void) const
|
||||||
|
{
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Json::Value
|
||||||
|
doServerDefinitions(RPC::JsonContext& context)
|
||||||
|
{
|
||||||
|
auto& params = context.params;
|
||||||
|
|
||||||
|
uint256 hash;
|
||||||
|
if (params.isMember(jss::hash))
|
||||||
|
{
|
||||||
|
if (!params[jss::hash].isString() ||
|
||||||
|
!hash.parseHex(params[jss::hash].asString()))
|
||||||
|
return RPC::invalid_field_error(jss::hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Definitions defs{};
|
||||||
|
if (defs.hashMatches(hash))
|
||||||
|
{
|
||||||
|
Json::Value jv = Json::objectValue;
|
||||||
|
jv[jss::hash] = to_string(hash);
|
||||||
|
return jv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defs();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ripple
|
||||||
@@ -19,410 +19,12 @@
|
|||||||
|
|
||||||
#include <ripple/app/main/Application.h>
|
#include <ripple/app/main/Application.h>
|
||||||
#include <ripple/app/misc/NetworkOPs.h>
|
#include <ripple/app/misc/NetworkOPs.h>
|
||||||
#include <ripple/app/reporting/P2pProxy.h>
|
|
||||||
#include <ripple/json/json_value.h>
|
|
||||||
#include <ripple/json/json_writer.h>
|
|
||||||
#include <ripple/net/RPCErr.h>
|
|
||||||
#include <ripple/protocol/LedgerFormats.h>
|
|
||||||
#include <ripple/protocol/SField.h>
|
|
||||||
#include <ripple/protocol/digest.h>
|
|
||||||
#include <ripple/protocol/jss.h>
|
#include <ripple/protocol/jss.h>
|
||||||
#include <ripple/rpc/Context.h>
|
#include <ripple/rpc/Context.h>
|
||||||
#include <ripple/rpc/Role.h>
|
#include <ripple/rpc/Role.h>
|
||||||
#include <ripple/rpc/impl/TransactionSign.h>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <magic/magic_enum.h>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#define MAGIC_ENUM(x) \
|
|
||||||
template <> \
|
|
||||||
struct magic_enum::customize::enum_range<x> \
|
|
||||||
{ \
|
|
||||||
static constexpr int min = -20000; \
|
|
||||||
static constexpr int max = 20000; \
|
|
||||||
};
|
|
||||||
|
|
||||||
MAGIC_ENUM(ripple::SerializedTypeID);
|
|
||||||
MAGIC_ENUM(ripple::LedgerEntryType);
|
|
||||||
MAGIC_ENUM(ripple::TELcodes);
|
|
||||||
MAGIC_ENUM(ripple::TEMcodes);
|
|
||||||
MAGIC_ENUM(ripple::TEFcodes);
|
|
||||||
MAGIC_ENUM(ripple::TERcodes);
|
|
||||||
MAGIC_ENUM(ripple::TEScodes);
|
|
||||||
MAGIC_ENUM(ripple::TECcodes);
|
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
class Definitions
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Json::Value
|
|
||||||
generate()
|
|
||||||
{
|
|
||||||
// RH TODO: probably a better way to do this?
|
|
||||||
#define STR(x) \
|
|
||||||
([&] { \
|
|
||||||
std::ostringstream ss; \
|
|
||||||
return ss << (x), ss.str(); \
|
|
||||||
}())
|
|
||||||
|
|
||||||
Json::Value ret{Json::objectValue};
|
|
||||||
ret[jss::TYPES] = Json::objectValue;
|
|
||||||
|
|
||||||
auto const translate = [](std::string inp) -> std::string {
|
|
||||||
auto replace = [&](const char* f, const char* r) -> std::string {
|
|
||||||
std::string out = inp;
|
|
||||||
boost::replace_all(out, f, r);
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto find = [&](const char* s) -> bool {
|
|
||||||
return inp.find(s) != std::string::npos;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (find("UINT"))
|
|
||||||
{
|
|
||||||
if (find("256") || find("160") || find("128"))
|
|
||||||
return replace("UINT", "Hash");
|
|
||||||
else
|
|
||||||
return replace("UINT", "UInt");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inp == "OBJECT")
|
|
||||||
return "STObject";
|
|
||||||
if (inp == "ARRAY")
|
|
||||||
return "STArray";
|
|
||||||
if (inp == "AMM")
|
|
||||||
return "AMM";
|
|
||||||
if (inp == "ACCOUNT")
|
|
||||||
return "AccountID";
|
|
||||||
if (inp == "LEDGERENTRY")
|
|
||||||
return "LedgerEntry";
|
|
||||||
if (inp == "NOTPRESENT")
|
|
||||||
return "NotPresent";
|
|
||||||
if (inp == "PATHSET")
|
|
||||||
return "PathSet";
|
|
||||||
if (inp == "VL")
|
|
||||||
return "Blob";
|
|
||||||
if (inp == "DIR_NODE")
|
|
||||||
return "DirectoryNode";
|
|
||||||
if (inp == "PAYCHAN")
|
|
||||||
return "PayChannel";
|
|
||||||
|
|
||||||
static const std::map<std::string, std::string>
|
|
||||||
capitalization_exceptions = {
|
|
||||||
{"NFTOKEN", "NFToken"},
|
|
||||||
{"UNL", "UNL"},
|
|
||||||
{"XCHAIN", "XChain"},
|
|
||||||
{"ID", "ID"},
|
|
||||||
{"AMM", "AMM"},
|
|
||||||
{"URITOKEN", "URIToken"},
|
|
||||||
{"URI", "URI"}};
|
|
||||||
|
|
||||||
std::string out;
|
|
||||||
size_t pos = 0;
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
pos = inp.find("_");
|
|
||||||
if (pos == std::string::npos)
|
|
||||||
pos = inp.size();
|
|
||||||
std::string token = inp.substr(0, pos);
|
|
||||||
if (auto const e = capitalization_exceptions.find(token);
|
|
||||||
e != capitalization_exceptions.end())
|
|
||||||
out += e->second;
|
|
||||||
else if (token.size() > 1)
|
|
||||||
{
|
|
||||||
boost::algorithm::to_lower(token);
|
|
||||||
token.data()[0] -= ('a' - 'A');
|
|
||||||
out += token;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out += token;
|
|
||||||
if (pos == inp.size())
|
|
||||||
break;
|
|
||||||
inp = inp.substr(pos + 1);
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
};
|
|
||||||
|
|
||||||
ret[jss::TYPES]["Done"] = -1;
|
|
||||||
std::map<int32_t, std::string> type_map{{-1, "Done"}};
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<SerializedTypeID>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
std::string type_name =
|
|
||||||
translate(name.data() + 4 /* remove STI_ */);
|
|
||||||
int32_t type_value = static_cast<int32_t>(entry.first);
|
|
||||||
ret[jss::TYPES][type_name] = type_value;
|
|
||||||
type_map[type_value] = type_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret[jss::LEDGER_ENTRY_TYPES] = Json::objectValue;
|
|
||||||
ret[jss::LEDGER_ENTRY_TYPES][jss::Invalid] = -1;
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<LedgerEntryType>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
std::string type_name = translate(name.data() + 2 /* remove lt_ */);
|
|
||||||
int32_t type_value = static_cast<int32_t>(entry.first);
|
|
||||||
ret[jss::LEDGER_ENTRY_TYPES][type_name] = type_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret[jss::FIELDS] = Json::arrayValue;
|
|
||||||
|
|
||||||
uint32_t i = 0;
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "Generic";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 0;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = false;
|
|
||||||
v[jss::type] = "Unknown";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "Invalid";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = -1;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = false;
|
|
||||||
v[jss::type] = "Unknown";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "ObjectEndMarker";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 1;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = true;
|
|
||||||
v[jss::type] = "STObject";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "ArrayEndMarker";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 1;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = true;
|
|
||||||
v[jss::type] = "STArray";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "hash";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 257;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = false;
|
|
||||||
v[jss::type] = "Hash256";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "index";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 258;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = false;
|
|
||||||
v[jss::type] = "Hash256";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "taker_gets_funded";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 258;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = false;
|
|
||||||
v[jss::type] = "Amount";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Json::Value a = Json::arrayValue;
|
|
||||||
a[0U] = "taker_pays_funded";
|
|
||||||
Json::Value v = Json::objectValue;
|
|
||||||
v[jss::nth] = 259;
|
|
||||||
v[jss::isVLEncoded] = false;
|
|
||||||
v[jss::isSerialized] = false;
|
|
||||||
v[jss::isSigningField] = false;
|
|
||||||
v[jss::type] = "Amount";
|
|
||||||
a[1U] = v;
|
|
||||||
ret[jss::FIELDS][i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto const& [code, f] : ripple::SField::knownCodeToField)
|
|
||||||
{
|
|
||||||
if (f->fieldName == "")
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Json::Value innerObj = Json::objectValue;
|
|
||||||
|
|
||||||
uint32_t fc = code & 0xFFU;
|
|
||||||
uint32_t tc = code >> 16U;
|
|
||||||
|
|
||||||
innerObj[jss::nth] = fc;
|
|
||||||
|
|
||||||
innerObj[jss::isVLEncoded] =
|
|
||||||
(tc == 7U /* Blob */ || tc == 8U /* AccountID */ ||
|
|
||||||
tc == 19U /* Vector256 */);
|
|
||||||
|
|
||||||
innerObj[jss::isSerialized] =
|
|
||||||
(tc <
|
|
||||||
10000); /* TRANSACTION, LEDGER_ENTRY, VALIDATION, METADATA */
|
|
||||||
|
|
||||||
innerObj[jss::isSigningField] = f->shouldInclude(false);
|
|
||||||
|
|
||||||
innerObj[jss::type] = type_map[tc];
|
|
||||||
|
|
||||||
Json::Value innerArray = Json::arrayValue;
|
|
||||||
innerArray[0U] = f->fieldName;
|
|
||||||
innerArray[1U] = innerObj;
|
|
||||||
|
|
||||||
ret[jss::FIELDS][i++] = innerArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret[jss::TRANSACTION_RESULTS] = Json::objectValue;
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TELcodes>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
|
||||||
static_cast<int32_t>(entry.first);
|
|
||||||
}
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TEMcodes>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
|
||||||
static_cast<int32_t>(entry.first);
|
|
||||||
}
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TEFcodes>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
|
||||||
static_cast<int32_t>(entry.first);
|
|
||||||
}
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TERcodes>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
|
||||||
static_cast<int32_t>(entry.first);
|
|
||||||
}
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TEScodes>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
|
||||||
static_cast<int32_t>(entry.first);
|
|
||||||
}
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TECcodes>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
ret[jss::TRANSACTION_RESULTS][STR(name)] =
|
|
||||||
static_cast<int32_t>(entry.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const translate_tt = [](std::string inp) -> std::string {
|
|
||||||
if (inp == "PaychanClaim")
|
|
||||||
return "PaymentChannelClaim";
|
|
||||||
if (inp == "PaychanCreate")
|
|
||||||
return "PaymentChannelCreate";
|
|
||||||
if (inp == "PaychanFund")
|
|
||||||
return "PaymentChannelFund";
|
|
||||||
if (inp == "RegularKeySet")
|
|
||||||
return "SetRegularKey";
|
|
||||||
if (inp == "HookSet")
|
|
||||||
return "SetHook";
|
|
||||||
return inp;
|
|
||||||
};
|
|
||||||
|
|
||||||
ret[jss::TRANSACTION_TYPES] = Json::objectValue;
|
|
||||||
ret[jss::TRANSACTION_TYPES][jss::Invalid] = -1;
|
|
||||||
for (auto const& entry : magic_enum::enum_entries<TxType>())
|
|
||||||
{
|
|
||||||
const auto name = entry.second;
|
|
||||||
std::string type_name = translate_tt(translate(name.data() + 2));
|
|
||||||
int32_t type_value = static_cast<int32_t>(entry.first);
|
|
||||||
ret[jss::TRANSACTION_TYPES][type_name] = type_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret[jss::native_currency_code] = systemCurrencyCode();
|
|
||||||
// generate hash
|
|
||||||
{
|
|
||||||
const std::string out = Json::FastWriter().write(ret);
|
|
||||||
defsHash =
|
|
||||||
ripple::sha512Half(ripple::Slice{out.data(), out.size()});
|
|
||||||
ret[jss::hash] = to_string(*defsHash);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<uint256> defsHash;
|
|
||||||
Json::Value defs;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Definitions() : defs(generate()){};
|
|
||||||
|
|
||||||
bool
|
|
||||||
hashMatches(uint256 hash) const
|
|
||||||
{
|
|
||||||
return defsHash && *defsHash == hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value const&
|
|
||||||
operator()(void) const
|
|
||||||
{
|
|
||||||
return defs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Json::Value
|
|
||||||
doServerDefinitions(RPC::JsonContext& context)
|
|
||||||
{
|
|
||||||
auto& params = context.params;
|
|
||||||
|
|
||||||
uint256 hash;
|
|
||||||
if (params.isMember(jss::hash))
|
|
||||||
{
|
|
||||||
if (!params[jss::hash].isString() ||
|
|
||||||
!hash.parseHex(params[jss::hash].asString()))
|
|
||||||
return RPC::invalid_field_error(jss::hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const Definitions defs{};
|
|
||||||
if (defs.hashMatches(hash))
|
|
||||||
{
|
|
||||||
Json::Value jv = Json::objectValue;
|
|
||||||
jv[jss::hash] = to_string(hash);
|
|
||||||
jv[jss::native_currency_code] = systemCurrencyCode();
|
|
||||||
return jv;
|
|
||||||
}
|
|
||||||
|
|
||||||
return defs();
|
|
||||||
}
|
|
||||||
|
|
||||||
Json::Value
|
Json::Value
|
||||||
doServerInfo(RPC::JsonContext& context)
|
doServerInfo(RPC::JsonContext& context)
|
||||||
{
|
{
|
||||||
|
|||||||
372
src/test/rpc/ServerDefinitions_test.cpp
Normal file
372
src/test/rpc/ServerDefinitions_test.cpp
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012-2016 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include <ripple/beast/unit_test.h>
|
||||||
|
#include <ripple/protocol/jss.h>
|
||||||
|
#include <test/jtx.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
class ServerDefinitions_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Json::Value
|
||||||
|
loadJson(std::string content)
|
||||||
|
{
|
||||||
|
// If the string is empty, return an empty Json::Value
|
||||||
|
if (content.empty())
|
||||||
|
{
|
||||||
|
std::cout << "JSON string was empty"
|
||||||
|
<< "\n";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::Value jsonValue;
|
||||||
|
Json::Reader reader;
|
||||||
|
reader.parse(content, jsonValue);
|
||||||
|
return jsonValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testServerDefinitions()
|
||||||
|
{
|
||||||
|
using namespace test::jtx;
|
||||||
|
|
||||||
|
std::string jsonLE = R"json({
|
||||||
|
"AccountRoot" : 97,
|
||||||
|
"Amendments" : 102,
|
||||||
|
"Any" : 0,
|
||||||
|
"Check" : 67,
|
||||||
|
"Child" : 7378,
|
||||||
|
"Contract" : 99,
|
||||||
|
"DepositPreauth" : 112,
|
||||||
|
"DirectoryNode" : 100,
|
||||||
|
"EmittedTxn" : 69,
|
||||||
|
"Escrow" : 117,
|
||||||
|
"FeeSettings" : 115,
|
||||||
|
"GeneratorMap" : 103,
|
||||||
|
"Hook" : 72,
|
||||||
|
"HookDefinition" : 68,
|
||||||
|
"HookState" : 118,
|
||||||
|
"ImportVLSequence" : 73,
|
||||||
|
"Invalid" : -1,
|
||||||
|
"LedgerHashes" : 104,
|
||||||
|
"NFTokenOffer" : 55,
|
||||||
|
"NFTokenPage" : 80,
|
||||||
|
"NegativeUNL" : 78,
|
||||||
|
"Nickname" : 110,
|
||||||
|
"Offer" : 111,
|
||||||
|
"PayChannel" : 120,
|
||||||
|
"RippleState" : 114,
|
||||||
|
"SignerList" : 83,
|
||||||
|
"Ticket" : 84,
|
||||||
|
"UNLReport" : 82,
|
||||||
|
"URIToken" : 85
|
||||||
|
})json";
|
||||||
|
|
||||||
|
std::string jsonTT = R"json({
|
||||||
|
"AccountDelete" : 21,
|
||||||
|
"AccountSet" : 3,
|
||||||
|
"Amendment" : 100,
|
||||||
|
"CheckCancel" : 18,
|
||||||
|
"CheckCash" : 17,
|
||||||
|
"CheckCreate" : 16,
|
||||||
|
"ClaimReward" : 98,
|
||||||
|
"Contract" : 9,
|
||||||
|
"DepositPreauth" : 19,
|
||||||
|
"EmitFailure" : 103,
|
||||||
|
"EscrowCancel" : 4,
|
||||||
|
"EscrowCreate" : 1,
|
||||||
|
"EscrowFinish" : 2,
|
||||||
|
"Fee" : 101,
|
||||||
|
"GenesisMint" : 96,
|
||||||
|
"Import" : 97,
|
||||||
|
"Invalid" : -1,
|
||||||
|
"Invoke" : 99,
|
||||||
|
"NFTokenAcceptOffer" : 29,
|
||||||
|
"NFTokenBurn" : 26,
|
||||||
|
"NFTokenCancelOffer" : 28,
|
||||||
|
"NFTokenCreateOffer" : 27,
|
||||||
|
"NFTokenMint" : 25,
|
||||||
|
"NicknameSet" : 6,
|
||||||
|
"OfferCancel" : 8,
|
||||||
|
"OfferCreate" : 7,
|
||||||
|
"Payment" : 0,
|
||||||
|
"PaymentChannelClaim" : 15,
|
||||||
|
"PaymentChannelCreate" : 13,
|
||||||
|
"PaymentChannelFund" : 14,
|
||||||
|
"SetHook" : 22,
|
||||||
|
"SetRegularKey" : 5,
|
||||||
|
"SignerListSet" : 12,
|
||||||
|
"SpinalTap" : 11,
|
||||||
|
"TicketCreate" : 10,
|
||||||
|
"TrustSet" : 20,
|
||||||
|
"UNLModify" : 102,
|
||||||
|
"UNLReport" : 104,
|
||||||
|
"URITokenBurn" : 46,
|
||||||
|
"URITokenBuy" : 47,
|
||||||
|
"URITokenCancelSellOffer" : 49,
|
||||||
|
"URITokenCreateSellOffer" : 48,
|
||||||
|
"URITokenMint" : 45
|
||||||
|
})json";
|
||||||
|
|
||||||
|
std::string jsonTY = R"json({
|
||||||
|
"AccountID" : 8,
|
||||||
|
"Amount" : 6,
|
||||||
|
"Blob" : 7,
|
||||||
|
"Done" : -1,
|
||||||
|
"Hash128" : 4,
|
||||||
|
"Hash160" : 17,
|
||||||
|
"Hash256" : 5,
|
||||||
|
"LedgerEntry" : 10002,
|
||||||
|
"Metadata" : 10004,
|
||||||
|
"NotPresent" : 0,
|
||||||
|
"PathSet" : 18,
|
||||||
|
"STArray" : 15,
|
||||||
|
"STObject" : 14,
|
||||||
|
"Transaction" : 10001,
|
||||||
|
"UInt16" : 1,
|
||||||
|
"UInt192" : 21,
|
||||||
|
"UInt32" : 2,
|
||||||
|
"UInt384" : 22,
|
||||||
|
"UInt512" : 23,
|
||||||
|
"UInt64" : 3,
|
||||||
|
"UInt8" : 16,
|
||||||
|
"UInt96" : 20,
|
||||||
|
"Unknown" : -2,
|
||||||
|
"Validation" : 10003,
|
||||||
|
"Vector256" : 19
|
||||||
|
})json";
|
||||||
|
|
||||||
|
std::string jsonTEC = R"json({
|
||||||
|
"tecAMM_BALANCE" : 163,
|
||||||
|
"tecAMM_FAILED_BID" : 167,
|
||||||
|
"tecAMM_FAILED_DEPOSIT" : 164,
|
||||||
|
"tecAMM_FAILED_VOTE" : 168,
|
||||||
|
"tecAMM_FAILED_WITHDRAW" : 165,
|
||||||
|
"tecAMM_INVALID_TOKENS" : 166,
|
||||||
|
"tecAMM_UNFUNDED" : 162,
|
||||||
|
"tecBAD_XCHAIN_TRANSFER_ISSUE" : 171,
|
||||||
|
"tecCANT_ACCEPT_OWN_NFTOKEN_OFFER" : 158,
|
||||||
|
"tecCLAIM" : 100,
|
||||||
|
"tecCRYPTOCONDITION_ERROR" : 146,
|
||||||
|
"tecDIR_FULL" : 121,
|
||||||
|
"tecDST_TAG_NEEDED" : 143,
|
||||||
|
"tecDUPLICATE" : 149,
|
||||||
|
"tecEXPIRED" : 148,
|
||||||
|
"tecFAILED_PROCESSING" : 105,
|
||||||
|
"tecFROZEN" : 137,
|
||||||
|
"tecHAS_OBLIGATIONS" : 151,
|
||||||
|
"tecHOOK_REJECTED" : 153,
|
||||||
|
"tecINSUFFICIENT_FUNDS" : 159,
|
||||||
|
"tecINSUFFICIENT_PAYMENT" : 161,
|
||||||
|
"tecINSUFFICIENT_RESERVE" : 141,
|
||||||
|
"tecINSUFF_FEE" : 136,
|
||||||
|
"tecINSUF_RESERVE_LINE" : 122,
|
||||||
|
"tecINSUF_RESERVE_OFFER" : 123,
|
||||||
|
"tecINTERNAL" : 144,
|
||||||
|
"tecINVARIANT_FAILED" : 147,
|
||||||
|
"tecKILLED" : 150,
|
||||||
|
"tecLAST_POSSIBLE_ENTRY" : 255,
|
||||||
|
"tecMAX_SEQUENCE_REACHED" : 154,
|
||||||
|
"tecNEED_MASTER_KEY" : 142,
|
||||||
|
"tecNFTOKEN_BUY_SELL_MISMATCH" : 156,
|
||||||
|
"tecNFTOKEN_OFFER_TYPE_MISMATCH" : 157,
|
||||||
|
"tecNO_ALTERNATIVE_KEY" : 130,
|
||||||
|
"tecNO_AUTH" : 134,
|
||||||
|
"tecNO_DST" : 124,
|
||||||
|
"tecNO_DST_INSUF_XRP" : 125,
|
||||||
|
"tecNO_ENTRY" : 140,
|
||||||
|
"tecNO_ISSUER" : 133,
|
||||||
|
"tecNO_LINE" : 135,
|
||||||
|
"tecNO_LINE_INSUF_RESERVE" : 126,
|
||||||
|
"tecNO_LINE_REDUNDANT" : 127,
|
||||||
|
"tecNO_PERMISSION" : 139,
|
||||||
|
"tecNO_REGULAR_KEY" : 131,
|
||||||
|
"tecNO_SUITABLE_NFTOKEN_PAGE" : 155,
|
||||||
|
"tecNO_TARGET" : 138,
|
||||||
|
"tecOBJECT_NOT_FOUND" : 160,
|
||||||
|
"tecOVERSIZE" : 145,
|
||||||
|
"tecOWNERS" : 132,
|
||||||
|
"tecPATH_DRY" : 128,
|
||||||
|
"tecPATH_PARTIAL" : 101,
|
||||||
|
"tecPRECISION_LOSS" : 170,
|
||||||
|
"tecREQUIRES_FLAG" : 169,
|
||||||
|
"tecTOO_SOON" : 152,
|
||||||
|
"tecUNFUNDED" : 129,
|
||||||
|
"tecUNFUNDED_ADD" : 102,
|
||||||
|
"tecUNFUNDED_OFFER" : 103,
|
||||||
|
"tecUNFUNDED_PAYMENT" : 104,
|
||||||
|
"tecXCHAIN_ACCOUNT_CREATE_PAST" : 182,
|
||||||
|
"tecXCHAIN_ACCOUNT_CREATE_TOO_MANY" : 183,
|
||||||
|
"tecXCHAIN_BAD_CLAIM_ID" : 173,
|
||||||
|
"tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR" : 186,
|
||||||
|
"tecXCHAIN_CLAIM_NO_QUORUM" : 174,
|
||||||
|
"tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE" : 176,
|
||||||
|
"tecXCHAIN_INSUFF_CREATE_AMOUNT" : 181,
|
||||||
|
"tecXCHAIN_NO_CLAIM_ID" : 172,
|
||||||
|
"tecXCHAIN_NO_SIGNERS_LIST" : 179,
|
||||||
|
"tecXCHAIN_PAYMENT_FAILED" : 184,
|
||||||
|
"tecXCHAIN_PROOF_UNKNOWN_KEY" : 175,
|
||||||
|
"tecXCHAIN_REWARD_MISMATCH" : 178,
|
||||||
|
"tecXCHAIN_SELF_COMMIT" : 185,
|
||||||
|
"tecXCHAIN_SENDING_ACCOUNT_MISMATCH" : 180,
|
||||||
|
"tecXCHAIN_WRONG_CHAIN" : 177,
|
||||||
|
"tefALREADY" : -198,
|
||||||
|
"tefBAD_ADD_AUTH" : -197,
|
||||||
|
"tefBAD_AUTH" : -196,
|
||||||
|
"tefBAD_AUTH_MASTER" : -183,
|
||||||
|
"tefBAD_LEDGER" : -195,
|
||||||
|
"tefBAD_QUORUM" : -185,
|
||||||
|
"tefBAD_SIGNATURE" : -186,
|
||||||
|
"tefCREATED" : -194,
|
||||||
|
"tefEXCEPTION" : -193,
|
||||||
|
"tefFAILURE" : -199,
|
||||||
|
"tefINTERNAL" : -192,
|
||||||
|
"tefINVARIANT_FAILED" : -182,
|
||||||
|
"tefMASTER_DISABLED" : -188,
|
||||||
|
"tefMAX_LEDGER" : -187,
|
||||||
|
"tefNFTOKEN_IS_NOT_TRANSFERABLE" : -179,
|
||||||
|
"tefNOT_MULTI_SIGNING" : -184,
|
||||||
|
"tefNO_AUTH_REQUIRED" : -191,
|
||||||
|
"tefNO_TICKET" : -180,
|
||||||
|
"tefPAST_IMPORT_SEQ" : -178,
|
||||||
|
"tefPAST_IMPORT_VL_SEQ" : -177,
|
||||||
|
"tefPAST_SEQ" : -190,
|
||||||
|
"tefTOO_BIG" : -181,
|
||||||
|
"tefWRONG_PRIOR" : -189,
|
||||||
|
"telBAD_DOMAIN" : -398,
|
||||||
|
"telBAD_PATH_COUNT" : -397,
|
||||||
|
"telBAD_PUBLIC_KEY" : -396,
|
||||||
|
"telCAN_NOT_QUEUE" : -392,
|
||||||
|
"telCAN_NOT_QUEUE_BALANCE" : -391,
|
||||||
|
"telCAN_NOT_QUEUE_BLOCKED" : -389,
|
||||||
|
"telCAN_NOT_QUEUE_BLOCKS" : -390,
|
||||||
|
"telCAN_NOT_QUEUE_FEE" : -388,
|
||||||
|
"telCAN_NOT_QUEUE_FULL" : -387,
|
||||||
|
"telCAN_NOT_QUEUE_IMPORT" : -381,
|
||||||
|
"telFAILED_PROCESSING" : -395,
|
||||||
|
"telIMPORT_VL_KEY_NOT_RECOGNISED" : -382,
|
||||||
|
"telINSUF_FEE_P" : -394,
|
||||||
|
"telLOCAL_ERROR" : -399,
|
||||||
|
"telNETWORK_ID_MAKES_TX_NON_CANONICAL" : -384,
|
||||||
|
"telNON_LOCAL_EMITTED_TXN" : -383,
|
||||||
|
"telNO_DST_PARTIAL" : -393,
|
||||||
|
"telREQUIRES_NETWORK_ID" : -385,
|
||||||
|
"telWRONG_NETWORK" : -386,
|
||||||
|
"temAMM_BAD_TOKENS" : -261,
|
||||||
|
"temBAD_AMOUNT" : -298,
|
||||||
|
"temBAD_CURRENCY" : -297,
|
||||||
|
"temBAD_EXPIRATION" : -296,
|
||||||
|
"temBAD_FEE" : -295,
|
||||||
|
"temBAD_ISSUER" : -294,
|
||||||
|
"temBAD_LIMIT" : -293,
|
||||||
|
"temBAD_NFTOKEN_TRANSFER_FEE" : -262,
|
||||||
|
"temBAD_OFFER" : -292,
|
||||||
|
"temBAD_PATH" : -291,
|
||||||
|
"temBAD_PATH_LOOP" : -290,
|
||||||
|
"temBAD_QUORUM" : -271,
|
||||||
|
"temBAD_REGKEY" : -289,
|
||||||
|
"temBAD_SEND_XRP_LIMIT" : -288,
|
||||||
|
"temBAD_SEND_XRP_MAX" : -287,
|
||||||
|
"temBAD_SEND_XRP_NO_DIRECT" : -286,
|
||||||
|
"temBAD_SEND_XRP_PARTIAL" : -285,
|
||||||
|
"temBAD_SEND_XRP_PATHS" : -284,
|
||||||
|
"temBAD_SEQUENCE" : -283,
|
||||||
|
"temBAD_SIGNATURE" : -282,
|
||||||
|
"temBAD_SIGNER" : -272,
|
||||||
|
"temBAD_SRC_ACCOUNT" : -281,
|
||||||
|
"temBAD_TICK_SIZE" : -269,
|
||||||
|
"temBAD_TRANSFER_RATE" : -280,
|
||||||
|
"temBAD_WEIGHT" : -270,
|
||||||
|
"temCANNOT_PREAUTH_SELF" : -267,
|
||||||
|
"temDISABLED" : -273,
|
||||||
|
"temDST_IS_SRC" : -279,
|
||||||
|
"temDST_NEEDED" : -278,
|
||||||
|
"temHOOK_DATA_TOO_LARGE" : -253,
|
||||||
|
"temHOOK_REJECTED" : -252,
|
||||||
|
"temINVALID" : -277,
|
||||||
|
"temINVALID_ACCOUNT_ID" : -268,
|
||||||
|
"temINVALID_COUNT" : -266,
|
||||||
|
"temINVALID_FLAG" : -276,
|
||||||
|
"temMALFORMED" : -299,
|
||||||
|
"temREDUNDANT" : -275,
|
||||||
|
"temRIPPLE_EMPTY" : -274,
|
||||||
|
"temSEQ_AND_TICKET" : -263,
|
||||||
|
"temUNCERTAIN" : -265,
|
||||||
|
"temUNKNOWN" : -264,
|
||||||
|
"temXCHAIN_BAD_PROOF" : -259,
|
||||||
|
"temXCHAIN_BRIDGE_BAD_ISSUES" : -258,
|
||||||
|
"temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT" : -256,
|
||||||
|
"temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT" : -255,
|
||||||
|
"temXCHAIN_BRIDGE_NONDOOR_OWNER" : -257,
|
||||||
|
"temXCHAIN_EQUAL_DOOR_ACCOUNTS" : -260,
|
||||||
|
"temXCHAIN_TOO_MANY_ATTESTATIONS" : -254,
|
||||||
|
"terFUNDS_SPENT" : -98,
|
||||||
|
"terINSUF_FEE_B" : -97,
|
||||||
|
"terLAST" : -91,
|
||||||
|
"terNO_ACCOUNT" : -96,
|
||||||
|
"terNO_AMM" : -87,
|
||||||
|
"terNO_AUTH" : -95,
|
||||||
|
"terNO_HOOK" : -86,
|
||||||
|
"terNO_LINE" : -94,
|
||||||
|
"terNO_RIPPLE" : -90,
|
||||||
|
"terOWNERS" : -93,
|
||||||
|
"terPRE_SEQ" : -92,
|
||||||
|
"terPRE_TICKET" : -88,
|
||||||
|
"terQUEUED" : -89,
|
||||||
|
"terRETRY" : -99,
|
||||||
|
"tesSUCCESS" : 0
|
||||||
|
})json";
|
||||||
|
|
||||||
|
{
|
||||||
|
Env env(*this);
|
||||||
|
auto const result = env.rpc("server_definitions");
|
||||||
|
BEAST_EXPECT(!result[jss::result].isMember(jss::error));
|
||||||
|
// FIELDS
|
||||||
|
// DA: Not Tested
|
||||||
|
// LEDGER ENTRY TYPES
|
||||||
|
BEAST_EXPECT(
|
||||||
|
result[jss::result]["LEDGER_ENTRY_TYPES"] == loadJson(jsonLE));
|
||||||
|
// TRANSACTION TYPES
|
||||||
|
BEAST_EXPECT(
|
||||||
|
result[jss::result]["TRANSACTION_TYPES"] == loadJson(jsonTT));
|
||||||
|
// TYPES
|
||||||
|
BEAST_EXPECT(result[jss::result]["TYPES"] == loadJson(jsonTY));
|
||||||
|
// TRANSACTION_RESULTS
|
||||||
|
BEAST_EXPECT(
|
||||||
|
result[jss::result]["TRANSACTION_RESULTS"] ==
|
||||||
|
loadJson(jsonTEC));
|
||||||
|
BEAST_EXPECT(result[jss::result][jss::status] == "success");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
run() override
|
||||||
|
{
|
||||||
|
testServerDefinitions();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(ServerDefinitions, rpc, ripple);
|
||||||
|
|
||||||
|
} // namespace test
|
||||||
|
} // namespace ripple
|
||||||
Reference in New Issue
Block a user