rippled
Loading...
Searching...
No Matches
ServerInfo.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2014 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/misc/NetworkOPs.h>
21#include <xrpld/rpc/Context.h>
22#include <xrpld/rpc/Role.h>
23#include <xrpl/json/json_value.h>
24#include <xrpl/json/json_writer.h>
25#include <xrpl/protocol/LedgerFormats.h>
26#include <xrpl/protocol/SField.h>
27#include <xrpl/protocol/TER.h>
28#include <xrpl/protocol/TxFormats.h>
29#include <xrpl/protocol/digest.h>
30#include <xrpl/protocol/jss.h>
31
32#include <boost/algorithm/string.hpp>
33
34#include <unordered_map>
35
36namespace ripple {
37
38namespace detail {
39
41{
42private:
44 // translate e.g. STI_LEDGERENTRY to LedgerEntry
45 translate(std::string const& inp);
46
49
50public:
52
53 bool
54 hashMatches(uint256 hash) const
55 {
56 return defsHash_ == hash;
57 }
58
59 Json::Value const&
60 get() const
61 {
62 return defs_;
63 }
64};
65
68{
69 auto replace = [&](char const* oldStr, char const* newStr) -> std::string {
70 std::string out = inp;
71 boost::replace_all(out, oldStr, newStr);
72 return out;
73 };
74
75 auto contains = [&](char const* s) -> bool {
76 return inp.find(s) != std::string::npos;
77 };
78
79 if (contains("UINT"))
80 {
81 if (contains("512") || contains("384") || contains("256") ||
82 contains("192") || contains("160") || contains("128"))
83 return replace("UINT", "Hash");
84 else
85 return replace("UINT", "UInt");
86 }
87
89 {"OBJECT", "STObject"},
90 {"ARRAY", "STArray"},
91 {"ACCOUNT", "AccountID"},
92 {"LEDGERENTRY", "LedgerEntry"},
93 {"NOTPRESENT", "NotPresent"},
94 {"PATHSET", "PathSet"},
95 {"VL", "Blob"},
96 {"XCHAIN_BRIDGE", "XChainBridge"},
97 };
98
99 if (auto const& it = replacements.find(inp); it != replacements.end())
100 {
101 return it->second;
102 }
103
105 size_t pos = 0;
106 std::string inpToProcess = inp;
107
108 // convert snake_case to CamelCase
109 for (;;)
110 {
111 pos = inpToProcess.find("_");
112 if (pos == std::string::npos)
113 pos = inpToProcess.size();
114 std::string token = inpToProcess.substr(0, pos);
115 if (token.size() > 1)
116 {
117 boost::algorithm::to_lower(token);
118 token.data()[0] -= ('a' - 'A');
119 out += token;
120 }
121 else
122 out += token;
123 if (pos == inpToProcess.size())
124 break;
125 inpToProcess = inpToProcess.substr(pos + 1);
126 }
127 return out;
128};
129
131{
132 // populate SerializedTypeID names and values
133 defs_[jss::TYPES] = Json::objectValue;
134
135 defs_[jss::TYPES]["Done"] = -1;
136 std::map<int32_t, std::string> typeMap{{-1, "Done"}};
137 for (auto const& [rawName, typeValue] : sTypeMap)
138 {
139 std::string typeName =
140 translate(std::string(rawName).substr(4) /* remove STI_ */);
141 defs_[jss::TYPES][typeName] = typeValue;
142 typeMap[typeValue] = typeName;
143 }
144
145 // populate LedgerEntryType names and values
146 defs_[jss::LEDGER_ENTRY_TYPES] = Json::objectValue;
147 defs_[jss::LEDGER_ENTRY_TYPES][jss::Invalid] = -1;
148
149 for (auto const& f : LedgerFormats::getInstance())
150 {
151 defs_[jss::LEDGER_ENTRY_TYPES][f.getName()] = f.getType();
152 }
153
154 // populate SField serialization data
155 defs_[jss::FIELDS] = Json::arrayValue;
156
157 uint32_t i = 0;
158 {
160 a[0U] = "Generic";
162 v[jss::nth] = 0;
163 v[jss::isVLEncoded] = false;
164 v[jss::isSerialized] = false;
165 v[jss::isSigningField] = false;
166 v[jss::type] = "Unknown";
167 a[1U] = v;
168 defs_[jss::FIELDS][i++] = a;
169 }
170
171 {
173 a[0U] = "Invalid";
175 v[jss::nth] = -1;
176 v[jss::isVLEncoded] = false;
177 v[jss::isSerialized] = false;
178 v[jss::isSigningField] = false;
179 v[jss::type] = "Unknown";
180 a[1U] = v;
181 defs_[jss::FIELDS][i++] = a;
182 }
183
184 {
186 a[0U] = "ObjectEndMarker";
188 v[jss::nth] = 1;
189 v[jss::isVLEncoded] = false;
190 v[jss::isSerialized] = true;
191 v[jss::isSigningField] = true;
192 v[jss::type] = "STObject";
193 a[1U] = v;
194 defs_[jss::FIELDS][i++] = a;
195 }
196
197 {
199 a[0U] = "ArrayEndMarker";
201 v[jss::nth] = 1;
202 v[jss::isVLEncoded] = false;
203 v[jss::isSerialized] = true;
204 v[jss::isSigningField] = true;
205 v[jss::type] = "STArray";
206 a[1U] = v;
207 defs_[jss::FIELDS][i++] = a;
208 }
209
210 {
212 a[0U] = "taker_gets_funded";
214 v[jss::nth] = 258;
215 v[jss::isVLEncoded] = false;
216 v[jss::isSerialized] = false;
217 v[jss::isSigningField] = false;
218 v[jss::type] = "Amount";
219 a[1U] = v;
220 defs_[jss::FIELDS][i++] = a;
221 }
222
223 {
225 a[0U] = "taker_pays_funded";
227 v[jss::nth] = 259;
228 v[jss::isVLEncoded] = false;
229 v[jss::isSerialized] = false;
230 v[jss::isSigningField] = false;
231 v[jss::type] = "Amount";
232 a[1U] = v;
233 defs_[jss::FIELDS][i++] = a;
234 }
235
236 for (auto const& [code, f] : ripple::SField::getKnownCodeToField())
237 {
238 if (f->fieldName == "")
239 continue;
240
242
243 uint32_t type = f->fieldType;
244
245 innerObj[jss::nth] = f->fieldValue;
246
247 // whether the field is variable-length encoded
248 // this means that the length is included before the content
249 innerObj[jss::isVLEncoded] =
250 (type == 7U /* Blob */ || type == 8U /* AccountID */ ||
251 type == 19U /* Vector256 */);
252
253 // whether the field is included in serialization
254 innerObj[jss::isSerialized] =
255 (type < 10000 && f->fieldName != "hash" &&
256 f->fieldName != "index"); /* hash, index, TRANSACTION,
257 LEDGER_ENTRY, VALIDATION, METADATA */
258
259 // whether the field is included in serialization when signing
260 innerObj[jss::isSigningField] = f->shouldInclude(false);
261
262 innerObj[jss::type] = typeMap[type];
263
264 Json::Value innerArray = Json::arrayValue;
265 innerArray[0U] = f->fieldName;
266 innerArray[1U] = innerObj;
267
268 defs_[jss::FIELDS][i++] = innerArray;
269 }
270
271 // populate TER code names and values
272 defs_[jss::TRANSACTION_RESULTS] = Json::objectValue;
273
274 for (auto const& [code, terInfo] : transResults())
275 {
276 defs_[jss::TRANSACTION_RESULTS][terInfo.first] = code;
277 }
278
279 // populate TxType names and values
280 defs_[jss::TRANSACTION_TYPES] = Json::objectValue;
281 defs_[jss::TRANSACTION_TYPES][jss::Invalid] = -1;
282 for (auto const& f : TxFormats::getInstance())
283 {
284 defs_[jss::TRANSACTION_TYPES][f.getName()] = f.getType();
285 }
286
287 // generate hash
288 {
291 defs_[jss::hash] = to_string(defsHash_);
292 }
293}
294
295} // namespace detail
296
299{
300 auto& params = context.params;
301
302 uint256 hash;
303 if (params.isMember(jss::hash))
304 {
305 if (!params[jss::hash].isString() ||
306 !hash.parseHex(params[jss::hash].asString()))
307 return RPC::invalid_field_error(jss::hash);
308 }
309
310 static const detail::ServerDefinitions defs{};
311 if (defs.hashMatches(hash))
312 {
314 jv[jss::hash] = to_string(hash);
315 return jv;
316 }
317 return defs.get();
318}
319
322{
324
325 ret[jss::info] = context.netOps.getServerInfo(
326 true,
327 context.role == Role::ADMIN,
328 context.params.isMember(jss::counters) &&
329 context.params[jss::counters].asBool());
330
331 return ret;
332}
333
334} // namespace ripple
Outputs a Value in JSON format without formatting (not human friendly).
Definition: json_writer.h:54
std::string write(const Value &root) override
Represents a JSON value.
Definition: json_value.h:148
Value get(UInt index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
Definition: json_value.cpp:847
bool asBool() const
Definition: json_value.cpp:625
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:949
static LedgerFormats const & getInstance()
virtual Json::Value getServerInfo(bool human, bool admin, bool counters)=0
static std::map< int, SField const * > const & getKnownCodeToField()
Definition: SField.h:302
An immutable linear range of bytes.
Definition: Slice.h:46
static TxFormats const & getInstance()
Definition: TxFormats.cpp:69
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:503
std::string translate(std::string const &inp)
Definition: ServerInfo.cpp:67
bool hashMatches(uint256 hash) const
Definition: ServerInfo.cpp:54
Json::Value const & get() const
Definition: ServerInfo.cpp:60
T data(T... args)
T find(T... args)
JSON (JavaScript Object Notation).
Definition: json_errors.h:25
@ arrayValue
array value (ordered list)
Definition: json_value.h:43
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:44
Json::Value invalid_field_error(std::string const &name)
Definition: ErrorCodes.h:315
static std::string to_string(TableType type)
to_string Returns the name of a table according to its TableType.
Definition: Node.cpp:45
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
static std::map< std::string, int > const sTypeMap
Definition: SField.h:110
Json::Value doServerInfo(RPC::JsonContext &)
Definition: ServerInfo.cpp:321
Json::Value doServerDefinitions(RPC::JsonContext &)
Definition: ServerInfo.cpp:298
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
std::unordered_map< TERUnderlyingType, std::pair< char const *const, char const *const > > const & transResults()
Definition: TER.cpp:35
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:225
T size(T... args)
NetworkOPs & netOps
Definition: Context.h:42
Json::Value params
Definition: Context.h:62
T substr(T... args)