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