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
24#include <xrpl/json/json_value.h>
25#include <xrpl/json/json_writer.h>
26#include <xrpl/protocol/LedgerFormats.h>
27#include <xrpl/protocol/SField.h>
28#include <xrpl/protocol/TER.h>
29#include <xrpl/protocol/TxFormats.h>
30#include <xrpl/protocol/digest.h>
31#include <xrpl/protocol/jss.h>
32
33#include <boost/algorithm/string.hpp>
34
35#include <unordered_map>
36
37namespace ripple {
38
39namespace detail {
40
42{
43private:
45 // translate e.g. STI_LEDGERENTRY to LedgerEntry
46 translate(std::string const& inp);
47
50
51public:
53
54 bool
55 hashMatches(uint256 hash) const
56 {
57 return defsHash_ == hash;
58 }
59
60 Json::Value const&
61 get() const
62 {
63 return defs_;
64 }
65};
66
69{
70 auto replace = [&](char const* oldStr, char const* newStr) -> std::string {
71 std::string out = inp;
72 boost::replace_all(out, oldStr, newStr);
73 return out;
74 };
75
76 auto contains = [&](char const* s) -> bool {
77 return inp.find(s) != std::string::npos;
78 };
79
80 if (contains("UINT"))
81 {
82 if (contains("512") || contains("384") || contains("256") ||
83 contains("192") || contains("160") || contains("128"))
84 return replace("UINT", "Hash");
85 else
86 return replace("UINT", "UInt");
87 }
88
90 {"OBJECT", "STObject"},
91 {"ARRAY", "STArray"},
92 {"ACCOUNT", "AccountID"},
93 {"LEDGERENTRY", "LedgerEntry"},
94 {"NOTPRESENT", "NotPresent"},
95 {"PATHSET", "PathSet"},
96 {"VL", "Blob"},
97 {"XCHAIN_BRIDGE", "XChainBridge"},
98 };
99
100 if (auto const& it = replacements.find(inp); it != replacements.end())
101 {
102 return it->second;
103 }
104
106 size_t pos = 0;
107 std::string inpToProcess = inp;
108
109 // convert snake_case to CamelCase
110 for (;;)
111 {
112 pos = inpToProcess.find("_");
113 if (pos == std::string::npos)
114 pos = inpToProcess.size();
115 std::string token = inpToProcess.substr(0, pos);
116 if (token.size() > 1)
117 {
118 boost::algorithm::to_lower(token);
119 token.data()[0] -= ('a' - 'A');
120 out += token;
121 }
122 else
123 out += token;
124 if (pos == inpToProcess.size())
125 break;
126 inpToProcess = inpToProcess.substr(pos + 1);
127 }
128 return out;
129};
130
132{
133 // populate SerializedTypeID names and values
134 defs_[jss::TYPES] = Json::objectValue;
135
136 defs_[jss::TYPES]["Done"] = -1;
137 std::map<int32_t, std::string> typeMap{{-1, "Done"}};
138 for (auto const& [rawName, typeValue] : sTypeMap)
139 {
140 std::string typeName =
141 translate(std::string(rawName).substr(4) /* remove STI_ */);
142 defs_[jss::TYPES][typeName] = typeValue;
143 typeMap[typeValue] = typeName;
144 }
145
146 // populate LedgerEntryType names and values
147 defs_[jss::LEDGER_ENTRY_TYPES] = Json::objectValue;
148 defs_[jss::LEDGER_ENTRY_TYPES][jss::Invalid] = -1;
149
150 for (auto const& f : LedgerFormats::getInstance())
151 {
152 defs_[jss::LEDGER_ENTRY_TYPES][f.getName()] = f.getType();
153 }
154
155 // populate SField serialization data
156 defs_[jss::FIELDS] = Json::arrayValue;
157
158 uint32_t i = 0;
159 {
161 a[0U] = "Generic";
163 v[jss::nth] = 0;
164 v[jss::isVLEncoded] = false;
165 v[jss::isSerialized] = false;
166 v[jss::isSigningField] = false;
167 v[jss::type] = "Unknown";
168 a[1U] = v;
169 defs_[jss::FIELDS][i++] = a;
170 }
171
172 {
174 a[0U] = "Invalid";
176 v[jss::nth] = -1;
177 v[jss::isVLEncoded] = false;
178 v[jss::isSerialized] = false;
179 v[jss::isSigningField] = false;
180 v[jss::type] = "Unknown";
181 a[1U] = v;
182 defs_[jss::FIELDS][i++] = a;
183 }
184
185 {
187 a[0U] = "ObjectEndMarker";
189 v[jss::nth] = 1;
190 v[jss::isVLEncoded] = false;
191 v[jss::isSerialized] = true;
192 v[jss::isSigningField] = true;
193 v[jss::type] = "STObject";
194 a[1U] = v;
195 defs_[jss::FIELDS][i++] = a;
196 }
197
198 {
200 a[0U] = "ArrayEndMarker";
202 v[jss::nth] = 1;
203 v[jss::isVLEncoded] = false;
204 v[jss::isSerialized] = true;
205 v[jss::isSigningField] = true;
206 v[jss::type] = "STArray";
207 a[1U] = v;
208 defs_[jss::FIELDS][i++] = a;
209 }
210
211 {
213 a[0U] = "taker_gets_funded";
215 v[jss::nth] = 258;
216 v[jss::isVLEncoded] = false;
217 v[jss::isSerialized] = false;
218 v[jss::isSigningField] = false;
219 v[jss::type] = "Amount";
220 a[1U] = v;
221 defs_[jss::FIELDS][i++] = a;
222 }
223
224 {
226 a[0U] = "taker_pays_funded";
228 v[jss::nth] = 259;
229 v[jss::isVLEncoded] = false;
230 v[jss::isSerialized] = false;
231 v[jss::isSigningField] = false;
232 v[jss::type] = "Amount";
233 a[1U] = v;
234 defs_[jss::FIELDS][i++] = a;
235 }
236
237 for (auto const& [code, f] : ripple::SField::getKnownCodeToField())
238 {
239 if (f->fieldName == "")
240 continue;
241
243
244 uint32_t type = f->fieldType;
245
246 innerObj[jss::nth] = f->fieldValue;
247
248 // whether the field is variable-length encoded
249 // this means that the length is included before the content
250 innerObj[jss::isVLEncoded] =
251 (type == 7U /* Blob */ || type == 8U /* AccountID */ ||
252 type == 19U /* Vector256 */);
253
254 // whether the field is included in serialization
255 innerObj[jss::isSerialized] =
256 (type < 10000 && f->fieldName != "hash" &&
257 f->fieldName != "index"); /* hash, index, TRANSACTION,
258 LEDGER_ENTRY, VALIDATION, METADATA */
259
260 // whether the field is included in serialization when signing
261 innerObj[jss::isSigningField] = f->shouldInclude(false);
262
263 innerObj[jss::type] = typeMap[type];
264
265 Json::Value innerArray = Json::arrayValue;
266 innerArray[0U] = f->fieldName;
267 innerArray[1U] = innerObj;
268
269 defs_[jss::FIELDS][i++] = innerArray;
270 }
271
272 // populate TER code names and values
273 defs_[jss::TRANSACTION_RESULTS] = Json::objectValue;
274
275 for (auto const& [code, terInfo] : transResults())
276 {
277 defs_[jss::TRANSACTION_RESULTS][terInfo.first] = code;
278 }
279
280 // populate TxType names and values
281 defs_[jss::TRANSACTION_TYPES] = Json::objectValue;
282 defs_[jss::TRANSACTION_TYPES][jss::Invalid] = -1;
283 for (auto const& f : TxFormats::getInstance())
284 {
285 defs_[jss::TRANSACTION_TYPES][f.getName()] = f.getType();
286 }
287
288 // generate hash
289 {
292 defs_[jss::hash] = to_string(defsHash_);
293 }
294}
295
296} // namespace detail
297
300{
301 auto& params = context.params;
302
303 uint256 hash;
304 if (params.isMember(jss::hash))
305 {
306 if (!params[jss::hash].isString() ||
307 !hash.parseHex(params[jss::hash].asString()))
308 return RPC::invalid_field_error(jss::hash);
309 }
310
311 static const detail::ServerDefinitions defs{};
312 if (defs.hashMatches(hash))
313 {
315 jv[jss::hash] = to_string(hash);
316 return jv;
317 }
318 return defs.get();
319}
320
323{
325
326 ret[jss::info] = context.netOps.getServerInfo(
327 true,
328 context.role == Role::ADMIN,
329 context.params.isMember(jss::counters) &&
330 context.params[jss::counters].asBool());
331
332 return ret;
333}
334
335} // 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:68
bool hashMatches(uint256 hash) const
Definition: ServerInfo.cpp:55
Json::Value const & get() const
Definition: ServerInfo.cpp:61
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:47
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:322
Json::Value doServerDefinitions(RPC::JsonContext &)
Definition: ServerInfo.cpp:299
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:43
Json::Value params
Definition: Context.h:63
T substr(T... args)