rippled
Loading...
Searching...
No Matches
InboundTransactions.cpp
1#include <xrpld/app/ledger/InboundLedgers.h>
2#include <xrpld/app/ledger/InboundTransactions.h>
3#include <xrpld/app/ledger/detail/TransactionAcquire.h>
4#include <xrpld/app/main/Application.h>
5#include <xrpld/app/misc/NetworkOPs.h>
6#include <xrpld/core/JobQueue.h>
7
8#include <xrpl/basics/Log.h>
9#include <xrpl/protocol/RippleLedgerHash.h>
10#include <xrpl/resource/Fees.h>
11
12#include <memory>
13#include <mutex>
14
15namespace ripple {
16
17enum {
18 // Ideal number of peers to start with
20
21 // How many rounds to keep a set
23};
24
26{
27 // A transaction set we generated, acquired, or are acquiring
28public:
32
34 : mSeq(seq), mSet(set)
35 {
36 ;
37 }
39 {
40 ;
41 }
42};
43
45{
46public:
48 Application& app,
49 beast::insight::Collector::ptr const& collector,
50 std::function<void(std::shared_ptr<SHAMap> const&, bool)> gotSet,
52 : app_(app)
53 , m_seq(0)
55 , m_gotSet(std::move(gotSet))
56 , m_peerSetBuilder(std::move(peerSetBuilder))
57 , j_(app_.journal("InboundTransactions"))
58 {
61 m_zeroSet.mSet->setUnbacked();
62 }
63
65 getAcquire(uint256 const& hash)
66 {
67 {
69
70 auto it = m_map.find(hash);
71
72 if (it != m_map.end())
73 return it->second.mAcquire;
74 }
75 return {};
76 }
77
79 getSet(uint256 const& hash, bool acquire) override
80 {
82
83 {
85
86 if (auto it = m_map.find(hash); it != m_map.end())
87 {
88 if (acquire)
89 {
90 it->second.mSeq = m_seq;
91 if (it->second.mAcquire)
92 {
93 it->second.mAcquire->stillNeed();
94 }
95 }
96 return it->second.mSet;
97 }
98
99 if (!acquire || stopping_)
101
103 app_, hash, m_peerSetBuilder->build());
104
105 auto& obj = m_map[hash];
106 obj.mAcquire = ta;
107 obj.mSeq = m_seq;
108 }
109
110 ta->init(startPeers);
111
112 return {};
113 }
114
117 void
119 LedgerHash const& hash,
121 std::shared_ptr<protocol::TMLedgerData> packet_ptr) override
122 {
123 protocol::TMLedgerData& packet = *packet_ptr;
124
125 JLOG(j_.trace()) << "Got data (" << packet.nodes().size()
126 << ") for acquiring ledger: " << hash;
127
129
130 if (ta == nullptr)
131 {
132 peer->charge(Resource::feeUselessData, "ledger_data");
133 return;
134 }
135
137 data.reserve(packet.nodes().size());
138
139 for (auto const& node : packet.nodes())
140 {
141 if (!node.has_nodeid() || !node.has_nodedata())
142 {
143 peer->charge(Resource::feeMalformedRequest, "ledger_data");
144 return;
145 }
146
147 auto const id = deserializeSHAMapNodeID(node.nodeid());
148
149 if (!id)
150 {
151 peer->charge(Resource::feeInvalidData, "ledger_data");
152 return;
153 }
154
155 data.emplace_back(std::make_pair(*id, makeSlice(node.nodedata())));
156 }
157
158 if (!ta->takeNodes(data, peer).isUseful())
159 peer->charge(Resource::feeUselessData, "ledger_data not useful");
160 }
161
162 void
164 uint256 const& hash,
165 std::shared_ptr<SHAMap> const& set,
166 bool fromAcquire) override
167 {
168 bool isNew = true;
169
170 {
172
173 auto& inboundSet = m_map[hash];
174
175 if (inboundSet.mSeq < m_seq)
176 inboundSet.mSeq = m_seq;
177
178 if (inboundSet.mSet)
179 isNew = false;
180 else
181 inboundSet.mSet = set;
182
183 inboundSet.mAcquire.reset();
184 }
185
186 if (isNew)
187 m_gotSet(set, fromAcquire);
188 }
189
190 void
192 {
194
195 // Protect zero set from expiration
196 m_zeroSet.mSeq = seq;
197
198 if (m_seq != seq)
199 {
200 m_seq = seq;
201
202 auto it = m_map.begin();
203
204 std::uint32_t const minSeq =
205 (seq < setKeepRounds) ? 0 : (seq - setKeepRounds);
206 std::uint32_t maxSeq = seq + setKeepRounds;
207
208 while (it != m_map.end())
209 {
210 if (it->second.mSeq < minSeq || it->second.mSeq > maxSeq)
211 it = m_map.erase(it);
212 else
213 ++it;
214 }
215 }
216 }
217
218 void
219 stop() override
220 {
222 stopping_ = true;
223 m_map.clear();
224 }
225
226private:
228
230
232
233 bool stopping_{false};
236
237 // The empty transaction set whose hash is zero
239
241
243
245};
246
247//------------------------------------------------------------------------------
248
250
253 Application& app,
254 beast::insight::Collector::ptr const& collector,
255 std::function<void(std::shared_ptr<SHAMap> const&, bool)> gotSet)
256{
258 app, collector, std::move(gotSet), make_PeerSetBuilder(app));
259}
260
261} // namespace ripple
T begin(T... args)
A generic endpoint for log messages.
Definition Journal.h:41
Stream trace() const
Severity stream access functions.
Definition Journal.h:303
virtual Family & getNodeFamily()=0
InboundTransactionSet(std::uint32_t seq, std::shared_ptr< SHAMap > const &set)
TransactionAcquire::pointer mAcquire
std::shared_ptr< SHAMap > mSet
void giveSet(uint256 const &hash, std::shared_ptr< SHAMap > const &set, bool fromAcquire) override
Add a transaction set.
void newRound(std::uint32_t seq) override
Informs the container if a new consensus round.
TransactionAcquire::pointer getAcquire(uint256 const &hash)
std::function< void(std::shared_ptr< SHAMap > const &, bool)> m_gotSet
void gotData(LedgerHash const &hash, std::shared_ptr< Peer > peer, std::shared_ptr< protocol::TMLedgerData > packet_ptr) override
We received a TMLedgerData from a peer.
InboundTransactionsImp(Application &app, beast::insight::Collector::ptr const &collector, std::function< void(std::shared_ptr< SHAMap > const &, bool)> gotSet, std::unique_ptr< PeerSetBuilder > peerSetBuilder)
std::shared_ptr< SHAMap > getSet(uint256 const &hash, bool acquire) override
Find and return a transaction set, or nullptr if it is missing.
std::unique_ptr< PeerSetBuilder > m_peerSetBuilder
Manages the acquisition and lifetime of transaction sets.
T clear(T... args)
T end(T... args)
T erase(T... args)
T find(T... args)
T is_same_v
T make_pair(T... args)
Charge const feeMalformedRequest
Schedule of fees charged for imposing load on the server.
Charge const feeInvalidData
Charge const feeUselessData
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::optional< SHAMapNodeID > deserializeSHAMapNodeID(void const *data, std::size_t size)
Return an object representing a serialized SHAMap Node ID.
base_uint< 256 > uint256
Definition base_uint.h:539
bool set(T &target, std::string const &name, Section const &section)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
std::unique_ptr< PeerSetBuilder > make_PeerSetBuilder(Application &app)
Definition PeerSet.cpp:125
std::unique_ptr< InboundTransactions > make_InboundTransactions(Application &app, beast::insight::Collector::ptr const &collector, std::function< void(std::shared_ptr< SHAMap > const &, bool)> gotSet)
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:225
STL namespace.