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/basics/Log.h>
21 #include <ripple/app/tx/apply.h>
22 #include <ripple/app/tx/applySteps.h>
23 #include <ripple/app/misc/HashRouter.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  STTx const& tx, Rules const& rules,
39  Config const& config)
40 {
41  auto const id = tx.getTransactionID();
42  auto const flags = router.getFlags(id);
43  if (flags & SF_SIGBAD)
44  // Signature is known bad
45  return {Validity::SigBad, "Transaction has bad signature."};
46 
47  if (!(flags & SF_SIGGOOD))
48  {
49  // Don't know signature state. Check it.
50  auto const requireCanonicalSig =
54 
55  auto const sigVerify = tx.checkSign(requireCanonicalSig);
56  if (! sigVerify.first)
57  {
58  router.setFlags(id, SF_SIGBAD);
59  return {Validity::SigBad, sigVerify.second};
60  }
61  router.setFlags(id, SF_SIGGOOD);
62  }
63 
64  // Signature is now known good
65  if (flags & SF_LOCALBAD)
66  // ...but the local checks
67  // are known bad.
68  return {Validity::SigGoodOnly, "Local checks failed."};
69 
70  if (flags & SF_LOCALGOOD)
71  // ...and the local checks
72  // are known good.
73  return {Validity::Valid, ""};
74 
75  // Do the local checks
76  std::string reason;
77  if (!passesLocalChecks(tx, reason))
78  {
79  router.setFlags(id, SF_LOCALBAD);
80  return {Validity::SigGoodOnly, reason};
81  }
82  router.setFlags(id, SF_LOCALGOOD);
83  return {Validity::Valid, ""};
84 }
85 
86 void
87 forceValidity(HashRouter& router, uint256 const& txid,
88  Validity validity)
89 {
90  int flags = 0;
91  switch (validity)
92  {
93  case Validity::Valid:
94  flags |= SF_LOCALGOOD;
95  [[fallthrough]];
97  flags |= SF_SIGGOOD;
98  [[fallthrough]];
99  case Validity::SigBad:
100  // would be silly to call directly
101  break;
102  }
103  if (flags)
104  router.setFlags(txid, flags);
105 }
106 
109  STTx const& tx, ApplyFlags flags,
110  beast::Journal j)
111 {
112  auto pfresult = preflight(app, view.rules(), tx, flags, j);
113  auto pcresult = preclaim(pfresult, app, view);
114  return doApply(pcresult, app, view);
115 }
116 
119  STTx const& txn,
120  bool retryAssured, ApplyFlags flags,
121  beast::Journal j)
122 {
123  // Returns false if the transaction has need not be retried.
124  if (retryAssured)
125  flags = flags | tapRETRY;
126 
127  JLOG (j.debug()) << "TXN " << txn.getTransactionID ()
128  << (retryAssured ? "/retry" : "/final");
129 
130  try
131  {
132  auto const result = apply(app, view, txn, flags, j);
133  if (result.second)
134  {
135  JLOG (j.debug())
136  << "Transaction applied: " << transHuman (result.first);
137  return ApplyResult::Success;
138  }
139 
140  if (isTefFailure (result.first) || isTemMalformed (result.first) ||
141  isTelLocal (result.first))
142  {
143  // failure
144  JLOG (j.debug())
145  << "Transaction failure: " << transHuman (result.first);
146  return ApplyResult::Fail;
147  }
148 
149  JLOG (j.debug())
150  << "Transaction retry: " << transHuman (result.first);
151  return ApplyResult::Retry;
152  }
153  catch (std::exception const&)
154  {
155  JLOG (j.warn()) << "Throws";
156  return ApplyResult::Fail;
157  }
158 }
159 
160 } // ripple
ripple::Application
Definition: Application.h:85
std::string
STL class.
ripple::STTx::checkSign
std::pair< bool, std::string > checkSign(RequireFullyCanonicalSig requireCanonicalSig) const
Definition: STTx.cpp:182
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:108
ripple::HashRouter::getFlags
int getFlags(uint256 const &key)
Definition: HashRouter.cpp:84
std::pair
ripple::OpenView
Writable ledger view that accumulates state and tx changes.
Definition: OpenView.h:52
ripple::applyTransaction
ApplyResult applyTransaction(Application &app, OpenView &view, STTx const &tx, bool retryAssured, ApplyFlags flags, beast::Journal journal)
Transaction application helper.
Definition: apply.cpp:118
ripple::ApplyFlags
ApplyFlags
Definition: ApplyView.h:30
beast::Journal::warn
Stream warn() const
Definition: Journal.h:302
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:266
ripple::ApplyResult
ApplyResult
Enum class for return value from applyTransaction
Definition: apply.h:133
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:87
ripple::Validity::SigGoodOnly
@ SigGoodOnly
Signature is good, but local checks fail.
ripple::STTx::RequireFullyCanonicalSig::no
@ no
ripple::base_uint< 256 >
ripple::featureRequireFullyCanonicalSig
const uint256 featureRequireFullyCanonicalSig
Definition: Feature.cpp:179
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:336
ripple::passesLocalChecks
bool passesLocalChecks(STObject const &st, std::string &reason)
Definition: STTx.cpp:496
ripple::Config
Definition: Config.h:67
ripple::isTefFailure
bool isTefFailure(TER x)
Definition: TER.h:491
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:60
ripple::Rules::enabled
bool enabled(uint256 const &id) const
Returns true if a feature is enabled.
Definition: ReadView.cpp:107
ripple::ApplyResult::Success
@ Success
Applied to this ledger.
ripple::transHuman
std::string transHuman(TER code)
Definition: TER.cpp:191
ripple::STTx::getTransactionID
uint256 getTransactionID() const
Definition: STTx.h:120
ripple::tapRETRY
@ tapRETRY
Definition: ApplyView.h:41
ripple::preclaim
PreclaimResult preclaim(PreflightResult const &preflightResult, Application &app, OpenView const &view)
Gate a transaction based on static ledger information.
Definition: applySteps.cpp:285
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::RequireFullyCanonicalSig::yes
@ yes
ripple::Validity::Valid
@ Valid
Signature and local checks are good / passed.
ripple::isTelLocal
bool isTelLocal(TER x)
Definition: TER.h:481
ripple::Rules
Rules controlling protocol behavior.
Definition: ReadView.h:126
beast::Journal::debug
Stream debug() const
Definition: Journal.h:292
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:144
ripple::HashRouter::setFlags
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
Definition: HashRouter.cpp:91
ripple::isTemMalformed
bool isTemMalformed(TER x)
Definition: TER.h:486