rippled
Transaction.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/ledger/LedgerMaster.h>
21 #include <ripple/app/main/Application.h>
22 #include <ripple/app/misc/HashRouter.h>
23 #include <ripple/app/misc/Transaction.h>
24 #include <ripple/app/rdb/backend/PostgresDatabase.h>
25 #include <ripple/app/rdb/backend/SQLiteDatabase.h>
26 #include <ripple/app/tx/apply.h>
27 #include <ripple/basics/Log.h>
28 #include <ripple/basics/safe_cast.h>
29 #include <ripple/core/DatabaseCon.h>
30 #include <ripple/core/Pg.h>
31 #include <ripple/json/json_reader.h>
32 #include <ripple/protocol/ErrorCodes.h>
33 #include <ripple/protocol/Feature.h>
34 #include <ripple/protocol/jss.h>
35 
36 namespace ripple {
37 
39  std::shared_ptr<STTx const> const& stx,
40  std::string& reason,
41  Application& app) noexcept
42  : mTransaction(stx), mApp(app), j_(app.journal("Ledger"))
43 {
44  try
45  {
46  mTransactionID = mTransaction->getTransactionID();
47  }
48  catch (std::exception& e)
49  {
50  reason = e.what();
51  return;
52  }
53 
54  mStatus = NEW;
55 }
56 
57 //
58 // Misc.
59 //
60 
61 void
63 {
64  mStatus = ts;
65  mLedgerIndex = lseq;
66 }
67 
69 Transaction::sqlTransactionStatus(boost::optional<std::string> const& status)
70 {
71  char const c = (status) ? (*status)[0] : safe_cast<char>(txnSqlUnknown);
72 
73  switch (c)
74  {
75  case txnSqlNew:
76  return NEW;
77  case txnSqlConflict:
78  return CONFLICTED;
79  case txnSqlHeld:
80  return HELD;
81  case txnSqlValidated:
82  return COMMITTED;
83  case txnSqlIncluded:
84  return INCLUDED;
85  }
86 
87  assert(c == txnSqlUnknown);
88  return INVALID;
89 }
90 
93  boost::optional<std::uint64_t> const& ledgerSeq,
94  boost::optional<std::string> const& status,
95  Blob const& rawTxn,
96  Application& app)
97 {
98  std::uint32_t const inLedger =
99  rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
100 
101  SerialIter it(makeSlice(rawTxn));
102  auto txn = std::make_shared<STTx const>(it);
103  std::string reason;
104  auto tr = std::make_shared<Transaction>(txn, reason, app);
105 
106  tr->setStatus(sqlTransactionStatus(status));
107  tr->setLedger(inLedger);
108  return tr;
109 }
110 
113  TxSearched>
115 {
116  return load(id, app, std::nullopt, ec);
117 }
118 
121  TxSearched>
123  uint256 const& id,
124  Application& app,
126  error_code_i& ec)
127 {
129 
130  return load(id, app, op{range}, ec);
131 }
132 
135 {
136  auto const db =
137  dynamic_cast<PostgresDatabase*>(&app.getRelationalDatabase());
138 
139  if (!db)
140  {
141  Throw<std::runtime_error>("Failed to get relational database");
142  }
143 
144  return db->locateTransaction(id);
145 }
146 
149  TxSearched>
151  uint256 const& id,
152  Application& app,
154  error_code_i& ec)
155 {
156  auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
157 
158  if (!db)
159  {
160  Throw<std::runtime_error>("Failed to get relational database");
161  }
162 
163  return db->getTransaction(id, range, ec);
164 }
165 
166 // options 1 to include the date of the transaction
168 Transaction::getJson(JsonOptions options, bool binary) const
169 {
170  // Note, we explicitly suppress `include_date` option here
171  Json::Value ret(
172  mTransaction->getJson(options & ~JsonOptions::include_date, binary));
173 
174  // NOTE Binary STTx::getJson output might not be a JSON object
175  if (ret.isObject() && mLedgerIndex)
176  {
177  if (!(options & JsonOptions::disable_API_prior_V2))
178  {
179  // Behaviour before API version 2
180  ret[jss::inLedger] = mLedgerIndex;
181  }
182 
183  // TODO: disable_API_prior_V3 to disable output of both `date` and
184  // `ledger_index` elements (taking precedence over include_date)
185  ret[jss::ledger_index] = mLedgerIndex;
186 
187  if (options & JsonOptions::include_date)
188  {
190  if (ct)
191  ret[jss::date] = ct->time_since_epoch().count();
192  }
193  }
194 
195  return ret;
196 }
197 
198 } // namespace ripple
ripple::SQLiteDatabase
Definition: SQLiteDatabase.h:27
ripple::JsonOptions::disable_API_prior_V2
@ disable_API_prior_V2
Definition: STBase.h:44
ripple::COMMITTED
@ COMMITTED
Definition: Transaction.h:51
ripple::JsonOptions::include_date
@ include_date
Definition: STBase.h:43
ripple::Transaction::sqlTransactionStatus
static TransStatus sqlTransactionStatus(boost::optional< std::string > const &status)
Definition: Transaction.cpp:69
ripple::Application
Definition: Application.h:116
ripple::Transaction::transactionFromSQL
static Transaction::pointer transactionFromSQL(boost::optional< std::uint64_t > const &ledgerSeq, boost::optional< std::string > const &status, Blob const &rawTxn, Application &app)
Definition: Transaction.cpp:92
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
Json::Value::isObject
bool isObject() const
Definition: json_value.cpp:1027
std::string
STL class.
std::shared_ptr
STL class.
ripple::Transaction::getJson
Json::Value getJson(JsonOptions options, bool binary=false) const
Definition: Transaction.cpp:168
std::exception
STL class.
std::pair
ripple::TxSearched
TxSearched
Definition: Transaction.h:58
std::vector< unsigned char >
ripple::NEW
@ NEW
Definition: Transaction.h:47
ripple::HELD
@ HELD
Definition: Transaction.h:52
ripple::Transaction::mStatus
TransStatus mStatus
Definition: Transaction.h:391
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::TransStatus
TransStatus
Definition: Transaction.h:46
ripple::Transaction::mTransaction
std::shared_ptr< STTx const > mTransaction
Definition: Transaction.h:400
ripple::base_uint< 256 >
ripple::INCLUDED
@ INCLUDED
Definition: Transaction.h:49
ripple::txnSqlUnknown
@ txnSqlUnknown
Definition: STTx.h:43
ripple::Transaction::Transaction
Transaction(std::shared_ptr< STTx const > const &, std::string &, Application &) noexcept
Definition: Transaction.cpp:38
ripple::Transaction::Locator
Definition: Transaction.h:316
ripple::Application::getLedgerMaster
virtual LedgerMaster & getLedgerMaster()=0
ripple::Transaction::mLedgerIndex
LedgerIndex mLedgerIndex
Definition: Transaction.h:390
ripple::Application::getRelationalDatabase
virtual RelationalDatabase & getRelationalDatabase()=0
ripple::txnSqlValidated
@ txnSqlValidated
Definition: STTx.h:41
ripple::Transaction::locate
static Locator locate(uint256 const &id, Application &app)
Definition: Transaction.cpp:134
ripple::SerialIter
Definition: Serializer.h:311
std::uint32_t
ripple::txnSqlHeld
@ txnSqlHeld
Definition: STTx.h:40
ripple::CONFLICTED
@ CONFLICTED
Definition: Transaction.h:50
ripple::range
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:54
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Transaction::load
static std::variant< std::pair< std::shared_ptr< Transaction >, std::shared_ptr< TxMeta > >, TxSearched > load(uint256 const &id, Application &app, error_code_i &ec)
Definition: Transaction.cpp:114
ripple::JsonOptions
Note, should be treated as flags that can be | and &.
Definition: STBase.h:35
ripple::INVALID
@ INVALID
Definition: Transaction.h:48
ripple::LedgerMaster::getCloseTimeBySeq
std::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
Definition: LedgerMaster.cpp:1766
ripple::Transaction::setStatus
void setStatus(TransStatus status, std::uint32_t ledgerSeq)
Definition: Transaction.cpp:62
ripple::txnSqlIncluded
@ txnSqlIncluded
Definition: STTx.h:42
ripple::PostgresDatabase
Definition: PostgresDatabase.h:27
ripple::txnSqlConflict
@ txnSqlConflict
Definition: STTx.h:39
ripple::Transaction::mApp
Application & mApp
Definition: Transaction.h:401
ripple::txnSqlNew
@ txnSqlNew
Definition: STTx.h:38
std::optional
ripple::ClosedInterval
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition: RangeSet.h:45
std::exception::what
T what(T... args)
Json::Value
Represents a JSON value.
Definition: json_value.h:145
std::variant