rippled
Loading...
Searching...
No Matches
LedgerEntryHelpers.h
1#include <xrpld/rpc/detail/RPCHelpers.h>
2
3#include <xrpl/basics/StringUtilities.h>
4#include <xrpl/basics/strHex.h>
5#include <xrpl/beast/core/LexicalCast.h>
6#include <xrpl/json/json_errors.h>
7#include <xrpl/protocol/ErrorCodes.h>
8#include <xrpl/protocol/Indexes.h>
9#include <xrpl/protocol/RPCErr.h>
10#include <xrpl/protocol/STXChainBridge.h>
11#include <xrpl/protocol/jss.h>
12
13#include <functional>
14
15namespace ripple {
16
17namespace LedgerEntryHelpers {
18
21 Json::StaticString const field,
23{
25 auto error = RPC::missing_field_message(std::string(field.c_str()));
26 json[jss::error] = err.value_or("malformedRequest");
27 json[jss::error_code] = rpcINVALID_PARAMS;
28 json[jss::error_message] = std::move(error);
29 return Unexpected(json);
30}
31
34 std::string const& err,
35 Json::StaticString const field,
36 std::string const& type)
37{
39 auto error = RPC::expected_field_message(field, type);
40 json[jss::error] = err;
41 json[jss::error_code] = rpcINVALID_PARAMS;
42 json[jss::error_message] = std::move(error);
43 return Unexpected(json);
44}
45
47malformedError(std::string const& err, std::string const& message)
48{
50 json[jss::error] = err;
51 json[jss::error_code] = rpcINVALID_PARAMS;
52 json[jss::error_message] = message;
53 return Unexpected(json);
54}
55
58 Json::Value const& params,
61{
62 for (auto const field : fields)
63 {
64 if (!params.isMember(field) || params[field].isNull())
65 {
66 return missingFieldError(field, err);
67 }
68 }
69 return true;
70}
71
72template <class T>
74parse(Json::Value const& param);
75
76template <class T>
79 Json::Value const& params,
80 Json::StaticString const fieldName,
81 std::string const& err,
82 std::string const& expectedType)
83{
84 if (!params.isMember(fieldName) || params[fieldName].isNull())
85 {
86 return missingFieldError(fieldName);
87 }
88 if (auto obj = parse<T>(params[fieldName]))
89 {
90 return *obj;
91 }
92 return invalidFieldError(err, fieldName, expectedType);
93}
94
95template <>
97parse(Json::Value const& param)
98{
99 if (!param.isString())
100 return std::nullopt;
101
102 auto const account = parseBase58<AccountID>(param.asString());
103 if (!account || account->isZero())
104 {
105 return std::nullopt;
106 }
107
108 return account;
109}
110
113 Json::Value const& params,
114 Json::StaticString const fieldName,
115 std::string const& err)
116{
117 return required<AccountID>(params, fieldName, err, "AccountID");
118}
119
121parseHexBlob(Json::Value const& param, std::size_t maxLength)
122{
123 if (!param.isString())
124 return std::nullopt;
125
126 auto const blob = strUnHex(param.asString());
127 if (!blob || blob->empty() || blob->size() > maxLength)
128 return std::nullopt;
129
130 return blob;
131}
132
135 Json::Value const& params,
136 Json::StaticString const fieldName,
137 std::size_t maxLength,
138 std::string const& err)
139{
140 if (!params.isMember(fieldName) || params[fieldName].isNull())
141 {
142 return missingFieldError(fieldName);
143 }
144 if (auto blob = parseHexBlob(params[fieldName], maxLength))
145 {
146 return *blob;
147 }
148 return invalidFieldError(err, fieldName, "hex string");
149}
150
151template <>
153parse(Json::Value const& param)
154{
155 if (param.isUInt() || (param.isInt() && param.asInt() >= 0))
156 return param.asUInt();
157
158 if (param.isString())
159 {
161 if (beast::lexicalCastChecked(v, param.asString()))
162 return v;
163 }
164
165 return std::nullopt;
166}
167
170 Json::Value const& params,
171 Json::StaticString const fieldName,
172 std::string const& err)
173{
174 return required<std::uint32_t>(params, fieldName, err, "number");
175}
176
177template <>
179parse(Json::Value const& param)
180{
181 uint256 uNodeIndex;
182 if (!param.isString() || !uNodeIndex.parseHex(param.asString()))
183 {
184 return std::nullopt;
185 }
186
187 return uNodeIndex;
188}
189
192 Json::Value const& params,
193 Json::StaticString const fieldName,
194 std::string const& err)
195{
196 return required<uint256>(params, fieldName, err, "Hash256");
197}
198
199template <>
201parse(Json::Value const& param)
202{
203 uint192 field;
204 if (!param.isString() || !field.parseHex(param.asString()))
205 {
206 return std::nullopt;
207 }
208
209 return field;
210}
211
214 Json::Value const& params,
215 Json::StaticString const fieldName,
216 std::string const& err)
217{
218 return required<uint192>(params, fieldName, err, "Hash192");
219}
220
223{
224 if (auto const value = hasRequired(
225 params,
226 {jss::LockingChainDoor,
227 jss::LockingChainIssue,
228 jss::IssuingChainDoor,
229 jss::IssuingChainIssue});
230 !value)
231 {
232 return Unexpected(value.error());
233 }
234
235 auto const lockingChainDoor = requiredAccountID(
236 params, jss::LockingChainDoor, "malformedLockingChainDoor");
237 if (!lockingChainDoor)
238 {
239 return Unexpected(lockingChainDoor.error());
240 }
241
242 auto const issuingChainDoor = requiredAccountID(
243 params, jss::IssuingChainDoor, "malformedIssuingChainDoor");
244 if (!issuingChainDoor)
245 {
246 return Unexpected(issuingChainDoor.error());
247 }
248
249 Issue lockingChainIssue;
250 try
251 {
252 lockingChainIssue = issueFromJson(params[jss::LockingChainIssue]);
253 }
254 catch (std::runtime_error const& ex)
255 {
256 return invalidFieldError(
257 "malformedIssue", jss::LockingChainIssue, "Issue");
258 }
259
260 Issue issuingChainIssue;
261 try
262 {
263 issuingChainIssue = issueFromJson(params[jss::IssuingChainIssue]);
264 }
265 catch (std::runtime_error const& ex)
266 {
267 return invalidFieldError(
268 "malformedIssue", jss::IssuingChainIssue, "Issue");
269 }
270
271 return STXChainBridge(
272 *lockingChainDoor,
273 lockingChainIssue,
274 *issuingChainDoor,
275 issuingChainIssue);
276}
277
278} // namespace LedgerEntryHelpers
279
280} // namespace ripple
Lightweight wrapper to tag static string.
Definition json_value.h:44
Represents a JSON value.
Definition json_value.h:130
Int asInt() const
bool isString() const
UInt asUInt() const
std::string asString() const
Returns the unquoted string value.
bool isUInt() const
bool isNull() const
isNull() tests to see if this field is null.
bool isMember(char const *key) const
Return true if the object has a member named key.
bool isInt() const
A currency issued by an account.
Definition Issue.h:14
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:484
T is_same_v
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
std::optional< Blob > parseHexBlob(Json::Value const &param, std::size_t maxLength)
Expected< T, Json::Value > required(Json::Value const &params, Json::StaticString const fieldName, std::string const &err, std::string const &expectedType)
Expected< STXChainBridge, Json::Value > parseBridgeFields(Json::Value const &params)
Unexpected< Json::Value > malformedError(std::string const &err, std::string const &message)
Unexpected< Json::Value > invalidFieldError(std::string const &err, Json::StaticString const field, std::string const &type)
std::optional< T > parse(Json::Value const &param)
Expected< uint256, Json::Value > requiredUInt256(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Unexpected< Json::Value > missingFieldError(Json::StaticString const field, std::optional< std::string > err=std::nullopt)
Expected< bool, Json::Value > hasRequired(Json::Value const &params, std::initializer_list< Json::StaticString > fields, std::optional< std::string > err=std::nullopt)
Expected< AccountID, Json::Value > requiredAccountID(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Expected< std::uint32_t, Json::Value > requiredUInt32(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Expected< uint192, Json::Value > requiredUInt192(Json::Value const &params, Json::StaticString const fieldName, std::string const &err)
Expected< Blob, Json::Value > requiredHexBlob(Json::Value const &params, Json::StaticString const fieldName, std::size_t maxLength, std::string const &err)
std::string missing_field_message(std::string const &name)
Definition ErrorCodes.h:258
std::string expected_field_message(std::string const &name, std::string const &type)
Definition ErrorCodes.h:318
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:65
Issue issueFromJson(Json::Value const &v)
Definition Issue.cpp:76