rippled
Loading...
Searching...
No Matches
Transaction.cpp
1#include <xrpld/app/ledger/LedgerMaster.h>
2#include <xrpld/app/main/Application.h>
3#include <xrpld/app/misc/HashRouter.h>
4#include <xrpld/app/misc/Transaction.h>
5#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
6#include <xrpld/app/tx/apply.h>
7#include <xrpld/rpc/CTID.h>
8
9#include <xrpl/basics/safe_cast.h>
10#include <xrpl/protocol/ErrorCodes.h>
11#include <xrpl/protocol/jss.h>
12
13namespace xrpl {
14
16 : mTransaction(stx), mApp(app), j_(app.journal("Ledger"))
17{
18 try
19 {
20 mTransactionID = mTransaction->getTransactionID();
21 }
22 catch (std::exception& e)
23 {
24 reason = e.what();
25 return;
26 }
27
28 mStatus = NEW;
29}
30
31//
32// Misc.
33//
34
35void
37 TransStatus ts,
38 std::uint32_t lseq,
41{
42 mStatus = ts;
43 mLedgerIndex = lseq;
44 if (tseq)
45 mTxnSeq = tseq;
46 if (netID)
47 mNetworkID = netID;
48}
49
51Transaction::sqlTransactionStatus(boost::optional<std::string> const& status)
52{
53 char const c = (status) ? (*status)[0] : safe_cast<char>(txnSqlUnknown);
54
55 switch (c)
56 {
57 case txnSqlNew:
58 return NEW;
59 case txnSqlConflict:
60 return CONFLICTED;
61 case txnSqlHeld:
62 return HELD;
63 case txnSqlValidated:
64 return COMMITTED;
65 case txnSqlIncluded:
66 return INCLUDED;
67 }
68
69 XRPL_ASSERT(
70 c == txnSqlUnknown,
71 "xrpl::Transaction::sqlTransactionStatus : unknown transaction "
72 "status");
73 return INVALID;
74}
75
78 boost::optional<std::uint64_t> const& ledgerSeq,
79 boost::optional<std::string> const& status,
80 Blob const& rawTxn,
81 Application& app)
82{
83 std::uint32_t const inLedger = rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
84
85 SerialIter it(makeSlice(rawTxn));
86 auto txn = std::make_shared<STTx const>(it);
87 std::string reason;
88 auto tr = std::make_shared<Transaction>(txn, reason, app);
89
90 tr->setStatus(sqlTransactionStatus(status));
91 tr->setLedger(inLedger);
92 return tr;
93}
94
97{
98 return load(id, app, std::nullopt, ec);
99}
100
103{
105
106 return load(id, app, op{range}, ec);
107}
108
111 uint256 const& id,
112 Application& app,
114 error_code_i& ec)
115{
116 auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
117
118 if (!db)
119 {
120 Throw<std::runtime_error>("Failed to get relational database");
121 }
122
123 return db->getTransaction(id, range, ec);
124}
125
126// options 1 to include the date of the transaction
128Transaction::getJson(JsonOptions options, bool binary) const
129{
130 // Note, we explicitly suppress `include_date` option here
131 Json::Value ret(mTransaction->getJson(options & ~JsonOptions::include_date, binary));
132
133 // NOTE Binary STTx::getJson output might not be a JSON object
134 if (ret.isObject() && mLedgerIndex)
135 {
136 if (!(options & JsonOptions::disable_API_prior_V2))
137 {
138 // Behaviour before API version 2
139 ret[jss::inLedger] = mLedgerIndex;
140 }
141
142 // TODO: disable_API_prior_V3 to disable output of both `date` and
143 // `ledger_index` elements (taking precedence over include_date)
144 ret[jss::ledger_index] = mLedgerIndex;
145
146 if (options & JsonOptions::include_date)
147 {
149 if (ct)
150 ret[jss::date] = ct->time_since_epoch().count();
151 }
152
153 // compute outgoing CTID
154 // override local network id if it's explicitly in the txn
156 if (mTransaction->isFieldPresent(sfNetworkID))
157 netID = mTransaction->getFieldU32(sfNetworkID);
158
159 if (mTxnSeq && netID)
160 {
162 if (ctid)
163 ret[jss::ctid] = *ctid;
164 }
165 }
166
167 return ret;
168}
169
170} // namespace xrpl
Represents a JSON value.
Definition json_value.h:131
bool isObject() const
virtual LedgerMaster & getLedgerMaster()=0
virtual RelationalDatabase & getRelationalDatabase()=0
std::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
std::shared_ptr< STTx const > mTransaction
Application & mApp
std::optional< uint32_t > mTxnSeq
TransStatus mStatus
LedgerIndex mLedgerIndex
void setStatus(TransStatus status, std::uint32_t ledgerSeq, std::optional< uint32_t > transactionSeq=std::nullopt, std::optional< uint32_t > networkID=std::nullopt)
std::optional< uint32_t > mNetworkID
static Transaction::pointer transactionFromSQL(boost::optional< std::uint64_t > const &ledgerSeq, boost::optional< std::string > const &status, Blob const &rawTxn, Application &app)
static std::variant< std::pair< std::shared_ptr< Transaction >, std::shared_ptr< TxMeta > >, TxSearched > load(uint256 const &id, Application &app, error_code_i &ec)
Json::Value getJson(JsonOptions options, bool binary=false) const
Transaction(std::shared_ptr< STTx const > const &, std::string &, Application &) noexcept
static TransStatus sqlTransactionStatus(boost::optional< std::string > const &status)
T is_same_v
std::optional< std::string > encodeCTID(uint32_t ledgerSeq, uint32_t txnIndex, uint32_t networkID) noexcept
Encodes ledger sequence, transaction index, and network ID into a CTID string.
Definition CTID.h:34
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
TransStatus
Definition Transaction.h:27
@ INVALID
Definition Transaction.h:29
@ COMMITTED
Definition Transaction.h:32
@ CONFLICTED
Definition Transaction.h:31
@ INCLUDED
Definition Transaction.h:30
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:35
@ txnSqlNew
Definition STTx.h:20
@ txnSqlValidated
Definition STTx.h:23
@ txnSqlUnknown
Definition STTx.h:25
@ txnSqlConflict
Definition STTx.h:21
@ txnSqlHeld
Definition STTx.h:22
@ txnSqlIncluded
Definition STTx.h:24
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition RangeSet.h:26
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:214
error_code_i
Definition ErrorCodes.h:21
Note, should be treated as flags that can be | and &.
Definition STBase.h:18
T what(T... args)