rippled
apply.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 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/misc/HashRouter.h>
21 #include <ripple/app/tx/apply.h>
22 #include <ripple/app/tx/applySteps.h>
23 #include <ripple/basics/Log.h>
24 #include <ripple/protocol/Feature.h>
25 
26 namespace ripple {
27 
28 // These are the same flags defined as SF_PRIVATE1-4 in HashRouter.h
29 #define SF_SIGBAD SF_PRIVATE1 // Signature is bad
30 #define SF_SIGGOOD SF_PRIVATE2 // Signature is good
31 #define SF_LOCALBAD SF_PRIVATE3 // Local checks failed
32 #define SF_LOCALGOOD SF_PRIVATE4 // Local checks passed
33 
34 //------------------------------------------------------------------------------
35 
38  HashRouter& router,
39  STTx const& tx,
40  Rules const& rules,
41  Config const& config)
42 {
43  auto const id = tx.getTransactionID();
44  auto const flags = router.getFlags(id);
45  if (flags & SF_SIGBAD)
46  // Signature is known bad
47  return {Validity::SigBad, "Transaction has bad signature."};
48 
49  if (!(flags & SF_SIGGOOD))
50  {
51  // Don't know signature state. Check it.
52  auto const requireCanonicalSig =
56 
57  auto const sigVerify = tx.checkSign(requireCanonicalSig);
58  if (!sigVerify)
59  {
60  router.setFlags(id, SF_SIGBAD);
61  return {Validity::SigBad, sigVerify.error()};
62  }
63  router.setFlags(id, SF_SIGGOOD);
64  }
65 
66  // Signature is now known good
67  if (flags & SF_LOCALBAD)
68  // ...but the local checks
69  // are known bad.
70  return {Validity::SigGoodOnly, "Local checks failed."};
71 
72  if (flags & SF_LOCALGOOD)
73  // ...and the local checks
74  // are known good.
75  return {Validity::Valid, ""};
76 
77  // Do the local checks
78  std::string reason;
79  if (!passesLocalChecks(tx, reason))
80  {
81  router.setFlags(id, SF_LOCALBAD);
82  return {Validity::SigGoodOnly, reason};
83  }
84  router.setFlags(id, SF_LOCALGOOD);
85  return {Validity::Valid, ""};
86 }
87 
88 void
89 forceValidity(HashRouter& router, uint256 const& txid, Validity validity)
90 {
91  int flags = 0;
92  switch (validity)
93  {
94  case Validity::Valid:
95  flags |= SF_LOCALGOOD;
96  [[fallthrough]];
98  flags |= SF_SIGGOOD;
99  [[fallthrough]];
100  case Validity::SigBad:
101  // would be silly to call directly
102  break;
103  }
104  if (flags)
105  router.setFlags(txid, flags);
106 }
107 
110  Application& app,
111  OpenView& view,
112  STTx const& tx,
113  ApplyFlags flags,
114  beast::Journal j)
115 {
116  STAmountSO stAmountSO{view.rules().enabled(fixSTAmountCanonicalize)};
117 
118  auto pfresult = preflight(app, view.rules(), tx, flags, j);
119  auto pcresult = preclaim(pfresult, app, view);
120  return doApply(pcresult, app, view);
121 }
122 
125  Application& app,
126  OpenView& view,
127  STTx const& txn,
128  bool retryAssured,
129  ApplyFlags flags,
130  beast::Journal j)
131 {
132  // Returns false if the transaction has need not be retried.
133  if (retryAssured)
134  flags = flags | tapRETRY;
135 
136  JLOG(j.debug()) << "TXN " << txn.getTransactionID()
137  << (retryAssured ? "/retry" : "/final");
138 
139  try
140  {
141  auto const result = apply(app, view, txn, flags, j);
142  if (result.second)
143  {
144  JLOG(j.debug())
145  << "Transaction applied: " << transHuman(result.first);
146  return ApplyResult::Success;
147  }
148 
149  if (isTefFailure(result.first) || isTemMalformed(result.first) ||
150  isTelLocal(result.first))
151  {
152  // failure
153  JLOG(j.debug())
154  << "Transaction failure: " << transHuman(result.first);
155  return ApplyResult::Fail;
156  }
157 
158  JLOG(j.debug()) << "Transaction retry: " << transHuman(result.first);
159  return ApplyResult::Retry;
160  }
161  catch (std::exception const&)
162  {
163  JLOG(j.warn()) << "Throws";
164  return ApplyResult::Fail;
165  }
166 }
167 
168 } // namespace ripple
ripple::Application
Definition: Application.h:115
ripple::STAmountSO
RAII class to set and restore the STAmount canonicalize switchover.
Definition: STAmount.h:484
std::string
STL class.
std::exception
STL class.
ripple::apply
std::pair< TER, bool > apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition: apply.cpp:109
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:94
std::pair
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:55
ripple::applyTransaction
ApplyResult applyTransaction(Application &app, OpenView &view, STTx const &tx, bool retryAssured, ApplyFlags flags, beast::Journal journal)
Transaction application helper.
Definition: apply.cpp:124
ripple::fixSTAmountCanonicalize
const uint256 fixSTAmountCanonicalize
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:29
beast::Journal::warn
Stream warn() const
Definition: Journal.h:327
ripple::Validity
Validity
Describes the pre-processing validity of a transaction.
Definition: apply.h:40
ripple::preflight
PreflightResult preflight(Application &app, Rules const &rules, STTx const &tx, ApplyFlags flags, beast::Journal j)
Gate a transaction based on static information.
Definition: applySteps.cpp:418
ripple::ApplyResult
ApplyResult
Enum class for return value from applyTransaction
Definition: apply.h:134
ripple::HashRouter
Routing table for objects identified by hash.
Definition: HashRouter.h:53
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
ripple::Validity::SigGoodOnly
@ SigGoodOnly
Signature is good, but local checks fail.
ripple::STTx::RequireFullyCanonicalSig::no
@ no
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:75
ripple::featureRequireFullyCanonicalSig
const uint256 featureRequireFullyCanonicalSig
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::doApply
std::pair< TER, bool > doApply(PreclaimResult const &preclaimResult, Application &app, OpenView &view)
Apply a prechecked transaction to an OpenView.
Definition: applySteps.cpp:496
ripple::passesLocalChecks
bool passesLocalChecks(STObject const &st, std::string &reason)
Definition: STTx.cpp:506
ripple::Config
Definition: Config.h:68
ripple::isTefFailure
bool isTefFailure(TER x)
Definition: TER.h:572
ripple::ApplyResult::Retry
@ Retry
Should be retried in this ledger.
ripple::STTx
Definition: STTx.h:43
beast::Journal
A generic endpoint for log messages.
Definition: Journal.h:58
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:102
ripple::ApplyResult::Success
@ Success
Applied to this ledger.
ripple::transHuman
std::string transHuman(TER code)
Definition: TER.cpp:205
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:118
ripple::tapRETRY
@ tapRETRY
Definition: ApplyView.h:38
ripple::preclaim
PreclaimResult preclaim(PreflightResult const &preflightResult, Application &app, OpenView const &view)
Gate a transaction based on static ledger information.
Definition: applySteps.cpp:438
ripple::ApplyResult::Fail
@ Fail
Should not be retried in this ledger.
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STTx::checkSign
Expected< void, std::string > checkSign(RequireFullyCanonicalSig requireCanonicalSig) const
Definition: STTx.cpp:190
ripple::STTx::RequireFullyCanonicalSig::yes
@ yes
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
ripple::isTelLocal
bool isTelLocal(TER x)
Definition: TER.h:560
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:131
beast::Journal::debug
Stream debug() const
Definition: Journal.h:315
ripple::Validity::SigBad
@ SigBad
Signature is bad. Didn't do local checks.
ripple::OpenView::rules
Rules const & rules() const override
Returns the tx processing rules.
Definition: OpenView.cpp:152
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:102
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:566