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
7#include <xrpl/basics/Log.h>
8#include <xrpl/core/JobQueue.h>
9#include <xrpl/protocol/RippleLedgerHash.h>
10#include <xrpl/resource/Fees.h>
11
12#include <memory>
13#include <mutex>
14
15namespace xrpl {
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 {
35 ;
36 }
38 {
39 ;
40 }
41};
42
44{
45public:
47 Application& app,
48 beast::insight::Collector::ptr const& collector,
49 std::function<void(std::shared_ptr<SHAMap> const&, bool)> gotSet,
51 : app_(app)
52 , m_seq(0)
54 , m_gotSet(std::move(gotSet))
55 , m_peerSetBuilder(std::move(peerSetBuilder))
56 , j_(app_.journal("InboundTransactions"))
57 {
59 m_zeroSet.mSet->setUnbacked();
60 }
61
63 getAcquire(uint256 const& hash)
64 {
65 {
67
68 auto it = m_map.find(hash);
69
70 if (it != m_map.end())
71 return it->second.mAcquire;
72 }
73 return {};
74 }
75
77 getSet(uint256 const& hash, bool acquire) override
78 {
80
81 {
83
84 if (auto it = m_map.find(hash); it != m_map.end())
85 {
86 if (acquire)
87 {
88 it->second.mSeq = m_seq;
89 if (it->second.mAcquire)
90 {
91 it->second.mAcquire->stillNeed();
92 }
93 }
94 return it->second.mSet;
95 }
96
97 if (!acquire || stopping_)
99
101
102 auto& obj = m_map[hash];
103 obj.mAcquire = ta;
104 obj.mSeq = m_seq;
105 }
106
107 ta->init(startPeers);
108
109 return {};
110 }
111
114 void
116 override
117 {
118 protocol::TMLedgerData& packet = *packet_ptr;
119
120 JLOG(j_.trace()) << "Got data (" << packet.nodes().size() << ") for acquiring ledger: " << hash;
121
123
124 if (ta == nullptr)
125 {
126 peer->charge(Resource::feeUselessData, "ledger_data");
127 return;
128 }
129
131 data.reserve(packet.nodes().size());
132
133 for (auto const& node : packet.nodes())
134 {
135 if (!node.has_nodeid() || !node.has_nodedata())
136 {
137 peer->charge(Resource::feeMalformedRequest, "ledger_data");
138 return;
139 }
140
141 auto const id = deserializeSHAMapNodeID(node.nodeid());
142
143 if (!id)
144 {
145 peer->charge(Resource::feeInvalidData, "ledger_data");
146 return;
147 }
148
149 data.emplace_back(std::make_pair(*id, makeSlice(node.nodedata())));
150 }
151
152 if (!ta->takeNodes(data, peer).isUseful())
153 peer->charge(Resource::feeUselessData, "ledger_data not useful");
154 }
155
156 void
157 giveSet(uint256 const& hash, std::shared_ptr<SHAMap> const& set, bool fromAcquire) override
158 {
159 bool isNew = true;
160
161 {
163
164 auto& inboundSet = m_map[hash];
165
166 if (inboundSet.mSeq < m_seq)
167 inboundSet.mSeq = m_seq;
168
169 if (inboundSet.mSet)
170 isNew = false;
171 else
172 inboundSet.mSet = set;
173
174 inboundSet.mAcquire.reset();
175 }
176
177 if (isNew)
178 m_gotSet(set, fromAcquire);
179 }
180
181 void
183 {
185
186 // Protect zero set from expiration
187 m_zeroSet.mSeq = seq;
188
189 if (m_seq != seq)
190 {
191 m_seq = seq;
192
193 auto it = m_map.begin();
194
195 std::uint32_t const minSeq = (seq < setKeepRounds) ? 0 : (seq - setKeepRounds);
196 std::uint32_t maxSeq = seq + setKeepRounds;
197
198 while (it != m_map.end())
199 {
200 if (it->second.mSeq < minSeq || it->second.mSeq > maxSeq)
201 it = m_map.erase(it);
202 else
203 ++it;
204 }
205 }
206 }
207
208 void
209 stop() override
210 {
212 stopping_ = true;
213 m_map.clear();
214 }
215
216private:
218
220
222
223 bool stopping_{false};
226
227 // The empty transaction set whose hash is zero
229
231
233
235};
236
237//------------------------------------------------------------------------------
238
240
243 Application& app,
244 beast::insight::Collector::ptr const& collector,
245 std::function<void(std::shared_ptr<SHAMap> const&, bool)> gotSet)
246{
247 return std::make_unique<InboundTransactionsImp>(app, collector, std::move(gotSet), make_PeerSetBuilder(app));
248}
249
250} // namespace xrpl
T begin(T... args)
A generic endpoint for log messages.
Definition Journal.h:41
Stream trace() const
Severity stream access functions.
Definition Journal.h:295
virtual Family & getNodeFamily()=0
std::shared_ptr< SHAMap > mSet
TransactionAcquire::pointer mAcquire
InboundTransactionSet(std::uint32_t seq, std::shared_ptr< SHAMap > const &set)
void giveSet(uint256 const &hash, std::shared_ptr< SHAMap > const &set, bool fromAcquire) override
Add a transaction set.
InboundTransactionSet & m_zeroSet
TransactionAcquire::pointer getAcquire(uint256 const &hash)
std::unique_ptr< PeerSetBuilder > m_peerSetBuilder
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.
void newRound(std::uint32_t seq) override
Informs the container if a new consensus round.
std::shared_ptr< SHAMap > getSet(uint256 const &hash, bool acquire) override
Find and return a transaction set, or nullptr if it is missing.
InboundTransactionsImp(Application &app, beast::insight::Collector::ptr const &collector, std::function< void(std::shared_ptr< SHAMap > const &, bool)> gotSet, std::unique_ptr< PeerSetBuilder > peerSetBuilder)
Manages the acquisition and lifetime of transaction sets.
virtual ~InboundTransactions()=0
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)
STL namespace.
Charge const feeInvalidData
Charge const feeMalformedRequest
Schedule of fees charged for imposing load on the server.
Charge const feeUselessData
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
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,...
base_uint< 256 > uint256
Definition base_uint.h:527
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::optional< SHAMapNodeID > deserializeSHAMapNodeID(void const *data, std::size_t size)
Return an object representing a serialized SHAMap Node ID.
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
std::unique_ptr< PeerSetBuilder > make_PeerSetBuilder(Application &app)
Definition PeerSet.cpp:121