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  context.apiVersion,
67  failType,
68  context.role,
70  context.app,
72  *sync);
73 
74  ret[jss::deprecated] =
75  "Signing support in the 'submit' command has been "
76  "deprecated and will be removed in a future version "
77  "of the server. Please migrate to a standalone "
78  "signing tool.";
79 
80  return ret;
81  }
82 
83  Json::Value jvResult;
84 
85  auto ret = strUnHex(context.params[jss::tx_blob].asString());
86 
87  if (!ret || !ret->size())
89 
90  SerialIter sitTrans(makeSlice(*ret));
91 
93 
94  try
95  {
96  stpTrans = std::make_shared<STTx const>(std::ref(sitTrans));
97  }
98  catch (std::exception& e)
99  {
100  jvResult[jss::error] = "invalidTransaction";
101  jvResult[jss::error_exception] = e.what();
102 
103  return jvResult;
104  }
105 
106  {
107  if (!context.app.checkSigs())
109  context.app.getHashRouter(),
110  stpTrans->getTransactionID(),
112  auto [validity, reason] = checkValidity(
113  context.app.getHashRouter(),
114  *stpTrans,
115  context.ledgerMaster.getCurrentLedger()->rules(),
116  context.app.config());
117  if (validity != Validity::Valid)
118  {
119  jvResult[jss::error] = "invalidTransaction";
120  jvResult[jss::error_exception] = "fails local checks: " + reason;
121 
122  return jvResult;
123  }
124  }
125 
126  std::string reason;
127  auto tpTrans = std::make_shared<Transaction>(stpTrans, reason, context.app);
128  if (tpTrans->getStatus() != NEW)
129  {
130  jvResult[jss::error] = "invalidTransaction";
131  jvResult[jss::error_exception] = "fails local checks: " + reason;
132 
133  return jvResult;
134  }
135 
136  try
137  {
138  auto const failType = getFailHard(context);
139 
140  context.netOps.processTransaction(
141  tpTrans, isUnlimited(context.role), *sync, true, failType);
142  }
143  catch (std::exception& e)
144  {
145  jvResult[jss::error] = "internalSubmit";
146  jvResult[jss::error_exception] = e.what();
147 
148  return jvResult;
149  }
150 
151  try
152  {
153  jvResult[jss::tx_json] = tpTrans->getJson(JsonOptions::none);
154  jvResult[jss::tx_blob] =
155  strHex(tpTrans->getSTransaction()->getSerializer().peekData());
156 
157  if (temUNCERTAIN != tpTrans->getResult())
158  {
159  std::string sToken;
160  std::string sHuman;
161 
162  transResultInfo(tpTrans->getResult(), sToken, sHuman);
163 
164  jvResult[jss::engine_result] = sToken;
165  jvResult[jss::engine_result_code] = tpTrans->getResult();
166  jvResult[jss::engine_result_message] = sHuman;
167 
168  auto const submitResult = tpTrans->getSubmitResult();
169 
170  jvResult[jss::accepted] = submitResult.any();
171  jvResult[jss::applied] = submitResult.applied;
172  jvResult[jss::broadcast] = submitResult.broadcast;
173  jvResult[jss::queued] = submitResult.queued;
174  jvResult[jss::kept] = submitResult.kept;
175 
176  if (auto currentLedgerState = tpTrans->getCurrentLedgerState())
177  {
178  jvResult[jss::account_sequence_next] =
179  safe_cast<Json::Value::UInt>(
180  currentLedgerState->accountSeqNext);
181  jvResult[jss::account_sequence_available] =
182  safe_cast<Json::Value::UInt>(
183  currentLedgerState->accountSeqAvail);
184  jvResult[jss::open_ledger_cost] =
185  to_string(currentLedgerState->minFeeRequired);
186  jvResult[jss::validated_ledger_index] =
187  safe_cast<Json::Value::UInt>(
188  currentLedgerState->validatedLedger);
189  }
190  }
191 
192  return jvResult;
193  }
194  catch (std::exception& e)
195  {
196  jvResult[jss::error] = "internalJson";
197  jvResult[jss::error_exception] = e.what();
198 
199  return jvResult;
200  }
201 }
202 
203 } // 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:47
ripple::RPC::Context::ledgerMaster
LedgerMaster & ledgerMaster
Definition: Context.h:45
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:122
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::RPC::transactionSubmit
Json::Value transactionSubmit(Json::Value jvRequest, unsigned apiVersion, NetworkOPs::FailHard failType, Role role, std::chrono::seconds validatedLedgerAge, Application &app, ProcessTransactionFn const &processTransaction, RPC::SubmitSync sync)
Returns a Json::objectValue.
Definition: TransactionSign.cpp:824
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:375
ripple::NetworkOPs::FailHard
FailHard
Definition: NetworkOPs.h:95
ripple::LedgerMaster::getCurrentLedger
std::shared_ptr< ReadView const > getCurrentLedger()
Definition: LedgerMaster.cpp:1707
ripple::RPC::Context::netOps
NetworkOPs & netOps
Definition: Context.h:44
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:193
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:226
ripple::JsonOptions::none
@ none
Definition: STBase.h:42
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
ripple::RPC::Context::apiVersion
unsigned int apiVersion
Definition: Context.h:50
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:1130
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:180
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