rippled
Submit.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 <ripple/app/ledger/LedgerMaster.h>
21 #include <ripple/app/misc/HashRouter.h>
22 #include <ripple/app/misc/Transaction.h>
23 #include <ripple/app/tx/apply.h>
24 #include <ripple/basics/SubmitSync.h>
25 #include <ripple/net/RPCErr.h>
26 #include <ripple/protocol/ErrorCodes.h>
27 #include <ripple/resource/Fees.h>
28 #include <ripple/rpc/Context.h>
29 #include <ripple/rpc/GRPCHandlers.h>
30 #include <ripple/rpc/impl/RPCHelpers.h>
31 #include <ripple/rpc/impl/TransactionSign.h>
32 
33 namespace ripple {
34 
37 {
39  context.params.isMember("fail_hard") &&
40  context.params["fail_hard"].asBool());
41 }
42 
43 // {
44 // tx_json: <object>,
45 // secret: <secret>
46 // }
49 {
51 
52  auto const sync = RPC::getSubmitSyncMode(context.params);
53  if (!sync)
54  return sync.error();
55 
56  if (!context.params.isMember(jss::tx_blob))
57  {
58  auto const failType = getFailHard(context);
59 
60  if (context.role != Role::ADMIN && !context.app.config().canSign())
61  return RPC::make_error(
62  rpcNOT_SUPPORTED, "Signing is not supported by this server.");
63 
64  auto ret = RPC::transactionSubmit(
65  context.params,
66  failType,
67  context.role,
69  context.app,
71  *sync);
72 
73  ret[jss::deprecated] =
74  "Signing support in the 'submit' command has been "
75  "deprecated and will be removed in a future version "
76  "of the server. Please migrate to a standalone "
77  "signing tool.";
78 
79  return ret;
80  }
81 
82  Json::Value jvResult;
83 
84  auto ret = strUnHex(context.params[jss::tx_blob].asString());
85 
86  if (!ret || !ret->size())
88 
89  SerialIter sitTrans(makeSlice(*ret));
90 
92 
93  try
94  {
95  stpTrans = std::make_shared<STTx const>(std::ref(sitTrans));
96  }
97  catch (std::exception& e)
98  {
99  jvResult[jss::error] = "invalidTransaction";
100  jvResult[jss::error_exception] = e.what();
101 
102  return jvResult;
103  }
104 
105  {
106  if (!context.app.checkSigs())
108  context.app.getHashRouter(),
109  stpTrans->getTransactionID(),
111  auto [validity, reason] = checkValidity(
112  context.app.getHashRouter(),
113  *stpTrans,
114  context.ledgerMaster.getCurrentLedger()->rules(),
115  context.app.config());
116  if (validity != Validity::Valid)
117  {
118  jvResult[jss::error] = "invalidTransaction";
119  jvResult[jss::error_exception] = "fails local checks: " + reason;
120 
121  return jvResult;
122  }
123  }
124 
125  std::string reason;
126  auto tpTrans = std::make_shared<Transaction>(stpTrans, reason, context.app);
127  if (tpTrans->getStatus() != NEW)
128  {
129  jvResult[jss::error] = "invalidTransaction";
130  jvResult[jss::error_exception] = "fails local checks: " + reason;
131 
132  return jvResult;
133  }
134 
135  try
136  {
137  auto const failType = getFailHard(context);
138 
139  context.netOps.processTransaction(
140  tpTrans, isUnlimited(context.role), *sync, true, failType);
141  }
142  catch (std::exception& e)
143  {
144  jvResult[jss::error] = "internalSubmit";
145  jvResult[jss::error_exception] = e.what();
146 
147  return jvResult;
148  }
149 
150  try
151  {
152  jvResult[jss::tx_json] = tpTrans->getJson(JsonOptions::none);
153  jvResult[jss::tx_blob] =
154  strHex(tpTrans->getSTransaction()->getSerializer().peekData());
155 
156  if (temUNCERTAIN != tpTrans->getResult())
157  {
158  std::string sToken;
159  std::string sHuman;
160 
161  transResultInfo(tpTrans->getResult(), sToken, sHuman);
162 
163  jvResult[jss::engine_result] = sToken;
164  jvResult[jss::engine_result_code] = tpTrans->getResult();
165  jvResult[jss::engine_result_message] = sHuman;
166 
167  auto const submitResult = tpTrans->getSubmitResult();
168 
169  jvResult[jss::accepted] = submitResult.any();
170  jvResult[jss::applied] = submitResult.applied;
171  jvResult[jss::broadcast] = submitResult.broadcast;
172  jvResult[jss::queued] = submitResult.queued;
173  jvResult[jss::kept] = submitResult.kept;
174 
175  if (auto currentLedgerState = tpTrans->getCurrentLedgerState())
176  {
177  jvResult[jss::account_sequence_next] =
178  safe_cast<Json::Value::UInt>(
179  currentLedgerState->accountSeqNext);
180  jvResult[jss::account_sequence_available] =
181  safe_cast<Json::Value::UInt>(
182  currentLedgerState->accountSeqAvail);
183  jvResult[jss::open_ledger_cost] =
184  to_string(currentLedgerState->minFeeRequired);
185  jvResult[jss::validated_ledger_index] =
186  safe_cast<Json::Value::UInt>(
187  currentLedgerState->validatedLedger);
188  }
189  }
190 
191  return jvResult;
192  }
193  catch (std::exception& e)
194  {
195  jvResult[jss::error] = "internalJson";
196  jvResult[jss::error_exception] = e.what();
197 
198  return jvResult;
199  }
200 }
201 
202 } // namespace ripple
ripple::Application::checkSigs
virtual bool checkSigs() const =0
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::rpcNOT_SUPPORTED
@ rpcNOT_SUPPORTED
Definition: ErrorCodes.h:132
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:241
std::string
STL class.
std::shared_ptr
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
std::exception
STL class.
ripple::Resource::feeMediumBurdenRPC
const Charge feeMediumBurdenRPC
ripple::RPC::Context::loadType
Resource::Charge & loadType
Definition: Context.h:43
ripple::NEW
@ NEW
Definition: Transaction.h:46
ripple::RPC::Context::ledgerMaster
LedgerMaster & ledgerMaster
Definition: Context.h:45
ripple::RPC::transactionSubmit
Json::Value transactionSubmit(Json::Value jvRequest, NetworkOPs::FailHard failType, Role role, std::chrono::seconds validatedLedgerAge, Application &app, ProcessTransactionFn const &processTransaction, RPC::SubmitSync sync)
Returns a Json::objectValue.
Definition: TransactionSign.cpp:799
ripple::NetworkOPs::processTransaction
virtual void processTransaction(std::shared_ptr< Transaction > &transaction, bool bUnlimited, RPC::SubmitSync sync, bool bLocal, FailHard failType)=0
Process a transaction.
ripple::RPC::Context::role
Role role
Definition: Context.h:47
ripple::forceValidity
void forceValidity(HashRouter &router, uint256 const &txid, Validity validity)
Sets the validity of a given transaction in the cache.
Definition: apply.cpp:89
Json::Value::asBool
bool asBool() const
Definition: json_value.cpp:619
ripple::temUNCERTAIN
@ temUNCERTAIN
Definition: TER.h:121
ripple::Validity::SigGoodOnly
@ SigGoodOnly
Signature is good, but local checks fail.
ripple::RPC::getProcessTxnFn
ProcessTransactionFn getProcessTxnFn(NetworkOPs &netOPs)
Definition: TransactionSign.h:83
ripple::checkValidity
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
Definition: apply.cpp:37
ripple::doSubmit
Json::Value doSubmit(RPC::JsonContext &)
Definition: Submit.cpp:48
ripple::Role::ADMIN
@ ADMIN
ripple::JsonOptions::none
@ none
ripple::Application::config
virtual Config & config()=0
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
ripple::getFailHard
static NetworkOPs::FailHard getFailHard(RPC::JsonContext const &context)
Definition: Submit.cpp:36
ripple::SerialIter
Definition: Serializer.h:311
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
ripple::Config::canSign
bool canSign() const
Definition: Config.h:362
ripple::NetworkOPs::FailHard
FailHard
Definition: NetworkOPs.h:95
ripple::LedgerMaster::getCurrentLedger
std::shared_ptr< ReadView const > getCurrentLedger()
Definition: LedgerMaster.cpp:1659
ripple::RPC::Context::netOps
NetworkOPs & netOps
Definition: Context.h:44
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:191
ripple::isUnlimited
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Definition: Role.cpp:124
ripple::LedgerMaster::getValidatedLedgerAge
std::chrono::seconds getValidatedLedgerAge()
Definition: LedgerMaster.cpp:274
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::transResultInfo
bool transResultInfo(TER code, std::string &token, std::string &text)
Definition: TER.cpp:206
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
ripple::RPC::getSubmitSyncMode
ripple::Expected< RPC::SubmitSync, Json::Value > getSubmitSyncMode(Json::Value const &params)
Helper to parse submit_mode parameter to RPC submit.
Definition: RPCHelpers.cpp:1171
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::NetworkOPs::doFailHard
static FailHard doFailHard(bool noMeansDont)
Definition: NetworkOPs.h:97
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
ripple::strUnHex
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Definition: StringUtilities.h:52
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
ripple::Application::getHashRouter
virtual HashRouter & getHashRouter()=0
ripple::RPC::make_error
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
Definition: ErrorCodes.cpp:179
std::ref
T ref(T... args)
std::exception::what
T what(T... args)
Json::Value
Represents a JSON value.
Definition: json_value.h:145
Json::Value::asString
std::string asString() const
Returns the unquoted string value.
Definition: json_value.cpp:469