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