xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
xrpld
rpc
handlers
orderbook
DepositAuthorized.cpp
1
#include <xrpld/rpc/Context.h>
2
#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
3
4
#include <xrpl/basics/Slice.h>
5
#include <xrpl/basics/base_uint.h>
6
#include <xrpl/core/ServiceRegistry.h>
7
#include <xrpl/json/json_value.h>
8
#include <xrpl/ledger/ReadView.h>
9
#include <xrpl/ledger/helpers/CredentialHelpers.h>
10
#include <xrpl/protocol/AccountID.h>
11
#include <xrpl/protocol/ErrorCodes.h>
12
#include <xrpl/protocol/Indexes.h>
13
#include <xrpl/protocol/LedgerFormats.h>
14
#include <xrpl/protocol/Protocol.h>
15
#include <xrpl/protocol/RPCErr.h>
16
#include <xrpl/protocol/SField.h>
17
#include <xrpl/protocol/jss.h>
18
19
#include <
memory
>
20
#include <
set
>
21
#include <
utility
>
22
#include <
vector
>
23
24
namespace
xrpl
{
25
26
// {
27
// source_account : <ident>
28
// destination_account : <ident>
29
// ledger_hash : <ledger>
30
// ledger_index : <ledger_index>
31
// credentials : [<credentialID>,...]
32
// }
33
34
json::Value
35
doDepositAuthorized
(
rpc::JsonContext
& context)
36
{
37
json::Value
const
& params = context.
params
;
38
39
// Validate source_account.
40
if
(!params.
isMember
(jss::source_account))
41
return
rpc::missingFieldError
(jss::source_account);
42
if
(!params[jss::source_account].isString())
43
{
44
return
rpc::makeError
(
45
RpcInvalidParams
,
rpc::expectedFieldMessage
(jss::source_account,
"a string"
));
46
}
47
48
auto
srcID =
parseBase58<AccountID>
(params[jss::source_account].asString());
49
if
(!srcID)
50
return
rpcError
(
RpcActMalformed
);
51
auto
const
srcAcct{srcID.value()};
52
53
// Validate destination_account.
54
if
(!params.
isMember
(jss::destination_account))
55
return
rpc::missingFieldError
(jss::destination_account);
56
if
(!params[jss::destination_account].isString())
57
{
58
return
rpc::makeError
(
59
RpcInvalidParams
,
rpc::expectedFieldMessage
(jss::destination_account,
"a string"
));
60
}
61
62
auto
dstID =
parseBase58<AccountID>
(params[jss::destination_account].asString());
63
if
(!dstID)
64
return
rpcError
(
RpcActMalformed
);
65
auto
const
dstAcct{dstID.value()};
66
67
// Validate ledger.
68
std::shared_ptr<ReadView const>
ledger;
69
json::Value
result =
rpc::lookupLedger
(ledger, context);
70
71
if
(!ledger)
72
return
result;
73
74
// If source account is not in the ledger it can't be authorized.
75
if
(!ledger->exists(
keylet::account
(srcAcct)))
76
{
77
rpc::injectError
(
RpcSrcActNotFound
, result);
78
return
result;
79
}
80
81
// If destination account is not in the ledger you can't deposit to it, eh?
82
auto
const
sleDest = ledger->read(
keylet::account
(dstAcct));
83
if
(!sleDest)
84
{
85
rpc::injectError
(
RpcDstActNotFound
, result);
86
return
result;
87
}
88
89
bool
const
reqAuth = sleDest->isFlag(lsfDepositAuth) && (srcAcct != dstAcct);
90
bool
const
credentialsPresent = params.
isMember
(jss::credentials);
91
92
std::set<std::pair<AccountID, Slice>
> sorted;
93
std::vector<SLE::const_pointer>
lifeExtender;
94
if
(credentialsPresent)
95
{
96
auto
const
& creds(params[jss::credentials]);
97
if
(!creds.isArray() || !creds)
98
{
99
return
rpc::makeError
(
100
RpcInvalidParams
,
101
rpc::expectedFieldMessage
(
102
jss::credentials,
"is non-empty array of CredentialID(hash256)"
));
103
}
104
if
(creds.size() >
kMaxCredentialsArraySize
)
105
{
106
return
rpc::makeError
(
107
RpcInvalidParams
,
rpc::expectedFieldMessage
(jss::credentials,
"array too long"
));
108
}
109
110
lifeExtender.
reserve
(creds.size());
111
for
(
auto
const
& jo : creds)
112
{
113
if
(!jo.isString())
114
{
115
return
rpc::makeError
(
116
RpcInvalidParams
,
117
rpc::expectedFieldMessage
(
118
jss::credentials,
"an array of CredentialID(hash256)"
));
119
}
120
121
UInt256
credH;
122
auto
const
credS = jo.asString();
123
if
(!credH.
parseHex
(credS))
124
{
125
return
rpc::makeError
(
126
RpcInvalidParams
,
127
rpc::expectedFieldMessage
(
128
jss::credentials,
"an array of CredentialID(hash256)"
));
129
}
130
131
SLE::const_pointer
sleCred = ledger->read(
keylet::credential
(credH));
132
if
(!sleCred)
133
{
134
rpc::injectError
(
RpcBadCredentials
,
"credentials don't exist"
, result);
135
return
result;
136
}
137
138
if
(!sleCred->isFlag(lsfAccepted))
139
{
140
rpc::injectError
(
RpcBadCredentials
,
"credentials aren't accepted"
, result);
141
return
result;
142
}
143
144
if
(
credentials::checkExpired
(*sleCred, ledger->header().parentCloseTime))
145
{
146
rpc::injectError
(
RpcBadCredentials
,
"credentials are expired"
, result);
147
return
result;
148
}
149
150
if
((*sleCred)[sfSubject] != srcAcct)
151
{
152
rpc::injectError
(
153
RpcBadCredentials
,
"credentials doesn't belong to the root account"
, result);
154
return
result;
155
}
156
157
auto
[it, ins] = sorted.
emplace
((*sleCred)[sfIssuer], (*sleCred)[sfCredentialType]);
158
if
(!ins)
159
{
160
rpc::injectError
(
RpcBadCredentials
,
"duplicates in credentials"
, result);
161
return
result;
162
}
163
lifeExtender.
push_back
(std::move(sleCred));
164
}
165
}
166
167
// If the two accounts are the same OR if that flag is
168
// not set, then the deposit should be fine.
169
bool
depositAuthorized =
true
;
170
if
(reqAuth)
171
{
172
depositAuthorized = ledger->exists(
keylet::depositPreauth
(dstAcct, srcAcct)) ||
173
(credentialsPresent && ledger->exists(
keylet::depositPreauth
(dstAcct, sorted)));
174
}
175
176
result[jss::source_account] = params[jss::source_account].
asString
();
177
result[jss::destination_account] = 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 xrpl
json::Value
Represents a JSON value.
Definition
json_value.h:117
json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition
json_value.cpp:494
json::Value::isMember
bool isMember(char const *key) const
Return true if the object has a member named key.
Definition
json_value.cpp:1049
xrpl::BaseUInt::parseHex
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition
base_uint.h:525
xrpl::STLedgerEntry::const_pointer
std::shared_ptr< STLedgerEntry const > const_pointer
Definition
STLedgerEntry.h:36
std::set::emplace
T emplace(T... args)
memory
xrpl::credentials::checkExpired
bool checkExpired(SLE const &sleCredential, NetClock::time_point const &closed)
Definition
CredentialHelpers.cpp:38
xrpl::keylet::depositPreauth
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
Definition
Indexes.cpp:374
xrpl::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition
Indexes.cpp:220
xrpl::keylet::credential
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
Definition
Indexes.cpp:585
xrpl::rpc::injectError
void injectError(ErrorCodeI code, json::Value &json)
Add or update the json update to reflect the error code.
Definition
ErrorCodes.cpp:164
xrpl::rpc::expectedFieldMessage
std::string expectedFieldMessage(std::string const &name, std::string const &type)
Definition
ErrorCodes.h:297
xrpl::rpc::missingFieldError
json::Value missingFieldError(std::string const &name)
Definition
ErrorCodes.h:243
xrpl::rpc::makeError
json::Value makeError(ErrorCodeI code)
Returns a new json object that reflects the error code.
Definition
ErrorCodes.cpp:190
xrpl::rpc::lookupLedger
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext const &context, json::Value &result)
Looks up a ledger from a request and fills a json::Value with ledger data.
Definition
RPCLedgerHelpers.cpp:390
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::RpcDstActNotFound
@ RpcDstActNotFound
Definition
ErrorCodes.h:88
xrpl::RpcBadCredentials
@ RpcBadCredentials
Definition
ErrorCodes.h:135
xrpl::RpcActMalformed
@ RpcActMalformed
Definition
ErrorCodes.h:73
xrpl::RpcInvalidParams
@ RpcInvalidParams
Definition
ErrorCodes.h:67
xrpl::RpcSrcActNotFound
@ RpcSrcActNotFound
Definition
ErrorCodes.h:105
xrpl::parseBase58
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
Definition
AccountID.cpp:105
xrpl::rpcError
json::Value rpcError(ErrorCodeI iError)
Definition
RPCErr.cpp:13
xrpl::UInt256
BaseUInt< 256 > UInt256
Definition
base_uint.h:580
xrpl::kMaxCredentialsArraySize
constexpr std::size_t kMaxCredentialsArraySize
The maximum number of credentials can be passed in array.
Definition
Protocol.h:281
xrpl::doDepositAuthorized
json::Value doDepositAuthorized(rpc::JsonContext &)
Definition
DepositAuthorized.cpp:35
std::vector::push_back
T push_back(T... args)
std::vector::reserve
T reserve(T... args)
set
std::shared_ptr
xrpl::rpc::JsonContext
Definition
Context.h:41
xrpl::rpc::JsonContext::params
json::Value params
Definition
Context.h:51
utility
vector
Generated by
1.17.0