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/net/RPCErr.h>
25 #include <ripple/protocol/ErrorCodes.h>
26 #include <ripple/resource/Fees.h>
27 #include <ripple/rpc/Context.h>
28 #include <ripple/rpc/GRPCHandlers.h>
29 #include <ripple/rpc/impl/RPCHelpers.h>
30 #include <ripple/rpc/impl/TransactionSign.h>
31 
32 namespace ripple {
33 
36 {
38  context.params.isMember("fail_hard") &&
39  context.params["fail_hard"].asBool());
40 }
41 
42 // {
43 // tx_json: <object>,
44 // secret: <secret>
45 // }
48 {
50 
51  if (!context.params.isMember(jss::tx_blob))
52  {
53  auto const failType = getFailHard(context);
54 
55  if (context.role != Role::ADMIN && !context.app.config().canSign())
56  return RPC::make_error(
57  rpcNOT_SUPPORTED, "Signing is not supported by this server.");
58 
59  auto ret = RPC::transactionSubmit(
60  context.params,
61  failType,
62  context.role,
64  context.app,
65  RPC::getProcessTxnFn(context.netOps));
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->size())
82 
83  SerialIter sitTrans(makeSlice(*ret));
84 
86 
87  try
88  {
89  stpTrans = 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())
102  context.app.getHashRouter(),
103  stpTrans->getTransactionID(),
105  auto [validity, reason] = checkValidity(
106  context.app.getHashRouter(),
107  *stpTrans,
108  context.ledgerMaster.getCurrentLedger()->rules(),
109  context.app.config());
110  if (validity != Validity::Valid)
111  {
112  jvResult[jss::error] = "invalidTransaction";
113  jvResult[jss::error_exception] = "fails local checks: " + reason;
114 
115  return jvResult;
116  }
117  }
118 
119  std::string reason;
120  auto tpTrans = std::make_shared<Transaction>(stpTrans, reason, context.app);
121  if (tpTrans->getStatus() != NEW)
122  {
123  jvResult[jss::error] = "invalidTransaction";
124  jvResult[jss::error_exception] = "fails local checks: " + reason;
125 
126  return jvResult;
127  }
128 
129  try
130  {
131  auto const failType = getFailHard(context);
132 
133  context.netOps.processTransaction(
134  tpTrans, isUnlimited(context.role), true, failType);
135  }
136  catch (std::exception& e)
137  {
138  jvResult[jss::error] = "internalSubmit";
139  jvResult[jss::error_exception] = e.what();
140 
141  return jvResult;
142  }
143 
144  try
145  {
146  jvResult[jss::tx_json] = tpTrans->getJson(JsonOptions::none);
147  jvResult[jss::tx_blob] =
148  strHex(tpTrans->getSTransaction()->getSerializer().peekData());
149 
150  if (temUNCERTAIN != tpTrans->getResult())
151  {
152  std::string sToken;
153  std::string sHuman;
154 
155  transResultInfo(tpTrans->getResult(), sToken, sHuman);
156 
157  jvResult[jss::engine_result] = sToken;
158  jvResult[jss::engine_result_code] = tpTrans->getResult();
159  jvResult[jss::engine_result_message] = sHuman;
160 
161  auto const submitResult = tpTrans->getSubmitResult();
162 
163  jvResult[jss::accepted] = submitResult.any();
164  jvResult[jss::applied] = submitResult.applied;
165  jvResult[jss::broadcast] = submitResult.broadcast;
166  jvResult[jss::queued] = submitResult.queued;
167  jvResult[jss::kept] = submitResult.kept;
168 
169  if (auto currentLedgerState = tpTrans->getCurrentLedgerState())
170  {
171  jvResult[jss::account_sequence_next] =
172  safe_cast<Json::Value::UInt>(
173  currentLedgerState->accountSeqNext);
174  jvResult[jss::account_sequence_available] =
175  safe_cast<Json::Value::UInt>(
176  currentLedgerState->accountSeqAvail);
177  jvResult[jss::open_ledger_cost] =
178  to_string(currentLedgerState->minFeeRequired);
179  jvResult[jss::validated_ledger_index] =
180  safe_cast<Json::Value::UInt>(
181  currentLedgerState->validatedLedger);
182  }
183  }
184 
185  return jvResult;
186  }
187  catch (std::exception& e)
188  {
189  jvResult[jss::error] = "internalJson";
190  jvResult[jss::error_exception] = e.what();
191 
192  return jvResult;
193  }
194 }
195 
196 } // 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::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:82
ripple::RPC::transactionSubmit
Json::Value transactionSubmit(Json::Value jvRequest, NetworkOPs::FailHard failType, Role role, std::chrono::seconds validatedLedgerAge, Application &app, ProcessTransactionFn const &processTransaction)
Returns a Json::objectValue.
Definition: TransactionSign.cpp:799
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:47
ripple::Role::ADMIN
@ ADMIN
ripple::JsonOptions::none
@ none
ripple::Application::config
virtual Config & config()=0
ripple::NetworkOPs::processTransaction
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.
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
ripple::getFailHard
static NetworkOPs::FailHard getFailHard(RPC::JsonContext const &context)
Definition: Submit.cpp:35
ripple::SerialIter
Definition: Serializer.h:310
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:361
ripple::NetworkOPs::FailHard
FailHard
Definition: NetworkOPs.h:91
ripple::LedgerMaster::getCurrentLedger
std::shared_ptr< ReadView const > getCurrentLedger()
Definition: LedgerMaster.cpp:1654
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:195
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
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:93
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:50
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:178
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