rippled
Loading...
Searching...
No Matches
DepositAuthorized.cpp
1#include <xrpld/rpc/Context.h>
2#include <xrpld/rpc/detail/RPCHelpers.h>
3
4#include <xrpl/ledger/CredentialHelpers.h>
5#include <xrpl/ledger/ReadView.h>
6#include <xrpl/protocol/ErrorCodes.h>
7#include <xrpl/protocol/Indexes.h>
8#include <xrpl/protocol/RPCErr.h>
9#include <xrpl/protocol/jss.h>
10
11namespace ripple {
12
13// {
14// source_account : <ident>
15// destination_account : <ident>
16// ledger_hash : <ledger>
17// ledger_index : <ledger_index>
18// credentials : [<credentialID>,...]
19// }
20
23{
24 Json::Value const& params = context.params;
25
26 // Validate source_account.
27 if (!params.isMember(jss::source_account))
28 return RPC::missing_field_error(jss::source_account);
29 if (!params[jss::source_account].isString())
30 return RPC::make_error(
32 RPC::expected_field_message(jss::source_account, "a string"));
33
34 auto srcID = parseBase58<AccountID>(params[jss::source_account].asString());
35 if (!srcID)
37 auto const srcAcct{std::move(srcID.value())};
38
39 // Validate destination_account.
40 if (!params.isMember(jss::destination_account))
41 return RPC::missing_field_error(jss::destination_account);
42 if (!params[jss::destination_account].isString())
43 return RPC::make_error(
45 RPC::expected_field_message(jss::destination_account, "a string"));
46
47 auto dstID =
48 parseBase58<AccountID>(params[jss::destination_account].asString());
49 if (!dstID)
51 auto const dstAcct{std::move(dstID.value())};
52
53 // Validate ledger.
55 Json::Value result = RPC::lookupLedger(ledger, context);
56
57 if (!ledger)
58 return result;
59
60 // If source account is not in the ledger it can't be authorized.
61 if (!ledger->exists(keylet::account(srcAcct)))
62 {
64 return result;
65 }
66
67 // If destination account is not in the ledger you can't deposit to it, eh?
68 auto const sleDest = ledger->read(keylet::account(dstAcct));
69 if (!sleDest)
70 {
72 return result;
73 }
74
75 bool const reqAuth =
76 (sleDest->getFlags() & lsfDepositAuth) && (srcAcct != dstAcct);
77 bool const credentialsPresent = params.isMember(jss::credentials);
78
81 if (credentialsPresent)
82 {
83 auto const& creds(params[jss::credentials]);
84 if (!creds.isArray() || !creds)
85 {
86 return RPC::make_error(
89 jss::credentials,
90 "is non-empty array of CredentialID(hash256)"));
91 }
92 else if (creds.size() > maxCredentialsArraySize)
93 {
94 return RPC::make_error(
97 jss::credentials, "array too long"));
98 }
99
100 lifeExtender.reserve(creds.size());
101 for (auto const& jo : creds)
102 {
103 if (!jo.isString())
104 {
105 return RPC::make_error(
108 jss::credentials, "an array of CredentialID(hash256)"));
109 }
110
111 uint256 credH;
112 auto const credS = jo.asString();
113 if (!credH.parseHex(credS))
114 {
115 return RPC::make_error(
118 jss::credentials, "an array of CredentialID(hash256)"));
119 }
120
122 ledger->read(keylet::credential(credH));
123 if (!sleCred)
124 {
126 rpcBAD_CREDENTIALS, "credentials don't exist", result);
127 return result;
128 }
129
130 if (!(sleCred->getFlags() & lsfAccepted))
131 {
133 rpcBAD_CREDENTIALS, "credentials aren't accepted", result);
134 return result;
135 }
136
138 sleCred, ledger->info().parentCloseTime))
139 {
141 rpcBAD_CREDENTIALS, "credentials are expired", result);
142 return result;
143 }
144
145 if ((*sleCred)[sfSubject] != srcAcct)
146 {
149 "credentials doesn't belong to the root account",
150 result);
151 return result;
152 }
153
154 auto [it, ins] = sorted.emplace(
155 (*sleCred)[sfIssuer], (*sleCred)[sfCredentialType]);
156 if (!ins)
157 {
159 rpcBAD_CREDENTIALS, "duplicates in credentials", result);
160 return result;
161 }
162 lifeExtender.push_back(std::move(sleCred));
163 }
164 }
165
166 // If the two accounts are the same OR if that flag is
167 // not set, then the deposit should be fine.
168 bool depositAuthorized = true;
169 if (reqAuth)
170 depositAuthorized =
171 ledger->exists(keylet::depositPreauth(dstAcct, srcAcct)) ||
172 (credentialsPresent &&
173 ledger->exists(keylet::depositPreauth(dstAcct, sorted)));
174
175 result[jss::source_account] = params[jss::source_account].asString();
176 result[jss::destination_account] =
177 params[jss::destination_account].asString();
178 if (credentialsPresent)
179 result[jss::credentials] = params[jss::credentials];
180
181 result[jss::deposit_authorized] = depositAuthorized;
182 return result;
183}
184
185} // namespace ripple
Represents a JSON value.
Definition json_value.h:131
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:484
T emplace(T... args)
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
void inject_error(error_code_i code, JsonValue &json)
Add or update the json update to reflect the error code.
Definition ErrorCodes.h:214
std::string expected_field_message(std::string const &name, std::string const &type)
Definition ErrorCodes.h:318
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext &context, Json::Value &result)
Look up a ledger from a request and fill a Json::Result with the data representing a ledger.
Json::Value missing_field_error(std::string const &name)
Definition ErrorCodes.h:264
bool checkExpired(std::shared_ptr< SLE const > const &sleCredential, NetClock::time_point const &closed)
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition Indexes.cpp:534
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:165
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition Indexes.cpp:323
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
@ rpcSRC_ACT_NOT_FOUND
Definition ErrorCodes.h:103
@ rpcACT_MALFORMED
Definition ErrorCodes.h:71
@ rpcBAD_CREDENTIALS
Definition ErrorCodes.h:133
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:65
@ rpcDST_ACT_NOT_FOUND
Definition ErrorCodes.h:86
Json::Value rpcError(int iError)
Definition RPCErr.cpp:12
Json::Value doDepositAuthorized(RPC::JsonContext &context)
std::size_t constexpr maxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition Protocol.h:90
T push_back(T... args)
T reserve(T... args)