rippled
Loading...
Searching...
No Matches
LocalTxs.cpp
1#include <xrpld/app/ledger/Ledger.h>
2#include <xrpld/app/ledger/LocalTxs.h>
3
4#include <xrpl/protocol/Indexes.h>
5
6/*
7 This code prevents scenarios like the following:
81) A client submits a transaction.
92) The transaction gets into the ledger this server
10 believes will be the consensus ledger.
113) The server builds a succeeding open ledger without the
12 transaction (because it's in the prior ledger).
134) The local consensus ledger is not the majority ledger
14 (due to network conditions, Byzantine fault, etcetera)
15 the majority ledger does not include the transaction.
165) The server builds a new open ledger that does not include
17 the transaction or have it in a prior ledger.
186) The client submits another transaction and gets a terPRE_SEQ
19 preliminary result.
207) The server does not relay that second transaction, at least
21 not yet.
22
23With this code, when step 5 happens, the first transaction will
24be applied to that open ledger so the second transaction will
25succeed normally at step 6. Transactions remain tracked and
26test-applied to all new open ledgers until seen in a fully-
27validated ledger
28*/
29
30namespace xrpl {
31
32// This class wraps a pointer to a transaction along with
33// its expiration ledger. It also caches the issuing account.
35{
36public:
38 : m_txn(txn)
39 , m_expire(index + LocalTxs::holdLedgers)
40 , m_id(txn->getTransactionID())
41 , m_account(txn->getAccountID(sfAccount))
42 , m_seqProxy(txn->getSeqProxy())
43 {
44 if (txn->isFieldPresent(sfLastLedgerSequence))
45 m_expire = std::min(m_expire, txn->getFieldU32(sfLastLedgerSequence) + 1);
46 }
47
48 uint256 const&
49 getID() const
50 {
51 return m_id;
52 }
53
56 {
57 return m_seqProxy;
58 }
59
60 bool
62 {
63 return i > m_expire;
64 }
65
67 getTX() const
68 {
69 return m_txn;
70 }
71
72 AccountID const&
73 getAccount() const
74 {
75 return m_account;
76 }
77
78private:
84};
85
86//------------------------------------------------------------------------------
87
88class LocalTxsImp : public LocalTxs
89{
90public:
91 LocalTxsImp() = default;
92
93 // Add a new transaction to the set of local transactions
94 void
96 {
98
99 m_txns.emplace_back(index, txn);
100 }
101
103 getTxSet() override
104 {
105 CanonicalTXSet tset(uint256{});
106
107 // Get the set of local transactions as a canonical
108 // set (so they apply in a valid order)
109 {
111
112 for (auto const& it : m_txns)
113 tset.insert(it.getTX());
114 }
115 return tset;
116 }
117
118 // Remove transactions that have either been accepted
119 // into a fully-validated ledger, are (now) impossible,
120 // or have expired
121 void
122 sweep(ReadView const& view) override
123 {
125
126 m_txns.remove_if([&view](auto const& txn) {
127 if (txn.isExpired(view.header().seq))
128 return true;
129 if (view.txExists(txn.getID()))
130 return true;
131
132 AccountID const acctID = txn.getAccount();
133 auto const sleAcct = view.read(keylet::account(acctID));
134
135 if (!sleAcct)
136 return false;
137
138 SeqProxy const acctSeq = SeqProxy::sequence(sleAcct->getFieldU32(sfSequence));
139 SeqProxy const seqProx = txn.getSeqProxy();
140
141 if (seqProx.isSeq())
142 return acctSeq > seqProx; // Remove tefPAST_SEQ
143
144 if (seqProx.isTicket() && acctSeq.value() <= seqProx.value())
145 // Keep ticket from the future. Note, however, that the
146 // transaction will not be held indefinitely since LocalTxs
147 // will only hold a transaction for a maximum of 5 ledgers.
148 return false;
149
150 // Ticket should have been created by now. Remove if ticket
151 // does not exist.
152 return !view.exists(keylet::ticket(acctID, seqProx));
153 });
154 }
155
157 size() override
158 {
160
161 return m_txns.size();
162 }
163
164private:
167};
168
174
175} // namespace xrpl
Holds transactions which were deferred to the next pass of consensus.
std::shared_ptr< STTx const > m_txn
Definition LocalTxs.cpp:79
AccountID m_account
Definition LocalTxs.cpp:82
AccountID const & getAccount() const
Definition LocalTxs.cpp:73
uint256 const & getID() const
Definition LocalTxs.cpp:49
uint256 m_id
Definition LocalTxs.cpp:81
LocalTx(LedgerIndex index, std::shared_ptr< STTx const > const &txn)
Definition LocalTxs.cpp:37
LedgerIndex m_expire
Definition LocalTxs.cpp:80
SeqProxy getSeqProxy() const
Definition LocalTxs.cpp:55
bool isExpired(LedgerIndex i) const
Definition LocalTxs.cpp:61
SeqProxy m_seqProxy
Definition LocalTxs.cpp:83
std::shared_ptr< STTx const > const & getTX() const
Definition LocalTxs.cpp:67
void sweep(ReadView const &view) override
Definition LocalTxs.cpp:122
std::mutex m_lock
Definition LocalTxs.cpp:165
LocalTxsImp()=default
std::list< LocalTx > m_txns
Definition LocalTxs.cpp:166
void push_back(LedgerIndex index, std::shared_ptr< STTx const > const &txn) override
Definition LocalTxs.cpp:95
std::size_t size() override
Definition LocalTxs.cpp:157
CanonicalTXSet getTxSet() override
Definition LocalTxs.cpp:103
A view into a ledger.
Definition ReadView.h:32
virtual bool exists(Keylet const &k) const =0
Determine if a state item exists.
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
virtual bool txExists(key_type const &key) const =0
Returns true if a tx exists in the tx map.
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
A type that represents either a sequence value or a ticket value.
Definition SeqProxy.h:37
static constexpr SeqProxy sequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
Definition SeqProxy.h:57
constexpr bool isTicket() const
Definition SeqProxy.h:75
constexpr std::uint32_t value() const
Definition SeqProxy.h:63
constexpr bool isSeq() const
Definition SeqProxy.h:69
T is_same_v
T min(T... args)
static ticket_t const ticket
Definition Indexes.h:149
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:160
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::unique_ptr< LocalTxs > make_LocalTxs()
Definition LocalTxs.cpp:170