xrpld
Loading...
Searching...
No Matches
Submit.cpp
1#include <xrpld/app/ledger/LedgerMaster.h>
2#include <xrpld/app/misc/Transaction.h>
3#include <xrpld/rpc/Context.h>
4#include <xrpld/rpc/Role.h>
5#include <xrpld/rpc/detail/TransactionSign.h>
6
7#include <xrpl/basics/Slice.h>
8#include <xrpl/basics/StringUtilities.h>
9#include <xrpl/basics/safe_cast.h>
10#include <xrpl/basics/strHex.h>
11#include <xrpl/json/json_value.h>
12#include <xrpl/protocol/ErrorCodes.h>
13#include <xrpl/protocol/RPCErr.h>
14#include <xrpl/protocol/STTx.h>
15#include <xrpl/protocol/Serializer.h>
16#include <xrpl/protocol/TER.h>
17#include <xrpl/protocol/XRPAmount.h>
18#include <xrpl/protocol/jss.h>
19#include <xrpl/resource/Fees.h>
20#include <xrpl/tx/apply.h>
21
22#include <exception>
23#include <expected>
24#include <functional>
25#include <memory>
26
27namespace xrpl {
28
29static std::expected<NetworkOPs::FailHard, json::Value>
31{
32 if (context.params.isMember(jss::fail_hard) && !context.params[jss::fail_hard].isBool())
33 {
34 return std::unexpected(RPC::expectedFieldError(jss::fail_hard, "boolean"));
35 }
37 context.params.isMember(jss::fail_hard) && context.params[jss::fail_hard].asBool());
38}
39
40// {
41// tx_blob: <string> XOR tx_json: <object>,
42// secret: <secret>
43// }
46{
48
49 if (!context.params.isMember(jss::tx_blob))
50 {
51 auto const failType = getFailHard(context);
52 if (!failType)
53 return failType.error();
54
55 if (context.role != Role::ADMIN && !context.app.config().canSign())
56 return RPC::makeError(RpcNotSupported, "Signing is not supported by this server.");
57
58 auto ret = RPC::transactionSubmit(
59 context.params,
60 context.apiVersion,
61 *failType,
62 context.role,
64 context.app,
66
67 ret[jss::deprecated] =
68 "Signing support in the 'submit' command has been "
69 "deprecated and will be removed in a future version "
70 "of the server. Please migrate to a standalone "
71 "signing tool.";
72
73 return ret;
74 }
75
76 json::Value jvResult;
77
78 auto ret = strUnHex(context.params[jss::tx_blob].asString());
79
80 if (!ret || ret->empty())
82
83 SerialIter sitTrans(makeSlice(*ret));
84
86
87 try
88 {
89 stTx = std::make_shared<STTx const>(std::ref(sitTrans));
90 }
91 catch (std::exception& e)
92 {
93 jvResult[jss::error] = "invalidTransaction";
94 jvResult[jss::error_exception] = e.what();
95
96 return jvResult;
97 }
98
99 {
100 if (!context.app.checkSigs())
101 {
103 context.app.getHashRouter(), stTx->getTransactionID(), Validity::SigGoodOnly);
104 }
105 auto [validity, reason] = checkValidity(
106 context.app.getHashRouter(), *stTx, context.ledgerMaster.getCurrentLedger()->rules());
107 if (validity != Validity::Valid)
108 {
109 jvResult[jss::error] = "invalidTransaction";
110 jvResult[jss::error_exception] = "fails local checks: " + reason;
111
112 return jvResult;
113 }
114 }
115
116 std::string reason;
117 auto transaction = std::make_shared<Transaction>(stTx, reason, context.app);
118 if (transaction->getStatus() != TransStatus::NEW)
119 {
120 jvResult[jss::error] = "invalidTransaction";
121 jvResult[jss::error_exception] = "fails local checks: " + reason;
122
123 return jvResult;
124 }
125
126 try
127 {
128 auto const failType = getFailHard(context);
129 if (!failType)
130 return failType.error();
131
132 context.netOps.processTransaction(transaction, isUnlimited(context.role), true, *failType);
133 }
134 catch (std::exception& e)
135 {
136 jvResult[jss::error] = "internalSubmit";
137 jvResult[jss::error_exception] = e.what();
138
139 return jvResult;
140 }
141
142 try
143 {
144 jvResult[jss::tx_json] = transaction->getJson(JsonOptions::Values::None);
145 jvResult[jss::tx_blob] = strHex(transaction->getSTransaction()->getSerializer().peekData());
146
147 if (temUNCERTAIN != transaction->getResult())
148 {
149 std::string sToken;
150 std::string sHuman;
151
152 transResultInfo(transaction->getResult(), sToken, sHuman);
153
154 jvResult[jss::engine_result] = sToken;
155 jvResult[jss::engine_result_code] = transaction->getResult();
156 jvResult[jss::engine_result_message] = sHuman;
157
158 auto const submitResult = transaction->getSubmitResult();
159
160 jvResult[jss::accepted] = submitResult.any();
161 jvResult[jss::applied] = submitResult.applied;
162 jvResult[jss::broadcast] = submitResult.broadcast;
163 jvResult[jss::queued] = submitResult.queued;
164 jvResult[jss::kept] = submitResult.kept;
165
166 if (auto currentLedgerState = transaction->getCurrentLedgerState())
167 {
168 jvResult[jss::account_sequence_next] =
169 safeCast<json::Value::UInt>(currentLedgerState->accountSeqNext);
170 jvResult[jss::account_sequence_available] =
171 safeCast<json::Value::UInt>(currentLedgerState->accountSeqAvail);
172 jvResult[jss::open_ledger_cost] = to_string(currentLedgerState->minFeeRequired);
173 jvResult[jss::validated_ledger_index] =
174 safeCast<json::Value::UInt>(currentLedgerState->validatedLedger);
175 }
176 }
177
178 return jvResult;
179 }
180 catch (std::exception& e)
181 {
182 jvResult[jss::error] = "internalJson";
183 jvResult[jss::error_exception] = e.what();
184
185 return jvResult;
186 }
187}
188
189} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
bool asBool() const
bool isBool() const
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.
virtual Config & config()=0
virtual bool checkSigs() const =0
bool canSign() const
Definition Config.h:328
std::chrono::seconds getValidatedLedgerAge()
std::shared_ptr< ReadView const > getCurrentLedger()
static FailHard doFailHard(bool noMeansDont)
Definition NetworkOPs.h:77
virtual void processTransaction(std::shared_ptr< Transaction > &transaction, bool bUnlimited, bool bLocal, FailHard failType)=0
Process transactions as they arrive from the network or which are submitted by clients.
virtual HashRouter & getHashRouter()=0
T make_shared(T... args)
json::Value makeError(ErrorCodeI code)
Returns a new json object that reflects the error code.
json::Value transactionSubmit(json::Value jvRequest, unsigned apiVersion, NetworkOPs::FailHard failType, Role role, std::chrono::seconds validatedLedgerAge, Application &app, ProcessTransactionFn const &processTransaction)
Returns a json::ValueType::Object.
ProcessTransactionFn getProcessTxnFn(NetworkOPs &netOPs)
json::Value expectedFieldError(std::string const &name, std::string const &type)
Definition ErrorCodes.h:297
Charge const kFeeMediumBurdenRpc
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
@ RpcNotSupported
Definition ErrorCodes.h:114
@ RpcInvalidParams
Definition ErrorCodes.h:66
@ Valid
Signature and local checks are good / passed.
Definition apply.h:25
@ SigGoodOnly
Signature is good, but local checks fail.
Definition apply.h:23
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules)
Checks transaction signature and local checks.
Definition apply.cpp:37
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safeCast(Src s) noexcept
Definition safe_cast.h:21
bool transResultInfo(TER code, std::string &token, std::string &text)
Definition TER.cpp:232
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:633
json::Value rpcError(ErrorCodeI iError)
Definition RPCErr.cpp:13
@ ADMIN
Definition Role.h:24
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
static std::expected< NetworkOPs::FailHard, json::Value > getFailHard(RPC::JsonContext const &context)
Definition Submit.cpp:30
@ temUNCERTAIN
Definition TER.h:109
void forceValidity(HashRouter &router, uint256 const &txid, Validity validity)
Sets the validity of a given transaction in the cache.
Definition apply.cpp:112
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition Role.cpp:115
json::Value doSubmit(RPC::JsonContext &)
Definition Submit.cpp:45
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:215
T ref(T... args)
Application & app
Definition Context.h:21
Resource::Charge & loadType
Definition Context.h:22
unsigned int apiVersion
Definition Context.h:29
LedgerMaster & ledgerMaster
Definition Context.h:24
NetworkOPs & netOps
Definition Context.h:23
json::Value params
Definition Context.h:43
T unexpected(T... args)
T what(T... args)