rippled
Loading...
Searching...
No Matches
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 <xrpld/app/ledger/LedgerMaster.h>
21#include <xrpld/app/main/Application.h>
22#include <xrpld/app/misc/HashRouter.h>
23#include <xrpld/app/misc/Transaction.h>
24#include <xrpld/app/rdb/backend/SQLiteDatabase.h>
25#include <xrpld/app/tx/apply.h>
26#include <xrpld/rpc/CTID.h>
27
28#include <xrpl/basics/safe_cast.h>
29#include <xrpl/protocol/ErrorCodes.h>
30#include <xrpl/protocol/jss.h>
31
32namespace ripple {
33
36 std::string& reason,
37 Application& app) noexcept
38 : mTransaction(stx), mApp(app), j_(app.journal("Ledger"))
39{
40 try
41 {
42 mTransactionID = mTransaction->getTransactionID();
43 }
44 catch (std::exception& e)
45 {
46 reason = e.what();
47 return;
48 }
49
50 mStatus = NEW;
51}
52
53//
54// Misc.
55//
56
57void
59 TransStatus ts,
60 std::uint32_t lseq,
63{
64 mStatus = ts;
65 mLedgerIndex = lseq;
66 if (tseq)
67 mTxnSeq = tseq;
68 if (netID)
69 mNetworkID = netID;
70}
71
73Transaction::sqlTransactionStatus(boost::optional<std::string> const& status)
74{
75 char const c = (status) ? (*status)[0] : safe_cast<char>(txnSqlUnknown);
76
77 switch (c)
78 {
79 case txnSqlNew:
80 return NEW;
81 case txnSqlConflict:
82 return CONFLICTED;
83 case txnSqlHeld:
84 return HELD;
85 case txnSqlValidated:
86 return COMMITTED;
87 case txnSqlIncluded:
88 return INCLUDED;
89 }
90
91 XRPL_ASSERT(
92 c == txnSqlUnknown,
93 "ripple::Transaction::sqlTransactionStatus : unknown transaction "
94 "status");
95 return INVALID;
96}
97
100 boost::optional<std::uint64_t> const& ledgerSeq,
101 boost::optional<std::string> const& status,
102 Blob const& rawTxn,
103 Application& app)
104{
105 std::uint32_t const inLedger =
106 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
107
108 SerialIter it(makeSlice(rawTxn));
109 auto txn = std::make_shared<STTx const>(it);
110 std::string reason;
111 auto tr = std::make_shared<Transaction>(txn, reason, app);
112
113 tr->setStatus(sqlTransactionStatus(status));
114 tr->setLedger(inLedger);
115 return tr;
116}
117
122{
123 return load(id, app, std::nullopt, ec);
124}
125
130 uint256 const& id,
131 Application& app,
133 error_code_i& ec)
134{
136
137 return load(id, app, op{range}, ec);
138}
139
144 uint256 const& id,
145 Application& app,
147 error_code_i& ec)
148{
149 auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
150
151 if (!db)
152 {
153 Throw<std::runtime_error>("Failed to get relational database");
154 }
155
156 return db->getTransaction(id, range, ec);
157}
158
159// options 1 to include the date of the transaction
161Transaction::getJson(JsonOptions options, bool binary) const
162{
163 // Note, we explicitly suppress `include_date` option here
164 Json::Value ret(
165 mTransaction->getJson(options & ~JsonOptions::include_date, binary));
166
167 // NOTE Binary STTx::getJson output might not be a JSON object
168 if (ret.isObject() && mLedgerIndex)
169 {
170 if (!(options & JsonOptions::disable_API_prior_V2))
171 {
172 // Behaviour before API version 2
173 ret[jss::inLedger] = mLedgerIndex;
174 }
175
176 // TODO: disable_API_prior_V3 to disable output of both `date` and
177 // `ledger_index` elements (taking precedence over include_date)
178 ret[jss::ledger_index] = mLedgerIndex;
179
180 if (options & JsonOptions::include_date)
181 {
183 if (ct)
184 ret[jss::date] = ct->time_since_epoch().count();
185 }
186
187 // compute outgoing CTID
188 // override local network id if it's explicitly in the txn
190 if (mTransaction->isFieldPresent(sfNetworkID))
191 netID = mTransaction->getFieldU32(sfNetworkID);
192
193 if (mTxnSeq && netID)
194 {
195 std::optional<std::string> const ctid =
197 if (ctid)
198 ret[jss::ctid] = *ctid;
199 }
200 }
201
202 return ret;
203}
204
205} // namespace ripple
Represents a JSON value.
Definition: json_value.h:149
bool isObject() const
virtual LedgerMaster & getLedgerMaster()=0
virtual RelationalDatabase & getRelationalDatabase()=0
std::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
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:99
Transaction(std::shared_ptr< STTx const > const &, std::string &, Application &) noexcept
Definition: Transaction.cpp:34
std::optional< uint32_t > mNetworkID
Definition: Transaction.h:402
std::optional< uint32_t > mTxnSeq
Definition: Transaction.h:401
LedgerIndex mLedgerIndex
Definition: Transaction.h:400
static std::variant< std::pair< std::shared_ptr< Transaction >, std::shared_ptr< TxMeta > >, TxSearched > load(uint256 const &id, Application &app, error_code_i &ec)
Application & mApp
Definition: Transaction.h:431
void setStatus(TransStatus status, std::uint32_t ledgerSeq, std::optional< uint32_t > transactionSeq=std::nullopt, std::optional< uint32_t > networkID=std::nullopt)
static TransStatus sqlTransactionStatus(boost::optional< std::string > const &status)
Definition: Transaction.cpp:73
Json::Value getJson(JsonOptions options, bool binary=false) const
TransStatus mStatus
Definition: Transaction.h:403
std::shared_ptr< STTx const > mTransaction
Definition: Transaction.h:430
std::optional< std::string > encodeCTID(uint32_t ledgerSeq, uint32_t txnIndex, uint32_t networkID) noexcept
Definition: CTID.h:43
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:25
@ INCLUDED
Definition: Transaction.h:49
@ CONFLICTED
Definition: Transaction.h:50
@ COMMITTED
Definition: Transaction.h:51
@ INVALID
Definition: Transaction.h:48
error_code_i
Definition: ErrorCodes.h:40
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition: RangeSet.h:45
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:244
@ txnSqlIncluded
Definition: STTx.h:43
@ txnSqlUnknown
Definition: STTx.h:44
@ txnSqlConflict
Definition: STTx.h:40
@ txnSqlHeld
Definition: STTx.h:41
@ txnSqlNew
Definition: STTx.h:39
@ txnSqlValidated
Definition: STTx.h:42
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition: RangeSet.h:54
Note, should be treated as flags that can be | and &.
Definition: STBase.h:37
T what(T... args)