rippled
Loading...
Searching...
No Matches
Transaction.h
1#ifndef XRPL_APP_MISC_TRANSACTION_H_INCLUDED
2#define XRPL_APP_MISC_TRANSACTION_H_INCLUDED
3
4#include <xrpl/basics/RangeSet.h>
5#include <xrpl/beast/utility/Journal.h>
6#include <xrpl/protocol/ErrorCodes.h>
7#include <xrpl/protocol/Protocol.h>
8#include <xrpl/protocol/STBase.h>
9#include <xrpl/protocol/STTx.h>
10#include <xrpl/protocol/TER.h>
11#include <xrpl/protocol/TxMeta.h>
12
13#include <optional>
14#include <variant>
15
16namespace ripple {
17
18//
19// Transactions should be constructed in JSON with. Use STObject::parseJson to
20// obtain a binary version.
21//
22
23class Application;
24class Database;
25class Rules;
26
28 NEW = 0, // just received / generated
29 INVALID = 1, // no valid signature, insufficient funds
30 INCLUDED = 2, // added to the current ledger
31 CONFLICTED = 3, // losing to a conflicting transaction
32 COMMITTED = 4, // known to be in a ledger
33 HELD = 5, // not valid now, maybe later
34 REMOVED = 6, // taken out of a ledger
35 OBSOLETE = 7, // a compatible transaction has taken precedence
36 INCOMPLETE = 8 // needs more signatures
37};
38
39enum class TxSearched { all, some, unknown };
40
41// This class is for constructing and examining transactions.
42// Transactions are static so manipulation functions are unnecessary.
43class Transaction : public std::enable_shared_from_this<Transaction>,
44 public CountedObject<Transaction>
45{
46public:
48 using ref = pointer const&;
49
53 Application&) noexcept;
54
55 // The two boost::optional parameters are because SOCI requires
56 // boost::optional (not std::optional) parameters.
59 boost::optional<std::uint64_t> const& ledgerSeq,
60 boost::optional<std::string> const& status,
61 Blob const& rawTxn,
62 Application& app);
63
64 // The boost::optional parameter is because SOCI requires
65 // boost::optional (not std::optional) parameters.
66 static TransStatus
67 sqlTransactionStatus(boost::optional<std::string> const& status);
68
71 {
72 return mTransaction;
73 }
74
75 uint256 const&
76 getID() const
77 {
78 return mTransactionID;
79 }
80
82 getLedger() const
83 {
84 return mLedgerIndex;
85 }
86
87 bool
89 {
90 return mLedgerIndex != 0;
91 }
92
94 getStatus() const
95 {
96 return mStatus;
97 }
98
99 TER
101 {
102 return mResult;
103 }
104
105 void
106 setResult(TER terResult)
107 {
108 mResult = terResult;
109 }
110
111 void
113 TransStatus status,
114 std::uint32_t ledgerSeq,
115 std::optional<uint32_t> transactionSeq = std::nullopt,
117
118 void
120 {
121 mStatus = status;
122 }
123
124 void
126 {
127 mLedgerIndex = ledger;
128 }
129
133 void
135 {
136 // Note that all access to mApplying are made by NetworkOPsImp, and must
137 // be done under that class's lock.
138 mApplying = true;
139 }
140
146 bool
148 {
149 // Note that all access to mApplying are made by NetworkOPsImp, and must
150 // be done under that class's lock.
151 return mApplying;
152 }
153
157 void
159 {
160 // Note that all access to mApplying are made by NetworkOPsImp, and must
161 // be done under that class's lock.
162 mApplying = false;
163 }
164
166 {
170 void
172 {
173 applied = false;
174 broadcast = false;
175 queued = false;
176 kept = false;
177 }
178
183 bool
184 any() const
185 {
186 return applied || broadcast || queued || kept;
187 }
188
189 bool applied = false;
190 bool broadcast = false;
191 bool queued = false;
192 bool kept = false;
193 };
194
201 {
202 return submitResult_;
203 }
204
208 void
213
217 void
219 {
220 submitResult_.applied = true;
221 }
222
226 void
228 {
229 submitResult_.queued = true;
230 }
231
235 void
237 {
239 }
240
244 void
246 {
247 submitResult_.kept = true;
248 }
249
271
278 {
279 return currentLedgerState_;
280 }
281
289 void
291 LedgerIndex validatedLedger,
292 XRPAmount fee,
293 std::uint32_t accountSeq,
294 std::uint32_t availableSeq)
295 {
296 currentLedgerState_.emplace(
297 validatedLedger, fee, accountSeq, availableSeq);
298 }
299
301 getJson(JsonOptions options, bool binary = false) const;
302
303 // Information used to locate a transaction.
304 // Contains a nodestore hash and ledger sequence pair if the transaction was
305 // found. Otherwise, contains the range of ledgers present in the database
306 // at the time of search.
307 struct Locator
308 {
311
312 // @return true if transaction was found, false otherwise
313 //
314 // Call this function first to determine the type of the contained info.
315 // Calling the wrong getter function will throw an exception.
316 // See documentation for the getter functions for more details
317 bool
323
324 // @return key used to find transaction in nodestore
325 //
326 // Throws if isFound() returns false
327 uint256 const&
332
333 // @return sequence of ledger containing the transaction
334 //
335 // Throws is isFound() returns false
336 uint32_t
341
342 // @return range of ledgers searched
343 //
344 // Throws if isFound() returns true
350 };
351
352 static Locator
353 locate(uint256 const& id, Application& app);
354
355 static std::variant<
358 load(uint256 const& id, Application& app, error_code_i& ec);
359
360 static std::variant<
363 load(
364 uint256 const& id,
365 Application& app,
367 error_code_i& ec);
368
369private:
370 static std::variant<
373 load(
374 uint256 const& id,
375 Application& app,
377 error_code_i& ec);
378
380
386 /* Note that all access to mApplying are made by NetworkOPsImp,
387 and must be done under that class's lock. This avoids the overhead of
388 taking a separate lock, and the consequences of a race condition are
389 nearly-zero.
390
391 1. If there is a race condition, and getApplying returns false when it
392 should be true, the transaction will be processed again. Not that
393 big a deal if it's a rare one-off. Most of the time, it'll get
394 tefALREADY or tefPAST_SEQ.
395 2. On the flip side, if it returns true, when it should be false, then
396 the transaction must have been attempted recently, so no big deal if
397 it doesn't immediately get tried right away.
398 3. If there's a race between setApplying and clearApplying, and the
399 flag ends up set, then a batch is about to try to process the
400 transaction and will call clearApplying later. If it ends up
401 cleared, then it might get attempted again later as is the case with
402 item 1.
403 */
404 bool mApplying = false;
405
408
410
414};
415
416} // namespace ripple
417
418#endif
Represents a JSON value.
Definition json_value.h:131
A generic endpoint for log messages.
Definition Journal.h:41
Tracks the number of instances of an object.
void setCurrentLedgerState(LedgerIndex validatedLedger, XRPAmount fee, std::uint32_t accountSeq, std::uint32_t availableSeq)
setCurrentLedgerState Set current ledger state of transaction
std::optional< CurrentLedgerState > currentLedgerState_
static Locator locate(uint256 const &id, Application &app)
static Transaction::pointer transactionFromSQL(boost::optional< std::uint64_t > const &ledgerSeq, boost::optional< std::string > const &status, Blob const &rawTxn, Application &app)
void setBroadcast()
setBroadcast Set this flag once was broadcasted via network
void setStatus(TransStatus status)
void clearSubmitResult()
clearSubmitResult Clear all flags in SubmitResult
bool getApplying()
Detect if transaction is being batched.
std::optional< uint32_t > mNetworkID
std::optional< uint32_t > mTxnSeq
void setQueued()
setQueued Set this flag once was put into heldtxns queue
LedgerIndex mLedgerIndex
pointer const & ref
Definition Transaction.h:48
void setApplied()
setApplied Set this flag once was applied to open ledger
static std::variant< std::pair< std::shared_ptr< Transaction >, std::shared_ptr< TxMeta > >, TxSearched > load(uint256 const &id, Application &app, error_code_i &ec)
TransStatus getStatus() const
Definition Transaction.h:94
LedgerIndex getLedger() const
Definition Transaction.h:82
void setApplying()
Set this flag once added to a batch.
void setKept()
setKept Set this flag once was put to localtxns queue
std::shared_ptr< STTx const > const & getSTransaction()
Definition Transaction.h:70
void setLedger(LedgerIndex ledger)
Application & mApp
SubmitResult submitResult_
different ways for transaction to be accepted
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)
bool isValidated() const
Definition Transaction.h:88
void clearApplying()
Indicate that transaction application has been attempted.
Json::Value getJson(JsonOptions options, bool binary=false) const
uint256 const & getID() const
Definition Transaction.h:76
TransStatus mStatus
std::shared_ptr< STTx const > mTransaction
void setResult(TER terResult)
std::optional< CurrentLedgerState > getCurrentLedgerState() const
getCurrentLedgerState Get current ledger state of transaction
SubmitResult getSubmitResult() const
getSubmitResult Return submit result
beast::Journal j_
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
@ CONFLICTED
Definition Transaction.h:31
@ INCOMPLETE
Definition Transaction.h:36
@ COMMITTED
Definition Transaction.h:32
boost::icl::closed_interval< T > ClosedInterval
A closed interval over the domain T.
Definition RangeSet.h:26
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
Definition RangeSet.h:35
@ temUNCERTAIN
Definition TER.h:104
Note, should be treated as flags that can be | and &.
Definition STBase.h:18
CurrentLedgerState(LedgerIndex li, XRPAmount fee, std::uint32_t accSeqNext, std::uint32_t accSeqAvail)
uint256 const & getNodestoreHash()
std::variant< std::pair< uint256, uint32_t >, ClosedInterval< uint32_t > > locator
ClosedInterval< uint32_t > const & getLedgerRangeSearched()
bool any() const
any Get true of any state is true
void clear()
clear Clear all states