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 detail::ServerDefinitions const 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(Value const &root) override
Represents a JSON value.
Definition json_value.h:149
bool asBool() const
bool isMember(char const *key) const
Return true if the object has a member named key.
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
static LedgerFormats const & getInstance()
virtual Json::Value getServerInfo(bool human, bool admin, bool counters)=0
static std::unordered_map< int, SField const * > const & getKnownCodeToField()
Definition SField.h:304
An immutable linear range of bytes.
Definition Slice.h:46
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:98
static TxFormats const & getInstance()
Definition TxFormats.cpp:71
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)
bool hashMatches(uint256 hash) const
Json::Value const & get() const
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:44
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:45
Json::Value invalid_field_error(std::string const &name)
Definition ErrorCodes.h:325
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:25
static std::map< std::string, int > const sTypeMap
Definition SField.h:110
Json::Value doServerInfo(RPC::JsonContext &)
Json::Value doServerDefinitions(RPC::JsonContext &)
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:224
T size(T... args)
NetworkOPs & netOps
Definition Context.h:43
T substr(T... args)