From c1f01947a1cf16da01a5ee3ca23d946ed373c2d9 Mon Sep 17 00:00:00 2001 From: bthomee Date: Thu, 13 Feb 2025 16:58:17 +0000 Subject: [PATCH] deploy: 97e3dae6f4390cf7516ed1f797c1ba31b3e1aa4a --- Charge_8cpp_source.html | 15 +- Charge_8h_source.html | 28 +- PeerImp_8cpp_source.html | 6805 +++++++++-------- PeerImp_8h_source.html | 112 +- classripple_1_1PeerImp.html | 152 +- classripple_1_1PeerImp_1_1Metrics.html | 6 +- ...sripple_1_1Resource_1_1Charge-members.html | 9 +- classripple_1_1Resource_1_1Charge.html | 26 +- ..._1tx__reduce__relay__test_1_1PeerTest.html | 142 +- functions_func_o.html | 26 +- functions_o.html | 38 +- namespaceripple.html | 6 +- search/all_10.js | 755 +- search/functions_f.js | 6 +- 14 files changed, 4085 insertions(+), 4041 deletions(-) diff --git a/Charge_8cpp_source.html b/Charge_8cpp_source.html index d2b4cf953b..ec1f439049 100644 --- a/Charge_8cpp_source.html +++ b/Charge_8cpp_source.html @@ -145,16 +145,23 @@ $(function() {
67 return m_cost <=> c.m_cost;
68}
69
-
70} // namespace Resource
-
71} // namespace ripple
+
70Charge
+
71Charge::operator*(value_type m) const
+
72{
+
73 return Charge(m_cost * m, m_label);
+
74}
+
75
+
76} // namespace Resource
+
77} // namespace ripple
A consumption charge.
Definition: Charge.h:31
int value_type
The type used to hold a consumption charge.
Definition: Charge.h:34
+
Charge operator*(value_type m) const
Definition: Charge.cpp:71
Charge()=delete
-
std::string m_label
Definition: Charge.h:62
-
value_type m_cost
Definition: Charge.h:61
+
std::string m_label
Definition: Charge.h:65
+
value_type m_cost
Definition: Charge.h:64
std::string to_string() const
Converts this charge into a human readable string.
Definition: Charge.cpp:44
bool operator==(Charge const &) const
Definition: Charge.cpp:59
value_type cost() const
Return the cost of the charge in Resource::Manager units.
Definition: Charge.cpp:38
diff --git a/Charge_8h_source.html b/Charge_8h_source.html index 9ba81de512..2686330c23 100644 --- a/Charge_8h_source.html +++ b/Charge_8h_source.html @@ -129,25 +129,29 @@ $(function() {
57 std::strong_ordering
58 operator<=>(Charge const&) const;
59
-
60private:
-
61 value_type m_cost;
-
62 std::string m_label;
-
63};
-
64
-
65std::ostream&
-
66operator<<(std::ostream& os, Charge const& v);
+
60 Charge
+
61 operator*(value_type m) const;
+
62
+
63private:
+
64 value_type m_cost;
+
65 std::string m_label;
+
66};
67
-
68} // namespace Resource
-
69} // namespace ripple
+
68std::ostream&
+
69operator<<(std::ostream& os, Charge const& v);
70
-
71#endif
+
71} // namespace Resource
+
72} // namespace ripple
+
73
+
74#endif
A consumption charge.
Definition: Charge.h:31
int value_type
The type used to hold a consumption charge.
Definition: Charge.h:34
+
Charge operator*(value_type m) const
Definition: Charge.cpp:71
Charge()=delete
-
std::string m_label
Definition: Charge.h:62
-
value_type m_cost
Definition: Charge.h:61
+
std::string m_label
Definition: Charge.h:65
+
value_type m_cost
Definition: Charge.h:64
std::string to_string() const
Converts this charge into a human readable string.
Definition: Charge.cpp:44
bool operator==(Charge const &) const
Definition: Charge.cpp:59
value_type cost() const
Return the cost of the charge in Resource::Manager units.
Definition: Charge.cpp:38
diff --git a/PeerImp_8cpp_source.html b/PeerImp_8cpp_source.html index bcdf82bf72..fa6c322af8 100644 --- a/PeerImp_8cpp_source.html +++ b/PeerImp_8cpp_source.html @@ -109,3453 +109,3464 @@ $(function() {
31#include <xrpld/overlay/Cluster.h>
32#include <xrpld/overlay/detail/PeerImp.h>
33#include <xrpld/overlay/detail/Tuning.h>
-
34#include <xrpld/overlay/predicates.h>
-
35#include <xrpld/perflog/PerfLog.h>
-
36#include <xrpl/basics/UptimeClock.h>
-
37#include <xrpl/basics/base64.h>
-
38#include <xrpl/basics/random.h>
-
39#include <xrpl/basics/safe_cast.h>
-
40#include <xrpl/beast/core/LexicalCast.h>
-
41// #include <xrpl/beast/core/SemanticVersion.h>
-
42#include <xrpl/protocol/digest.h>
+
34#include <xrpld/perflog/PerfLog.h>
+
35#include <xrpl/basics/UptimeClock.h>
+
36#include <xrpl/basics/base64.h>
+
37#include <xrpl/basics/random.h>
+
38#include <xrpl/basics/safe_cast.h>
+
39#include <xrpl/protocol/digest.h>
+
40
+
41#include <boost/algorithm/string/predicate.hpp>
+
42#include <boost/beast/core/ostream.hpp>
43
-
44#include <boost/algorithm/string/predicate.hpp>
-
45#include <boost/beast/core/ostream.hpp>
-
46
-
47#include <algorithm>
-
48#include <memory>
-
49#include <mutex>
-
50#include <numeric>
-
51#include <sstream>
-
52
-
53using namespace std::chrono_literals;
-
54
-
55namespace ripple {
-
56
-
57namespace {
-
59std::chrono::milliseconds constexpr peerHighLatency{300};
-
60
-
62std::chrono::seconds constexpr peerTimerInterval{60};
-
63} // namespace
+
44#include <algorithm>
+
45#include <memory>
+
46#include <mutex>
+
47#include <numeric>
+
48#include <sstream>
+
49
+
50using namespace std::chrono_literals;
+
51
+
52namespace ripple {
+
53
+
54namespace {
+
56std::chrono::milliseconds constexpr peerHighLatency{300};
+
57
+
59std::chrono::seconds constexpr peerTimerInterval{60};
+
60} // namespace
+
61
+
62// TODO: Remove this exclusion once unit tests are added after the hotfix
+
63// release.
64
-
65// TODO: Remove this exclusion once unit tests are added after the hotfix
-
66// release.
-
67
-
68PeerImp::PeerImp(
-
69 Application& app,
-
70 id_t id,
-
71 std::shared_ptr<PeerFinder::Slot> const& slot,
-
72 http_request_type&& request,
-
73 PublicKey const& publicKey,
-
74 ProtocolVersion protocol,
-
75 Resource::Consumer consumer,
-
76 std::unique_ptr<stream_type>&& stream_ptr,
-
77 OverlayImpl& overlay)
-
78 : Child(overlay)
-
79 , app_(app)
-
80 , id_(id)
-
81 , sink_(app_.journal("Peer"), makePrefix(id))
-
82 , p_sink_(app_.journal("Protocol"), makePrefix(id))
-
83 , journal_(sink_)
-
84 , p_journal_(p_sink_)
-
85 , stream_ptr_(std::move(stream_ptr))
-
86 , socket_(stream_ptr_->next_layer().socket())
-
87 , stream_(*stream_ptr_)
-
88 , strand_(socket_.get_executor())
-
89 , timer_(waitable_timer{socket_.get_executor()})
-
90 , remote_address_(slot->remote_endpoint())
-
91 , overlay_(overlay)
-
92 , inbound_(true)
-
93 , protocol_(protocol)
-
94 , tracking_(Tracking::unknown)
-
95 , trackingTime_(clock_type::now())
-
96 , publicKey_(publicKey)
-
97 , lastPingTime_(clock_type::now())
-
98 , creationTime_(clock_type::now())
-
99 , squelch_(app_.journal("Squelch"))
-
100 , usage_(consumer)
-
101 , fee_{Resource::feeTrivialPeer, ""}
-
102 , slot_(slot)
-
103 , request_(std::move(request))
-
104 , headers_(request_)
-
105 , compressionEnabled_(
-
106 peerFeatureEnabled(
-
107 headers_,
-
108 FEATURE_COMPR,
-
109 "lz4",
-
110 app_.config().COMPRESSION)
-
111 ? Compressed::On
-
112 : Compressed::Off)
-
113 , txReduceRelayEnabled_(peerFeatureEnabled(
-
114 headers_,
-
115 FEATURE_TXRR,
-
116 app_.config().TX_REDUCE_RELAY_ENABLE))
-
117 , vpReduceRelayEnabled_(peerFeatureEnabled(
-
118 headers_,
-
119 FEATURE_VPRR,
-
120 app_.config().VP_REDUCE_RELAY_ENABLE))
-
121 , ledgerReplayEnabled_(peerFeatureEnabled(
-
122 headers_,
-
123 FEATURE_LEDGER_REPLAY,
-
124 app_.config().LEDGER_REPLAY))
-
125 , ledgerReplayMsgHandler_(app, app.getLedgerReplayer())
-
126{
-
127 JLOG(journal_.info()) << "compression enabled "
-
128 << (compressionEnabled_ == Compressed::On)
-
129 << " vp reduce-relay enabled "
-
130 << vpReduceRelayEnabled_
-
131 << " tx reduce-relay enabled "
-
132 << txReduceRelayEnabled_ << " on " << remote_address_
-
133 << " " << id_;
-
134}
-
135
-
136PeerImp::~PeerImp()
-
137{
-
138 const bool inCluster{cluster()};
-
139
-
140 overlay_.deletePeer(id_);
-
141 overlay_.onPeerDeactivate(id_);
-
142 overlay_.peerFinder().on_closed(slot_);
-
143 overlay_.remove(slot_);
-
144
-
145 if (inCluster)
-
146 {
-
147 JLOG(journal_.warn()) << name() << " left cluster";
-
148 }
-
149}
-
150
-
151// Helper function to check for valid uint256 values in protobuf buffers
-
152static bool
-
153stringIsUint256Sized(std::string const& pBuffStr)
-
154{
-
155 return pBuffStr.size() == uint256::size();
-
156}
-
157
-
158void
-
159PeerImp::run()
-
160{
-
161 if (!strand_.running_in_this_thread())
-
162 return post(strand_, std::bind(&PeerImp::run, shared_from_this()));
-
163
-
164 auto parseLedgerHash =
-
165 [](std::string_view value) -> std::optional<uint256> {
-
166 if (uint256 ret; ret.parseHex(value))
-
167 return ret;
+
65PeerImp::PeerImp(
+
66 Application& app,
+
67 id_t id,
+
68 std::shared_ptr<PeerFinder::Slot> const& slot,
+
69 http_request_type&& request,
+
70 PublicKey const& publicKey,
+
71 ProtocolVersion protocol,
+
72 Resource::Consumer consumer,
+
73 std::unique_ptr<stream_type>&& stream_ptr,
+
74 OverlayImpl& overlay)
+
75 : Child(overlay)
+
76 , app_(app)
+
77 , id_(id)
+
78 , sink_(app_.journal("Peer"), makePrefix(id))
+
79 , p_sink_(app_.journal("Protocol"), makePrefix(id))
+
80 , journal_(sink_)
+
81 , p_journal_(p_sink_)
+
82 , stream_ptr_(std::move(stream_ptr))
+
83 , socket_(stream_ptr_->next_layer().socket())
+
84 , stream_(*stream_ptr_)
+
85 , strand_(socket_.get_executor())
+
86 , timer_(waitable_timer{socket_.get_executor()})
+
87 , remote_address_(slot->remote_endpoint())
+
88 , overlay_(overlay)
+
89 , inbound_(true)
+
90 , protocol_(protocol)
+
91 , tracking_(Tracking::unknown)
+
92 , trackingTime_(clock_type::now())
+
93 , publicKey_(publicKey)
+
94 , lastPingTime_(clock_type::now())
+
95 , creationTime_(clock_type::now())
+
96 , squelch_(app_.journal("Squelch"))
+
97 , usage_(consumer)
+
98 , fee_{Resource::feeTrivialPeer, ""}
+
99 , slot_(slot)
+
100 , request_(std::move(request))
+
101 , headers_(request_)
+
102 , compressionEnabled_(
+
103 peerFeatureEnabled(
+
104 headers_,
+
105 FEATURE_COMPR,
+
106 "lz4",
+
107 app_.config().COMPRESSION)
+
108 ? Compressed::On
+
109 : Compressed::Off)
+
110 , txReduceRelayEnabled_(peerFeatureEnabled(
+
111 headers_,
+
112 FEATURE_TXRR,
+
113 app_.config().TX_REDUCE_RELAY_ENABLE))
+
114 , vpReduceRelayEnabled_(peerFeatureEnabled(
+
115 headers_,
+
116 FEATURE_VPRR,
+
117 app_.config().VP_REDUCE_RELAY_ENABLE))
+
118 , ledgerReplayEnabled_(peerFeatureEnabled(
+
119 headers_,
+
120 FEATURE_LEDGER_REPLAY,
+
121 app_.config().LEDGER_REPLAY))
+
122 , ledgerReplayMsgHandler_(app, app.getLedgerReplayer())
+
123{
+
124 JLOG(journal_.info()) << "compression enabled "
+
125 << (compressionEnabled_ == Compressed::On)
+
126 << " vp reduce-relay enabled "
+
127 << vpReduceRelayEnabled_
+
128 << " tx reduce-relay enabled "
+
129 << txReduceRelayEnabled_ << " on " << remote_address_
+
130 << " " << id_;
+
131}
+
132
+
133PeerImp::~PeerImp()
+
134{
+
135 const bool inCluster{cluster()};
+
136
+
137 overlay_.deletePeer(id_);
+
138 overlay_.onPeerDeactivate(id_);
+
139 overlay_.peerFinder().on_closed(slot_);
+
140 overlay_.remove(slot_);
+
141
+
142 if (inCluster)
+
143 {
+
144 JLOG(journal_.warn()) << name() << " left cluster";
+
145 }
+
146}
+
147
+
148// Helper function to check for valid uint256 values in protobuf buffers
+
149static bool
+
150stringIsUint256Sized(std::string const& pBuffStr)
+
151{
+
152 return pBuffStr.size() == uint256::size();
+
153}
+
154
+
155void
+
156PeerImp::run()
+
157{
+
158 if (!strand_.running_in_this_thread())
+
159 return post(strand_, std::bind(&PeerImp::run, shared_from_this()));
+
160
+
161 auto parseLedgerHash =
+
162 [](std::string_view value) -> std::optional<uint256> {
+
163 if (uint256 ret; ret.parseHex(value))
+
164 return ret;
+
165
+
166 if (auto const s = base64_decode(value); s.size() == uint256::size())
+
167 return uint256{s};
168
-
169 if (auto const s = base64_decode(value); s.size() == uint256::size())
-
170 return uint256{s};
+
169 return std::nullopt;
+
170 };
171
-
172 return std::nullopt;
-
173 };
+
172 std::optional<uint256> closed;
+
173 std::optional<uint256> previous;
174
-
175 std::optional<uint256> closed;
-
176 std::optional<uint256> previous;
-
177
-
178 if (auto const iter = headers_.find("Closed-Ledger");
-
179 iter != headers_.end())
-
180 {
-
181 closed = parseLedgerHash(iter->value());
-
182
-
183 if (!closed)
-
184 fail("Malformed handshake data (1)");
-
185 }
-
186
-
187 if (auto const iter = headers_.find("Previous-Ledger");
-
188 iter != headers_.end())
-
189 {
-
190 previous = parseLedgerHash(iter->value());
-
191
-
192 if (!previous)
-
193 fail("Malformed handshake data (2)");
-
194 }
+
175 if (auto const iter = headers_.find("Closed-Ledger");
+
176 iter != headers_.end())
+
177 {
+
178 closed = parseLedgerHash(iter->value());
+
179
+
180 if (!closed)
+
181 fail("Malformed handshake data (1)");
+
182 }
+
183
+
184 if (auto const iter = headers_.find("Previous-Ledger");
+
185 iter != headers_.end())
+
186 {
+
187 previous = parseLedgerHash(iter->value());
+
188
+
189 if (!previous)
+
190 fail("Malformed handshake data (2)");
+
191 }
+
192
+
193 if (previous && !closed)
+
194 fail("Malformed handshake data (3)");
195
-
196 if (previous && !closed)
-
197 fail("Malformed handshake data (3)");
-
198
-
199 {
-
200 std::lock_guard<std::mutex> sl(recentLock_);
-
201 if (closed)
-
202 closedLedgerHash_ = *closed;
-
203 if (previous)
-
204 previousLedgerHash_ = *previous;
-
205 }
-
206
-
207 if (inbound_)
-
208 doAccept();
-
209 else
-
210 doProtocolStart();
-
211
-
212 // Anything else that needs to be done with the connection should be
-
213 // done in doProtocolStart
-
214}
-
215
-
216void
-
217PeerImp::stop()
-
218{
-
219 if (!strand_.running_in_this_thread())
-
220 return post(strand_, std::bind(&PeerImp::stop, shared_from_this()));
-
221 if (socket_.is_open())
-
222 {
-
223 // The rationale for using different severity levels is that
-
224 // outbound connections are under our control and may be logged
-
225 // at a higher level, but inbound connections are more numerous and
-
226 // uncontrolled so to prevent log flooding the severity is reduced.
-
227 //
-
228 if (inbound_)
-
229 {
-
230 JLOG(journal_.debug()) << "Stop";
-
231 }
-
232 else
-
233 {
-
234 JLOG(journal_.info()) << "Stop";
-
235 }
-
236 }
-
237 close();
-
238}
-
239
-
240//------------------------------------------------------------------------------
-
241
-
242void
-
243PeerImp::send(std::shared_ptr<Message> const& m)
-
244{
-
245 if (!strand_.running_in_this_thread())
-
246 return post(strand_, std::bind(&PeerImp::send, shared_from_this(), m));
-
247 if (gracefulClose_)
-
248 return;
-
249 if (detaching_)
-
250 return;
-
251
-
252 auto validator = m->getValidatorKey();
-
253 if (validator && !squelch_.expireSquelch(*validator))
-
254 return;
-
255
-
256 overlay_.reportTraffic(
-
257 safe_cast<TrafficCount::category>(m->getCategory()),
-
258 false,
-
259 static_cast<int>(m->getBuffer(compressionEnabled_).size()));
-
260
-
261 auto sendq_size = send_queue_.size();
-
262
-
263 if (sendq_size < Tuning::targetSendQueue)
-
264 {
-
265 // To detect a peer that does not read from their
-
266 // side of the connection, we expect a peer to have
-
267 // a small senq periodically
-
268 large_sendq_ = 0;
-
269 }
-
270 else if (auto sink = journal_.debug();
-
271 sink && (sendq_size % Tuning::sendQueueLogFreq) == 0)
-
272 {
-
273 std::string const n = name();
-
274 sink << (n.empty() ? remote_address_.to_string() : n)
-
275 << " sendq: " << sendq_size;
-
276 }
-
277
-
278 send_queue_.push(m);
+
196 {
+
197 std::lock_guard<std::mutex> sl(recentLock_);
+
198 if (closed)
+
199 closedLedgerHash_ = *closed;
+
200 if (previous)
+
201 previousLedgerHash_ = *previous;
+
202 }
+
203
+
204 if (inbound_)
+
205 doAccept();
+
206 else
+
207 doProtocolStart();
+
208
+
209 // Anything else that needs to be done with the connection should be
+
210 // done in doProtocolStart
+
211}
+
212
+
213void
+
214PeerImp::stop()
+
215{
+
216 if (!strand_.running_in_this_thread())
+
217 return post(strand_, std::bind(&PeerImp::stop, shared_from_this()));
+
218 if (socket_.is_open())
+
219 {
+
220 // The rationale for using different severity levels is that
+
221 // outbound connections are under our control and may be logged
+
222 // at a higher level, but inbound connections are more numerous and
+
223 // uncontrolled so to prevent log flooding the severity is reduced.
+
224 //
+
225 if (inbound_)
+
226 {
+
227 JLOG(journal_.debug()) << "Stop";
+
228 }
+
229 else
+
230 {
+
231 JLOG(journal_.info()) << "Stop";
+
232 }
+
233 }
+
234 close();
+
235}
+
236
+
237//------------------------------------------------------------------------------
+
238
+
239void
+
240PeerImp::send(std::shared_ptr<Message> const& m)
+
241{
+
242 if (!strand_.running_in_this_thread())
+
243 return post(strand_, std::bind(&PeerImp::send, shared_from_this(), m));
+
244 if (gracefulClose_)
+
245 return;
+
246 if (detaching_)
+
247 return;
+
248
+
249 auto validator = m->getValidatorKey();
+
250 if (validator && !squelch_.expireSquelch(*validator))
+
251 return;
+
252
+
253 overlay_.reportTraffic(
+
254 safe_cast<TrafficCount::category>(m->getCategory()),
+
255 false,
+
256 static_cast<int>(m->getBuffer(compressionEnabled_).size()));
+
257
+
258 auto sendq_size = send_queue_.size();
+
259
+
260 if (sendq_size < Tuning::targetSendQueue)
+
261 {
+
262 // To detect a peer that does not read from their
+
263 // side of the connection, we expect a peer to have
+
264 // a small senq periodically
+
265 large_sendq_ = 0;
+
266 }
+
267 else if (auto sink = journal_.debug();
+
268 sink && (sendq_size % Tuning::sendQueueLogFreq) == 0)
+
269 {
+
270 std::string const n = name();
+
271 sink << (n.empty() ? remote_address_.to_string() : n)
+
272 << " sendq: " << sendq_size;
+
273 }
+
274
+
275 send_queue_.push(m);
+
276
+
277 if (sendq_size != 0)
+
278 return;
279
-
280 if (sendq_size != 0)
-
281 return;
-
282
-
283 boost::asio::async_write(
-
284 stream_,
-
285 boost::asio::buffer(
-
286 send_queue_.front()->getBuffer(compressionEnabled_)),
-
287 bind_executor(
-
288 strand_,
-
289 std::bind(
-
290 &PeerImp::onWriteMessage,
-
291 shared_from_this(),
-
292 std::placeholders::_1,
-
293 std::placeholders::_2)));
-
294}
-
295
-
296void
-
297PeerImp::sendTxQueue()
-
298{
-
299 if (!strand_.running_in_this_thread())
-
300 return post(
-
301 strand_, std::bind(&PeerImp::sendTxQueue, shared_from_this()));
-
302
-
303 if (!txQueue_.empty())
-
304 {
-
305 protocol::TMHaveTransactions ht;
-
306 std::for_each(txQueue_.begin(), txQueue_.end(), [&](auto const& hash) {
-
307 ht.add_hashes(hash.data(), hash.size());
-
308 });
-
309 JLOG(p_journal_.trace()) << "sendTxQueue " << txQueue_.size();
-
310 txQueue_.clear();
-
311 send(std::make_shared<Message>(ht, protocol::mtHAVE_TRANSACTIONS));
-
312 }
-
313}
-
314
-
315void
-
316PeerImp::addTxQueue(uint256 const& hash)
-
317{
-
318 if (!strand_.running_in_this_thread())
-
319 return post(
-
320 strand_, std::bind(&PeerImp::addTxQueue, shared_from_this(), hash));
-
321
-
322 if (txQueue_.size() == reduce_relay::MAX_TX_QUEUE_SIZE)
-
323 {
-
324 JLOG(p_journal_.warn()) << "addTxQueue exceeds the cap";
-
325 sendTxQueue();
-
326 }
-
327
-
328 txQueue_.insert(hash);
-
329 JLOG(p_journal_.trace()) << "addTxQueue " << txQueue_.size();
-
330}
-
331
-
332void
-
333PeerImp::removeTxQueue(uint256 const& hash)
-
334{
-
335 if (!strand_.running_in_this_thread())
-
336 return post(
-
337 strand_,
-
338 std::bind(&PeerImp::removeTxQueue, shared_from_this(), hash));
-
339
-
340 auto removed = txQueue_.erase(hash);
-
341 JLOG(p_journal_.trace()) << "removeTxQueue " << removed;
-
342}
-
343
-
344void
-
345PeerImp::charge(Resource::Charge const& fee, std::string const& context)
-
346{
-
347 if ((usage_.charge(fee, context) == Resource::drop) &&
-
348 usage_.disconnect(p_journal_) && strand_.running_in_this_thread())
-
349 {
-
350 // Sever the connection
-
351 overlay_.incPeerDisconnectCharges();
-
352 fail("charge: Resources");
-
353 }
-
354}
-
355
-
356//------------------------------------------------------------------------------
-
357
-
358bool
-
359PeerImp::crawl() const
-
360{
-
361 auto const iter = headers_.find("Crawl");
-
362 if (iter == headers_.end())
-
363 return false;
-
364 return boost::iequals(iter->value(), "public");
-
365}
-
366
-
367bool
-
368PeerImp::cluster() const
-
369{
-
370 return static_cast<bool>(app_.cluster().member(publicKey_));
-
371}
-
372
-
373std::string
-
374PeerImp::getVersion() const
-
375{
-
376 if (inbound_)
-
377 return headers_["User-Agent"];
-
378 return headers_["Server"];
-
379}
-
380
-
381Json::Value
-
382PeerImp::json()
-
383{
-
384 Json::Value ret(Json::objectValue);
+
280 boost::asio::async_write(
+
281 stream_,
+
282 boost::asio::buffer(
+
283 send_queue_.front()->getBuffer(compressionEnabled_)),
+
284 bind_executor(
+
285 strand_,
+
286 std::bind(
+
287 &PeerImp::onWriteMessage,
+
288 shared_from_this(),
+
289 std::placeholders::_1,
+
290 std::placeholders::_2)));
+
291}
+
292
+
293void
+
294PeerImp::sendTxQueue()
+
295{
+
296 if (!strand_.running_in_this_thread())
+
297 return post(
+
298 strand_, std::bind(&PeerImp::sendTxQueue, shared_from_this()));
+
299
+
300 if (!txQueue_.empty())
+
301 {
+
302 protocol::TMHaveTransactions ht;
+
303 std::for_each(txQueue_.begin(), txQueue_.end(), [&](auto const& hash) {
+
304 ht.add_hashes(hash.data(), hash.size());
+
305 });
+
306 JLOG(p_journal_.trace()) << "sendTxQueue " << txQueue_.size();
+
307 txQueue_.clear();
+
308 send(std::make_shared<Message>(ht, protocol::mtHAVE_TRANSACTIONS));
+
309 }
+
310}
+
311
+
312void
+
313PeerImp::addTxQueue(uint256 const& hash)
+
314{
+
315 if (!strand_.running_in_this_thread())
+
316 return post(
+
317 strand_, std::bind(&PeerImp::addTxQueue, shared_from_this(), hash));
+
318
+
319 if (txQueue_.size() == reduce_relay::MAX_TX_QUEUE_SIZE)
+
320 {
+
321 JLOG(p_journal_.warn()) << "addTxQueue exceeds the cap";
+
322 sendTxQueue();
+
323 }
+
324
+
325 txQueue_.insert(hash);
+
326 JLOG(p_journal_.trace()) << "addTxQueue " << txQueue_.size();
+
327}
+
328
+
329void
+
330PeerImp::removeTxQueue(uint256 const& hash)
+
331{
+
332 if (!strand_.running_in_this_thread())
+
333 return post(
+
334 strand_,
+
335 std::bind(&PeerImp::removeTxQueue, shared_from_this(), hash));
+
336
+
337 auto removed = txQueue_.erase(hash);
+
338 JLOG(p_journal_.trace()) << "removeTxQueue " << removed;
+
339}
+
340
+
341void
+
342PeerImp::charge(Resource::Charge const& fee, std::string const& context)
+
343{
+
344 if ((usage_.charge(fee, context) == Resource::drop) &&
+
345 usage_.disconnect(p_journal_) && strand_.running_in_this_thread())
+
346 {
+
347 // Sever the connection
+
348 overlay_.incPeerDisconnectCharges();
+
349 fail("charge: Resources");
+
350 }
+
351}
+
352
+
353//------------------------------------------------------------------------------
+
354
+
355bool
+
356PeerImp::crawl() const
+
357{
+
358 auto const iter = headers_.find("Crawl");
+
359 if (iter == headers_.end())
+
360 return false;
+
361 return boost::iequals(iter->value(), "public");
+
362}
+
363
+
364bool
+
365PeerImp::cluster() const
+
366{
+
367 return static_cast<bool>(app_.cluster().member(publicKey_));
+
368}
+
369
+
370std::string
+
371PeerImp::getVersion() const
+
372{
+
373 if (inbound_)
+
374 return headers_["User-Agent"];
+
375 return headers_["Server"];
+
376}
+
377
+
378Json::Value
+
379PeerImp::json()
+
380{
+
381 Json::Value ret(Json::objectValue);
+
382
+
383 ret[jss::public_key] = toBase58(TokenType::NodePublic, publicKey_);
+
384 ret[jss::address] = remote_address_.to_string();
385
-
386 ret[jss::public_key] = toBase58(TokenType::NodePublic, publicKey_);
-
387 ret[jss::address] = remote_address_.to_string();
+
386 if (inbound_)
+
387 ret[jss::inbound] = true;
388
-
389 if (inbound_)
-
390 ret[jss::inbound] = true;
-
391
-
392 if (cluster())
-
393 {
-
394 ret[jss::cluster] = true;
-
395
-
396 if (auto const n = name(); !n.empty())
-
397 // Could move here if Json::Value supported moving from a string
-
398 ret[jss::name] = n;
-
399 }
+
389 if (cluster())
+
390 {
+
391 ret[jss::cluster] = true;
+
392
+
393 if (auto const n = name(); !n.empty())
+
394 // Could move here if Json::Value supported moving from a string
+
395 ret[jss::name] = n;
+
396 }
+
397
+
398 if (auto const d = domain(); !d.empty())
+
399 ret[jss::server_domain] = std::string{d};
400
-
401 if (auto const d = domain(); !d.empty())
-
402 ret[jss::server_domain] = std::string{d};
+
401 if (auto const nid = headers_["Network-ID"]; !nid.empty())
+
402 ret[jss::network_id] = std::string{nid};
403
-
404 if (auto const nid = headers_["Network-ID"]; !nid.empty())
-
405 ret[jss::network_id] = std::string{nid};
-
406
-
407 ret[jss::load] = usage_.balance();
+
404 ret[jss::load] = usage_.balance();
+
405
+
406 if (auto const version = getVersion(); !version.empty())
+
407 ret[jss::version] = std::string{version};
408
-
409 if (auto const version = getVersion(); !version.empty())
-
410 ret[jss::version] = std::string{version};
-
411
-
412 ret[jss::protocol] = to_string(protocol_);
-
413
-
414 {
-
415 std::lock_guard sl(recentLock_);
-
416 if (latency_)
-
417 ret[jss::latency] = static_cast<Json::UInt>(latency_->count());
-
418 }
+
409 ret[jss::protocol] = to_string(protocol_);
+
410
+
411 {
+
412 std::lock_guard sl(recentLock_);
+
413 if (latency_)
+
414 ret[jss::latency] = static_cast<Json::UInt>(latency_->count());
+
415 }
+
416
+
417 ret[jss::uptime] = static_cast<Json::UInt>(
+
418 std::chrono::duration_cast<std::chrono::seconds>(uptime()).count());
419
-
420 ret[jss::uptime] = static_cast<Json::UInt>(
-
421 std::chrono::duration_cast<std::chrono::seconds>(uptime()).count());
+
420 std::uint32_t minSeq, maxSeq;
+
421 ledgerRange(minSeq, maxSeq);
422
-
423 std::uint32_t minSeq, maxSeq;
-
424 ledgerRange(minSeq, maxSeq);
-
425
-
426 if ((minSeq != 0) || (maxSeq != 0))
-
427 ret[jss::complete_ledgers] =
-
428 std::to_string(minSeq) + " - " + std::to_string(maxSeq);
-
429
-
430 switch (tracking_.load())
-
431 {
-
432 case Tracking::diverged:
-
433 ret[jss::track] = "diverged";
-
434 break;
-
435
-
436 case Tracking::unknown:
-
437 ret[jss::track] = "unknown";
-
438 break;
-
439
-
440 case Tracking::converged:
-
441 // Nothing to do here
-
442 break;
-
443 }
-
444
-
445 uint256 closedLedgerHash;
-
446 protocol::TMStatusChange last_status;
-
447 {
-
448 std::lock_guard sl(recentLock_);
-
449 closedLedgerHash = closedLedgerHash_;
-
450 last_status = last_status_;
-
451 }
+
423 if ((minSeq != 0) || (maxSeq != 0))
+
424 ret[jss::complete_ledgers] =
+
425 std::to_string(minSeq) + " - " + std::to_string(maxSeq);
+
426
+
427 switch (tracking_.load())
+
428 {
+
429 case Tracking::diverged:
+
430 ret[jss::track] = "diverged";
+
431 break;
+
432
+
433 case Tracking::unknown:
+
434 ret[jss::track] = "unknown";
+
435 break;
+
436
+
437 case Tracking::converged:
+
438 // Nothing to do here
+
439 break;
+
440 }
+
441
+
442 uint256 closedLedgerHash;
+
443 protocol::TMStatusChange last_status;
+
444 {
+
445 std::lock_guard sl(recentLock_);
+
446 closedLedgerHash = closedLedgerHash_;
+
447 last_status = last_status_;
+
448 }
+
449
+
450 if (closedLedgerHash != beast::zero)
+
451 ret[jss::ledger] = to_string(closedLedgerHash);
452
-
453 if (closedLedgerHash != beast::zero)
-
454 ret[jss::ledger] = to_string(closedLedgerHash);
-
455
-
456 if (last_status.has_newstatus())
-
457 {
-
458 switch (last_status.newstatus())
-
459 {
-
460 case protocol::nsCONNECTING:
-
461 ret[jss::status] = "connecting";
-
462 break;
-
463
-
464 case protocol::nsCONNECTED:
-
465 ret[jss::status] = "connected";
-
466 break;
-
467
-
468 case protocol::nsMONITORING:
-
469 ret[jss::status] = "monitoring";
-
470 break;
-
471
-
472 case protocol::nsVALIDATING:
-
473 ret[jss::status] = "validating";
-
474 break;
-
475
-
476 case protocol::nsSHUTTING:
-
477 ret[jss::status] = "shutting";
-
478 break;
-
479
-
480 default:
-
481 JLOG(p_journal_.warn())
-
482 << "Unknown status: " << last_status.newstatus();
-
483 }
-
484 }
-
485
-
486 ret[jss::metrics] = Json::Value(Json::objectValue);
-
487 ret[jss::metrics][jss::total_bytes_recv] =
-
488 std::to_string(metrics_.recv.total_bytes());
-
489 ret[jss::metrics][jss::total_bytes_sent] =
-
490 std::to_string(metrics_.sent.total_bytes());
-
491 ret[jss::metrics][jss::avg_bps_recv] =
-
492 std::to_string(metrics_.recv.average_bytes());
-
493 ret[jss::metrics][jss::avg_bps_sent] =
-
494 std::to_string(metrics_.sent.average_bytes());
+
453 if (last_status.has_newstatus())
+
454 {
+
455 switch (last_status.newstatus())
+
456 {
+
457 case protocol::nsCONNECTING:
+
458 ret[jss::status] = "connecting";
+
459 break;
+
460
+
461 case protocol::nsCONNECTED:
+
462 ret[jss::status] = "connected";
+
463 break;
+
464
+
465 case protocol::nsMONITORING:
+
466 ret[jss::status] = "monitoring";
+
467 break;
+
468
+
469 case protocol::nsVALIDATING:
+
470 ret[jss::status] = "validating";
+
471 break;
+
472
+
473 case protocol::nsSHUTTING:
+
474 ret[jss::status] = "shutting";
+
475 break;
+
476
+
477 default:
+
478 JLOG(p_journal_.warn())
+
479 << "Unknown status: " << last_status.newstatus();
+
480 }
+
481 }
+
482
+
483 ret[jss::metrics] = Json::Value(Json::objectValue);
+
484 ret[jss::metrics][jss::total_bytes_recv] =
+
485 std::to_string(metrics_.recv.total_bytes());
+
486 ret[jss::metrics][jss::total_bytes_sent] =
+
487 std::to_string(metrics_.sent.total_bytes());
+
488 ret[jss::metrics][jss::avg_bps_recv] =
+
489 std::to_string(metrics_.recv.average_bytes());
+
490 ret[jss::metrics][jss::avg_bps_sent] =
+
491 std::to_string(metrics_.sent.average_bytes());
+
492
+
493 return ret;
+
494}
495
-
496 return ret;
-
497}
-
498
-
499bool
-
500PeerImp::supportsFeature(ProtocolFeature f) const
-
501{
-
502 switch (f)
-
503 {
-
504 case ProtocolFeature::ValidatorListPropagation:
-
505 return protocol_ >= make_protocol(2, 1);
-
506 case ProtocolFeature::ValidatorList2Propagation:
-
507 return protocol_ >= make_protocol(2, 2);
-
508 case ProtocolFeature::LedgerReplay:
-
509 return ledgerReplayEnabled_;
-
510 }
-
511 return false;
-
512}
-
513
-
514//------------------------------------------------------------------------------
-
515
-
516bool
-
517PeerImp::hasLedger(uint256 const& hash, std::uint32_t seq) const
-
518{
-
519 {
-
520 std::lock_guard sl(recentLock_);
-
521 if ((seq != 0) && (seq >= minLedger_) && (seq <= maxLedger_) &&
-
522 (tracking_.load() == Tracking::converged))
+
496bool
+
497PeerImp::supportsFeature(ProtocolFeature f) const
+
498{
+
499 switch (f)
+
500 {
+
501 case ProtocolFeature::ValidatorListPropagation:
+
502 return protocol_ >= make_protocol(2, 1);
+
503 case ProtocolFeature::ValidatorList2Propagation:
+
504 return protocol_ >= make_protocol(2, 2);
+
505 case ProtocolFeature::LedgerReplay:
+
506 return ledgerReplayEnabled_;
+
507 }
+
508 return false;
+
509}
+
510
+
511//------------------------------------------------------------------------------
+
512
+
513bool
+
514PeerImp::hasLedger(uint256 const& hash, std::uint32_t seq) const
+
515{
+
516 {
+
517 std::lock_guard sl(recentLock_);
+
518 if ((seq != 0) && (seq >= minLedger_) && (seq <= maxLedger_) &&
+
519 (tracking_.load() == Tracking::converged))
+
520 return true;
+
521 if (std::find(recentLedgers_.begin(), recentLedgers_.end(), hash) !=
+
522 recentLedgers_.end())
523 return true;
-
524 if (std::find(recentLedgers_.begin(), recentLedgers_.end(), hash) !=
-
525 recentLedgers_.end())
-
526 return true;
-
527 }
-
528 return false;
-
529}
-
530
-
531void
-
532PeerImp::ledgerRange(std::uint32_t& minSeq, std::uint32_t& maxSeq) const
-
533{
-
534 std::lock_guard sl(recentLock_);
-
535
-
536 minSeq = minLedger_;
-
537 maxSeq = maxLedger_;
-
538}
-
539
-
540bool
-
541PeerImp::hasTxSet(uint256 const& hash) const
-
542{
-
543 std::lock_guard sl(recentLock_);
-
544 return std::find(recentTxSets_.begin(), recentTxSets_.end(), hash) !=
-
545 recentTxSets_.end();
-
546}
-
547
-
548void
-
549PeerImp::cycleStatus()
-
550{
-
551 // Operations on closedLedgerHash_ and previousLedgerHash_ must be
-
552 // guarded by recentLock_.
-
553 std::lock_guard sl(recentLock_);
-
554 previousLedgerHash_ = closedLedgerHash_;
-
555 closedLedgerHash_.zero();
-
556}
-
557
-
558bool
-
559PeerImp::hasRange(std::uint32_t uMin, std::uint32_t uMax)
-
560{
-
561 std::lock_guard sl(recentLock_);
-
562 return (tracking_ != Tracking::diverged) && (uMin >= minLedger_) &&
-
563 (uMax <= maxLedger_);
-
564}
-
565
-
566//------------------------------------------------------------------------------
-
567
-
568void
-
569PeerImp::close()
-
570{
-
571 XRPL_ASSERT(
-
572 strand_.running_in_this_thread(),
-
573 "ripple::PeerImp::close : strand in this thread");
-
574 if (socket_.is_open())
-
575 {
-
576 detaching_ = true; // DEPRECATED
-
577 error_code ec;
-
578 timer_.cancel(ec);
-
579 socket_.close(ec);
-
580 overlay_.incPeerDisconnect();
-
581 if (inbound_)
-
582 {
-
583 JLOG(journal_.debug()) << "Closed";
-
584 }
-
585 else
-
586 {
-
587 JLOG(journal_.info()) << "Closed";
-
588 }
-
589 }
-
590}
-
591
-
592void
-
593PeerImp::fail(std::string const& reason)
-
594{
-
595 if (!strand_.running_in_this_thread())
-
596 return post(
-
597 strand_,
-
598 std::bind(
-
599 (void(Peer::*)(std::string const&)) & PeerImp::fail,
-
600 shared_from_this(),
-
601 reason));
-
602 if (journal_.active(beast::severities::kWarning) && socket_.is_open())
-
603 {
-
604 std::string const n = name();
-
605 JLOG(journal_.warn()) << (n.empty() ? remote_address_.to_string() : n)
-
606 << " failed: " << reason;
-
607 }
-
608 close();
-
609}
-
610
-
611void
-
612PeerImp::fail(std::string const& name, error_code ec)
-
613{
-
614 XRPL_ASSERT(
-
615 strand_.running_in_this_thread(),
-
616 "ripple::PeerImp::fail : strand in this thread");
-
617 if (socket_.is_open())
-
618 {
-
619 JLOG(journal_.warn())
-
620 << name << " from " << toBase58(TokenType::NodePublic, publicKey_)
-
621 << " at " << remote_address_.to_string() << ": " << ec.message();
-
622 }
-
623 close();
-
624}
-
625
-
626void
-
627PeerImp::gracefulClose()
-
628{
+
524 }
+
525 return false;
+
526}
+
527
+
528void
+
529PeerImp::ledgerRange(std::uint32_t& minSeq, std::uint32_t& maxSeq) const
+
530{
+
531 std::lock_guard sl(recentLock_);
+
532
+
533 minSeq = minLedger_;
+
534 maxSeq = maxLedger_;
+
535}
+
536
+
537bool
+
538PeerImp::hasTxSet(uint256 const& hash) const
+
539{
+
540 std::lock_guard sl(recentLock_);
+
541 return std::find(recentTxSets_.begin(), recentTxSets_.end(), hash) !=
+
542 recentTxSets_.end();
+
543}
+
544
+
545void
+
546PeerImp::cycleStatus()
+
547{
+
548 // Operations on closedLedgerHash_ and previousLedgerHash_ must be
+
549 // guarded by recentLock_.
+
550 std::lock_guard sl(recentLock_);
+
551 previousLedgerHash_ = closedLedgerHash_;
+
552 closedLedgerHash_.zero();
+
553}
+
554
+
555bool
+
556PeerImp::hasRange(std::uint32_t uMin, std::uint32_t uMax)
+
557{
+
558 std::lock_guard sl(recentLock_);
+
559 return (tracking_ != Tracking::diverged) && (uMin >= minLedger_) &&
+
560 (uMax <= maxLedger_);
+
561}
+
562
+
563//------------------------------------------------------------------------------
+
564
+
565void
+
566PeerImp::close()
+
567{
+
568 XRPL_ASSERT(
+
569 strand_.running_in_this_thread(),
+
570 "ripple::PeerImp::close : strand in this thread");
+
571 if (socket_.is_open())
+
572 {
+
573 detaching_ = true; // DEPRECATED
+
574 error_code ec;
+
575 timer_.cancel(ec);
+
576 socket_.close(ec);
+
577 overlay_.incPeerDisconnect();
+
578 if (inbound_)
+
579 {
+
580 JLOG(journal_.debug()) << "Closed";
+
581 }
+
582 else
+
583 {
+
584 JLOG(journal_.info()) << "Closed";
+
585 }
+
586 }
+
587}
+
588
+
589void
+
590PeerImp::fail(std::string const& reason)
+
591{
+
592 if (!strand_.running_in_this_thread())
+
593 return post(
+
594 strand_,
+
595 std::bind(
+
596 (void(Peer::*)(std::string const&)) & PeerImp::fail,
+
597 shared_from_this(),
+
598 reason));
+
599 if (journal_.active(beast::severities::kWarning) && socket_.is_open())
+
600 {
+
601 std::string const n = name();
+
602 JLOG(journal_.warn()) << (n.empty() ? remote_address_.to_string() : n)
+
603 << " failed: " << reason;
+
604 }
+
605 close();
+
606}
+
607
+
608void
+
609PeerImp::fail(std::string const& name, error_code ec)
+
610{
+
611 XRPL_ASSERT(
+
612 strand_.running_in_this_thread(),
+
613 "ripple::PeerImp::fail : strand in this thread");
+
614 if (socket_.is_open())
+
615 {
+
616 JLOG(journal_.warn())
+
617 << name << " from " << toBase58(TokenType::NodePublic, publicKey_)
+
618 << " at " << remote_address_.to_string() << ": " << ec.message();
+
619 }
+
620 close();
+
621}
+
622
+
623void
+
624PeerImp::gracefulClose()
+
625{
+
626 XRPL_ASSERT(
+
627 strand_.running_in_this_thread(),
+
628 "ripple::PeerImp::gracefulClose : strand in this thread");
629 XRPL_ASSERT(
-
630 strand_.running_in_this_thread(),
-
631 "ripple::PeerImp::gracefulClose : strand in this thread");
-
632 XRPL_ASSERT(
-
633 socket_.is_open(), "ripple::PeerImp::gracefulClose : socket is open");
-
634 XRPL_ASSERT(
-
635 !gracefulClose_,
-
636 "ripple::PeerImp::gracefulClose : socket is not closing");
-
637 gracefulClose_ = true;
-
638 if (send_queue_.size() > 0)
-
639 return;
-
640 setTimer();
-
641 stream_.async_shutdown(bind_executor(
-
642 strand_,
-
643 std::bind(
-
644 &PeerImp::onShutdown, shared_from_this(), std::placeholders::_1)));
-
645}
-
646
-
647void
-
648PeerImp::setTimer()
-
649{
-
650 error_code ec;
-
651 timer_.expires_from_now(peerTimerInterval, ec);
-
652
-
653 if (ec)
-
654 {
-
655 JLOG(journal_.error()) << "setTimer: " << ec.message();
-
656 return;
-
657 }
-
658 timer_.async_wait(bind_executor(
-
659 strand_,
-
660 std::bind(
-
661 &PeerImp::onTimer, shared_from_this(), std::placeholders::_1)));
-
662}
-
663
-
664// convenience for ignoring the error code
-
665void
-
666PeerImp::cancelTimer()
-
667{
-
668 error_code ec;
-
669 timer_.cancel(ec);
-
670}
-
671
-
672//------------------------------------------------------------------------------
-
673
-
674std::string
-
675PeerImp::makePrefix(id_t id)
-
676{
-
677 std::stringstream ss;
-
678 ss << "[" << std::setfill('0') << std::setw(3) << id << "] ";
-
679 return ss.str();
-
680}
-
681
-
682void
-
683PeerImp::onTimer(error_code const& ec)
-
684{
-
685 if (!socket_.is_open())
+
630 socket_.is_open(), "ripple::PeerImp::gracefulClose : socket is open");
+
631 XRPL_ASSERT(
+
632 !gracefulClose_,
+
633 "ripple::PeerImp::gracefulClose : socket is not closing");
+
634 gracefulClose_ = true;
+
635 if (send_queue_.size() > 0)
+
636 return;
+
637 setTimer();
+
638 stream_.async_shutdown(bind_executor(
+
639 strand_,
+
640 std::bind(
+
641 &PeerImp::onShutdown, shared_from_this(), std::placeholders::_1)));
+
642}
+
643
+
644void
+
645PeerImp::setTimer()
+
646{
+
647 error_code ec;
+
648 timer_.expires_from_now(peerTimerInterval, ec);
+
649
+
650 if (ec)
+
651 {
+
652 JLOG(journal_.error()) << "setTimer: " << ec.message();
+
653 return;
+
654 }
+
655 timer_.async_wait(bind_executor(
+
656 strand_,
+
657 std::bind(
+
658 &PeerImp::onTimer, shared_from_this(), std::placeholders::_1)));
+
659}
+
660
+
661// convenience for ignoring the error code
+
662void
+
663PeerImp::cancelTimer()
+
664{
+
665 error_code ec;
+
666 timer_.cancel(ec);
+
667}
+
668
+
669//------------------------------------------------------------------------------
+
670
+
671std::string
+
672PeerImp::makePrefix(id_t id)
+
673{
+
674 std::stringstream ss;
+
675 ss << "[" << std::setfill('0') << std::setw(3) << id << "] ";
+
676 return ss.str();
+
677}
+
678
+
679void
+
680PeerImp::onTimer(error_code const& ec)
+
681{
+
682 if (!socket_.is_open())
+
683 return;
+
684
+
685 if (ec == boost::asio::error::operation_aborted)
686 return;
687
-
688 if (ec == boost::asio::error::operation_aborted)
-
689 return;
-
690
-
691 if (ec)
-
692 {
-
693 // This should never happen
-
694 JLOG(journal_.error()) << "onTimer: " << ec.message();
-
695 return close();
-
696 }
-
697
-
698 if (large_sendq_++ >= Tuning::sendqIntervals)
-
699 {
-
700 fail("Large send queue");
-
701 return;
-
702 }
-
703
-
704 if (auto const t = tracking_.load(); !inbound_ && t != Tracking::converged)
-
705 {
-
706 clock_type::duration duration;
-
707
-
708 {
-
709 std::lock_guard sl(recentLock_);
-
710 duration = clock_type::now() - trackingTime_;
-
711 }
-
712
-
713 if ((t == Tracking::diverged &&
-
714 (duration > app_.config().MAX_DIVERGED_TIME)) ||
-
715 (t == Tracking::unknown &&
-
716 (duration > app_.config().MAX_UNKNOWN_TIME)))
-
717 {
-
718 overlay_.peerFinder().on_failure(slot_);
-
719 fail("Not useful");
-
720 return;
-
721 }
-
722 }
-
723
-
724 // Already waiting for PONG
-
725 if (lastPingSeq_)
-
726 {
-
727 fail("Ping Timeout");
-
728 return;
-
729 }
+
688 if (ec)
+
689 {
+
690 // This should never happen
+
691 JLOG(journal_.error()) << "onTimer: " << ec.message();
+
692 return close();
+
693 }
+
694
+
695 if (large_sendq_++ >= Tuning::sendqIntervals)
+
696 {
+
697 fail("Large send queue");
+
698 return;
+
699 }
+
700
+
701 if (auto const t = tracking_.load(); !inbound_ && t != Tracking::converged)
+
702 {
+
703 clock_type::duration duration;
+
704
+
705 {
+
706 std::lock_guard sl(recentLock_);
+
707 duration = clock_type::now() - trackingTime_;
+
708 }
+
709
+
710 if ((t == Tracking::diverged &&
+
711 (duration > app_.config().MAX_DIVERGED_TIME)) ||
+
712 (t == Tracking::unknown &&
+
713 (duration > app_.config().MAX_UNKNOWN_TIME)))
+
714 {
+
715 overlay_.peerFinder().on_failure(slot_);
+
716 fail("Not useful");
+
717 return;
+
718 }
+
719 }
+
720
+
721 // Already waiting for PONG
+
722 if (lastPingSeq_)
+
723 {
+
724 fail("Ping Timeout");
+
725 return;
+
726 }
+
727
+
728 lastPingTime_ = clock_type::now();
+
729 lastPingSeq_ = rand_int<std::uint32_t>();
730
-
731 lastPingTime_ = clock_type::now();
-
732 lastPingSeq_ = rand_int<std::uint32_t>();
-
733
-
734 protocol::TMPing message;
-
735 message.set_type(protocol::TMPing::ptPING);
-
736 message.set_seq(*lastPingSeq_);
-
737
-
738 send(std::make_shared<Message>(message, protocol::mtPING));
+
731 protocol::TMPing message;
+
732 message.set_type(protocol::TMPing::ptPING);
+
733 message.set_seq(*lastPingSeq_);
+
734
+
735 send(std::make_shared<Message>(message, protocol::mtPING));
+
736
+
737 setTimer();
+
738}
739
-
740 setTimer();
-
741}
-
742
-
743void
-
744PeerImp::onShutdown(error_code ec)
-
745{
-
746 cancelTimer();
-
747 // If we don't get eof then something went wrong
-
748 if (!ec)
-
749 {
-
750 JLOG(journal_.error()) << "onShutdown: expected error condition";
-
751 return close();
-
752 }
-
753 if (ec != boost::asio::error::eof)
-
754 return fail("onShutdown", ec);
-
755 close();
-
756}
-
757
-
758//------------------------------------------------------------------------------
-
759void
-
760PeerImp::doAccept()
-
761{
-
762 XRPL_ASSERT(
-
763 read_buffer_.size() == 0,
-
764 "ripple::PeerImp::doAccept : empty read buffer");
-
765
-
766 JLOG(journal_.debug()) << "doAccept: " << remote_address_;
-
767
-
768 auto const sharedValue = makeSharedValue(*stream_ptr_, journal_);
-
769
-
770 // This shouldn't fail since we already computed
-
771 // the shared value successfully in OverlayImpl
-
772 if (!sharedValue)
-
773 return fail("makeSharedValue: Unexpected failure");
-
774
-
775 JLOG(journal_.info()) << "Protocol: " << to_string(protocol_);
-
776 JLOG(journal_.info()) << "Public Key: "
-
777 << toBase58(TokenType::NodePublic, publicKey_);
-
778
-
779 if (auto member = app_.cluster().member(publicKey_))
-
780 {
-
781 {
-
782 std::unique_lock lock{nameMutex_};
-
783 name_ = *member;
-
784 }
-
785 JLOG(journal_.info()) << "Cluster name: " << *member;
-
786 }
-
787
-
788 overlay_.activate(shared_from_this());
-
789
-
790 // XXX Set timer: connection is in grace period to be useful.
-
791 // XXX Set timer: connection idle (idle may vary depending on connection
-
792 // type.)
-
793
-
794 auto write_buffer = std::make_shared<boost::beast::multi_buffer>();
-
795
-
796 boost::beast::ostream(*write_buffer) << makeResponse(
-
797 !overlay_.peerFinder().config().peerPrivate,
-
798 request_,
-
799 overlay_.setup().public_ip,
-
800 remote_address_.address(),
-
801 *sharedValue,
-
802 overlay_.setup().networkID,
-
803 protocol_,
-
804 app_);
-
805
-
806 // Write the whole buffer and only start protocol when that's done.
-
807 boost::asio::async_write(
-
808 stream_,
-
809 write_buffer->data(),
-
810 boost::asio::transfer_all(),
-
811 bind_executor(
-
812 strand_,
-
813 [this, write_buffer, self = shared_from_this()](
-
814 error_code ec, std::size_t bytes_transferred) {
-
815 if (!socket_.is_open())
-
816 return;
-
817 if (ec == boost::asio::error::operation_aborted)
-
818 return;
-
819 if (ec)
-
820 return fail("onWriteResponse", ec);
-
821 if (write_buffer->size() == bytes_transferred)
-
822 return doProtocolStart();
-
823 return fail("Failed to write header");
-
824 }));
-
825}
-
826
-
827std::string
-
828PeerImp::name() const
-
829{
-
830 std::shared_lock read_lock{nameMutex_};
-
831 return name_;
-
832}
-
833
-
834std::string
-
835PeerImp::domain() const
-
836{
-
837 return headers_["Server-Domain"];
-
838}
-
839
-
840//------------------------------------------------------------------------------
-
841
-
842// Protocol logic
-
843
-
844void
-
845PeerImp::doProtocolStart()
-
846{
-
847 onReadMessage(error_code(), 0);
-
848
-
849 // Send all the validator lists that have been loaded
-
850 if (inbound_ && supportsFeature(ProtocolFeature::ValidatorListPropagation))
-
851 {
-
852 app_.validators().for_each_available(
-
853 [&](std::string const& manifest,
-
854 std::uint32_t version,
-
855 std::map<std::size_t, ValidatorBlobInfo> const& blobInfos,
-
856 PublicKey const& pubKey,
-
857 std::size_t maxSequence,
-
858 uint256 const& hash) {
-
859 ValidatorList::sendValidatorList(
-
860 *this,
-
861 0,
-
862 pubKey,
-
863 maxSequence,
-
864 version,
-
865 manifest,
-
866 blobInfos,
-
867 app_.getHashRouter(),
-
868 p_journal_);
-
869
-
870 // Don't send it next time.
-
871 app_.getHashRouter().addSuppressionPeer(hash, id_);
-
872 });
-
873 }
+
740void
+
741PeerImp::onShutdown(error_code ec)
+
742{
+
743 cancelTimer();
+
744 // If we don't get eof then something went wrong
+
745 if (!ec)
+
746 {
+
747 JLOG(journal_.error()) << "onShutdown: expected error condition";
+
748 return close();
+
749 }
+
750 if (ec != boost::asio::error::eof)
+
751 return fail("onShutdown", ec);
+
752 close();
+
753}
+
754
+
755//------------------------------------------------------------------------------
+
756void
+
757PeerImp::doAccept()
+
758{
+
759 XRPL_ASSERT(
+
760 read_buffer_.size() == 0,
+
761 "ripple::PeerImp::doAccept : empty read buffer");
+
762
+
763 JLOG(journal_.debug()) << "doAccept: " << remote_address_;
+
764
+
765 auto const sharedValue = makeSharedValue(*stream_ptr_, journal_);
+
766
+
767 // This shouldn't fail since we already computed
+
768 // the shared value successfully in OverlayImpl
+
769 if (!sharedValue)
+
770 return fail("makeSharedValue: Unexpected failure");
+
771
+
772 JLOG(journal_.info()) << "Protocol: " << to_string(protocol_);
+
773 JLOG(journal_.info()) << "Public Key: "
+
774 << toBase58(TokenType::NodePublic, publicKey_);
+
775
+
776 if (auto member = app_.cluster().member(publicKey_))
+
777 {
+
778 {
+
779 std::unique_lock lock{nameMutex_};
+
780 name_ = *member;
+
781 }
+
782 JLOG(journal_.info()) << "Cluster name: " << *member;
+
783 }
+
784
+
785 overlay_.activate(shared_from_this());
+
786
+
787 // XXX Set timer: connection is in grace period to be useful.
+
788 // XXX Set timer: connection idle (idle may vary depending on connection
+
789 // type.)
+
790
+
791 auto write_buffer = std::make_shared<boost::beast::multi_buffer>();
+
792
+
793 boost::beast::ostream(*write_buffer) << makeResponse(
+
794 !overlay_.peerFinder().config().peerPrivate,
+
795 request_,
+
796 overlay_.setup().public_ip,
+
797 remote_address_.address(),
+
798 *sharedValue,
+
799 overlay_.setup().networkID,
+
800 protocol_,
+
801 app_);
+
802
+
803 // Write the whole buffer and only start protocol when that's done.
+
804 boost::asio::async_write(
+
805 stream_,
+
806 write_buffer->data(),
+
807 boost::asio::transfer_all(),
+
808 bind_executor(
+
809 strand_,
+
810 [this, write_buffer, self = shared_from_this()](
+
811 error_code ec, std::size_t bytes_transferred) {
+
812 if (!socket_.is_open())
+
813 return;
+
814 if (ec == boost::asio::error::operation_aborted)
+
815 return;
+
816 if (ec)
+
817 return fail("onWriteResponse", ec);
+
818 if (write_buffer->size() == bytes_transferred)
+
819 return doProtocolStart();
+
820 return fail("Failed to write header");
+
821 }));
+
822}
+
823
+
824std::string
+
825PeerImp::name() const
+
826{
+
827 std::shared_lock read_lock{nameMutex_};
+
828 return name_;
+
829}
+
830
+
831std::string
+
832PeerImp::domain() const
+
833{
+
834 return headers_["Server-Domain"];
+
835}
+
836
+
837//------------------------------------------------------------------------------
+
838
+
839// Protocol logic
+
840
+
841void
+
842PeerImp::doProtocolStart()
+
843{
+
844 onReadMessage(error_code(), 0);
+
845
+
846 // Send all the validator lists that have been loaded
+
847 if (inbound_ && supportsFeature(ProtocolFeature::ValidatorListPropagation))
+
848 {
+
849 app_.validators().for_each_available(
+
850 [&](std::string const& manifest,
+
851 std::uint32_t version,
+
852 std::map<std::size_t, ValidatorBlobInfo> const& blobInfos,
+
853 PublicKey const& pubKey,
+
854 std::size_t maxSequence,
+
855 uint256 const& hash) {
+
856 ValidatorList::sendValidatorList(
+
857 *this,
+
858 0,
+
859 pubKey,
+
860 maxSequence,
+
861 version,
+
862 manifest,
+
863 blobInfos,
+
864 app_.getHashRouter(),
+
865 p_journal_);
+
866
+
867 // Don't send it next time.
+
868 app_.getHashRouter().addSuppressionPeer(hash, id_);
+
869 });
+
870 }
+
871
+
872 if (auto m = overlay_.getManifestsMessage())
+
873 send(m);
874
-
875 if (auto m = overlay_.getManifestsMessage())
-
876 send(m);
+
875 setTimer();
+
876}
877
-
878 setTimer();
-
879}
-
880
-
881// Called repeatedly with protocol message data
-
882void
-
883PeerImp::onReadMessage(error_code ec, std::size_t bytes_transferred)
-
884{
-
885 if (!socket_.is_open())
-
886 return;
-
887 if (ec == boost::asio::error::operation_aborted)
-
888 return;
-
889 if (ec == boost::asio::error::eof)
-
890 {
-
891 JLOG(journal_.info()) << "EOF";
-
892 return gracefulClose();
-
893 }
-
894 if (ec)
-
895 return fail("onReadMessage", ec);
-
896 if (auto stream = journal_.trace())
-
897 {
-
898 if (bytes_transferred > 0)
-
899 stream << "onReadMessage: " << bytes_transferred << " bytes";
-
900 else
-
901 stream << "onReadMessage";
-
902 }
-
903
-
904 metrics_.recv.add_message(bytes_transferred);
-
905
-
906 read_buffer_.commit(bytes_transferred);
-
907
-
908 auto hint = Tuning::readBufferBytes;
-
909
-
910 while (read_buffer_.size() > 0)
-
911 {
-
912 std::size_t bytes_consumed;
-
913
-
914 using namespace std::chrono_literals;
-
915 std::tie(bytes_consumed, ec) = perf::measureDurationAndLog(
-
916 [&]() {
-
917 return invokeProtocolMessage(read_buffer_.data(), *this, hint);
-
918 },
-
919 "invokeProtocolMessage",
-
920 350ms,
-
921 journal_);
-
922
-
923 if (ec)
-
924 return fail("onReadMessage", ec);
-
925 if (!socket_.is_open())
-
926 return;
-
927 if (gracefulClose_)
-
928 return;
-
929 if (bytes_consumed == 0)
-
930 break;
-
931 read_buffer_.consume(bytes_consumed);
-
932 }
-
933
-
934 // Timeout on writes only
-
935 stream_.async_read_some(
-
936 read_buffer_.prepare(std::max(Tuning::readBufferBytes, hint)),
-
937 bind_executor(
-
938 strand_,
-
939 std::bind(
-
940 &PeerImp::onReadMessage,
-
941 shared_from_this(),
-
942 std::placeholders::_1,
-
943 std::placeholders::_2)));
-
944}
-
945
-
946void
-
947PeerImp::onWriteMessage(error_code ec, std::size_t bytes_transferred)
-
948{
-
949 if (!socket_.is_open())
-
950 return;
-
951 if (ec == boost::asio::error::operation_aborted)
-
952 return;
-
953 if (ec)
-
954 return fail("onWriteMessage", ec);
-
955 if (auto stream = journal_.trace())
-
956 {
-
957 if (bytes_transferred > 0)
-
958 stream << "onWriteMessage: " << bytes_transferred << " bytes";
-
959 else
-
960 stream << "onWriteMessage";
-
961 }
-
962
-
963 metrics_.sent.add_message(bytes_transferred);
-
964
-
965 XRPL_ASSERT(
-
966 !send_queue_.empty(),
-
967 "ripple::PeerImp::onWriteMessage : non-empty send buffer");
-
968 send_queue_.pop();
-
969 if (!send_queue_.empty())
-
970 {
-
971 // Timeout on writes only
-
972 return boost::asio::async_write(
-
973 stream_,
-
974 boost::asio::buffer(
-
975 send_queue_.front()->getBuffer(compressionEnabled_)),
-
976 bind_executor(
-
977 strand_,
-
978 std::bind(
-
979 &PeerImp::onWriteMessage,
-
980 shared_from_this(),
-
981 std::placeholders::_1,
-
982 std::placeholders::_2)));
-
983 }
-
984
-
985 if (gracefulClose_)
-
986 {
-
987 return stream_.async_shutdown(bind_executor(
-
988 strand_,
-
989 std::bind(
-
990 &PeerImp::onShutdown,
-
991 shared_from_this(),
-
992 std::placeholders::_1)));
-
993 }
-
994}
-
995
-
996//------------------------------------------------------------------------------
-
997//
-
998// ProtocolHandler
-
999//
-
1000//------------------------------------------------------------------------------
-
1001
-
1002void
-
1003PeerImp::onMessageUnknown(std::uint16_t type)
-
1004{
-
1005 // TODO
-
1006}
-
1007
-
1008void
-
1009PeerImp::onMessageBegin(
-
1010 std::uint16_t type,
-
1011 std::shared_ptr<::google::protobuf::Message> const& m,
-
1012 std::size_t size,
-
1013 std::size_t uncompressed_size,
-
1014 bool isCompressed)
-
1015{
-
1016 auto const name = protocolMessageName(type);
-
1017 load_event_ = app_.getJobQueue().makeLoadEvent(jtPEER, name);
-
1018 fee_ = {Resource::feeTrivialPeer, name};
-
1019 auto const category = TrafficCount::categorize(*m, type, true);
-
1020 overlay_.reportTraffic(category, true, static_cast<int>(size));
-
1021 using namespace protocol;
-
1022 if ((type == MessageType::mtTRANSACTION ||
-
1023 type == MessageType::mtHAVE_TRANSACTIONS ||
-
1024 type == MessageType::mtTRANSACTIONS ||
-
1025 // GET_OBJECTS
-
1026 category == TrafficCount::category::get_transactions ||
-
1027 // GET_LEDGER
-
1028 category == TrafficCount::category::ld_tsc_get ||
-
1029 category == TrafficCount::category::ld_tsc_share ||
-
1030 // LEDGER_DATA
-
1031 category == TrafficCount::category::gl_tsc_share ||
-
1032 category == TrafficCount::category::gl_tsc_get) &&
-
1033 (txReduceRelayEnabled() || app_.config().TX_REDUCE_RELAY_METRICS))
-
1034 {
-
1035 overlay_.addTxMetrics(
-
1036 static_cast<MessageType>(type), static_cast<std::uint64_t>(size));
-
1037 }
-
1038 JLOG(journal_.trace()) << "onMessageBegin: " << type << " " << size << " "
-
1039 << uncompressed_size << " " << isCompressed;
-
1040}
-
1041
-
1042void
-
1043PeerImp::onMessageEnd(
-
1044 std::uint16_t,
-
1045 std::shared_ptr<::google::protobuf::Message> const&)
-
1046{
-
1047 load_event_.reset();
-
1048 charge(fee_.fee, fee_.context);
-
1049}
-
1050
-
1051void
-
1052PeerImp::onMessage(std::shared_ptr<protocol::TMManifests> const& m)
-
1053{
-
1054 auto const s = m->list_size();
-
1055
-
1056 if (s == 0)
-
1057 {
-
1058 fee_.update(Resource::feeUselessData, "empty");
-
1059 return;
-
1060 }
+
878// Called repeatedly with protocol message data
+
879void
+
880PeerImp::onReadMessage(error_code ec, std::size_t bytes_transferred)
+
881{
+
882 if (!socket_.is_open())
+
883 return;
+
884 if (ec == boost::asio::error::operation_aborted)
+
885 return;
+
886 if (ec == boost::asio::error::eof)
+
887 {
+
888 JLOG(journal_.info()) << "EOF";
+
889 return gracefulClose();
+
890 }
+
891 if (ec)
+
892 return fail("onReadMessage", ec);
+
893 if (auto stream = journal_.trace())
+
894 {
+
895 if (bytes_transferred > 0)
+
896 stream << "onReadMessage: " << bytes_transferred << " bytes";
+
897 else
+
898 stream << "onReadMessage";
+
899 }
+
900
+
901 metrics_.recv.add_message(bytes_transferred);
+
902
+
903 read_buffer_.commit(bytes_transferred);
+
904
+
905 auto hint = Tuning::readBufferBytes;
+
906
+
907 while (read_buffer_.size() > 0)
+
908 {
+
909 std::size_t bytes_consumed;
+
910
+
911 using namespace std::chrono_literals;
+
912 std::tie(bytes_consumed, ec) = perf::measureDurationAndLog(
+
913 [&]() {
+
914 return invokeProtocolMessage(read_buffer_.data(), *this, hint);
+
915 },
+
916 "invokeProtocolMessage",
+
917 350ms,
+
918 journal_);
+
919
+
920 if (ec)
+
921 return fail("onReadMessage", ec);
+
922 if (!socket_.is_open())
+
923 return;
+
924 if (gracefulClose_)
+
925 return;
+
926 if (bytes_consumed == 0)
+
927 break;
+
928 read_buffer_.consume(bytes_consumed);
+
929 }
+
930
+
931 // Timeout on writes only
+
932 stream_.async_read_some(
+
933 read_buffer_.prepare(std::max(Tuning::readBufferBytes, hint)),
+
934 bind_executor(
+
935 strand_,
+
936 std::bind(
+
937 &PeerImp::onReadMessage,
+
938 shared_from_this(),
+
939 std::placeholders::_1,
+
940 std::placeholders::_2)));
+
941}
+
942
+
943void
+
944PeerImp::onWriteMessage(error_code ec, std::size_t bytes_transferred)
+
945{
+
946 if (!socket_.is_open())
+
947 return;
+
948 if (ec == boost::asio::error::operation_aborted)
+
949 return;
+
950 if (ec)
+
951 return fail("onWriteMessage", ec);
+
952 if (auto stream = journal_.trace())
+
953 {
+
954 if (bytes_transferred > 0)
+
955 stream << "onWriteMessage: " << bytes_transferred << " bytes";
+
956 else
+
957 stream << "onWriteMessage";
+
958 }
+
959
+
960 metrics_.sent.add_message(bytes_transferred);
+
961
+
962 XRPL_ASSERT(
+
963 !send_queue_.empty(),
+
964 "ripple::PeerImp::onWriteMessage : non-empty send buffer");
+
965 send_queue_.pop();
+
966 if (!send_queue_.empty())
+
967 {
+
968 // Timeout on writes only
+
969 return boost::asio::async_write(
+
970 stream_,
+
971 boost::asio::buffer(
+
972 send_queue_.front()->getBuffer(compressionEnabled_)),
+
973 bind_executor(
+
974 strand_,
+
975 std::bind(
+
976 &PeerImp::onWriteMessage,
+
977 shared_from_this(),
+
978 std::placeholders::_1,
+
979 std::placeholders::_2)));
+
980 }
+
981
+
982 if (gracefulClose_)
+
983 {
+
984 return stream_.async_shutdown(bind_executor(
+
985 strand_,
+
986 std::bind(
+
987 &PeerImp::onShutdown,
+
988 shared_from_this(),
+
989 std::placeholders::_1)));
+
990 }
+
991}
+
992
+
993//------------------------------------------------------------------------------
+
994//
+
995// ProtocolHandler
+
996//
+
997//------------------------------------------------------------------------------
+
998
+
999void
+
1000PeerImp::onMessageUnknown(std::uint16_t type)
+
1001{
+
1002 // TODO
+
1003}
+
1004
+
1005void
+
1006PeerImp::onMessageBegin(
+
1007 std::uint16_t type,
+
1008 std::shared_ptr<::google::protobuf::Message> const& m,
+
1009 std::size_t size,
+
1010 std::size_t uncompressed_size,
+
1011 bool isCompressed)
+
1012{
+
1013 auto const name = protocolMessageName(type);
+
1014 load_event_ = app_.getJobQueue().makeLoadEvent(jtPEER, name);
+
1015 fee_ = {Resource::feeTrivialPeer, name};
+
1016 auto const category = TrafficCount::categorize(*m, type, true);
+
1017 overlay_.reportTraffic(category, true, static_cast<int>(size));
+
1018 using namespace protocol;
+
1019 if ((type == MessageType::mtTRANSACTION ||
+
1020 type == MessageType::mtHAVE_TRANSACTIONS ||
+
1021 type == MessageType::mtTRANSACTIONS ||
+
1022 // GET_OBJECTS
+
1023 category == TrafficCount::category::get_transactions ||
+
1024 // GET_LEDGER
+
1025 category == TrafficCount::category::ld_tsc_get ||
+
1026 category == TrafficCount::category::ld_tsc_share ||
+
1027 // LEDGER_DATA
+
1028 category == TrafficCount::category::gl_tsc_share ||
+
1029 category == TrafficCount::category::gl_tsc_get) &&
+
1030 (txReduceRelayEnabled() || app_.config().TX_REDUCE_RELAY_METRICS))
+
1031 {
+
1032 overlay_.addTxMetrics(
+
1033 static_cast<MessageType>(type), static_cast<std::uint64_t>(size));
+
1034 }
+
1035 JLOG(journal_.trace()) << "onMessageBegin: " << type << " " << size << " "
+
1036 << uncompressed_size << " " << isCompressed;
+
1037}
+
1038
+
1039void
+
1040PeerImp::onMessageEnd(
+
1041 std::uint16_t,
+
1042 std::shared_ptr<::google::protobuf::Message> const&)
+
1043{
+
1044 load_event_.reset();
+
1045 charge(fee_.fee, fee_.context);
+
1046}
+
1047
+
1048void
+
1049PeerImp::onMessage(std::shared_ptr<protocol::TMManifests> const& m)
+
1050{
+
1051 auto const s = m->list_size();
+
1052
+
1053 if (s == 0)
+
1054 {
+
1055 fee_.update(Resource::feeUselessData, "empty");
+
1056 return;
+
1057 }
+
1058
+
1059 if (s > 100)
+
1060 fee_.update(Resource::feeModerateBurdenPeer, "oversize");
1061
-
1062 if (s > 100)
-
1063 fee_.update(Resource::feeModerateBurdenPeer, "oversize");
-
1064
-
1065 app_.getJobQueue().addJob(
-
1066 jtMANIFEST, "receiveManifests", [this, that = shared_from_this(), m]() {
-
1067 overlay_.onManifests(m, that);
-
1068 });
-
1069}
-
1070
-
1071void
-
1072PeerImp::onMessage(std::shared_ptr<protocol::TMPing> const& m)
-
1073{
-
1074 if (m->type() == protocol::TMPing::ptPING)
-
1075 {
-
1076 // We have received a ping request, reply with a pong
-
1077 fee_.update(Resource::feeModerateBurdenPeer, "ping request");
-
1078 m->set_type(protocol::TMPing::ptPONG);
-
1079 send(std::make_shared<Message>(*m, protocol::mtPING));
-
1080 return;
-
1081 }
-
1082
-
1083 if (m->type() == protocol::TMPing::ptPONG && m->has_seq())
-
1084 {
-
1085 // Only reset the ping sequence if we actually received a
-
1086 // PONG with the correct cookie. That way, any peers which
-
1087 // respond with incorrect cookies will eventually time out.
-
1088 if (m->seq() == lastPingSeq_)
-
1089 {
-
1090 lastPingSeq_.reset();
-
1091
-
1092 // Update latency estimate
-
1093 auto const rtt = std::chrono::round<std::chrono::milliseconds>(
-
1094 clock_type::now() - lastPingTime_);
-
1095
-
1096 std::lock_guard sl(recentLock_);
-
1097
-
1098 if (latency_)
-
1099 latency_ = (*latency_ * 7 + rtt) / 8;
-
1100 else
-
1101 latency_ = rtt;
-
1102 }
-
1103
-
1104 return;
-
1105 }
-
1106}
-
1107
-
1108void
-
1109PeerImp::onMessage(std::shared_ptr<protocol::TMCluster> const& m)
-
1110{
-
1111 // VFALCO NOTE I think we should drop the peer immediately
-
1112 if (!cluster())
-
1113 {
-
1114 fee_.fee = Resource::feeUselessData;
-
1115 return;
-
1116 }
-
1117
-
1118 for (int i = 0; i < m->clusternodes().size(); ++i)
-
1119 {
-
1120 protocol::TMClusterNode const& node = m->clusternodes(i);
-
1121
-
1122 std::string name;
-
1123 if (node.has_nodename())
-
1124 name = node.nodename();
+
1062 app_.getJobQueue().addJob(
+
1063 jtMANIFEST, "receiveManifests", [this, that = shared_from_this(), m]() {
+
1064 overlay_.onManifests(m, that);
+
1065 });
+
1066}
+
1067
+
1068void
+
1069PeerImp::onMessage(std::shared_ptr<protocol::TMPing> const& m)
+
1070{
+
1071 if (m->type() == protocol::TMPing::ptPING)
+
1072 {
+
1073 // We have received a ping request, reply with a pong
+
1074 fee_.update(Resource::feeModerateBurdenPeer, "ping request");
+
1075 m->set_type(protocol::TMPing::ptPONG);
+
1076 send(std::make_shared<Message>(*m, protocol::mtPING));
+
1077 return;
+
1078 }
+
1079
+
1080 if (m->type() == protocol::TMPing::ptPONG && m->has_seq())
+
1081 {
+
1082 // Only reset the ping sequence if we actually received a
+
1083 // PONG with the correct cookie. That way, any peers which
+
1084 // respond with incorrect cookies will eventually time out.
+
1085 if (m->seq() == lastPingSeq_)
+
1086 {
+
1087 lastPingSeq_.reset();
+
1088
+
1089 // Update latency estimate
+
1090 auto const rtt = std::chrono::round<std::chrono::milliseconds>(
+
1091 clock_type::now() - lastPingTime_);
+
1092
+
1093 std::lock_guard sl(recentLock_);
+
1094
+
1095 if (latency_)
+
1096 latency_ = (*latency_ * 7 + rtt) / 8;
+
1097 else
+
1098 latency_ = rtt;
+
1099 }
+
1100
+
1101 return;
+
1102 }
+
1103}
+
1104
+
1105void
+
1106PeerImp::onMessage(std::shared_ptr<protocol::TMCluster> const& m)
+
1107{
+
1108 // VFALCO NOTE I think we should drop the peer immediately
+
1109 if (!cluster())
+
1110 {
+
1111 fee_.update(Resource::feeUselessData, "unknown cluster");
+
1112 return;
+
1113 }
+
1114
+
1115 for (int i = 0; i < m->clusternodes().size(); ++i)
+
1116 {
+
1117 protocol::TMClusterNode const& node = m->clusternodes(i);
+
1118
+
1119 std::string name;
+
1120 if (node.has_nodename())
+
1121 name = node.nodename();
+
1122
+
1123 auto const publicKey =
+
1124 parseBase58<PublicKey>(TokenType::NodePublic, node.publickey());
1125
-
1126 auto const publicKey =
-
1127 parseBase58<PublicKey>(TokenType::NodePublic, node.publickey());
-
1128
-
1129 // NIKB NOTE We should drop the peer immediately if
-
1130 // they send us a public key we can't parse
-
1131 if (publicKey)
-
1132 {
-
1133 auto const reportTime =
-
1134 NetClock::time_point{NetClock::duration{node.reporttime()}};
-
1135
-
1136 app_.cluster().update(
-
1137 *publicKey, name, node.nodeload(), reportTime);
-
1138 }
-
1139 }
-
1140
-
1141 int loadSources = m->loadsources().size();
-
1142 if (loadSources != 0)
-
1143 {
-
1144 Resource::Gossip gossip;
-
1145 gossip.items.reserve(loadSources);
-
1146 for (int i = 0; i < m->loadsources().size(); ++i)
-
1147 {
-
1148 protocol::TMLoadSource const& node = m->loadsources(i);
-
1149 Resource::Gossip::Item item;
-
1150 item.address = beast::IP::Endpoint::from_string(node.name());
-
1151 item.balance = node.cost();
-
1152 if (item.address != beast::IP::Endpoint())
-
1153 gossip.items.push_back(item);
-
1154 }
-
1155 overlay_.resourceManager().importConsumers(name(), gossip);
-
1156 }
-
1157
-
1158 // Calculate the cluster fee:
-
1159 auto const thresh = app_.timeKeeper().now() - 90s;
-
1160 std::uint32_t clusterFee = 0;
+
1126 // NIKB NOTE We should drop the peer immediately if
+
1127 // they send us a public key we can't parse
+
1128 if (publicKey)
+
1129 {
+
1130 auto const reportTime =
+
1131 NetClock::time_point{NetClock::duration{node.reporttime()}};
+
1132
+
1133 app_.cluster().update(
+
1134 *publicKey, name, node.nodeload(), reportTime);
+
1135 }
+
1136 }
+
1137
+
1138 int loadSources = m->loadsources().size();
+
1139 if (loadSources != 0)
+
1140 {
+
1141 Resource::Gossip gossip;
+
1142 gossip.items.reserve(loadSources);
+
1143 for (int i = 0; i < m->loadsources().size(); ++i)
+
1144 {
+
1145 protocol::TMLoadSource const& node = m->loadsources(i);
+
1146 Resource::Gossip::Item item;
+
1147 item.address = beast::IP::Endpoint::from_string(node.name());
+
1148 item.balance = node.cost();
+
1149 if (item.address != beast::IP::Endpoint())
+
1150 gossip.items.push_back(item);
+
1151 }
+
1152 overlay_.resourceManager().importConsumers(name(), gossip);
+
1153 }
+
1154
+
1155 // Calculate the cluster fee:
+
1156 auto const thresh = app_.timeKeeper().now() - 90s;
+
1157 std::uint32_t clusterFee = 0;
+
1158
+
1159 std::vector<std::uint32_t> fees;
+
1160 fees.reserve(app_.cluster().size());
1161
-
1162 std::vector<std::uint32_t> fees;
-
1163 fees.reserve(app_.cluster().size());
-
1164
-
1165 app_.cluster().for_each([&fees, thresh](ClusterNode const& status) {
-
1166 if (status.getReportTime() >= thresh)
-
1167 fees.push_back(status.getLoadFee());
-
1168 });
-
1169
-
1170 if (!fees.empty())
-
1171 {
-
1172 auto const index = fees.size() / 2;
-
1173 std::nth_element(fees.begin(), fees.begin() + index, fees.end());
-
1174 clusterFee = fees[index];
-
1175 }
+
1162 app_.cluster().for_each([&fees, thresh](ClusterNode const& status) {
+
1163 if (status.getReportTime() >= thresh)
+
1164 fees.push_back(status.getLoadFee());
+
1165 });
+
1166
+
1167 if (!fees.empty())
+
1168 {
+
1169 auto const index = fees.size() / 2;
+
1170 std::nth_element(fees.begin(), fees.begin() + index, fees.end());
+
1171 clusterFee = fees[index];
+
1172 }
+
1173
+
1174 app_.getFeeTrack().setClusterFee(clusterFee);
+
1175}
1176
-
1177 app_.getFeeTrack().setClusterFee(clusterFee);
-
1178}
-
1179
-
1180void
-
1181PeerImp::onMessage(std::shared_ptr<protocol::TMEndpoints> const& m)
-
1182{
-
1183 // Don't allow endpoints from peers that are not known tracking or are
-
1184 // not using a version of the message that we support:
-
1185 if (tracking_.load() != Tracking::converged || m->version() != 2)
-
1186 return;
-
1187
-
1188 // The number is arbitrary and doesn't have any real significance or
-
1189 // implication for the protocol.
-
1190 if (m->endpoints_v2().size() >= 1024)
-
1191 {
-
1192 charge(Resource::feeInvalidData, "endpoints too large");
-
1193 return;
-
1194 }
+
1177void
+
1178PeerImp::onMessage(std::shared_ptr<protocol::TMEndpoints> const& m)
+
1179{
+
1180 // Don't allow endpoints from peers that are not known tracking or are
+
1181 // not using a version of the message that we support:
+
1182 if (tracking_.load() != Tracking::converged || m->version() != 2)
+
1183 return;
+
1184
+
1185 // The number is arbitrary and doesn't have any real significance or
+
1186 // implication for the protocol.
+
1187 if (m->endpoints_v2().size() >= 1024)
+
1188 {
+
1189 fee_.update(Resource::feeUselessData, "endpoints too large");
+
1190 return;
+
1191 }
+
1192
+
1193 std::vector<PeerFinder::Endpoint> endpoints;
+
1194 endpoints.reserve(m->endpoints_v2().size());
1195
-
1196 std::vector<PeerFinder::Endpoint> endpoints;
-
1197 endpoints.reserve(m->endpoints_v2().size());
-
1198
-
1199 for (auto const& tm : m->endpoints_v2())
-
1200 {
-
1201 auto result = beast::IP::Endpoint::from_string_checked(tm.endpoint());
-
1202
-
1203 if (!result)
-
1204 {
-
1205 JLOG(p_journal_.error()) << "failed to parse incoming endpoint: {"
-
1206 << tm.endpoint() << "}";
-
1207 charge(Resource::feeInvalidData, "endpoints malformed");
-
1208 continue;
-
1209 }
-
1210
-
1211 // If hops == 0, this Endpoint describes the peer we are connected
-
1212 // to -- in that case, we take the remote address seen on the
-
1213 // socket and store that in the IP::Endpoint. If this is the first
-
1214 // time, then we'll verify that their listener can receive incoming
-
1215 // by performing a connectivity test. if hops > 0, then we just
-
1216 // take the address/port we were given
-
1217 if (tm.hops() == 0)
-
1218 result = remote_address_.at_port(result->port());
-
1219
-
1220 endpoints.emplace_back(*result, tm.hops());
-
1221 }
-
1222
-
1223 if (!endpoints.empty())
-
1224 overlay_.peerFinder().on_endpoints(slot_, endpoints);
-
1225}
-
1226
-
1227void
-
1228PeerImp::onMessage(std::shared_ptr<protocol::TMTransaction> const& m)
-
1229{
-
1230 handleTransaction(m, true, false);
-
1231}
-
1232
-
1233void
-
1234PeerImp::handleTransaction(
-
1235 std::shared_ptr<protocol::TMTransaction> const& m,
-
1236 bool eraseTxQueue,
-
1237 bool batch)
-
1238{
-
1239 XRPL_ASSERT(
-
1240 eraseTxQueue != batch,
-
1241 ("ripple::PeerImp::handleTransaction correct function params"));
-
1242 if (tracking_.load() == Tracking::diverged)
-
1243 return;
-
1244
-
1245 if (app_.getOPs().isNeedNetworkLedger())
-
1246 {
-
1247 // If we've never been in synch, there's nothing we can do
-
1248 // with a transaction
-
1249 JLOG(p_journal_.debug())
-
1250 << "Ignoring incoming transaction: " << "Need network ledger";
-
1251 return;
-
1252 }
-
1253
-
1254 SerialIter sit(makeSlice(m->rawtransaction()));
-
1255
-
1256 try
-
1257 {
-
1258 auto stx = std::make_shared<STTx const>(sit);
-
1259 uint256 txID = stx->getTransactionID();
+
1196 auto malformed = 0;
+
1197 for (auto const& tm : m->endpoints_v2())
+
1198 {
+
1199 auto result = beast::IP::Endpoint::from_string_checked(tm.endpoint());
+
1200
+
1201 if (!result)
+
1202 {
+
1203 JLOG(p_journal_.error()) << "failed to parse incoming endpoint: {"
+
1204 << tm.endpoint() << "}";
+
1205 malformed++;
+
1206 continue;
+
1207 }
+
1208
+
1209 // If hops == 0, this Endpoint describes the peer we are connected
+
1210 // to -- in that case, we take the remote address seen on the
+
1211 // socket and store that in the IP::Endpoint. If this is the first
+
1212 // time, then we'll verify that their listener can receive incoming
+
1213 // by performing a connectivity test. if hops > 0, then we just
+
1214 // take the address/port we were given
+
1215 if (tm.hops() == 0)
+
1216 result = remote_address_.at_port(result->port());
+
1217
+
1218 endpoints.emplace_back(*result, tm.hops());
+
1219 }
+
1220
+
1221 // Charge the peer for each malformed endpoint. As there still may be
+
1222 // multiple valid endpoints we don't return early.
+
1223 if (malformed > 0)
+
1224 {
+
1225 fee_.update(
+
1226 Resource::feeInvalidData * malformed,
+
1227 std::to_string(malformed) + " malformed endpoints");
+
1228 }
+
1229
+
1230 if (!endpoints.empty())
+
1231 overlay_.peerFinder().on_endpoints(slot_, endpoints);
+
1232}
+
1233
+
1234void
+
1235PeerImp::onMessage(std::shared_ptr<protocol::TMTransaction> const& m)
+
1236{
+
1237 handleTransaction(m, true, false);
+
1238}
+
1239
+
1240void
+
1241PeerImp::handleTransaction(
+
1242 std::shared_ptr<protocol::TMTransaction> const& m,
+
1243 bool eraseTxQueue,
+
1244 bool batch)
+
1245{
+
1246 XRPL_ASSERT(
+
1247 eraseTxQueue != batch,
+
1248 ("ripple::PeerImp::handleTransaction correct function params"));
+
1249 if (tracking_.load() == Tracking::diverged)
+
1250 return;
+
1251
+
1252 if (app_.getOPs().isNeedNetworkLedger())
+
1253 {
+
1254 // If we've never been in synch, there's nothing we can do
+
1255 // with a transaction
+
1256 JLOG(p_journal_.debug())
+
1257 << "Ignoring incoming transaction: " << "Need network ledger";
+
1258 return;
+
1259 }
1260
-
1261 int flags;
-
1262 constexpr std::chrono::seconds tx_interval = 10s;
-
1263
-
1264 if (!app_.getHashRouter().shouldProcess(txID, id_, flags, tx_interval))
-
1265 {
-
1266 // we have seen this transaction recently
-
1267 if (flags & SF_BAD)
-
1268 {
-
1269 fee_.update(Resource::feeUselessData, "known bad");
-
1270 JLOG(p_journal_.debug()) << "Ignoring known bad tx " << txID;
-
1271 }
-
1272
-
1273 // Erase only if the server has seen this tx. If the server has not
-
1274 // seen this tx then the tx could not has been queued for this peer.
-
1275 else if (eraseTxQueue && txReduceRelayEnabled())
-
1276 removeTxQueue(txID);
-
1277
-
1278 return;
-
1279 }
-
1280
-
1281 JLOG(p_journal_.debug()) << "Got tx " << txID;
-
1282
-
1283 bool checkSignature = true;
-
1284 if (cluster())
-
1285 {
-
1286 if (!m->has_deferred() || !m->deferred())
-
1287 {
-
1288 // Skip local checks if a server we trust
-
1289 // put the transaction in its open ledger
-
1290 flags |= SF_TRUSTED;
-
1291 }
-
1292
-
1293 // for non-validator nodes only -- localPublicKey is set for
-
1294 // validators only
-
1295 if (!app_.getValidationPublicKey())
-
1296 {
-
1297 // For now, be paranoid and have each validator
-
1298 // check each transaction, regardless of source
-
1299 checkSignature = false;
-
1300 }
-
1301 }
-
1302
-
1303 if (app_.getLedgerMaster().getValidatedLedgerAge() > 4min)
-
1304 {
-
1305 JLOG(p_journal_.trace())
-
1306 << "No new transactions until synchronized";
-
1307 }
-
1308 else if (
-
1309 app_.getJobQueue().getJobCount(jtTRANSACTION) >
-
1310 app_.config().MAX_TRANSACTIONS)
+
1261 SerialIter sit(makeSlice(m->rawtransaction()));
+
1262
+
1263 try
+
1264 {
+
1265 auto stx = std::make_shared<STTx const>(sit);
+
1266 uint256 txID = stx->getTransactionID();
+
1267
+
1268 int flags;
+
1269 constexpr std::chrono::seconds tx_interval = 10s;
+
1270
+
1271 if (!app_.getHashRouter().shouldProcess(txID, id_, flags, tx_interval))
+
1272 {
+
1273 // we have seen this transaction recently
+
1274 if (flags & SF_BAD)
+
1275 {
+
1276 fee_.update(Resource::feeUselessData, "known bad");
+
1277 JLOG(p_journal_.debug()) << "Ignoring known bad tx " << txID;
+
1278 }
+
1279
+
1280 // Erase only if the server has seen this tx. If the server has not
+
1281 // seen this tx then the tx could not has been queued for this peer.
+
1282 else if (eraseTxQueue && txReduceRelayEnabled())
+
1283 removeTxQueue(txID);
+
1284
+
1285 return;
+
1286 }
+
1287
+
1288 JLOG(p_journal_.debug()) << "Got tx " << txID;
+
1289
+
1290 bool checkSignature = true;
+
1291 if (cluster())
+
1292 {
+
1293 if (!m->has_deferred() || !m->deferred())
+
1294 {
+
1295 // Skip local checks if a server we trust
+
1296 // put the transaction in its open ledger
+
1297 flags |= SF_TRUSTED;
+
1298 }
+
1299
+
1300 // for non-validator nodes only -- localPublicKey is set for
+
1301 // validators only
+
1302 if (!app_.getValidationPublicKey())
+
1303 {
+
1304 // For now, be paranoid and have each validator
+
1305 // check each transaction, regardless of source
+
1306 checkSignature = false;
+
1307 }
+
1308 }
+
1309
+
1310 if (app_.getLedgerMaster().getValidatedLedgerAge() > 4min)
1311 {
-
1312 overlay_.incJqTransOverflow();
-
1313 JLOG(p_journal_.info()) << "Transaction queue is full";
+
1312 JLOG(p_journal_.trace())
+
1313 << "No new transactions until synchronized";
1314 }
-
1315 else
-
1316 {
-
1317 app_.getJobQueue().addJob(
-
1318 jtTRANSACTION,
-
1319 "recvTransaction->checkTransaction",
-
1320 [weak = std::weak_ptr<PeerImp>(shared_from_this()),
-
1321 flags,
-
1322 checkSignature,
-
1323 batch,
-
1324 stx]() {
-
1325 if (auto peer = weak.lock())
-
1326 peer->checkTransaction(
-
1327 flags, checkSignature, stx, batch);
-
1328 });
-
1329 }
-
1330 }
-
1331 catch (std::exception const& ex)
-
1332 {
-
1333 JLOG(p_journal_.warn())
-
1334 << "Transaction invalid: " << strHex(m->rawtransaction())
-
1335 << ". Exception: " << ex.what();
-
1336 }
-
1337}
-
1338
-
1339void
-
1340PeerImp::onMessage(std::shared_ptr<protocol::TMGetLedger> const& m)
-
1341{
-
1342 auto badData = [&](std::string const& msg) {
-
1343 charge(Resource::feeInvalidData, "get_ledger " + msg);
-
1344 JLOG(p_journal_.warn()) << "TMGetLedger: " << msg;
-
1345 };
-
1346 auto const itype{m->itype()};
-
1347
-
1348 // Verify ledger info type
-
1349 if (itype < protocol::liBASE || itype > protocol::liTS_CANDIDATE)
-
1350 return badData("Invalid ledger info type");
-
1351
-
1352 auto const ltype = [&m]() -> std::optional<::protocol::TMLedgerType> {
-
1353 if (m->has_ltype())
-
1354 return m->ltype();
-
1355 return std::nullopt;
-
1356 }();
-
1357
-
1358 if (itype == protocol::liTS_CANDIDATE)
-
1359 {
-
1360 if (!m->has_ledgerhash())
-
1361 return badData("Invalid TX candidate set, missing TX set hash");
-
1362 }
-
1363 else if (
-
1364 !m->has_ledgerhash() && !m->has_ledgerseq() &&
-
1365 !(ltype && *ltype == protocol::ltCLOSED))
+
1315 else if (
+
1316 app_.getJobQueue().getJobCount(jtTRANSACTION) >
+
1317 app_.config().MAX_TRANSACTIONS)
+
1318 {
+
1319 overlay_.incJqTransOverflow();
+
1320 JLOG(p_journal_.info()) << "Transaction queue is full";
+
1321 }
+
1322 else
+
1323 {
+
1324 app_.getJobQueue().addJob(
+
1325 jtTRANSACTION,
+
1326 "recvTransaction->checkTransaction",
+
1327 [weak = std::weak_ptr<PeerImp>(shared_from_this()),
+
1328 flags,
+
1329 checkSignature,
+
1330 batch,
+
1331 stx]() {
+
1332 if (auto peer = weak.lock())
+
1333 peer->checkTransaction(
+
1334 flags, checkSignature, stx, batch);
+
1335 });
+
1336 }
+
1337 }
+
1338 catch (std::exception const& ex)
+
1339 {
+
1340 JLOG(p_journal_.warn())
+
1341 << "Transaction invalid: " << strHex(m->rawtransaction())
+
1342 << ". Exception: " << ex.what();
+
1343 }
+
1344}
+
1345
+
1346void
+
1347PeerImp::onMessage(std::shared_ptr<protocol::TMGetLedger> const& m)
+
1348{
+
1349 auto badData = [&](std::string const& msg) {
+
1350 fee_.update(Resource::feeInvalidData, "get_ledger " + msg);
+
1351 JLOG(p_journal_.warn()) << "TMGetLedger: " << msg;
+
1352 };
+
1353 auto const itype{m->itype()};
+
1354
+
1355 // Verify ledger info type
+
1356 if (itype < protocol::liBASE || itype > protocol::liTS_CANDIDATE)
+
1357 return badData("Invalid ledger info type");
+
1358
+
1359 auto const ltype = [&m]() -> std::optional<::protocol::TMLedgerType> {
+
1360 if (m->has_ltype())
+
1361 return m->ltype();
+
1362 return std::nullopt;
+
1363 }();
+
1364
+
1365 if (itype == protocol::liTS_CANDIDATE)
1366 {
-
1367 return badData("Invalid request");
-
1368 }
-
1369
-
1370 // Verify ledger type
-
1371 if (ltype && (*ltype < protocol::ltACCEPTED || *ltype > protocol::ltCLOSED))
-
1372 return badData("Invalid ledger type");
-
1373
-
1374 // Verify ledger hash
-
1375 if (m->has_ledgerhash() && !stringIsUint256Sized(m->ledgerhash()))
-
1376 return badData("Invalid ledger hash");
-
1377
-
1378 // Verify ledger sequence
-
1379 if (m->has_ledgerseq())
-
1380 {
-
1381 auto const ledgerSeq{m->ledgerseq()};
-
1382
-
1383 // Check if within a reasonable range
-
1384 using namespace std::chrono_literals;
-
1385 if (app_.getLedgerMaster().getValidatedLedgerAge() <= 10s &&
-
1386 ledgerSeq > app_.getLedgerMaster().getValidLedgerIndex() + 10)
-
1387 {
-
1388 return badData(
-
1389 "Invalid ledger sequence " + std::to_string(ledgerSeq));
-
1390 }
-
1391 }
-
1392
-
1393 // Verify ledger node IDs
-
1394 if (itype != protocol::liBASE)
-
1395 {
-
1396 if (m->nodeids_size() <= 0)
-
1397 return badData("Invalid ledger node IDs");
-
1398
-
1399 for (auto const& nodeId : m->nodeids())
-
1400 {
-
1401 if (deserializeSHAMapNodeID(nodeId) == std::nullopt)
-
1402 return badData("Invalid SHAMap node ID");
-
1403 }
-
1404 }
+
1367 if (!m->has_ledgerhash())
+
1368 return badData("Invalid TX candidate set, missing TX set hash");
+
1369 }
+
1370 else if (
+
1371 !m->has_ledgerhash() && !m->has_ledgerseq() &&
+
1372 !(ltype && *ltype == protocol::ltCLOSED))
+
1373 {
+
1374 return badData("Invalid request");
+
1375 }
+
1376
+
1377 // Verify ledger type
+
1378 if (ltype && (*ltype < protocol::ltACCEPTED || *ltype > protocol::ltCLOSED))
+
1379 return badData("Invalid ledger type");
+
1380
+
1381 // Verify ledger hash
+
1382 if (m->has_ledgerhash() && !stringIsUint256Sized(m->ledgerhash()))
+
1383 return badData("Invalid ledger hash");
+
1384
+
1385 // Verify ledger sequence
+
1386 if (m->has_ledgerseq())
+
1387 {
+
1388 auto const ledgerSeq{m->ledgerseq()};
+
1389
+
1390 // Check if within a reasonable range
+
1391 using namespace std::chrono_literals;
+
1392 if (app_.getLedgerMaster().getValidatedLedgerAge() <= 10s &&
+
1393 ledgerSeq > app_.getLedgerMaster().getValidLedgerIndex() + 10)
+
1394 {
+
1395 return badData(
+
1396 "Invalid ledger sequence " + std::to_string(ledgerSeq));
+
1397 }
+
1398 }
+
1399
+
1400 // Verify ledger node IDs
+
1401 if (itype != protocol::liBASE)
+
1402 {
+
1403 if (m->nodeids_size() <= 0)
+
1404 return badData("Invalid ledger node IDs");
1405
-
1406 // Verify query type
-
1407 if (m->has_querytype() && m->querytype() != protocol::qtINDIRECT)
-
1408 return badData("Invalid query type");
-
1409
-
1410 // Verify query depth
-
1411 if (m->has_querydepth())
-
1412 {
-
1413 if (m->querydepth() > Tuning::maxQueryDepth ||
-
1414 itype == protocol::liBASE)
-
1415 {
-
1416 return badData("Invalid query depth");
-
1417 }
-
1418 }
-
1419
-
1420 // Queue a job to process the request
-
1421 std::weak_ptr<PeerImp> weak = shared_from_this();
-
1422 app_.getJobQueue().addJob(jtLEDGER_REQ, "recvGetLedger", [weak, m]() {
-
1423 if (auto peer = weak.lock())
-
1424 peer->processLedgerRequest(m);
-
1425 });
-
1426}
-
1427
-
1428void
-
1429PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathRequest> const& m)
-
1430{
-
1431 JLOG(p_journal_.trace()) << "onMessage, TMProofPathRequest";
-
1432 if (!ledgerReplayEnabled_)
-
1433 {
-
1434 charge(Resource::feeMalformedRequest, "proof_path_request disabled");
-
1435 return;
-
1436 }
-
1437
-
1438 fee_.update(
-
1439 Resource::feeModerateBurdenPeer, "received a proof path request");
-
1440 std::weak_ptr<PeerImp> weak = shared_from_this();
-
1441 app_.getJobQueue().addJob(
-
1442 jtREPLAY_REQ, "recvProofPathRequest", [weak, m]() {
-
1443 if (auto peer = weak.lock())
-
1444 {
-
1445 auto reply =
-
1446 peer->ledgerReplayMsgHandler_.processProofPathRequest(m);
-
1447 if (reply.has_error())
-
1448 {
-
1449 if (reply.error() == protocol::TMReplyError::reBAD_REQUEST)
-
1450 peer->charge(
-
1451 Resource::feeMalformedRequest,
-
1452 "proof_path_request");
-
1453 else
-
1454 peer->charge(
-
1455 Resource::feeRequestNoReply, "proof_path_request");
-
1456 }
-
1457 else
-
1458 {
-
1459 peer->send(std::make_shared<Message>(
-
1460 reply, protocol::mtPROOF_PATH_RESPONSE));
-
1461 }
-
1462 }
-
1463 });
-
1464}
-
1465
-
1466void
-
1467PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathResponse> const& m)
-
1468{
-
1469 if (!ledgerReplayEnabled_)
-
1470 {
-
1471 charge(Resource::feeMalformedRequest, "proof_path_response disabled");
-
1472 return;
-
1473 }
-
1474
-
1475 if (!ledgerReplayMsgHandler_.processProofPathResponse(m))
-
1476 {
-
1477 charge(Resource::feeInvalidData, "proof_path_response");
-
1478 }
-
1479}
-
1480
-
1481void
-
1482PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaRequest> const& m)
-
1483{
-
1484 JLOG(p_journal_.trace()) << "onMessage, TMReplayDeltaRequest";
-
1485 if (!ledgerReplayEnabled_)
-
1486 {
-
1487 charge(Resource::feeMalformedRequest, "replay_delta_request disabled");
-
1488 return;
-
1489 }
-
1490
-
1491 fee_.fee = Resource::feeModerateBurdenPeer;
-
1492 std::weak_ptr<PeerImp> weak = shared_from_this();
-
1493 app_.getJobQueue().addJob(
-
1494 jtREPLAY_REQ, "recvReplayDeltaRequest", [weak, m]() {
-
1495 if (auto peer = weak.lock())
-
1496 {
-
1497 auto reply =
-
1498 peer->ledgerReplayMsgHandler_.processReplayDeltaRequest(m);
-
1499 if (reply.has_error())
-
1500 {
-
1501 if (reply.error() == protocol::TMReplyError::reBAD_REQUEST)
-
1502 peer->charge(
-
1503 Resource::feeMalformedRequest,
-
1504 "replay_delta_request");
-
1505 else
-
1506 peer->charge(
-
1507 Resource::feeRequestNoReply,
-
1508 "replay_delta_request");
-
1509 }
-
1510 else
-
1511 {
-
1512 peer->send(std::make_shared<Message>(
-
1513 reply, protocol::mtREPLAY_DELTA_RESPONSE));
-
1514 }
-
1515 }
-
1516 });
-
1517}
-
1518
-
1519void
-
1520PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaResponse> const& m)
-
1521{
-
1522 if (!ledgerReplayEnabled_)
-
1523 {
-
1524 charge(Resource::feeMalformedRequest, "replay_delta_response disabled");
-
1525 return;
-
1526 }
-
1527
-
1528 if (!ledgerReplayMsgHandler_.processReplayDeltaResponse(m))
-
1529 {
-
1530 charge(Resource::feeInvalidData, "replay_delta_response");
-
1531 }
-
1532}
-
1533
-
1534void
-
1535PeerImp::onMessage(std::shared_ptr<protocol::TMLedgerData> const& m)
-
1536{
-
1537 auto badData = [&](std::string const& msg) {
-
1538 fee_.update(Resource::feeInvalidData, msg);
-
1539 JLOG(p_journal_.warn()) << "TMLedgerData: " << msg;
-
1540 };
-
1541
-
1542 // Verify ledger hash
-
1543 if (!stringIsUint256Sized(m->ledgerhash()))
-
1544 return badData("Invalid ledger hash");
-
1545
-
1546 // Verify ledger sequence
-
1547 {
-
1548 auto const ledgerSeq{m->ledgerseq()};
-
1549 if (m->type() == protocol::liTS_CANDIDATE)
-
1550 {
-
1551 if (ledgerSeq != 0)
-
1552 {
-
1553 return badData(
-
1554 "Invalid ledger sequence " + std::to_string(ledgerSeq));
-
1555 }
-
1556 }
-
1557 else
-
1558 {
-
1559 // Check if within a reasonable range
-
1560 using namespace std::chrono_literals;
-
1561 if (app_.getLedgerMaster().getValidatedLedgerAge() <= 10s &&
-
1562 ledgerSeq > app_.getLedgerMaster().getValidLedgerIndex() + 10)
+
1406 for (auto const& nodeId : m->nodeids())
+
1407 {
+
1408 if (deserializeSHAMapNodeID(nodeId) == std::nullopt)
+
1409 return badData("Invalid SHAMap node ID");
+
1410 }
+
1411 }
+
1412
+
1413 // Verify query type
+
1414 if (m->has_querytype() && m->querytype() != protocol::qtINDIRECT)
+
1415 return badData("Invalid query type");
+
1416
+
1417 // Verify query depth
+
1418 if (m->has_querydepth())
+
1419 {
+
1420 if (m->querydepth() > Tuning::maxQueryDepth ||
+
1421 itype == protocol::liBASE)
+
1422 {
+
1423 return badData("Invalid query depth");
+
1424 }
+
1425 }
+
1426
+
1427 // Queue a job to process the request
+
1428 std::weak_ptr<PeerImp> weak = shared_from_this();
+
1429 app_.getJobQueue().addJob(jtLEDGER_REQ, "recvGetLedger", [weak, m]() {
+
1430 if (auto peer = weak.lock())
+
1431 peer->processLedgerRequest(m);
+
1432 });
+
1433}
+
1434
+
1435void
+
1436PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathRequest> const& m)
+
1437{
+
1438 JLOG(p_journal_.trace()) << "onMessage, TMProofPathRequest";
+
1439 if (!ledgerReplayEnabled_)
+
1440 {
+
1441 fee_.update(
+
1442 Resource::feeMalformedRequest, "proof_path_request disabled");
+
1443 return;
+
1444 }
+
1445
+
1446 fee_.update(
+
1447 Resource::feeModerateBurdenPeer, "received a proof path request");
+
1448 std::weak_ptr<PeerImp> weak = shared_from_this();
+
1449 app_.getJobQueue().addJob(
+
1450 jtREPLAY_REQ, "recvProofPathRequest", [weak, m]() {
+
1451 if (auto peer = weak.lock())
+
1452 {
+
1453 auto reply =
+
1454 peer->ledgerReplayMsgHandler_.processProofPathRequest(m);
+
1455 if (reply.has_error())
+
1456 {
+
1457 if (reply.error() == protocol::TMReplyError::reBAD_REQUEST)
+
1458 peer->charge(
+
1459 Resource::feeMalformedRequest,
+
1460 "proof_path_request");
+
1461 else
+
1462 peer->charge(
+
1463 Resource::feeRequestNoReply, "proof_path_request");
+
1464 }
+
1465 else
+
1466 {
+
1467 peer->send(std::make_shared<Message>(
+
1468 reply, protocol::mtPROOF_PATH_RESPONSE));
+
1469 }
+
1470 }
+
1471 });
+
1472}
+
1473
+
1474void
+
1475PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathResponse> const& m)
+
1476{
+
1477 if (!ledgerReplayEnabled_)
+
1478 {
+
1479 fee_.update(
+
1480 Resource::feeMalformedRequest, "proof_path_response disabled");
+
1481 return;
+
1482 }
+
1483
+
1484 if (!ledgerReplayMsgHandler_.processProofPathResponse(m))
+
1485 {
+
1486 fee_.update(Resource::feeInvalidData, "proof_path_response");
+
1487 }
+
1488}
+
1489
+
1490void
+
1491PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaRequest> const& m)
+
1492{
+
1493 JLOG(p_journal_.trace()) << "onMessage, TMReplayDeltaRequest";
+
1494 if (!ledgerReplayEnabled_)
+
1495 {
+
1496 fee_.update(
+
1497 Resource::feeMalformedRequest, "replay_delta_request disabled");
+
1498 return;
+
1499 }
+
1500
+
1501 fee_.fee = Resource::feeModerateBurdenPeer;
+
1502 std::weak_ptr<PeerImp> weak = shared_from_this();
+
1503 app_.getJobQueue().addJob(
+
1504 jtREPLAY_REQ, "recvReplayDeltaRequest", [weak, m]() {
+
1505 if (auto peer = weak.lock())
+
1506 {
+
1507 auto reply =
+
1508 peer->ledgerReplayMsgHandler_.processReplayDeltaRequest(m);
+
1509 if (reply.has_error())
+
1510 {
+
1511 if (reply.error() == protocol::TMReplyError::reBAD_REQUEST)
+
1512 peer->charge(
+
1513 Resource::feeMalformedRequest,
+
1514 "replay_delta_request");
+
1515 else
+
1516 peer->charge(
+
1517 Resource::feeRequestNoReply,
+
1518 "replay_delta_request");
+
1519 }
+
1520 else
+
1521 {
+
1522 peer->send(std::make_shared<Message>(
+
1523 reply, protocol::mtREPLAY_DELTA_RESPONSE));
+
1524 }
+
1525 }
+
1526 });
+
1527}
+
1528
+
1529void
+
1530PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaResponse> const& m)
+
1531{
+
1532 if (!ledgerReplayEnabled_)
+
1533 {
+
1534 fee_.update(
+
1535 Resource::feeMalformedRequest, "replay_delta_response disabled");
+
1536 return;
+
1537 }
+
1538
+
1539 if (!ledgerReplayMsgHandler_.processReplayDeltaResponse(m))
+
1540 {
+
1541 fee_.update(Resource::feeInvalidData, "replay_delta_response");
+
1542 }
+
1543}
+
1544
+
1545void
+
1546PeerImp::onMessage(std::shared_ptr<protocol::TMLedgerData> const& m)
+
1547{
+
1548 auto badData = [&](std::string const& msg) {
+
1549 fee_.update(Resource::feeInvalidData, msg);
+
1550 JLOG(p_journal_.warn()) << "TMLedgerData: " << msg;
+
1551 };
+
1552
+
1553 // Verify ledger hash
+
1554 if (!stringIsUint256Sized(m->ledgerhash()))
+
1555 return badData("Invalid ledger hash");
+
1556
+
1557 // Verify ledger sequence
+
1558 {
+
1559 auto const ledgerSeq{m->ledgerseq()};
+
1560 if (m->type() == protocol::liTS_CANDIDATE)
+
1561 {
+
1562 if (ledgerSeq != 0)
1563 {
1564 return badData(
1565 "Invalid ledger sequence " + std::to_string(ledgerSeq));
1566 }
1567 }
-
1568 }
-
1569
-
1570 // Verify ledger info type
-
1571 if (m->type() < protocol::liBASE || m->type() > protocol::liTS_CANDIDATE)
-
1572 return badData("Invalid ledger info type");
-
1573
-
1574 // Verify reply error
-
1575 if (m->has_error() &&
-
1576 (m->error() < protocol::reNO_LEDGER ||
-
1577 m->error() > protocol::reBAD_REQUEST))
-
1578 {
-
1579 return badData("Invalid reply error");
-
1580 }
-
1581
-
1582 // Verify ledger nodes.
-
1583 if (m->nodes_size() <= 0 || m->nodes_size() > Tuning::hardMaxReplyNodes)
-
1584 {
-
1585 return badData(
-
1586 "Invalid Ledger/TXset nodes " + std::to_string(m->nodes_size()));
-
1587 }
-
1588
-
1589 // If there is a request cookie, attempt to relay the message
-
1590 if (m->has_requestcookie())
-
1591 {
-
1592 if (auto peer = overlay_.findPeerByShortID(m->requestcookie()))
-
1593 {
-
1594 m->clear_requestcookie();
-
1595 peer->send(std::make_shared<Message>(*m, protocol::mtLEDGER_DATA));
-
1596 }
-
1597 else
-
1598 {
-
1599 JLOG(p_journal_.info()) << "Unable to route TX/ledger data reply";
-
1600 }
-
1601 return;
-
1602 }
-
1603
-
1604 uint256 const ledgerHash{m->ledgerhash()};
-
1605
-
1606 // Otherwise check if received data for a candidate transaction set
-
1607 if (m->type() == protocol::liTS_CANDIDATE)
-
1608 {
-
1609 std::weak_ptr<PeerImp> weak{shared_from_this()};
-
1610 app_.getJobQueue().addJob(
-
1611 jtTXN_DATA, "recvPeerData", [weak, ledgerHash, m]() {
-
1612 if (auto peer = weak.lock())
-
1613 {
-
1614 peer->app_.getInboundTransactions().gotData(
-
1615 ledgerHash, peer, m);
-
1616 }
-
1617 });
-
1618 return;
-
1619 }
-
1620
-
1621 // Consume the message
-
1622 app_.getInboundLedgers().gotLedgerData(ledgerHash, shared_from_this(), m);
-
1623}
-
1624
-
1625void
-
1626PeerImp::onMessage(std::shared_ptr<protocol::TMProposeSet> const& m)
-
1627{
-
1628 protocol::TMProposeSet& set = *m;
-
1629
-
1630 auto const sig = makeSlice(set.signature());
+
1568 else
+
1569 {
+
1570 // Check if within a reasonable range
+
1571 using namespace std::chrono_literals;
+
1572 if (app_.getLedgerMaster().getValidatedLedgerAge() <= 10s &&
+
1573 ledgerSeq > app_.getLedgerMaster().getValidLedgerIndex() + 10)
+
1574 {
+
1575 return badData(
+
1576 "Invalid ledger sequence " + std::to_string(ledgerSeq));
+
1577 }
+
1578 }
+
1579 }
+
1580
+
1581 // Verify ledger info type
+
1582 if (m->type() < protocol::liBASE || m->type() > protocol::liTS_CANDIDATE)
+
1583 return badData("Invalid ledger info type");
+
1584
+
1585 // Verify reply error
+
1586 if (m->has_error() &&
+
1587 (m->error() < protocol::reNO_LEDGER ||
+
1588 m->error() > protocol::reBAD_REQUEST))
+
1589 {
+
1590 return badData("Invalid reply error");
+
1591 }
+
1592
+
1593 // Verify ledger nodes.
+
1594 if (m->nodes_size() <= 0 || m->nodes_size() > Tuning::hardMaxReplyNodes)
+
1595 {
+
1596 return badData(
+
1597 "Invalid Ledger/TXset nodes " + std::to_string(m->nodes_size()));
+
1598 }
+
1599
+
1600 // If there is a request cookie, attempt to relay the message
+
1601 if (m->has_requestcookie())
+
1602 {
+
1603 if (auto peer = overlay_.findPeerByShortID(m->requestcookie()))
+
1604 {
+
1605 m->clear_requestcookie();
+
1606 peer->send(std::make_shared<Message>(*m, protocol::mtLEDGER_DATA));
+
1607 }
+
1608 else
+
1609 {
+
1610 JLOG(p_journal_.info()) << "Unable to route TX/ledger data reply";
+
1611 }
+
1612 return;
+
1613 }
+
1614
+
1615 uint256 const ledgerHash{m->ledgerhash()};
+
1616
+
1617 // Otherwise check if received data for a candidate transaction set
+
1618 if (m->type() == protocol::liTS_CANDIDATE)
+
1619 {
+
1620 std::weak_ptr<PeerImp> weak{shared_from_this()};
+
1621 app_.getJobQueue().addJob(
+
1622 jtTXN_DATA, "recvPeerData", [weak, ledgerHash, m]() {
+
1623 if (auto peer = weak.lock())
+
1624 {
+
1625 peer->app_.getInboundTransactions().gotData(
+
1626 ledgerHash, peer, m);
+
1627 }
+
1628 });
+
1629 return;
+
1630 }
1631
-
1632 // Preliminary check for the validity of the signature: A DER encoded
-
1633 // signature can't be longer than 72 bytes.
-
1634 if ((std::clamp<std::size_t>(sig.size(), 64, 72) != sig.size()) ||
-
1635 (publicKeyType(makeSlice(set.nodepubkey())) != KeyType::secp256k1))
-
1636 {
-
1637 JLOG(p_journal_.warn()) << "Proposal: malformed";
-
1638 fee_.update(
-
1639 Resource::feeInvalidSignature,
-
1640 " signature can't be longer than 72 bytes");
-
1641 return;
-
1642 }
-
1643
-
1644 if (!stringIsUint256Sized(set.currenttxhash()) ||
-
1645 !stringIsUint256Sized(set.previousledger()))
-
1646 {
-
1647 JLOG(p_journal_.warn()) << "Proposal: malformed";
-
1648 fee_.update(Resource::feeMalformedRequest, "bad hashes");
-
1649 return;
-
1650 }
-
1651
-
1652 // RH TODO: when isTrusted = false we should probably also cache a key
-
1653 // suppression for 30 seconds to avoid doing a relatively expensive lookup
-
1654 // every time a spam packet is received
-
1655 PublicKey const publicKey{makeSlice(set.nodepubkey())};
-
1656 auto const isTrusted = app_.validators().trusted(publicKey);
-
1657
-
1658 // If the operator has specified that untrusted proposals be dropped then
-
1659 // this happens here I.e. before further wasting CPU verifying the signature
-
1660 // of an untrusted key
-
1661 if (!isTrusted && app_.config().RELAY_UNTRUSTED_PROPOSALS == -1)
-
1662 return;
-
1663
-
1664 uint256 const proposeHash{set.currenttxhash()};
-
1665 uint256 const prevLedger{set.previousledger()};
-
1666
-
1667 NetClock::time_point const closeTime{NetClock::duration{set.closetime()}};
+
1632 // Consume the message
+
1633 app_.getInboundLedgers().gotLedgerData(ledgerHash, shared_from_this(), m);
+
1634}
+
1635
+
1636void
+
1637PeerImp::onMessage(std::shared_ptr<protocol::TMProposeSet> const& m)
+
1638{
+
1639 protocol::TMProposeSet& set = *m;
+
1640
+
1641 auto const sig = makeSlice(set.signature());
+
1642
+
1643 // Preliminary check for the validity of the signature: A DER encoded
+
1644 // signature can't be longer than 72 bytes.
+
1645 if ((std::clamp<std::size_t>(sig.size(), 64, 72) != sig.size()) ||
+
1646 (publicKeyType(makeSlice(set.nodepubkey())) != KeyType::secp256k1))
+
1647 {
+
1648 JLOG(p_journal_.warn()) << "Proposal: malformed";
+
1649 fee_.update(
+
1650 Resource::feeInvalidSignature,
+
1651 " signature can't be longer than 72 bytes");
+
1652 return;
+
1653 }
+
1654
+
1655 if (!stringIsUint256Sized(set.currenttxhash()) ||
+
1656 !stringIsUint256Sized(set.previousledger()))
+
1657 {
+
1658 JLOG(p_journal_.warn()) << "Proposal: malformed";
+
1659 fee_.update(Resource::feeMalformedRequest, "bad hashes");
+
1660 return;
+
1661 }
+
1662
+
1663 // RH TODO: when isTrusted = false we should probably also cache a key
+
1664 // suppression for 30 seconds to avoid doing a relatively expensive lookup
+
1665 // every time a spam packet is received
+
1666 PublicKey const publicKey{makeSlice(set.nodepubkey())};
+
1667 auto const isTrusted = app_.validators().trusted(publicKey);
1668
-
1669 uint256 const suppression = proposalUniqueId(
-
1670 proposeHash,
-
1671 prevLedger,
-
1672 set.proposeseq(),
-
1673 closeTime,
-
1674 publicKey.slice(),
-
1675 sig);
-
1676
-
1677 if (auto [added, relayed] =
-
1678 app_.getHashRouter().addSuppressionPeerWithStatus(suppression, id_);
-
1679 !added)
-
1680 {
-
1681 // Count unique messages (Slots has it's own 'HashRouter'), which a peer
-
1682 // receives within IDLED seconds since the message has been relayed.
-
1683 if (reduceRelayReady() && relayed &&
-
1684 (stopwatch().now() - *relayed) < reduce_relay::IDLED)
-
1685 overlay_.updateSlotAndSquelch(
-
1686 suppression, publicKey, id_, protocol::mtPROPOSE_LEDGER);
-
1687 JLOG(p_journal_.trace()) << "Proposal: duplicate";
-
1688 return;
-
1689 }
-
1690
-
1691 if (!isTrusted)
-
1692 {
-
1693 if (tracking_.load() == Tracking::diverged)
-
1694 {
-
1695 JLOG(p_journal_.debug())
-
1696 << "Proposal: Dropping untrusted (peer divergence)";
-
1697 return;
-
1698 }
-
1699
-
1700 if (!cluster() && app_.getFeeTrack().isLoadedLocal())
-
1701 {
-
1702 JLOG(p_journal_.debug()) << "Proposal: Dropping untrusted (load)";
-
1703 return;
-
1704 }
-
1705 }
-
1706
-
1707 JLOG(p_journal_.trace())
-
1708 << "Proposal: " << (isTrusted ? "trusted" : "untrusted");
-
1709
-
1710 auto proposal = RCLCxPeerPos(
-
1711 publicKey,
-
1712 sig,
-
1713 suppression,
-
1714 RCLCxPeerPos::Proposal{
-
1715 prevLedger,
-
1716 set.proposeseq(),
-
1717 proposeHash,
-
1718 closeTime,
-
1719 app_.timeKeeper().closeTime(),
-
1720 calcNodeID(app_.validatorManifests().getMasterKey(publicKey))});
-
1721
-
1722 std::weak_ptr<PeerImp> weak = shared_from_this();
-
1723 app_.getJobQueue().addJob(
-
1724 isTrusted ? jtPROPOSAL_t : jtPROPOSAL_ut,
-
1725 "recvPropose->checkPropose",
-
1726 [weak, isTrusted, m, proposal]() {
-
1727 if (auto peer = weak.lock())
-
1728 peer->checkPropose(isTrusted, m, proposal);
-
1729 });
-
1730}
-
1731
-
1732void
-
1733PeerImp::onMessage(std::shared_ptr<protocol::TMStatusChange> const& m)
-
1734{
-
1735 JLOG(p_journal_.trace()) << "Status: Change";
-
1736
-
1737 if (!m->has_networktime())
-
1738 m->set_networktime(app_.timeKeeper().now().time_since_epoch().count());
-
1739
-
1740 {
-
1741 std::lock_guard sl(recentLock_);
-
1742 if (!last_status_.has_newstatus() || m->has_newstatus())
-
1743 last_status_ = *m;
-
1744 else
-
1745 {
-
1746 // preserve old status
-
1747 protocol::NodeStatus status = last_status_.newstatus();
-
1748 last_status_ = *m;
-
1749 m->set_newstatus(status);
-
1750 }
-
1751 }
-
1752
-
1753 if (m->newevent() == protocol::neLOST_SYNC)
-
1754 {
-
1755 bool outOfSync{false};
+
1669 // If the operator has specified that untrusted proposals be dropped then
+
1670 // this happens here I.e. before further wasting CPU verifying the signature
+
1671 // of an untrusted key
+
1672 if (!isTrusted && app_.config().RELAY_UNTRUSTED_PROPOSALS == -1)
+
1673 return;
+
1674
+
1675 uint256 const proposeHash{set.currenttxhash()};
+
1676 uint256 const prevLedger{set.previousledger()};
+
1677
+
1678 NetClock::time_point const closeTime{NetClock::duration{set.closetime()}};
+
1679
+
1680 uint256 const suppression = proposalUniqueId(
+
1681 proposeHash,
+
1682 prevLedger,
+
1683 set.proposeseq(),
+
1684 closeTime,
+
1685 publicKey.slice(),
+
1686 sig);
+
1687
+
1688 if (auto [added, relayed] =
+
1689 app_.getHashRouter().addSuppressionPeerWithStatus(suppression, id_);
+
1690 !added)
+
1691 {
+
1692 // Count unique messages (Slots has it's own 'HashRouter'), which a peer
+
1693 // receives within IDLED seconds since the message has been relayed.
+
1694 if (reduceRelayReady() && relayed &&
+
1695 (stopwatch().now() - *relayed) < reduce_relay::IDLED)
+
1696 overlay_.updateSlotAndSquelch(
+
1697 suppression, publicKey, id_, protocol::mtPROPOSE_LEDGER);
+
1698 JLOG(p_journal_.trace()) << "Proposal: duplicate";
+
1699 return;
+
1700 }
+
1701
+
1702 if (!isTrusted)
+
1703 {
+
1704 if (tracking_.load() == Tracking::diverged)
+
1705 {
+
1706 JLOG(p_journal_.debug())
+
1707 << "Proposal: Dropping untrusted (peer divergence)";
+
1708 return;
+
1709 }
+
1710
+
1711 if (!cluster() && app_.getFeeTrack().isLoadedLocal())
+
1712 {
+
1713 JLOG(p_journal_.debug()) << "Proposal: Dropping untrusted (load)";
+
1714 return;
+
1715 }
+
1716 }
+
1717
+
1718 JLOG(p_journal_.trace())
+
1719 << "Proposal: " << (isTrusted ? "trusted" : "untrusted");
+
1720
+
1721 auto proposal = RCLCxPeerPos(
+
1722 publicKey,
+
1723 sig,
+
1724 suppression,
+
1725 RCLCxPeerPos::Proposal{
+
1726 prevLedger,
+
1727 set.proposeseq(),
+
1728 proposeHash,
+
1729 closeTime,
+
1730 app_.timeKeeper().closeTime(),
+
1731 calcNodeID(app_.validatorManifests().getMasterKey(publicKey))});
+
1732
+
1733 std::weak_ptr<PeerImp> weak = shared_from_this();
+
1734 app_.getJobQueue().addJob(
+
1735 isTrusted ? jtPROPOSAL_t : jtPROPOSAL_ut,
+
1736 "recvPropose->checkPropose",
+
1737 [weak, isTrusted, m, proposal]() {
+
1738 if (auto peer = weak.lock())
+
1739 peer->checkPropose(isTrusted, m, proposal);
+
1740 });
+
1741}
+
1742
+
1743void
+
1744PeerImp::onMessage(std::shared_ptr<protocol::TMStatusChange> const& m)
+
1745{
+
1746 JLOG(p_journal_.trace()) << "Status: Change";
+
1747
+
1748 if (!m->has_networktime())
+
1749 m->set_networktime(app_.timeKeeper().now().time_since_epoch().count());
+
1750
+
1751 {
+
1752 std::lock_guard sl(recentLock_);
+
1753 if (!last_status_.has_newstatus() || m->has_newstatus())
+
1754 last_status_ = *m;
+
1755 else
1756 {
-
1757 // Operations on closedLedgerHash_ and previousLedgerHash_ must be
-
1758 // guarded by recentLock_.
-
1759 std::lock_guard sl(recentLock_);
-
1760 if (!closedLedgerHash_.isZero())
-
1761 {
-
1762 outOfSync = true;
-
1763 closedLedgerHash_.zero();
-
1764 }
-
1765 previousLedgerHash_.zero();
-
1766 }
-
1767 if (outOfSync)
-
1768 {
-
1769 JLOG(p_journal_.debug()) << "Status: Out of sync";
-
1770 }
-
1771 return;
-
1772 }
-
1773
-
1774 {
-
1775 uint256 closedLedgerHash{};
-
1776 bool const peerChangedLedgers{
-
1777 m->has_ledgerhash() && stringIsUint256Sized(m->ledgerhash())};
-
1778
+
1757 // preserve old status
+
1758 protocol::NodeStatus status = last_status_.newstatus();
+
1759 last_status_ = *m;
+
1760 m->set_newstatus(status);
+
1761 }
+
1762 }
+
1763
+
1764 if (m->newevent() == protocol::neLOST_SYNC)
+
1765 {
+
1766 bool outOfSync{false};
+
1767 {
+
1768 // Operations on closedLedgerHash_ and previousLedgerHash_ must be
+
1769 // guarded by recentLock_.
+
1770 std::lock_guard sl(recentLock_);
+
1771 if (!closedLedgerHash_.isZero())
+
1772 {
+
1773 outOfSync = true;
+
1774 closedLedgerHash_.zero();
+
1775 }
+
1776 previousLedgerHash_.zero();
+
1777 }
+
1778 if (outOfSync)
1779 {
-
1780 // Operations on closedLedgerHash_ and previousLedgerHash_ must be
-
1781 // guarded by recentLock_.
-
1782 std::lock_guard sl(recentLock_);
-
1783 if (peerChangedLedgers)
-
1784 {
-
1785 closedLedgerHash_ = m->ledgerhash();
-
1786 closedLedgerHash = closedLedgerHash_;
-
1787 addLedger(closedLedgerHash, sl);
-
1788 }
-
1789 else
-
1790 {
-
1791 closedLedgerHash_.zero();
-
1792 }
-
1793
-
1794 if (m->has_ledgerhashprevious() &&
-
1795 stringIsUint256Sized(m->ledgerhashprevious()))
-
1796 {
-
1797 previousLedgerHash_ = m->ledgerhashprevious();
-
1798 addLedger(previousLedgerHash_, sl);
+
1780 JLOG(p_journal_.debug()) << "Status: Out of sync";
+
1781 }
+
1782 return;
+
1783 }
+
1784
+
1785 {
+
1786 uint256 closedLedgerHash{};
+
1787 bool const peerChangedLedgers{
+
1788 m->has_ledgerhash() && stringIsUint256Sized(m->ledgerhash())};
+
1789
+
1790 {
+
1791 // Operations on closedLedgerHash_ and previousLedgerHash_ must be
+
1792 // guarded by recentLock_.
+
1793 std::lock_guard sl(recentLock_);
+
1794 if (peerChangedLedgers)
+
1795 {
+
1796 closedLedgerHash_ = m->ledgerhash();
+
1797 closedLedgerHash = closedLedgerHash_;
+
1798 addLedger(closedLedgerHash, sl);
1799 }
1800 else
1801 {
-
1802 previousLedgerHash_.zero();
+
1802 closedLedgerHash_.zero();
1803 }
-
1804 }
-
1805 if (peerChangedLedgers)
-
1806 {
-
1807 JLOG(p_journal_.debug()) << "LCL is " << closedLedgerHash;
-
1808 }
-
1809 else
-
1810 {
-
1811 JLOG(p_journal_.debug()) << "Status: No ledger";
-
1812 }
-
1813 }
-
1814
-
1815 if (m->has_firstseq() && m->has_lastseq())
-
1816 {
-
1817 std::lock_guard sl(recentLock_);
-
1818
-
1819 minLedger_ = m->firstseq();
-
1820 maxLedger_ = m->lastseq();
-
1821
-
1822 if ((maxLedger_ < minLedger_) || (minLedger_ == 0) || (maxLedger_ == 0))
-
1823 minLedger_ = maxLedger_ = 0;
+
1804
+
1805 if (m->has_ledgerhashprevious() &&
+
1806 stringIsUint256Sized(m->ledgerhashprevious()))
+
1807 {
+
1808 previousLedgerHash_ = m->ledgerhashprevious();
+
1809 addLedger(previousLedgerHash_, sl);
+
1810 }
+
1811 else
+
1812 {
+
1813 previousLedgerHash_.zero();
+
1814 }
+
1815 }
+
1816 if (peerChangedLedgers)
+
1817 {
+
1818 JLOG(p_journal_.debug()) << "LCL is " << closedLedgerHash;
+
1819 }
+
1820 else
+
1821 {
+
1822 JLOG(p_journal_.debug()) << "Status: No ledger";
+
1823 }
1824 }
1825
-
1826 if (m->has_ledgerseq() &&
-
1827 app_.getLedgerMaster().getValidatedLedgerAge() < 2min)
-
1828 {
-
1829 checkTracking(
-
1830 m->ledgerseq(), app_.getLedgerMaster().getValidLedgerIndex());
-
1831 }
+
1826 if (m->has_firstseq() && m->has_lastseq())
+
1827 {
+
1828 std::lock_guard sl(recentLock_);
+
1829
+
1830 minLedger_ = m->firstseq();
+
1831 maxLedger_ = m->lastseq();
1832
-
1833 app_.getOPs().pubPeerStatus([=, this]() -> Json::Value {
-
1834 Json::Value j = Json::objectValue;
-
1835
-
1836 if (m->has_newstatus())
-
1837 {
-
1838 switch (m->newstatus())
-
1839 {
-
1840 case protocol::nsCONNECTING:
-
1841 j[jss::status] = "CONNECTING";
-
1842 break;
-
1843 case protocol::nsCONNECTED:
-
1844 j[jss::status] = "CONNECTED";
-
1845 break;
-
1846 case protocol::nsMONITORING:
-
1847 j[jss::status] = "MONITORING";
-
1848 break;
-
1849 case protocol::nsVALIDATING:
-
1850 j[jss::status] = "VALIDATING";
-
1851 break;
-
1852 case protocol::nsSHUTTING:
-
1853 j[jss::status] = "SHUTTING";
-
1854 break;
-
1855 }
-
1856 }
-
1857
-
1858 if (m->has_newevent())
-
1859 {
-
1860 switch (m->newevent())
-
1861 {
-
1862 case protocol::neCLOSING_LEDGER:
-
1863 j[jss::action] = "CLOSING_LEDGER";
-
1864 break;
-
1865 case protocol::neACCEPTED_LEDGER:
-
1866 j[jss::action] = "ACCEPTED_LEDGER";
-
1867 break;
-
1868 case protocol::neSWITCHED_LEDGER:
-
1869 j[jss::action] = "SWITCHED_LEDGER";
-
1870 break;
-
1871 case protocol::neLOST_SYNC:
-
1872 j[jss::action] = "LOST_SYNC";
-
1873 break;
-
1874 }
-
1875 }
-
1876
-
1877 if (m->has_ledgerseq())
-
1878 {
-
1879 j[jss::ledger_index] = m->ledgerseq();
-
1880 }
-
1881
-
1882 if (m->has_ledgerhash())
-
1883 {
-
1884 uint256 closedLedgerHash{};
-
1885 {
-
1886 std::lock_guard sl(recentLock_);
-
1887 closedLedgerHash = closedLedgerHash_;
-
1888 }
-
1889 j[jss::ledger_hash] = to_string(closedLedgerHash);
-
1890 }
-
1891
-
1892 if (m->has_networktime())
-
1893 {
-
1894 j[jss::date] = Json::UInt(m->networktime());
-
1895 }
-
1896
-
1897 if (m->has_firstseq() && m->has_lastseq())
-
1898 {
-
1899 j[jss::ledger_index_min] = Json::UInt(m->firstseq());
-
1900 j[jss::ledger_index_max] = Json::UInt(m->lastseq());
+
1833 if ((maxLedger_ < minLedger_) || (minLedger_ == 0) || (maxLedger_ == 0))
+
1834 minLedger_ = maxLedger_ = 0;
+
1835 }
+
1836
+
1837 if (m->has_ledgerseq() &&
+
1838 app_.getLedgerMaster().getValidatedLedgerAge() < 2min)
+
1839 {
+
1840 checkTracking(
+
1841 m->ledgerseq(), app_.getLedgerMaster().getValidLedgerIndex());
+
1842 }
+
1843
+
1844 app_.getOPs().pubPeerStatus([=, this]() -> Json::Value {
+
1845 Json::Value j = Json::objectValue;
+
1846
+
1847 if (m->has_newstatus())
+
1848 {
+
1849 switch (m->newstatus())
+
1850 {
+
1851 case protocol::nsCONNECTING:
+
1852 j[jss::status] = "CONNECTING";
+
1853 break;
+
1854 case protocol::nsCONNECTED:
+
1855 j[jss::status] = "CONNECTED";
+
1856 break;
+
1857 case protocol::nsMONITORING:
+
1858 j[jss::status] = "MONITORING";
+
1859 break;
+
1860 case protocol::nsVALIDATING:
+
1861 j[jss::status] = "VALIDATING";
+
1862 break;
+
1863 case protocol::nsSHUTTING:
+
1864 j[jss::status] = "SHUTTING";
+
1865 break;
+
1866 }
+
1867 }
+
1868
+
1869 if (m->has_newevent())
+
1870 {
+
1871 switch (m->newevent())
+
1872 {
+
1873 case protocol::neCLOSING_LEDGER:
+
1874 j[jss::action] = "CLOSING_LEDGER";
+
1875 break;
+
1876 case protocol::neACCEPTED_LEDGER:
+
1877 j[jss::action] = "ACCEPTED_LEDGER";
+
1878 break;
+
1879 case protocol::neSWITCHED_LEDGER:
+
1880 j[jss::action] = "SWITCHED_LEDGER";
+
1881 break;
+
1882 case protocol::neLOST_SYNC:
+
1883 j[jss::action] = "LOST_SYNC";
+
1884 break;
+
1885 }
+
1886 }
+
1887
+
1888 if (m->has_ledgerseq())
+
1889 {
+
1890 j[jss::ledger_index] = m->ledgerseq();
+
1891 }
+
1892
+
1893 if (m->has_ledgerhash())
+
1894 {
+
1895 uint256 closedLedgerHash{};
+
1896 {
+
1897 std::lock_guard sl(recentLock_);
+
1898 closedLedgerHash = closedLedgerHash_;
+
1899 }
+
1900 j[jss::ledger_hash] = to_string(closedLedgerHash);
1901 }
1902
-
1903 return j;
-
1904 });
-
1905}
-
1906
-
1907void
-
1908PeerImp::checkTracking(std::uint32_t validationSeq)
-
1909{
-
1910 std::uint32_t serverSeq;
-
1911 {
-
1912 // Extract the sequence number of the highest
-
1913 // ledger this peer has
-
1914 std::lock_guard sl(recentLock_);
-
1915
-
1916 serverSeq = maxLedger_;
-
1917 }
-
1918 if (serverSeq != 0)
-
1919 {
-
1920 // Compare the peer's ledger sequence to the
-
1921 // sequence of a recently-validated ledger
-
1922 checkTracking(serverSeq, validationSeq);
-
1923 }
-
1924}
-
1925
-
1926void
-
1927PeerImp::checkTracking(std::uint32_t seq1, std::uint32_t seq2)
-
1928{
-
1929 int diff = std::max(seq1, seq2) - std::min(seq1, seq2);
-
1930
-
1931 if (diff < Tuning::convergedLedgerLimit)
-
1932 {
-
1933 // The peer's ledger sequence is close to the validation's
-
1934 tracking_ = Tracking::converged;
-
1935 }
+
1903 if (m->has_networktime())
+
1904 {
+
1905 j[jss::date] = Json::UInt(m->networktime());
+
1906 }
+
1907
+
1908 if (m->has_firstseq() && m->has_lastseq())
+
1909 {
+
1910 j[jss::ledger_index_min] = Json::UInt(m->firstseq());
+
1911 j[jss::ledger_index_max] = Json::UInt(m->lastseq());
+
1912 }
+
1913
+
1914 return j;
+
1915 });
+
1916}
+
1917
+
1918void
+
1919PeerImp::checkTracking(std::uint32_t validationSeq)
+
1920{
+
1921 std::uint32_t serverSeq;
+
1922 {
+
1923 // Extract the sequence number of the highest
+
1924 // ledger this peer has
+
1925 std::lock_guard sl(recentLock_);
+
1926
+
1927 serverSeq = maxLedger_;
+
1928 }
+
1929 if (serverSeq != 0)
+
1930 {
+
1931 // Compare the peer's ledger sequence to the
+
1932 // sequence of a recently-validated ledger
+
1933 checkTracking(serverSeq, validationSeq);
+
1934 }
+
1935}
1936
-
1937 if ((diff > Tuning::divergedLedgerLimit) &&
-
1938 (tracking_.load() != Tracking::diverged))
-
1939 {
-
1940 // The peer's ledger sequence is way off the validation's
-
1941 std::lock_guard sl(recentLock_);
-
1942
-
1943 tracking_ = Tracking::diverged;
-
1944 trackingTime_ = clock_type::now();
-
1945 }
-
1946}
+
1937void
+
1938PeerImp::checkTracking(std::uint32_t seq1, std::uint32_t seq2)
+
1939{
+
1940 int diff = std::max(seq1, seq2) - std::min(seq1, seq2);
+
1941
+
1942 if (diff < Tuning::convergedLedgerLimit)
+
1943 {
+
1944 // The peer's ledger sequence is close to the validation's
+
1945 tracking_ = Tracking::converged;
+
1946 }
1947
-
1948void
-
1949PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactionSet> const& m)
-
1950{
-
1951 if (!stringIsUint256Sized(m->hash()))
-
1952 {
-
1953 fee_.update(Resource::feeMalformedRequest, "bad hash");
-
1954 return;
-
1955 }
-
1956
-
1957 uint256 const hash{m->hash()};
+
1948 if ((diff > Tuning::divergedLedgerLimit) &&
+
1949 (tracking_.load() != Tracking::diverged))
+
1950 {
+
1951 // The peer's ledger sequence is way off the validation's
+
1952 std::lock_guard sl(recentLock_);
+
1953
+
1954 tracking_ = Tracking::diverged;
+
1955 trackingTime_ = clock_type::now();
+
1956 }
+
1957}
1958
-
1959 if (m->status() == protocol::tsHAVE)
-
1960 {
-
1961 std::lock_guard sl(recentLock_);
-
1962
-
1963 if (std::find(recentTxSets_.begin(), recentTxSets_.end(), hash) !=
-
1964 recentTxSets_.end())
-
1965 {
-
1966 fee_.update(Resource::feeUselessData, "duplicate (tsHAVE)");
-
1967 return;
-
1968 }
+
1959void
+
1960PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactionSet> const& m)
+
1961{
+
1962 if (!stringIsUint256Sized(m->hash()))
+
1963 {
+
1964 fee_.update(Resource::feeMalformedRequest, "bad hash");
+
1965 return;
+
1966 }
+
1967
+
1968 uint256 const hash{m->hash()};
1969
-
1970 recentTxSets_.push_back(hash);
-
1971 }
-
1972}
+
1970 if (m->status() == protocol::tsHAVE)
+
1971 {
+
1972 std::lock_guard sl(recentLock_);
1973
-
1974void
-
1975PeerImp::onValidatorListMessage(
-
1976 std::string const& messageType,
-
1977 std::string const& manifest,
-
1978 std::uint32_t version,
-
1979 std::vector<ValidatorBlobInfo> const& blobs)
-
1980{
-
1981 // If there are no blobs, the message is malformed (possibly because of
-
1982 // ValidatorList class rules), so charge accordingly and skip processing.
-
1983 if (blobs.empty())
-
1984 {
-
1985 JLOG(p_journal_.warn()) << "Ignored malformed " << messageType
-
1986 << " from peer " << remote_address_;
-
1987 // This shouldn't ever happen with a well-behaved peer
-
1988 fee_.update(Resource::feeHeavyBurdenPeer, "no blobs");
-
1989 return;
-
1990 }
-
1991
-
1992 auto const hash = sha512Half(manifest, blobs, version);
-
1993
-
1994 JLOG(p_journal_.debug())
-
1995 << "Received " << messageType << " from " << remote_address_.to_string()
-
1996 << " (" << id_ << ")";
-
1997
-
1998 if (!app_.getHashRouter().addSuppressionPeer(hash, id_))
-
1999 {
-
2000 JLOG(p_journal_.debug())
-
2001 << messageType << ": received duplicate " << messageType;
-
2002 // Charging this fee here won't hurt the peer in the normal
-
2003 // course of operation (ie. refresh every 5 minutes), but
-
2004 // will add up if the peer is misbehaving.
-
2005 fee_.update(Resource::feeUselessData, "duplicate");
-
2006 return;
-
2007 }
+
1974 if (std::find(recentTxSets_.begin(), recentTxSets_.end(), hash) !=
+
1975 recentTxSets_.end())
+
1976 {
+
1977 fee_.update(Resource::feeUselessData, "duplicate (tsHAVE)");
+
1978 return;
+
1979 }
+
1980
+
1981 recentTxSets_.push_back(hash);
+
1982 }
+
1983}
+
1984
+
1985void
+
1986PeerImp::onValidatorListMessage(
+
1987 std::string const& messageType,
+
1988 std::string const& manifest,
+
1989 std::uint32_t version,
+
1990 std::vector<ValidatorBlobInfo> const& blobs)
+
1991{
+
1992 // If there are no blobs, the message is malformed (possibly because of
+
1993 // ValidatorList class rules), so charge accordingly and skip processing.
+
1994 if (blobs.empty())
+
1995 {
+
1996 JLOG(p_journal_.warn()) << "Ignored malformed " << messageType
+
1997 << " from peer " << remote_address_;
+
1998 // This shouldn't ever happen with a well-behaved peer
+
1999 fee_.update(Resource::feeHeavyBurdenPeer, "no blobs");
+
2000 return;
+
2001 }
+
2002
+
2003 auto const hash = sha512Half(manifest, blobs, version);
+
2004
+
2005 JLOG(p_journal_.debug())
+
2006 << "Received " << messageType << " from " << remote_address_.to_string()
+
2007 << " (" << id_ << ")";
2008
-
2009 auto const applyResult = app_.validators().applyListsAndBroadcast(
-
2010 manifest,
-
2011 version,
-
2012 blobs,
-
2013 remote_address_.to_string(),
-
2014 hash,
-
2015 app_.overlay(),
-
2016 app_.getHashRouter(),
-
2017 app_.getOPs());
-
2018
-
2019 JLOG(p_journal_.debug())
-
2020 << "Processed " << messageType << " version " << version << " from "
-
2021 << (applyResult.publisherKey ? strHex(*applyResult.publisherKey)
-
2022 : "unknown or invalid publisher")
-
2023 << " from " << remote_address_.to_string() << " (" << id_
-
2024 << ") with best result " << to_string(applyResult.bestDisposition());
-
2025
-
2026 // Act based on the best result
-
2027 switch (applyResult.bestDisposition())
-
2028 {
-
2029 // New list
-
2030 case ListDisposition::accepted:
-
2031 // Newest list is expired, and that needs to be broadcast, too
-
2032 case ListDisposition::expired:
-
2033 // Future list
-
2034 case ListDisposition::pending: {
-
2035 std::lock_guard<std::mutex> sl(recentLock_);
+
2009 if (!app_.getHashRouter().addSuppressionPeer(hash, id_))
+
2010 {
+
2011 JLOG(p_journal_.debug())
+
2012 << messageType << ": received duplicate " << messageType;
+
2013 // Charging this fee here won't hurt the peer in the normal
+
2014 // course of operation (ie. refresh every 5 minutes), but
+
2015 // will add up if the peer is misbehaving.
+
2016 fee_.update(Resource::feeUselessData, "duplicate");
+
2017 return;
+
2018 }
+
2019
+
2020 auto const applyResult = app_.validators().applyListsAndBroadcast(
+
2021 manifest,
+
2022 version,
+
2023 blobs,
+
2024 remote_address_.to_string(),
+
2025 hash,
+
2026 app_.overlay(),
+
2027 app_.getHashRouter(),
+
2028 app_.getOPs());
+
2029
+
2030 JLOG(p_journal_.debug())
+
2031 << "Processed " << messageType << " version " << version << " from "
+
2032 << (applyResult.publisherKey ? strHex(*applyResult.publisherKey)
+
2033 : "unknown or invalid publisher")
+
2034 << " from " << remote_address_.to_string() << " (" << id_
+
2035 << ") with best result " << to_string(applyResult.bestDisposition());
2036
-
2037 XRPL_ASSERT(
-
2038 applyResult.publisherKey,
-
2039 "ripple::PeerImp::onValidatorListMessage : publisher key is "
-
2040 "set");
-
2041 auto const& pubKey = *applyResult.publisherKey;
-
2042#ifndef NDEBUG
-
2043 if (auto const iter = publisherListSequences_.find(pubKey);
-
2044 iter != publisherListSequences_.end())
-
2045 {
-
2046 XRPL_ASSERT(
-
2047 iter->second < applyResult.sequence,
-
2048 "ripple::PeerImp::onValidatorListMessage : lower sequence");
-
2049 }
-
2050#endif
-
2051 publisherListSequences_[pubKey] = applyResult.sequence;
-
2052 }
-
2053 break;
-
2054 case ListDisposition::same_sequence:
-
2055 case ListDisposition::known_sequence:
-
2056#ifndef NDEBUG
-
2057 {
-
2058 std::lock_guard<std::mutex> sl(recentLock_);
-
2059 XRPL_ASSERT(
-
2060 applyResult.sequence && applyResult.publisherKey,
-
2061 "ripple::PeerImp::onValidatorListMessage : nonzero sequence "
-
2062 "and set publisher key");
-
2063 XRPL_ASSERT(
-
2064 publisherListSequences_[*applyResult.publisherKey] <=
-
2065 applyResult.sequence,
-
2066 "ripple::PeerImp::onValidatorListMessage : maximum sequence");
-
2067 }
-
2068#endif // !NDEBUG
-
2069
-
2070 break;
-
2071 case ListDisposition::stale:
-
2072 case ListDisposition::untrusted:
-
2073 case ListDisposition::invalid:
-
2074 case ListDisposition::unsupported_version:
-
2075 break;
-
2076 default:
-
2077 UNREACHABLE(
-
2078 "ripple::PeerImp::onValidatorListMessage : invalid best list "
-
2079 "disposition");
-
2080 }
-
2081
-
2082 // Charge based on the worst result
-
2083 switch (applyResult.worstDisposition())
-
2084 {
-
2085 case ListDisposition::accepted:
-
2086 case ListDisposition::expired:
-
2087 case ListDisposition::pending:
-
2088 // No charges for good data
-
2089 break;
-
2090 case ListDisposition::same_sequence:
-
2091 case ListDisposition::known_sequence:
-
2092 // Charging this fee here won't hurt the peer in the normal
-
2093 // course of operation (ie. refresh every 5 minutes), but
-
2094 // will add up if the peer is misbehaving.
-
2095 fee_.update(
-
2096 Resource::feeUselessData,
-
2097 " duplicate (same_sequence or known_sequence)");
-
2098 break;
-
2099 case ListDisposition::stale:
-
2100 // There are very few good reasons for a peer to send an
-
2101 // old list, particularly more than once.
-
2102 fee_.update(Resource::feeInvalidData, "expired");
-
2103 break;
-
2104 case ListDisposition::untrusted:
-
2105 // Charging this fee here won't hurt the peer in the normal
-
2106 // course of operation (ie. refresh every 5 minutes), but
-
2107 // will add up if the peer is misbehaving.
-
2108 fee_.update(Resource::feeUselessData, "untrusted");
+
2037 // Act based on the best result
+
2038 switch (applyResult.bestDisposition())
+
2039 {
+
2040 // New list
+
2041 case ListDisposition::accepted:
+
2042 // Newest list is expired, and that needs to be broadcast, too
+
2043 case ListDisposition::expired:
+
2044 // Future list
+
2045 case ListDisposition::pending: {
+
2046 std::lock_guard<std::mutex> sl(recentLock_);
+
2047
+
2048 XRPL_ASSERT(
+
2049 applyResult.publisherKey,
+
2050 "ripple::PeerImp::onValidatorListMessage : publisher key is "
+
2051 "set");
+
2052 auto const& pubKey = *applyResult.publisherKey;
+
2053#ifndef NDEBUG
+
2054 if (auto const iter = publisherListSequences_.find(pubKey);
+
2055 iter != publisherListSequences_.end())
+
2056 {
+
2057 XRPL_ASSERT(
+
2058 iter->second < applyResult.sequence,
+
2059 "ripple::PeerImp::onValidatorListMessage : lower sequence");
+
2060 }
+
2061#endif
+
2062 publisherListSequences_[pubKey] = applyResult.sequence;
+
2063 }
+
2064 break;
+
2065 case ListDisposition::same_sequence:
+
2066 case ListDisposition::known_sequence:
+
2067#ifndef NDEBUG
+
2068 {
+
2069 std::lock_guard<std::mutex> sl(recentLock_);
+
2070 XRPL_ASSERT(
+
2071 applyResult.sequence && applyResult.publisherKey,
+
2072 "ripple::PeerImp::onValidatorListMessage : nonzero sequence "
+
2073 "and set publisher key");
+
2074 XRPL_ASSERT(
+
2075 publisherListSequences_[*applyResult.publisherKey] <=
+
2076 applyResult.sequence,
+
2077 "ripple::PeerImp::onValidatorListMessage : maximum sequence");
+
2078 }
+
2079#endif // !NDEBUG
+
2080
+
2081 break;
+
2082 case ListDisposition::stale:
+
2083 case ListDisposition::untrusted:
+
2084 case ListDisposition::invalid:
+
2085 case ListDisposition::unsupported_version:
+
2086 break;
+
2087 default:
+
2088 UNREACHABLE(
+
2089 "ripple::PeerImp::onValidatorListMessage : invalid best list "
+
2090 "disposition");
+
2091 }
+
2092
+
2093 // Charge based on the worst result
+
2094 switch (applyResult.worstDisposition())
+
2095 {
+
2096 case ListDisposition::accepted:
+
2097 case ListDisposition::expired:
+
2098 case ListDisposition::pending:
+
2099 // No charges for good data
+
2100 break;
+
2101 case ListDisposition::same_sequence:
+
2102 case ListDisposition::known_sequence:
+
2103 // Charging this fee here won't hurt the peer in the normal
+
2104 // course of operation (ie. refresh every 5 minutes), but
+
2105 // will add up if the peer is misbehaving.
+
2106 fee_.update(
+
2107 Resource::feeUselessData,
+
2108 " duplicate (same_sequence or known_sequence)");
2109 break;
-
2110 case ListDisposition::invalid:
-
2111 // This shouldn't ever happen with a well-behaved peer
-
2112 fee_.update(
-
2113 Resource::feeInvalidSignature, "invalid list disposition");
+
2110 case ListDisposition::stale:
+
2111 // There are very few good reasons for a peer to send an
+
2112 // old list, particularly more than once.
+
2113 fee_.update(Resource::feeInvalidData, "expired");
2114 break;
-
2115 case ListDisposition::unsupported_version:
-
2116 // During a version transition, this may be legitimate.
-
2117 // If it happens frequently, that's probably bad.
-
2118 fee_.update(Resource::feeInvalidData, "version");
-
2119 break;
-
2120 default:
-
2121 UNREACHABLE(
-
2122 "ripple::PeerImp::onValidatorListMessage : invalid worst list "
-
2123 "disposition");
-
2124 }
-
2125
-
2126 // Log based on all the results.
-
2127 for (auto const& [disp, count] : applyResult.dispositions)
-
2128 {
-
2129 switch (disp)
-
2130 {
-
2131 // New list
-
2132 case ListDisposition::accepted:
-
2133 JLOG(p_journal_.debug())
-
2134 << "Applied " << count << " new " << messageType
-
2135 << "(s) from peer " << remote_address_;
-
2136 break;
-
2137 // Newest list is expired, and that needs to be broadcast, too
-
2138 case ListDisposition::expired:
-
2139 JLOG(p_journal_.debug())
-
2140 << "Applied " << count << " expired " << messageType
-
2141 << "(s) from peer " << remote_address_;
-
2142 break;
-
2143 // Future list
-
2144 case ListDisposition::pending:
-
2145 JLOG(p_journal_.debug())
-
2146 << "Processed " << count << " future " << messageType
-
2147 << "(s) from peer " << remote_address_;
-
2148 break;
-
2149 case ListDisposition::same_sequence:
-
2150 JLOG(p_journal_.warn())
-
2151 << "Ignored " << count << " " << messageType
-
2152 << "(s) with current sequence from peer "
-
2153 << remote_address_;
-
2154 break;
-
2155 case ListDisposition::known_sequence:
-
2156 JLOG(p_journal_.warn())
-
2157 << "Ignored " << count << " " << messageType
-
2158 << "(s) with future sequence from peer " << remote_address_;
+
2115 case ListDisposition::untrusted:
+
2116 // Charging this fee here won't hurt the peer in the normal
+
2117 // course of operation (ie. refresh every 5 minutes), but
+
2118 // will add up if the peer is misbehaving.
+
2119 fee_.update(Resource::feeUselessData, "untrusted");
+
2120 break;
+
2121 case ListDisposition::invalid:
+
2122 // This shouldn't ever happen with a well-behaved peer
+
2123 fee_.update(
+
2124 Resource::feeInvalidSignature, "invalid list disposition");
+
2125 break;
+
2126 case ListDisposition::unsupported_version:
+
2127 // During a version transition, this may be legitimate.
+
2128 // If it happens frequently, that's probably bad.
+
2129 fee_.update(Resource::feeInvalidData, "version");
+
2130 break;
+
2131 default:
+
2132 UNREACHABLE(
+
2133 "ripple::PeerImp::onValidatorListMessage : invalid worst list "
+
2134 "disposition");
+
2135 }
+
2136
+
2137 // Log based on all the results.
+
2138 for (auto const& [disp, count] : applyResult.dispositions)
+
2139 {
+
2140 switch (disp)
+
2141 {
+
2142 // New list
+
2143 case ListDisposition::accepted:
+
2144 JLOG(p_journal_.debug())
+
2145 << "Applied " << count << " new " << messageType
+
2146 << "(s) from peer " << remote_address_;
+
2147 break;
+
2148 // Newest list is expired, and that needs to be broadcast, too
+
2149 case ListDisposition::expired:
+
2150 JLOG(p_journal_.debug())
+
2151 << "Applied " << count << " expired " << messageType
+
2152 << "(s) from peer " << remote_address_;
+
2153 break;
+
2154 // Future list
+
2155 case ListDisposition::pending:
+
2156 JLOG(p_journal_.debug())
+
2157 << "Processed " << count << " future " << messageType
+
2158 << "(s) from peer " << remote_address_;
2159 break;
-
2160 case ListDisposition::stale:
+
2160 case ListDisposition::same_sequence:
2161 JLOG(p_journal_.warn())
-
2162 << "Ignored " << count << "stale " << messageType
-
2163 << "(s) from peer " << remote_address_;
-
2164 break;
-
2165 case ListDisposition::untrusted:
-
2166 JLOG(p_journal_.warn())
-
2167 << "Ignored " << count << " untrusted " << messageType
-
2168 << "(s) from peer " << remote_address_;
-
2169 break;
-
2170 case ListDisposition::unsupported_version:
-
2171 JLOG(p_journal_.warn())
-
2172 << "Ignored " << count << "unsupported version "
-
2173 << messageType << "(s) from peer " << remote_address_;
-
2174 break;
-
2175 case ListDisposition::invalid:
-
2176 JLOG(p_journal_.warn())
-
2177 << "Ignored " << count << "invalid " << messageType
-
2178 << "(s) from peer " << remote_address_;
-
2179 break;
-
2180 default:
-
2181 UNREACHABLE(
-
2182 "ripple::PeerImp::onValidatorListMessage : invalid list "
-
2183 "disposition");
-
2184 }
-
2185 }
-
2186}
-
2187
-
2188void
-
2189PeerImp::onMessage(std::shared_ptr<protocol::TMValidatorList> const& m)
-
2190{
-
2191 try
-
2192 {
-
2193 if (!supportsFeature(ProtocolFeature::ValidatorListPropagation))
-
2194 {
-
2195 JLOG(p_journal_.debug())
-
2196 << "ValidatorList: received validator list from peer using "
-
2197 << "protocol version " << to_string(protocol_)
-
2198 << " which shouldn't support this feature.";
-
2199 fee_.update(Resource::feeUselessData, "unsupported peer");
-
2200 return;
-
2201 }
-
2202 onValidatorListMessage(
-
2203 "ValidatorList",
-
2204 m->manifest(),
-
2205 m->version(),
-
2206 ValidatorList::parseBlobs(*m));
-
2207 }
-
2208 catch (std::exception const& e)
-
2209 {
-
2210 JLOG(p_journal_.warn()) << "ValidatorList: Exception, " << e.what()
-
2211 << " from peer " << remote_address_;
-
2212 using namespace std::string_literals;
-
2213 fee_.update(Resource::feeInvalidData, e.what());
-
2214 }
-
2215}
-
2216
-
2217void
-
2218PeerImp::onMessage(
-
2219 std::shared_ptr<protocol::TMValidatorListCollection> const& m)
-
2220{
-
2221 try
-
2222 {
-
2223 if (!supportsFeature(ProtocolFeature::ValidatorList2Propagation))
-
2224 {
-
2225 JLOG(p_journal_.debug())
-
2226 << "ValidatorListCollection: received validator list from peer "
-
2227 << "using protocol version " << to_string(protocol_)
-
2228 << " which shouldn't support this feature.";
-
2229 fee_.update(Resource::feeUselessData, "unsupported peer");
-
2230 return;
-
2231 }
-
2232 else if (m->version() < 2)
-
2233 {
-
2234 JLOG(p_journal_.debug())
-
2235 << "ValidatorListCollection: received invalid validator list "
-
2236 "version "
-
2237 << m->version() << " from peer using protocol version "
-
2238 << to_string(protocol_);
-
2239 fee_.update(Resource::feeInvalidData, "wrong version");
-
2240 return;
-
2241 }
-
2242 onValidatorListMessage(
-
2243 "ValidatorListCollection",
-
2244 m->manifest(),
-
2245 m->version(),
-
2246 ValidatorList::parseBlobs(*m));
-
2247 }
-
2248 catch (std::exception const& e)
-
2249 {
-
2250 JLOG(p_journal_.warn()) << "ValidatorListCollection: Exception, "
-
2251 << e.what() << " from peer " << remote_address_;
-
2252 using namespace std::string_literals;
-
2253 fee_.update(Resource::feeInvalidData, e.what());
-
2254 }
-
2255}
-
2256
-
2257void
-
2258PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
-
2259{
-
2260 if (m->validation().size() < 50)
-
2261 {
-
2262 JLOG(p_journal_.warn()) << "Validation: Too small";
-
2263 fee_.update(Resource::feeMalformedRequest, "too small");
-
2264 return;
+
2162 << "Ignored " << count << " " << messageType
+
2163 << "(s) with current sequence from peer "
+
2164 << remote_address_;
+
2165 break;
+
2166 case ListDisposition::known_sequence:
+
2167 JLOG(p_journal_.warn())
+
2168 << "Ignored " << count << " " << messageType
+
2169 << "(s) with future sequence from peer " << remote_address_;
+
2170 break;
+
2171 case ListDisposition::stale:
+
2172 JLOG(p_journal_.warn())
+
2173 << "Ignored " << count << "stale " << messageType
+
2174 << "(s) from peer " << remote_address_;
+
2175 break;
+
2176 case ListDisposition::untrusted:
+
2177 JLOG(p_journal_.warn())
+
2178 << "Ignored " << count << " untrusted " << messageType
+
2179 << "(s) from peer " << remote_address_;
+
2180 break;
+
2181 case ListDisposition::unsupported_version:
+
2182 JLOG(p_journal_.warn())
+
2183 << "Ignored " << count << "unsupported version "
+
2184 << messageType << "(s) from peer " << remote_address_;
+
2185 break;
+
2186 case ListDisposition::invalid:
+
2187 JLOG(p_journal_.warn())
+
2188 << "Ignored " << count << "invalid " << messageType
+
2189 << "(s) from peer " << remote_address_;
+
2190 break;
+
2191 default:
+
2192 UNREACHABLE(
+
2193 "ripple::PeerImp::onValidatorListMessage : invalid list "
+
2194 "disposition");
+
2195 }
+
2196 }
+
2197}
+
2198
+
2199void
+
2200PeerImp::onMessage(std::shared_ptr<protocol::TMValidatorList> const& m)
+
2201{
+
2202 try
+
2203 {
+
2204 if (!supportsFeature(ProtocolFeature::ValidatorListPropagation))
+
2205 {
+
2206 JLOG(p_journal_.debug())
+
2207 << "ValidatorList: received validator list from peer using "
+
2208 << "protocol version " << to_string(protocol_)
+
2209 << " which shouldn't support this feature.";
+
2210 fee_.update(Resource::feeUselessData, "unsupported peer");
+
2211 return;
+
2212 }
+
2213 onValidatorListMessage(
+
2214 "ValidatorList",
+
2215 m->manifest(),
+
2216 m->version(),
+
2217 ValidatorList::parseBlobs(*m));
+
2218 }
+
2219 catch (std::exception const& e)
+
2220 {
+
2221 JLOG(p_journal_.warn()) << "ValidatorList: Exception, " << e.what()
+
2222 << " from peer " << remote_address_;
+
2223 using namespace std::string_literals;
+
2224 fee_.update(Resource::feeInvalidData, e.what());
+
2225 }
+
2226}
+
2227
+
2228void
+
2229PeerImp::onMessage(
+
2230 std::shared_ptr<protocol::TMValidatorListCollection> const& m)
+
2231{
+
2232 try
+
2233 {
+
2234 if (!supportsFeature(ProtocolFeature::ValidatorList2Propagation))
+
2235 {
+
2236 JLOG(p_journal_.debug())
+
2237 << "ValidatorListCollection: received validator list from peer "
+
2238 << "using protocol version " << to_string(protocol_)
+
2239 << " which shouldn't support this feature.";
+
2240 fee_.update(Resource::feeUselessData, "unsupported peer");
+
2241 return;
+
2242 }
+
2243 else if (m->version() < 2)
+
2244 {
+
2245 JLOG(p_journal_.debug())
+
2246 << "ValidatorListCollection: received invalid validator list "
+
2247 "version "
+
2248 << m->version() << " from peer using protocol version "
+
2249 << to_string(protocol_);
+
2250 fee_.update(Resource::feeInvalidData, "wrong version");
+
2251 return;
+
2252 }
+
2253 onValidatorListMessage(
+
2254 "ValidatorListCollection",
+
2255 m->manifest(),
+
2256 m->version(),
+
2257 ValidatorList::parseBlobs(*m));
+
2258 }
+
2259 catch (std::exception const& e)
+
2260 {
+
2261 JLOG(p_journal_.warn()) << "ValidatorListCollection: Exception, "
+
2262 << e.what() << " from peer " << remote_address_;
+
2263 using namespace std::string_literals;
+
2264 fee_.update(Resource::feeInvalidData, e.what());
2265 }
-
2266
-
2267 try
-
2268 {
-
2269 auto const closeTime = app_.timeKeeper().closeTime();
-
2270
-
2271 std::shared_ptr<STValidation> val;
-
2272 {
-
2273 SerialIter sit(makeSlice(m->validation()));
-
2274 val = std::make_shared<STValidation>(
-
2275 std::ref(sit),
-
2276 [this](PublicKey const& pk) {
-
2277 return calcNodeID(
-
2278 app_.validatorManifests().getMasterKey(pk));
-
2279 },
-
2280 false);
-
2281 val->setSeen(closeTime);
-
2282 }
-
2283
-
2284 if (!isCurrent(
-
2285 app_.getValidations().parms(),
-
2286 app_.timeKeeper().closeTime(),
-
2287 val->getSignTime(),
-
2288 val->getSeenTime()))
-
2289 {
-
2290 JLOG(p_journal_.trace()) << "Validation: Not current";
-
2291 fee_.update(Resource::feeUselessData, "not current");
-
2292 return;
+
2266}
+
2267
+
2268void
+
2269PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
+
2270{
+
2271 if (m->validation().size() < 50)
+
2272 {
+
2273 JLOG(p_journal_.warn()) << "Validation: Too small";
+
2274 fee_.update(Resource::feeMalformedRequest, "too small");
+
2275 return;
+
2276 }
+
2277
+
2278 try
+
2279 {
+
2280 auto const closeTime = app_.timeKeeper().closeTime();
+
2281
+
2282 std::shared_ptr<STValidation> val;
+
2283 {
+
2284 SerialIter sit(makeSlice(m->validation()));
+
2285 val = std::make_shared<STValidation>(
+
2286 std::ref(sit),
+
2287 [this](PublicKey const& pk) {
+
2288 return calcNodeID(
+
2289 app_.validatorManifests().getMasterKey(pk));
+
2290 },
+
2291 false);
+
2292 val->setSeen(closeTime);
2293 }
2294
-
2295 // RH TODO: when isTrusted = false we should probably also cache a key
-
2296 // suppression for 30 seconds to avoid doing a relatively expensive
-
2297 // lookup every time a spam packet is received
-
2298 auto const isTrusted =
-
2299 app_.validators().trusted(val->getSignerPublic());
-
2300
-
2301 // If the operator has specified that untrusted validations be dropped
-
2302 // then this happens here I.e. before further wasting CPU verifying the
-
2303 // signature of an untrusted key
-
2304 if (!isTrusted && app_.config().RELAY_UNTRUSTED_VALIDATIONS == -1)
-
2305 return;
-
2306
-
2307 auto key = sha512Half(makeSlice(m->validation()));
-
2308
-
2309 if (auto [added, relayed] =
-
2310 app_.getHashRouter().addSuppressionPeerWithStatus(key, id_);
-
2311 !added)
-
2312 {
-
2313 // Count unique messages (Slots has it's own 'HashRouter'), which a
-
2314 // peer receives within IDLED seconds since the message has been
-
2315 // relayed. Wait WAIT_ON_BOOTUP time to let the server establish
-
2316 // connections to peers.
-
2317 if (reduceRelayReady() && relayed &&
-
2318 (stopwatch().now() - *relayed) < reduce_relay::IDLED)
-
2319 overlay_.updateSlotAndSquelch(
-
2320 key, val->getSignerPublic(), id_, protocol::mtVALIDATION);
-
2321 JLOG(p_journal_.trace()) << "Validation: duplicate";
-
2322 return;
-
2323 }
-
2324
-
2325 if (!isTrusted && (tracking_.load() == Tracking::diverged))
-
2326 {
-
2327 JLOG(p_journal_.debug())
-
2328 << "Dropping untrusted validation from diverged peer";
-
2329 }
-
2330 else if (isTrusted || !app_.getFeeTrack().isLoadedLocal())
-
2331 {
-
2332 std::string const name = [isTrusted, val]() {
-
2333 std::string ret =
-
2334 isTrusted ? "Trusted validation" : "Untrusted validation";
+
2295 if (!isCurrent(
+
2296 app_.getValidations().parms(),
+
2297 app_.timeKeeper().closeTime(),
+
2298 val->getSignTime(),
+
2299 val->getSeenTime()))
+
2300 {
+
2301 JLOG(p_journal_.trace()) << "Validation: Not current";
+
2302 fee_.update(Resource::feeUselessData, "not current");
+
2303 return;
+
2304 }
+
2305
+
2306 // RH TODO: when isTrusted = false we should probably also cache a key
+
2307 // suppression for 30 seconds to avoid doing a relatively expensive
+
2308 // lookup every time a spam packet is received
+
2309 auto const isTrusted =
+
2310 app_.validators().trusted(val->getSignerPublic());
+
2311
+
2312 // If the operator has specified that untrusted validations be dropped
+
2313 // then this happens here I.e. before further wasting CPU verifying the
+
2314 // signature of an untrusted key
+
2315 if (!isTrusted && app_.config().RELAY_UNTRUSTED_VALIDATIONS == -1)
+
2316 return;
+
2317
+
2318 auto key = sha512Half(makeSlice(m->validation()));
+
2319
+
2320 if (auto [added, relayed] =
+
2321 app_.getHashRouter().addSuppressionPeerWithStatus(key, id_);
+
2322 !added)
+
2323 {
+
2324 // Count unique messages (Slots has it's own 'HashRouter'), which a
+
2325 // peer receives within IDLED seconds since the message has been
+
2326 // relayed. Wait WAIT_ON_BOOTUP time to let the server establish
+
2327 // connections to peers.
+
2328 if (reduceRelayReady() && relayed &&
+
2329 (stopwatch().now() - *relayed) < reduce_relay::IDLED)
+
2330 overlay_.updateSlotAndSquelch(
+
2331 key, val->getSignerPublic(), id_, protocol::mtVALIDATION);
+
2332 JLOG(p_journal_.trace()) << "Validation: duplicate";
+
2333 return;
+
2334 }
2335
-
2336#ifdef DEBUG
-
2337 ret += " " +
-
2338 std::to_string(val->getFieldU32(sfLedgerSequence)) + ": " +
-
2339 to_string(val->getNodeID());
-
2340#endif
-
2341
-
2342 return ret;
-
2343 }();
-
2344
-
2345 std::weak_ptr<PeerImp> weak = shared_from_this();
-
2346 app_.getJobQueue().addJob(
-
2347 isTrusted ? jtVALIDATION_t : jtVALIDATION_ut,
-
2348 name,
-
2349 [weak, val, m, key]() {
-
2350 if (auto peer = weak.lock())
-
2351 peer->checkValidation(val, key, m);
-
2352 });
-
2353 }
-
2354 else
-
2355 {
-
2356 JLOG(p_journal_.debug())
-
2357 << "Dropping untrusted validation for load";
-
2358 }
-
2359 }
-
2360 catch (std::exception const& e)
-
2361 {
-
2362 JLOG(p_journal_.warn())
-
2363 << "Exception processing validation: " << e.what();
-
2364 using namespace std::string_literals;
-
2365 fee_.update(Resource::feeMalformedRequest, e.what());
-
2366 }
-
2367}
-
2368
-
2369void
-
2370PeerImp::onMessage(std::shared_ptr<protocol::TMGetObjectByHash> const& m)
-
2371{
-
2372 protocol::TMGetObjectByHash& packet = *m;
-
2373
-
2374 JLOG(p_journal_.trace()) << "received TMGetObjectByHash " << packet.type()
-
2375 << " " << packet.objects_size();
-
2376
-
2377 if (packet.query())
-
2378 {
-
2379 // this is a query
-
2380 if (send_queue_.size() >= Tuning::dropSendQueue)
-
2381 {
-
2382 JLOG(p_journal_.debug()) << "GetObject: Large send queue";
-
2383 return;
-
2384 }
-
2385
-
2386 if (packet.type() == protocol::TMGetObjectByHash::otFETCH_PACK)
-
2387 {
-
2388 doFetchPack(m);
-
2389 return;
-
2390 }
-
2391
-
2392 if (packet.type() == protocol::TMGetObjectByHash::otTRANSACTIONS)
-
2393 {
-
2394 if (!txReduceRelayEnabled())
-
2395 {
-
2396 JLOG(p_journal_.error())
-
2397 << "TMGetObjectByHash: tx reduce-relay is disabled";
-
2398 fee_.update(Resource::feeMalformedRequest, "disabled");
-
2399 return;
-
2400 }
-
2401
-
2402 std::weak_ptr<PeerImp> weak = shared_from_this();
-
2403 app_.getJobQueue().addJob(
-
2404 jtREQUESTED_TXN, "doTransactions", [weak, m]() {
-
2405 if (auto peer = weak.lock())
-
2406 peer->doTransactions(m);
-
2407 });
-
2408 return;
-
2409 }
-
2410
-
2411 fee_.update(
-
2412 Resource::feeModerateBurdenPeer,
-
2413 " received a get object by hash request");
-
2414
-
2415 protocol::TMGetObjectByHash reply;
-
2416
-
2417 reply.set_query(false);
-
2418
-
2419 if (packet.has_seq())
-
2420 reply.set_seq(packet.seq());
+
2336 if (!isTrusted && (tracking_.load() == Tracking::diverged))
+
2337 {
+
2338 JLOG(p_journal_.debug())
+
2339 << "Dropping untrusted validation from diverged peer";
+
2340 }
+
2341 else if (isTrusted || !app_.getFeeTrack().isLoadedLocal())
+
2342 {
+
2343 std::string const name = [isTrusted, val]() {
+
2344 std::string ret =
+
2345 isTrusted ? "Trusted validation" : "Untrusted validation";
+
2346
+
2347#ifdef DEBUG
+
2348 ret += " " +
+
2349 std::to_string(val->getFieldU32(sfLedgerSequence)) + ": " +
+
2350 to_string(val->getNodeID());
+
2351#endif
+
2352
+
2353 return ret;
+
2354 }();
+
2355
+
2356 std::weak_ptr<PeerImp> weak = shared_from_this();
+
2357 app_.getJobQueue().addJob(
+
2358 isTrusted ? jtVALIDATION_t : jtVALIDATION_ut,
+
2359 name,
+
2360 [weak, val, m, key]() {
+
2361 if (auto peer = weak.lock())
+
2362 peer->checkValidation(val, key, m);
+
2363 });
+
2364 }
+
2365 else
+
2366 {
+
2367 JLOG(p_journal_.debug())
+
2368 << "Dropping untrusted validation for load";
+
2369 }
+
2370 }
+
2371 catch (std::exception const& e)
+
2372 {
+
2373 JLOG(p_journal_.warn())
+
2374 << "Exception processing validation: " << e.what();
+
2375 using namespace std::string_literals;
+
2376 fee_.update(Resource::feeMalformedRequest, e.what());
+
2377 }
+
2378}
+
2379
+
2380void
+
2381PeerImp::onMessage(std::shared_ptr<protocol::TMGetObjectByHash> const& m)
+
2382{
+
2383 protocol::TMGetObjectByHash& packet = *m;
+
2384
+
2385 JLOG(p_journal_.trace()) << "received TMGetObjectByHash " << packet.type()
+
2386 << " " << packet.objects_size();
+
2387
+
2388 if (packet.query())
+
2389 {
+
2390 // this is a query
+
2391 if (send_queue_.size() >= Tuning::dropSendQueue)
+
2392 {
+
2393 JLOG(p_journal_.debug()) << "GetObject: Large send queue";
+
2394 return;
+
2395 }
+
2396
+
2397 if (packet.type() == protocol::TMGetObjectByHash::otFETCH_PACK)
+
2398 {
+
2399 doFetchPack(m);
+
2400 return;
+
2401 }
+
2402
+
2403 if (packet.type() == protocol::TMGetObjectByHash::otTRANSACTIONS)
+
2404 {
+
2405 if (!txReduceRelayEnabled())
+
2406 {
+
2407 JLOG(p_journal_.error())
+
2408 << "TMGetObjectByHash: tx reduce-relay is disabled";
+
2409 fee_.update(Resource::feeMalformedRequest, "disabled");
+
2410 return;
+
2411 }
+
2412
+
2413 std::weak_ptr<PeerImp> weak = shared_from_this();
+
2414 app_.getJobQueue().addJob(
+
2415 jtREQUESTED_TXN, "doTransactions", [weak, m]() {
+
2416 if (auto peer = weak.lock())
+
2417 peer->doTransactions(m);
+
2418 });
+
2419 return;
+
2420 }
2421
-
2422 reply.set_type(packet.type());
+
2422 protocol::TMGetObjectByHash reply;
2423
-
2424 if (packet.has_ledgerhash())
-
2425 {
-
2426 if (!stringIsUint256Sized(packet.ledgerhash()))
-
2427 {
-
2428 fee_.update(Resource::feeMalformedRequest, "ledger hash");
-
2429 return;
-
2430 }
-
2431
-
2432 reply.set_ledgerhash(packet.ledgerhash());
-
2433 }
-
2434
-
2435 // This is a very minimal implementation
-
2436 for (int i = 0; i < packet.objects_size(); ++i)
-
2437 {
-
2438 auto const& obj = packet.objects(i);
-
2439 if (obj.has_hash() && stringIsUint256Sized(obj.hash()))
-
2440 {
-
2441 uint256 const hash{obj.hash()};
-
2442 // VFALCO TODO Move this someplace more sensible so we dont
-
2443 // need to inject the NodeStore interfaces.
-
2444 std::uint32_t seq{obj.has_ledgerseq() ? obj.ledgerseq() : 0};
-
2445 auto nodeObject{app_.getNodeStore().fetchNodeObject(hash, seq)};
-
2446 if (nodeObject)
-
2447 {
-
2448 protocol::TMIndexedObject& newObj = *reply.add_objects();
-
2449 newObj.set_hash(hash.begin(), hash.size());
-
2450 newObj.set_data(
-
2451 &nodeObject->getData().front(),
-
2452 nodeObject->getData().size());
-
2453
-
2454 if (obj.has_nodeid())
-
2455 newObj.set_index(obj.nodeid());
-
2456 if (obj.has_ledgerseq())
-
2457 newObj.set_ledgerseq(obj.ledgerseq());
-
2458
-
2459 // VFALCO NOTE "seq" in the message is obsolete
-
2460 }
-
2461 }
-
2462 }
-
2463
-
2464 JLOG(p_journal_.trace()) << "GetObj: " << reply.objects_size() << " of "
-
2465 << packet.objects_size();
-
2466 send(std::make_shared<Message>(reply, protocol::mtGET_OBJECTS));
-
2467 }
-
2468 else
-
2469 {
-
2470 // this is a reply
-
2471 std::uint32_t pLSeq = 0;
-
2472 bool pLDo = true;
-
2473 bool progress = false;
+
2424 reply.set_query(false);
+
2425
+
2426 if (packet.has_seq())
+
2427 reply.set_seq(packet.seq());
+
2428
+
2429 reply.set_type(packet.type());
+
2430
+
2431 if (packet.has_ledgerhash())
+
2432 {
+
2433 if (!stringIsUint256Sized(packet.ledgerhash()))
+
2434 {
+
2435 fee_.update(Resource::feeMalformedRequest, "ledger hash");
+
2436 return;
+
2437 }
+
2438
+
2439 reply.set_ledgerhash(packet.ledgerhash());
+
2440 }
+
2441
+
2442 fee_.update(
+
2443 Resource::feeModerateBurdenPeer,
+
2444 " received a get object by hash request");
+
2445
+
2446 // This is a very minimal implementation
+
2447 for (int i = 0; i < packet.objects_size(); ++i)
+
2448 {
+
2449 auto const& obj = packet.objects(i);
+
2450 if (obj.has_hash() && stringIsUint256Sized(obj.hash()))
+
2451 {
+
2452 uint256 const hash{obj.hash()};
+
2453 // VFALCO TODO Move this someplace more sensible so we dont
+
2454 // need to inject the NodeStore interfaces.
+
2455 std::uint32_t seq{obj.has_ledgerseq() ? obj.ledgerseq() : 0};
+
2456 auto nodeObject{app_.getNodeStore().fetchNodeObject(hash, seq)};
+
2457 if (nodeObject)
+
2458 {
+
2459 protocol::TMIndexedObject& newObj = *reply.add_objects();
+
2460 newObj.set_hash(hash.begin(), hash.size());
+
2461 newObj.set_data(
+
2462 &nodeObject->getData().front(),
+
2463 nodeObject->getData().size());
+
2464
+
2465 if (obj.has_nodeid())
+
2466 newObj.set_index(obj.nodeid());
+
2467 if (obj.has_ledgerseq())
+
2468 newObj.set_ledgerseq(obj.ledgerseq());
+
2469
+
2470 // VFALCO NOTE "seq" in the message is obsolete
+
2471 }
+
2472 }
+
2473 }
2474
-
2475 for (int i = 0; i < packet.objects_size(); ++i)
-
2476 {
-
2477 const protocol::TMIndexedObject& obj = packet.objects(i);
-
2478
-
2479 if (obj.has_hash() && stringIsUint256Sized(obj.hash()))
-
2480 {
-
2481 if (obj.has_ledgerseq())
-
2482 {
-
2483 if (obj.ledgerseq() != pLSeq)
-
2484 {
-
2485 if (pLDo && (pLSeq != 0))
-
2486 {
-
2487 JLOG(p_journal_.debug())
-
2488 << "GetObj: Full fetch pack for " << pLSeq;
-
2489 }
-
2490 pLSeq = obj.ledgerseq();
-
2491 pLDo = !app_.getLedgerMaster().haveLedger(pLSeq);
-
2492
-
2493 if (!pLDo)
-
2494 {
-
2495 JLOG(p_journal_.debug())
-
2496 << "GetObj: Late fetch pack for " << pLSeq;
-
2497 }
-
2498 else
-
2499 progress = true;
-
2500 }
-
2501 }
-
2502
-
2503 if (pLDo)
-
2504 {
-
2505 uint256 const hash{obj.hash()};
-
2506
-
2507 app_.getLedgerMaster().addFetchPack(
-
2508 hash,
-
2509 std::make_shared<Blob>(
-
2510 obj.data().begin(), obj.data().end()));
-
2511 }
-
2512 }
-
2513 }
-
2514
-
2515 if (pLDo && (pLSeq != 0))
-
2516 {
-
2517 JLOG(p_journal_.debug())
-
2518 << "GetObj: Partial fetch pack for " << pLSeq;
-
2519 }
-
2520 if (packet.type() == protocol::TMGetObjectByHash::otFETCH_PACK)
-
2521 app_.getLedgerMaster().gotFetchPack(progress, pLSeq);
-
2522 }
-
2523}
-
2524
-
2525void
-
2526PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactions> const& m)
-
2527{
-
2528 if (!txReduceRelayEnabled())
-
2529 {
-
2530 JLOG(p_journal_.error())
-
2531 << "TMHaveTransactions: tx reduce-relay is disabled";
-
2532 fee_.update(Resource::feeMalformedRequest, "disabled");
-
2533 return;
-
2534 }
+
2475 JLOG(p_journal_.trace()) << "GetObj: " << reply.objects_size() << " of "
+
2476 << packet.objects_size();
+
2477 send(std::make_shared<Message>(reply, protocol::mtGET_OBJECTS));
+
2478 }
+
2479 else
+
2480 {
+
2481 // this is a reply
+
2482 std::uint32_t pLSeq = 0;
+
2483 bool pLDo = true;
+
2484 bool progress = false;
+
2485
+
2486 for (int i = 0; i < packet.objects_size(); ++i)
+
2487 {
+
2488 const protocol::TMIndexedObject& obj = packet.objects(i);
+
2489
+
2490 if (obj.has_hash() && stringIsUint256Sized(obj.hash()))
+
2491 {
+
2492 if (obj.has_ledgerseq())
+
2493 {
+
2494 if (obj.ledgerseq() != pLSeq)
+
2495 {
+
2496 if (pLDo && (pLSeq != 0))
+
2497 {
+
2498 JLOG(p_journal_.debug())
+
2499 << "GetObj: Full fetch pack for " << pLSeq;
+
2500 }
+
2501 pLSeq = obj.ledgerseq();
+
2502 pLDo = !app_.getLedgerMaster().haveLedger(pLSeq);
+
2503
+
2504 if (!pLDo)
+
2505 {
+
2506 JLOG(p_journal_.debug())
+
2507 << "GetObj: Late fetch pack for " << pLSeq;
+
2508 }
+
2509 else
+
2510 progress = true;
+
2511 }
+
2512 }
+
2513
+
2514 if (pLDo)
+
2515 {
+
2516 uint256 const hash{obj.hash()};
+
2517
+
2518 app_.getLedgerMaster().addFetchPack(
+
2519 hash,
+
2520 std::make_shared<Blob>(
+
2521 obj.data().begin(), obj.data().end()));
+
2522 }
+
2523 }
+
2524 }
+
2525
+
2526 if (pLDo && (pLSeq != 0))
+
2527 {
+
2528 JLOG(p_journal_.debug())
+
2529 << "GetObj: Partial fetch pack for " << pLSeq;
+
2530 }
+
2531 if (packet.type() == protocol::TMGetObjectByHash::otFETCH_PACK)
+
2532 app_.getLedgerMaster().gotFetchPack(progress, pLSeq);
+
2533 }
+
2534}
2535
-
2536 std::weak_ptr<PeerImp> weak = shared_from_this();
-
2537 app_.getJobQueue().addJob(
-
2538 jtMISSING_TXN, "handleHaveTransactions", [weak, m]() {
-
2539 if (auto peer = weak.lock())
-
2540 peer->handleHaveTransactions(m);
-
2541 });
-
2542}
-
2543
-
2544void
-
2545PeerImp::handleHaveTransactions(
-
2546 std::shared_ptr<protocol::TMHaveTransactions> const& m)
-
2547{
-
2548 protocol::TMGetObjectByHash tmBH;
-
2549 tmBH.set_type(protocol::TMGetObjectByHash_ObjectType_otTRANSACTIONS);
-
2550 tmBH.set_query(true);
-
2551
-
2552 JLOG(p_journal_.trace())
-
2553 << "received TMHaveTransactions " << m->hashes_size();
+
2536void
+
2537PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactions> const& m)
+
2538{
+
2539 if (!txReduceRelayEnabled())
+
2540 {
+
2541 JLOG(p_journal_.error())
+
2542 << "TMHaveTransactions: tx reduce-relay is disabled";
+
2543 fee_.update(Resource::feeMalformedRequest, "disabled");
+
2544 return;
+
2545 }
+
2546
+
2547 std::weak_ptr<PeerImp> weak = shared_from_this();
+
2548 app_.getJobQueue().addJob(
+
2549 jtMISSING_TXN, "handleHaveTransactions", [weak, m]() {
+
2550 if (auto peer = weak.lock())
+
2551 peer->handleHaveTransactions(m);
+
2552 });
+
2553}
2554
-
2555 for (std::uint32_t i = 0; i < m->hashes_size(); i++)
-
2556 {
-
2557 if (!stringIsUint256Sized(m->hashes(i)))
-
2558 {
-
2559 JLOG(p_journal_.error())
-
2560 << "TMHaveTransactions with invalid hash size";
-
2561 fee_.update(Resource::feeMalformedRequest, "hash size");
-
2562 return;
-
2563 }
-
2564
-
2565 uint256 hash(m->hashes(i));
-
2566
-
2567 auto txn = app_.getMasterTransaction().fetch_from_cache(hash);
-
2568
-
2569 JLOG(p_journal_.trace()) << "checking transaction " << (bool)txn;
-
2570
-
2571 if (!txn)
-
2572 {
-
2573 JLOG(p_journal_.debug()) << "adding transaction to request";
-
2574
-
2575 auto obj = tmBH.add_objects();
-
2576 obj->set_hash(hash.data(), hash.size());
-
2577 }
-
2578 else
-
2579 {
-
2580 // Erase only if a peer has seen this tx. If the peer has not
-
2581 // seen this tx then the tx could not has been queued for this
-
2582 // peer.
-
2583 removeTxQueue(hash);
-
2584 }
-
2585 }
-
2586
-
2587 JLOG(p_journal_.trace())
-
2588 << "transaction request object is " << tmBH.objects_size();
-
2589
-
2590 if (tmBH.objects_size() > 0)
-
2591 send(std::make_shared<Message>(tmBH, protocol::mtGET_OBJECTS));
-
2592}
-
2593
-
2594void
-
2595PeerImp::onMessage(std::shared_ptr<protocol::TMTransactions> const& m)
-
2596{
-
2597 if (!txReduceRelayEnabled())
-
2598 {
-
2599 JLOG(p_journal_.error())
-
2600 << "TMTransactions: tx reduce-relay is disabled";
-
2601 fee_.update(Resource::feeMalformedRequest, "disabled");
-
2602 return;
-
2603 }
+
2555void
+
2556PeerImp::handleHaveTransactions(
+
2557 std::shared_ptr<protocol::TMHaveTransactions> const& m)
+
2558{
+
2559 protocol::TMGetObjectByHash tmBH;
+
2560 tmBH.set_type(protocol::TMGetObjectByHash_ObjectType_otTRANSACTIONS);
+
2561 tmBH.set_query(true);
+
2562
+
2563 JLOG(p_journal_.trace())
+
2564 << "received TMHaveTransactions " << m->hashes_size();
+
2565
+
2566 for (std::uint32_t i = 0; i < m->hashes_size(); i++)
+
2567 {
+
2568 if (!stringIsUint256Sized(m->hashes(i)))
+
2569 {
+
2570 JLOG(p_journal_.error())
+
2571 << "TMHaveTransactions with invalid hash size";
+
2572 fee_.update(Resource::feeMalformedRequest, "hash size");
+
2573 return;
+
2574 }
+
2575
+
2576 uint256 hash(m->hashes(i));
+
2577
+
2578 auto txn = app_.getMasterTransaction().fetch_from_cache(hash);
+
2579
+
2580 JLOG(p_journal_.trace()) << "checking transaction " << (bool)txn;
+
2581
+
2582 if (!txn)
+
2583 {
+
2584 JLOG(p_journal_.debug()) << "adding transaction to request";
+
2585
+
2586 auto obj = tmBH.add_objects();
+
2587 obj->set_hash(hash.data(), hash.size());
+
2588 }
+
2589 else
+
2590 {
+
2591 // Erase only if a peer has seen this tx. If the peer has not
+
2592 // seen this tx then the tx could not has been queued for this
+
2593 // peer.
+
2594 removeTxQueue(hash);
+
2595 }
+
2596 }
+
2597
+
2598 JLOG(p_journal_.trace())
+
2599 << "transaction request object is " << tmBH.objects_size();
+
2600
+
2601 if (tmBH.objects_size() > 0)
+
2602 send(std::make_shared<Message>(tmBH, protocol::mtGET_OBJECTS));
+
2603}
2604
-
2605 JLOG(p_journal_.trace())
-
2606 << "received TMTransactions " << m->transactions_size();
-
2607
-
2608 overlay_.addTxMetrics(m->transactions_size());
-
2609
-
2610 for (std::uint32_t i = 0; i < m->transactions_size(); ++i)
-
2611 handleTransaction(
-
2612 std::shared_ptr<protocol::TMTransaction>(
-
2613 m->mutable_transactions(i), [](protocol::TMTransaction*) {}),
-
2614 false,
-
2615 true);
-
2616}
-
2617
-
2618void
-
2619PeerImp::onMessage(std::shared_ptr<protocol::TMSquelch> const& m)
-
2620{
-
2621 using on_message_fn =
-
2622 void (PeerImp::*)(std::shared_ptr<protocol::TMSquelch> const&);
-
2623 if (!strand_.running_in_this_thread())
-
2624 return post(
-
2625 strand_,
-
2626 std::bind(
-
2627 (on_message_fn)&PeerImp::onMessage, shared_from_this(), m));
+
2605void
+
2606PeerImp::onMessage(std::shared_ptr<protocol::TMTransactions> const& m)
+
2607{
+
2608 if (!txReduceRelayEnabled())
+
2609 {
+
2610 JLOG(p_journal_.error())
+
2611 << "TMTransactions: tx reduce-relay is disabled";
+
2612 fee_.update(Resource::feeMalformedRequest, "disabled");
+
2613 return;
+
2614 }
+
2615
+
2616 JLOG(p_journal_.trace())
+
2617 << "received TMTransactions " << m->transactions_size();
+
2618
+
2619 overlay_.addTxMetrics(m->transactions_size());
+
2620
+
2621 for (std::uint32_t i = 0; i < m->transactions_size(); ++i)
+
2622 handleTransaction(
+
2623 std::shared_ptr<protocol::TMTransaction>(
+
2624 m->mutable_transactions(i), [](protocol::TMTransaction*) {}),
+
2625 false,
+
2626 true);
+
2627}
2628
-
2629 if (!m->has_validatorpubkey())
-
2630 {
-
2631 charge(Resource::feeInvalidData, "squelch no pubkey");
-
2632 return;
-
2633 }
-
2634 auto validator = m->validatorpubkey();
-
2635 auto const slice{makeSlice(validator)};
-
2636 if (!publicKeyType(slice))
-
2637 {
-
2638 charge(Resource::feeInvalidData, "squelch bad pubkey");
-
2639 return;
-
2640 }
-
2641 PublicKey key(slice);
-
2642
-
2643 // Ignore non-validator squelch
-
2644 if (!app_.validators().listed(key))
-
2645 {
-
2646 charge(Resource::feeInvalidData, "squelch non-validator");
-
2647 JLOG(p_journal_.debug())
-
2648 << "onMessage: TMSquelch discarding non-validator squelch "
-
2649 << slice;
+
2629void
+
2630PeerImp::onMessage(std::shared_ptr<protocol::TMSquelch> const& m)
+
2631{
+
2632 using on_message_fn =
+
2633 void (PeerImp::*)(std::shared_ptr<protocol::TMSquelch> const&);
+
2634 if (!strand_.running_in_this_thread())
+
2635 return post(
+
2636 strand_,
+
2637 std::bind(
+
2638 (on_message_fn)&PeerImp::onMessage, shared_from_this(), m));
+
2639
+
2640 if (!m->has_validatorpubkey())
+
2641 {
+
2642 fee_.update(Resource::feeInvalidData, "squelch no pubkey");
+
2643 return;
+
2644 }
+
2645 auto validator = m->validatorpubkey();
+
2646 auto const slice{makeSlice(validator)};
+
2647 if (!publicKeyType(slice))
+
2648 {
+
2649 fee_.update(Resource::feeInvalidData, "squelch bad pubkey");
2650 return;
2651 }
-
2652
-
2653 // Ignore the squelch for validator's own messages.
-
2654 if (key == app_.getValidationPublicKey())
-
2655 {
-
2656 JLOG(p_journal_.debug())
-
2657 << "onMessage: TMSquelch discarding validator's squelch " << slice;
-
2658 return;
-
2659 }
-
2660
-
2661 std::uint32_t duration =
-
2662 m->has_squelchduration() ? m->squelchduration() : 0;
-
2663 if (!m->squelch())
-
2664 squelch_.removeSquelch(key);
-
2665 else if (!squelch_.addSquelch(key, std::chrono::seconds{duration}))
-
2666 charge(Resource::feeInvalidData, "squelch duration");
-
2667
-
2668 JLOG(p_journal_.debug())
-
2669 << "onMessage: TMSquelch " << slice << " " << id() << " " << duration;
-
2670}
+
2652 PublicKey key(slice);
+
2653
+
2654 // Ignore non-validator squelch
+
2655 if (!app_.validators().listed(key))
+
2656 {
+
2657 fee_.update(Resource::feeInvalidData, "squelch non-validator");
+
2658 JLOG(p_journal_.debug())
+
2659 << "onMessage: TMSquelch discarding non-validator squelch "
+
2660 << slice;
+
2661 return;
+
2662 }
+
2663
+
2664 // Ignore the squelch for validator's own messages.
+
2665 if (key == app_.getValidationPublicKey())
+
2666 {
+
2667 JLOG(p_journal_.debug())
+
2668 << "onMessage: TMSquelch discarding validator's squelch " << slice;
+
2669 return;
+
2670 }
2671
-
2672//--------------------------------------------------------------------------
-
2673
-
2674void
-
2675PeerImp::addLedger(
-
2676 uint256 const& hash,
-
2677 std::lock_guard<std::mutex> const& lockedRecentLock)
-
2678{
-
2679 // lockedRecentLock is passed as a reminder that recentLock_ must be
-
2680 // locked by the caller.
-
2681 (void)lockedRecentLock;
+
2672 std::uint32_t duration =
+
2673 m->has_squelchduration() ? m->squelchduration() : 0;
+
2674 if (!m->squelch())
+
2675 squelch_.removeSquelch(key);
+
2676 else if (!squelch_.addSquelch(key, std::chrono::seconds{duration}))
+
2677 fee_.update(Resource::feeInvalidData, "squelch duration");
+
2678
+
2679 JLOG(p_journal_.debug())
+
2680 << "onMessage: TMSquelch " << slice << " " << id() << " " << duration;
+
2681}
2682
-
2683 if (std::find(recentLedgers_.begin(), recentLedgers_.end(), hash) !=
-
2684 recentLedgers_.end())
-
2685 return;
-
2686
-
2687 recentLedgers_.push_back(hash);
-
2688}
-
2689
-
2690void
-
2691PeerImp::doFetchPack(const std::shared_ptr<protocol::TMGetObjectByHash>& packet)
-
2692{
-
2693 // VFALCO TODO Invert this dependency using an observer and shared state
-
2694 // object. Don't queue fetch pack jobs if we're under load or we already
-
2695 // have some queued.
-
2696 if (app_.getFeeTrack().isLoadedLocal() ||
-
2697 (app_.getLedgerMaster().getValidatedLedgerAge() > 40s) ||
-
2698 (app_.getJobQueue().getJobCount(jtPACK) > 10))
-
2699 {
-
2700 JLOG(p_journal_.info()) << "Too busy to make fetch pack";
-
2701 return;
-
2702 }
-
2703
-
2704 if (!stringIsUint256Sized(packet->ledgerhash()))
-
2705 {
-
2706 JLOG(p_journal_.warn()) << "FetchPack hash size malformed";
-
2707 fee_.update(Resource::feeMalformedRequest, "hash size");
-
2708 return;
-
2709 }
-
2710
-
2711 fee_.fee = Resource::feeHeavyBurdenPeer;
-
2712
-
2713 uint256 const hash{packet->ledgerhash()};
+
2683//--------------------------------------------------------------------------
+
2684
+
2685void
+
2686PeerImp::addLedger(
+
2687 uint256 const& hash,
+
2688 std::lock_guard<std::mutex> const& lockedRecentLock)
+
2689{
+
2690 // lockedRecentLock is passed as a reminder that recentLock_ must be
+
2691 // locked by the caller.
+
2692 (void)lockedRecentLock;
+
2693
+
2694 if (std::find(recentLedgers_.begin(), recentLedgers_.end(), hash) !=
+
2695 recentLedgers_.end())
+
2696 return;
+
2697
+
2698 recentLedgers_.push_back(hash);
+
2699}
+
2700
+
2701void
+
2702PeerImp::doFetchPack(const std::shared_ptr<protocol::TMGetObjectByHash>& packet)
+
2703{
+
2704 // VFALCO TODO Invert this dependency using an observer and shared state
+
2705 // object. Don't queue fetch pack jobs if we're under load or we already
+
2706 // have some queued.
+
2707 if (app_.getFeeTrack().isLoadedLocal() ||
+
2708 (app_.getLedgerMaster().getValidatedLedgerAge() > 40s) ||
+
2709 (app_.getJobQueue().getJobCount(jtPACK) > 10))
+
2710 {
+
2711 JLOG(p_journal_.info()) << "Too busy to make fetch pack";
+
2712 return;
+
2713 }
2714
-
2715 std::weak_ptr<PeerImp> weak = shared_from_this();
-
2716 auto elapsed = UptimeClock::now();
-
2717 auto const pap = &app_;
-
2718 app_.getJobQueue().addJob(
-
2719 jtPACK, "MakeFetchPack", [pap, weak, packet, hash, elapsed]() {
-
2720 pap->getLedgerMaster().makeFetchPack(weak, packet, hash, elapsed);
-
2721 });
-
2722}
+
2715 if (!stringIsUint256Sized(packet->ledgerhash()))
+
2716 {
+
2717 JLOG(p_journal_.warn()) << "FetchPack hash size malformed";
+
2718 fee_.update(Resource::feeMalformedRequest, "hash size");
+
2719 return;
+
2720 }
+
2721
+
2722 fee_.fee = Resource::feeHeavyBurdenPeer;
2723
-
2724void
-
2725PeerImp::doTransactions(
-
2726 std::shared_ptr<protocol::TMGetObjectByHash> const& packet)
-
2727{
-
2728 protocol::TMTransactions reply;
-
2729
-
2730 JLOG(p_journal_.trace()) << "received TMGetObjectByHash requesting tx "
-
2731 << packet->objects_size();
-
2732
-
2733 if (packet->objects_size() > reduce_relay::MAX_TX_QUEUE_SIZE)
-
2734 {
-
2735 JLOG(p_journal_.error()) << "doTransactions, invalid number of hashes";
-
2736 fee_.update(Resource::feeMalformedRequest, "too big");
-
2737 return;
-
2738 }
-
2739
-
2740 for (std::uint32_t i = 0; i < packet->objects_size(); ++i)
-
2741 {
-
2742 auto const& obj = packet->objects(i);
+
2724 uint256 const hash{packet->ledgerhash()};
+
2725
+
2726 std::weak_ptr<PeerImp> weak = shared_from_this();
+
2727 auto elapsed = UptimeClock::now();
+
2728 auto const pap = &app_;
+
2729 app_.getJobQueue().addJob(
+
2730 jtPACK, "MakeFetchPack", [pap, weak, packet, hash, elapsed]() {
+
2731 pap->getLedgerMaster().makeFetchPack(weak, packet, hash, elapsed);
+
2732 });
+
2733}
+
2734
+
2735void
+
2736PeerImp::doTransactions(
+
2737 std::shared_ptr<protocol::TMGetObjectByHash> const& packet)
+
2738{
+
2739 protocol::TMTransactions reply;
+
2740
+
2741 JLOG(p_journal_.trace()) << "received TMGetObjectByHash requesting tx "
+
2742 << packet->objects_size();
2743
-
2744 if (!stringIsUint256Sized(obj.hash()))
-
2745 {
-
2746 fee_.update(Resource::feeMalformedRequest, "hash size");
-
2747 return;
-
2748 }
-
2749
-
2750 uint256 hash(obj.hash());
-
2751
-
2752 auto txn = app_.getMasterTransaction().fetch_from_cache(hash);
-
2753
-
2754 if (!txn)
-
2755 {
-
2756 JLOG(p_journal_.error()) << "doTransactions, transaction not found "
-
2757 << Slice(hash.data(), hash.size());
-
2758 fee_.update(Resource::feeMalformedRequest, "tx not found");
-
2759 return;
-
2760 }
-
2761
-
2762 Serializer s;
-
2763 auto tx = reply.add_transactions();
-
2764 auto sttx = txn->getSTransaction();
-
2765 sttx->add(s);
-
2766 tx->set_rawtransaction(s.data(), s.size());
-
2767 tx->set_status(
-
2768 txn->getStatus() == INCLUDED ? protocol::tsCURRENT
-
2769 : protocol::tsNEW);
-
2770 tx->set_receivetimestamp(
-
2771 app_.timeKeeper().now().time_since_epoch().count());
-
2772 tx->set_deferred(txn->getSubmitResult().queued);
-
2773 }
-
2774
-
2775 if (reply.transactions_size() > 0)
-
2776 send(std::make_shared<Message>(reply, protocol::mtTRANSACTIONS));
-
2777}
-
2778
-
2779void
-
2780PeerImp::checkTransaction(
-
2781 int flags,
-
2782 bool checkSignature,
-
2783 std::shared_ptr<STTx const> const& stx,
-
2784 bool batch)
-
2785{
-
2786 // VFALCO TODO Rewrite to not use exceptions
-
2787 try
-
2788 {
-
2789 // Expired?
-
2790 if (stx->isFieldPresent(sfLastLedgerSequence) &&
-
2791 (stx->getFieldU32(sfLastLedgerSequence) <
-
2792 app_.getLedgerMaster().getValidLedgerIndex()))
-
2793 {
-
2794 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
-
2795 charge(Resource::feeUselessData, "expired tx");
-
2796 return;
-
2797 }
-
2798
-
2799 if (isPseudoTx(*stx))
-
2800 {
-
2801 // Don't do anything with pseudo transactions except put them in the
-
2802 // TransactionMaster cache
-
2803 std::string reason;
-
2804 auto tx = std::make_shared<Transaction>(stx, reason, app_);
-
2805 XRPL_ASSERT(
-
2806 tx->getStatus() == NEW,
-
2807 "ripple::PeerImp::checkTransaction Transaction created "
-
2808 "correctly");
-
2809 if (tx->getStatus() == NEW)
-
2810 {
-
2811 JLOG(p_journal_.debug())
-
2812 << "Processing " << (batch ? "batch" : "unsolicited")
-
2813 << " pseudo-transaction tx " << tx->getID();
-
2814
-
2815 app_.getMasterTransaction().canonicalize(&tx);
-
2816 // Tell the overlay about it, but don't relay it.
-
2817 auto const toSkip =
-
2818 app_.getHashRouter().shouldRelay(tx->getID());
-
2819 if (toSkip)
-
2820 {
-
2821 JLOG(p_journal_.debug())
-
2822 << "Passing skipped pseudo pseudo-transaction tx "
-
2823 << tx->getID();
-
2824 app_.overlay().relay(tx->getID(), {}, *toSkip);
-
2825 }
-
2826 if (!batch)
-
2827 {
-
2828 JLOG(p_journal_.debug())
-
2829 << "Charging for pseudo-transaction tx " << tx->getID();
-
2830 charge(Resource::feeUselessData, "pseudo tx");
-
2831 }
-
2832
-
2833 return;
-
2834 }
-
2835 }
-
2836
-
2837 if (checkSignature)
-
2838 {
-
2839 // Check the signature before handing off to the job queue.
-
2840 if (auto [valid, validReason] = checkValidity(
-
2841 app_.getHashRouter(),
-
2842 *stx,
-
2843 app_.getLedgerMaster().getValidatedRules(),
-
2844 app_.config());
-
2845 valid != Validity::Valid)
-
2846 {
-
2847 if (!validReason.empty())
-
2848 {
-
2849 JLOG(p_journal_.trace())
-
2850 << "Exception checking transaction: " << validReason;
-
2851 }
-
2852
-
2853 // Probably not necessary to set SF_BAD, but doesn't hurt.
-
2854 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
-
2855 charge(
-
2856 Resource::feeInvalidSignature,
-
2857 "check transaction signature failure");
-
2858 return;
-
2859 }
-
2860 }
-
2861 else
-
2862 {
-
2863 forceValidity(
-
2864 app_.getHashRouter(), stx->getTransactionID(), Validity::Valid);
-
2865 }
-
2866
-
2867 std::string reason;
-
2868 auto tx = std::make_shared<Transaction>(stx, reason, app_);
-
2869
-
2870 if (tx->getStatus() == INVALID)
-
2871 {
-
2872 if (!reason.empty())
-
2873 {
-
2874 JLOG(p_journal_.trace())
-
2875 << "Exception checking transaction: " << reason;
-
2876 }
-
2877 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
-
2878 charge(Resource::feeInvalidSignature, "tx (impossible)");
-
2879 return;
-
2880 }
-
2881
-
2882 bool const trusted(flags & SF_TRUSTED);
-
2883 app_.getOPs().processTransaction(
-
2884 tx, trusted, false, NetworkOPs::FailHard::no);
-
2885 }
-
2886 catch (std::exception const& ex)
-
2887 {
-
2888 JLOG(p_journal_.warn())
-
2889 << "Exception in " << __func__ << ": " << ex.what();
-
2890 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
-
2891 using namespace std::string_literals;
-
2892 charge(Resource::feeInvalidData, "tx "s + ex.what());
-
2893 }
-
2894}
-
2895
-
2896// Called from our JobQueue
-
2897void
-
2898PeerImp::checkPropose(
-
2899 bool isTrusted,
-
2900 std::shared_ptr<protocol::TMProposeSet> const& packet,
-
2901 RCLCxPeerPos peerPos)
-
2902{
-
2903 JLOG(p_journal_.trace())
-
2904 << "Checking " << (isTrusted ? "trusted" : "UNTRUSTED") << " proposal";
-
2905
-
2906 XRPL_ASSERT(packet, "ripple::PeerImp::checkPropose : non-null packet");
-
2907
-
2908 if (!cluster() && !peerPos.checkSign())
-
2909 {
-
2910 std::string desc{"Proposal fails sig check"};
-
2911 JLOG(p_journal_.warn()) << desc;
-
2912 charge(Resource::feeInvalidSignature, desc);
-
2913 return;
-
2914 }
-
2915
-
2916 bool relay;
-
2917
-
2918 if (isTrusted)
-
2919 relay = app_.getOPs().processTrustedProposal(peerPos);
-
2920 else
-
2921 relay = app_.config().RELAY_UNTRUSTED_PROPOSALS == 1 || cluster();
-
2922
-
2923 if (relay)
-
2924 {
-
2925 // haveMessage contains peers, which are suppressed; i.e. the peers
-
2926 // are the source of the message, consequently the message should
-
2927 // not be relayed to these peers. But the message must be counted
-
2928 // as part of the squelch logic.
-
2929 auto haveMessage = app_.overlay().relay(
-
2930 *packet, peerPos.suppressionID(), peerPos.publicKey());
-
2931 if (reduceRelayReady() && !haveMessage.empty())
-
2932 overlay_.updateSlotAndSquelch(
-
2933 peerPos.suppressionID(),
-
2934 peerPos.publicKey(),
-
2935 std::move(haveMessage),
-
2936 protocol::mtPROPOSE_LEDGER);
-
2937 }
-
2938}
-
2939
-
2940void
-
2941PeerImp::checkValidation(
-
2942 std::shared_ptr<STValidation> const& val,
-
2943 uint256 const& key,
-
2944 std::shared_ptr<protocol::TMValidation> const& packet)
-
2945{
-
2946 if (!val->isValid())
-
2947 {
-
2948 std::string desc{"Validation forwarded by peer is invalid"};
-
2949 JLOG(p_journal_.debug()) << desc;
-
2950 charge(Resource::feeInvalidSignature, desc);
-
2951 return;
-
2952 }
-
2953
-
2954 // FIXME it should be safe to remove this try/catch. Investigate codepaths.
-
2955 try
-
2956 {
-
2957 if (app_.getOPs().recvValidation(val, std::to_string(id())) ||
-
2958 cluster())
-
2959 {
-
2960 // haveMessage contains peers, which are suppressed; i.e. the peers
-
2961 // are the source of the message, consequently the message should
-
2962 // not be relayed to these peers. But the message must be counted
-
2963 // as part of the squelch logic.
-
2964 auto haveMessage =
-
2965 overlay_.relay(*packet, key, val->getSignerPublic());
-
2966 if (reduceRelayReady() && !haveMessage.empty())
-
2967 {
-
2968 overlay_.updateSlotAndSquelch(
-
2969 key,
-
2970 val->getSignerPublic(),
-
2971 std::move(haveMessage),
-
2972 protocol::mtVALIDATION);
-
2973 }
-
2974 }
-
2975 }
-
2976 catch (std::exception const& ex)
-
2977 {
-
2978 JLOG(p_journal_.trace())
-
2979 << "Exception processing validation: " << ex.what();
-
2980 using namespace std::string_literals;
-
2981 charge(Resource::feeMalformedRequest, "validation "s + ex.what());
-
2982 }
-
2983}
-
2984
-
2985// Returns the set of peers that can help us get
-
2986// the TX tree with the specified root hash.
-
2987//
-
2988static std::shared_ptr<PeerImp>
-
2989getPeerWithTree(OverlayImpl& ov, uint256 const& rootHash, PeerImp const* skip)
-
2990{
-
2991 std::shared_ptr<PeerImp> ret;
-
2992 int retScore = 0;
-
2993
-
2994 ov.for_each([&](std::shared_ptr<PeerImp>&& p) {
-
2995 if (p->hasTxSet(rootHash) && p.get() != skip)
-
2996 {
-
2997 auto score = p->getScore(true);
-
2998 if (!ret || (score > retScore))
-
2999 {
-
3000 ret = std::move(p);
-
3001 retScore = score;
-
3002 }
-
3003 }
-
3004 });
-
3005
-
3006 return ret;
-
3007}
-
3008
-
3009// Returns a random peer weighted by how likely to
-
3010// have the ledger and how responsive it is.
-
3011//
-
3012static std::shared_ptr<PeerImp>
-
3013getPeerWithLedger(
-
3014 OverlayImpl& ov,
-
3015 uint256 const& ledgerHash,
-
3016 LedgerIndex ledger,
-
3017 PeerImp const* skip)
-
3018{
-
3019 std::shared_ptr<PeerImp> ret;
-
3020 int retScore = 0;
-
3021
-
3022 ov.for_each([&](std::shared_ptr<PeerImp>&& p) {
-
3023 if (p->hasLedger(ledgerHash, ledger) && p.get() != skip)
-
3024 {
-
3025 auto score = p->getScore(true);
-
3026 if (!ret || (score > retScore))
-
3027 {
-
3028 ret = std::move(p);
-
3029 retScore = score;
-
3030 }
-
3031 }
-
3032 });
-
3033
-
3034 return ret;
-
3035}
-
3036
-
3037void
-
3038PeerImp::sendLedgerBase(
-
3039 std::shared_ptr<Ledger const> const& ledger,
-
3040 protocol::TMLedgerData& ledgerData)
-
3041{
-
3042 JLOG(p_journal_.trace()) << "sendLedgerBase: Base data";
-
3043
-
3044 Serializer s(sizeof(LedgerInfo));
-
3045 addRaw(ledger->info(), s);
-
3046 ledgerData.add_nodes()->set_nodedata(s.getDataPtr(), s.getLength());
+
2744 if (packet->objects_size() > reduce_relay::MAX_TX_QUEUE_SIZE)
+
2745 {
+
2746 JLOG(p_journal_.error()) << "doTransactions, invalid number of hashes";
+
2747 fee_.update(Resource::feeMalformedRequest, "too big");
+
2748 return;
+
2749 }
+
2750
+
2751 for (std::uint32_t i = 0; i < packet->objects_size(); ++i)
+
2752 {
+
2753 auto const& obj = packet->objects(i);
+
2754
+
2755 if (!stringIsUint256Sized(obj.hash()))
+
2756 {
+
2757 fee_.update(Resource::feeMalformedRequest, "hash size");
+
2758 return;
+
2759 }
+
2760
+
2761 uint256 hash(obj.hash());
+
2762
+
2763 auto txn = app_.getMasterTransaction().fetch_from_cache(hash);
+
2764
+
2765 if (!txn)
+
2766 {
+
2767 JLOG(p_journal_.error()) << "doTransactions, transaction not found "
+
2768 << Slice(hash.data(), hash.size());
+
2769 fee_.update(Resource::feeMalformedRequest, "tx not found");
+
2770 return;
+
2771 }
+
2772
+
2773 Serializer s;
+
2774 auto tx = reply.add_transactions();
+
2775 auto sttx = txn->getSTransaction();
+
2776 sttx->add(s);
+
2777 tx->set_rawtransaction(s.data(), s.size());
+
2778 tx->set_status(
+
2779 txn->getStatus() == INCLUDED ? protocol::tsCURRENT
+
2780 : protocol::tsNEW);
+
2781 tx->set_receivetimestamp(
+
2782 app_.timeKeeper().now().time_since_epoch().count());
+
2783 tx->set_deferred(txn->getSubmitResult().queued);
+
2784 }
+
2785
+
2786 if (reply.transactions_size() > 0)
+
2787 send(std::make_shared<Message>(reply, protocol::mtTRANSACTIONS));
+
2788}
+
2789
+
2790void
+
2791PeerImp::checkTransaction(
+
2792 int flags,
+
2793 bool checkSignature,
+
2794 std::shared_ptr<STTx const> const& stx,
+
2795 bool batch)
+
2796{
+
2797 // VFALCO TODO Rewrite to not use exceptions
+
2798 try
+
2799 {
+
2800 // Expired?
+
2801 if (stx->isFieldPresent(sfLastLedgerSequence) &&
+
2802 (stx->getFieldU32(sfLastLedgerSequence) <
+
2803 app_.getLedgerMaster().getValidLedgerIndex()))
+
2804 {
+
2805 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
+
2806 charge(Resource::feeUselessData, "expired tx");
+
2807 return;
+
2808 }
+
2809
+
2810 if (isPseudoTx(*stx))
+
2811 {
+
2812 // Don't do anything with pseudo transactions except put them in the
+
2813 // TransactionMaster cache
+
2814 std::string reason;
+
2815 auto tx = std::make_shared<Transaction>(stx, reason, app_);
+
2816 XRPL_ASSERT(
+
2817 tx->getStatus() == NEW,
+
2818 "ripple::PeerImp::checkTransaction Transaction created "
+
2819 "correctly");
+
2820 if (tx->getStatus() == NEW)
+
2821 {
+
2822 JLOG(p_journal_.debug())
+
2823 << "Processing " << (batch ? "batch" : "unsolicited")
+
2824 << " pseudo-transaction tx " << tx->getID();
+
2825
+
2826 app_.getMasterTransaction().canonicalize(&tx);
+
2827 // Tell the overlay about it, but don't relay it.
+
2828 auto const toSkip =
+
2829 app_.getHashRouter().shouldRelay(tx->getID());
+
2830 if (toSkip)
+
2831 {
+
2832 JLOG(p_journal_.debug())
+
2833 << "Passing skipped pseudo pseudo-transaction tx "
+
2834 << tx->getID();
+
2835 app_.overlay().relay(tx->getID(), {}, *toSkip);
+
2836 }
+
2837 if (!batch)
+
2838 {
+
2839 JLOG(p_journal_.debug())
+
2840 << "Charging for pseudo-transaction tx " << tx->getID();
+
2841 charge(Resource::feeUselessData, "pseudo tx");
+
2842 }
+
2843
+
2844 return;
+
2845 }
+
2846 }
+
2847
+
2848 if (checkSignature)
+
2849 {
+
2850 // Check the signature before handing off to the job queue.
+
2851 if (auto [valid, validReason] = checkValidity(
+
2852 app_.getHashRouter(),
+
2853 *stx,
+
2854 app_.getLedgerMaster().getValidatedRules(),
+
2855 app_.config());
+
2856 valid != Validity::Valid)
+
2857 {
+
2858 if (!validReason.empty())
+
2859 {
+
2860 JLOG(p_journal_.trace())
+
2861 << "Exception checking transaction: " << validReason;
+
2862 }
+
2863
+
2864 // Probably not necessary to set SF_BAD, but doesn't hurt.
+
2865 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
+
2866 charge(
+
2867 Resource::feeInvalidSignature,
+
2868 "check transaction signature failure");
+
2869 return;
+
2870 }
+
2871 }
+
2872 else
+
2873 {
+
2874 forceValidity(
+
2875 app_.getHashRouter(), stx->getTransactionID(), Validity::Valid);
+
2876 }
+
2877
+
2878 std::string reason;
+
2879 auto tx = std::make_shared<Transaction>(stx, reason, app_);
+
2880
+
2881 if (tx->getStatus() == INVALID)
+
2882 {
+
2883 if (!reason.empty())
+
2884 {
+
2885 JLOG(p_journal_.trace())
+
2886 << "Exception checking transaction: " << reason;
+
2887 }
+
2888 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
+
2889 charge(Resource::feeInvalidSignature, "tx (impossible)");
+
2890 return;
+
2891 }
+
2892
+
2893 bool const trusted(flags & SF_TRUSTED);
+
2894 app_.getOPs().processTransaction(
+
2895 tx, trusted, false, NetworkOPs::FailHard::no);
+
2896 }
+
2897 catch (std::exception const& ex)
+
2898 {
+
2899 JLOG(p_journal_.warn())
+
2900 << "Exception in " << __func__ << ": " << ex.what();
+
2901 app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
+
2902 using namespace std::string_literals;
+
2903 charge(Resource::feeInvalidData, "tx "s + ex.what());
+
2904 }
+
2905}
+
2906
+
2907// Called from our JobQueue
+
2908void
+
2909PeerImp::checkPropose(
+
2910 bool isTrusted,
+
2911 std::shared_ptr<protocol::TMProposeSet> const& packet,
+
2912 RCLCxPeerPos peerPos)
+
2913{
+
2914 JLOG(p_journal_.trace())
+
2915 << "Checking " << (isTrusted ? "trusted" : "UNTRUSTED") << " proposal";
+
2916
+
2917 XRPL_ASSERT(packet, "ripple::PeerImp::checkPropose : non-null packet");
+
2918
+
2919 if (!cluster() && !peerPos.checkSign())
+
2920 {
+
2921 std::string desc{"Proposal fails sig check"};
+
2922 JLOG(p_journal_.warn()) << desc;
+
2923 charge(Resource::feeInvalidSignature, desc);
+
2924 return;
+
2925 }
+
2926
+
2927 bool relay;
+
2928
+
2929 if (isTrusted)
+
2930 relay = app_.getOPs().processTrustedProposal(peerPos);
+
2931 else
+
2932 relay = app_.config().RELAY_UNTRUSTED_PROPOSALS == 1 || cluster();
+
2933
+
2934 if (relay)
+
2935 {
+
2936 // haveMessage contains peers, which are suppressed; i.e. the peers
+
2937 // are the source of the message, consequently the message should
+
2938 // not be relayed to these peers. But the message must be counted
+
2939 // as part of the squelch logic.
+
2940 auto haveMessage = app_.overlay().relay(
+
2941 *packet, peerPos.suppressionID(), peerPos.publicKey());
+
2942 if (reduceRelayReady() && !haveMessage.empty())
+
2943 overlay_.updateSlotAndSquelch(
+
2944 peerPos.suppressionID(),
+
2945 peerPos.publicKey(),
+
2946 std::move(haveMessage),
+
2947 protocol::mtPROPOSE_LEDGER);
+
2948 }
+
2949}
+
2950
+
2951void
+
2952PeerImp::checkValidation(
+
2953 std::shared_ptr<STValidation> const& val,
+
2954 uint256 const& key,
+
2955 std::shared_ptr<protocol::TMValidation> const& packet)
+
2956{
+
2957 if (!val->isValid())
+
2958 {
+
2959 std::string desc{"Validation forwarded by peer is invalid"};
+
2960 JLOG(p_journal_.debug()) << desc;
+
2961 charge(Resource::feeInvalidSignature, desc);
+
2962 return;
+
2963 }
+
2964
+
2965 // FIXME it should be safe to remove this try/catch. Investigate codepaths.
+
2966 try
+
2967 {
+
2968 if (app_.getOPs().recvValidation(val, std::to_string(id())) ||
+
2969 cluster())
+
2970 {
+
2971 // haveMessage contains peers, which are suppressed; i.e. the peers
+
2972 // are the source of the message, consequently the message should
+
2973 // not be relayed to these peers. But the message must be counted
+
2974 // as part of the squelch logic.
+
2975 auto haveMessage =
+
2976 overlay_.relay(*packet, key, val->getSignerPublic());
+
2977 if (reduceRelayReady() && !haveMessage.empty())
+
2978 {
+
2979 overlay_.updateSlotAndSquelch(
+
2980 key,
+
2981 val->getSignerPublic(),
+
2982 std::move(haveMessage),
+
2983 protocol::mtVALIDATION);
+
2984 }
+
2985 }
+
2986 }
+
2987 catch (std::exception const& ex)
+
2988 {
+
2989 JLOG(p_journal_.trace())
+
2990 << "Exception processing validation: " << ex.what();
+
2991 using namespace std::string_literals;
+
2992 charge(Resource::feeMalformedRequest, "validation "s + ex.what());
+
2993 }
+
2994}
+
2995
+
2996// Returns the set of peers that can help us get
+
2997// the TX tree with the specified root hash.
+
2998//
+
2999static std::shared_ptr<PeerImp>
+
3000getPeerWithTree(OverlayImpl& ov, uint256 const& rootHash, PeerImp const* skip)
+
3001{
+
3002 std::shared_ptr<PeerImp> ret;
+
3003 int retScore = 0;
+
3004
+
3005 ov.for_each([&](std::shared_ptr<PeerImp>&& p) {
+
3006 if (p->hasTxSet(rootHash) && p.get() != skip)
+
3007 {
+
3008 auto score = p->getScore(true);
+
3009 if (!ret || (score > retScore))
+
3010 {
+
3011 ret = std::move(p);
+
3012 retScore = score;
+
3013 }
+
3014 }
+
3015 });
+
3016
+
3017 return ret;
+
3018}
+
3019
+
3020// Returns a random peer weighted by how likely to
+
3021// have the ledger and how responsive it is.
+
3022//
+
3023static std::shared_ptr<PeerImp>
+
3024getPeerWithLedger(
+
3025 OverlayImpl& ov,
+
3026 uint256 const& ledgerHash,
+
3027 LedgerIndex ledger,
+
3028 PeerImp const* skip)
+
3029{
+
3030 std::shared_ptr<PeerImp> ret;
+
3031 int retScore = 0;
+
3032
+
3033 ov.for_each([&](std::shared_ptr<PeerImp>&& p) {
+
3034 if (p->hasLedger(ledgerHash, ledger) && p.get() != skip)
+
3035 {
+
3036 auto score = p->getScore(true);
+
3037 if (!ret || (score > retScore))
+
3038 {
+
3039 ret = std::move(p);
+
3040 retScore = score;
+
3041 }
+
3042 }
+
3043 });
+
3044
+
3045 return ret;
+
3046}
3047
-
3048 auto const& stateMap{ledger->stateMap()};
-
3049 if (stateMap.getHash() != beast::zero)
-
3050 {
-
3051 // Return account state root node if possible
-
3052 Serializer root(768);
-
3053
-
3054 stateMap.serializeRoot(root);
-
3055 ledgerData.add_nodes()->set_nodedata(
-
3056 root.getDataPtr(), root.getLength());
-
3057
-
3058 if (ledger->info().txHash != beast::zero)
-
3059 {
-
3060 auto const& txMap{ledger->txMap()};
-
3061 if (txMap.getHash() != beast::zero)
-
3062 {
-
3063 // Return TX root node if possible
-
3064 root.erase();
-
3065 txMap.serializeRoot(root);
-
3066 ledgerData.add_nodes()->set_nodedata(
-
3067 root.getDataPtr(), root.getLength());
-
3068 }
-
3069 }
-
3070 }
-
3071
-
3072 auto message{
-
3073 std::make_shared<Message>(ledgerData, protocol::mtLEDGER_DATA)};
-
3074 send(message);
-
3075}
-
3076
-
3077std::shared_ptr<Ledger const>
-
3078PeerImp::getLedger(std::shared_ptr<protocol::TMGetLedger> const& m)
-
3079{
-
3080 JLOG(p_journal_.trace()) << "getLedger: Ledger";
-
3081
-
3082 std::shared_ptr<Ledger const> ledger;
-
3083
-
3084 if (m->has_ledgerhash())
-
3085 {
-
3086 // Attempt to find ledger by hash
-
3087 uint256 const ledgerHash{m->ledgerhash()};
-
3088 ledger = app_.getLedgerMaster().getLedgerByHash(ledgerHash);
-
3089 if (!ledger)
-
3090 {
-
3091 JLOG(p_journal_.trace())
-
3092 << "getLedger: Don't have ledger with hash " << ledgerHash;
-
3093
-
3094 if (m->has_querytype() && !m->has_requestcookie())
-
3095 {
-
3096 // Attempt to relay the request to a peer
-
3097 if (auto const peer = getPeerWithLedger(
-
3098 overlay_,
-
3099 ledgerHash,
-
3100 m->has_ledgerseq() ? m->ledgerseq() : 0,
-
3101 this))
-
3102 {
-
3103 m->set_requestcookie(id());
-
3104 peer->send(
-
3105 std::make_shared<Message>(*m, protocol::mtGET_LEDGER));
-
3106 JLOG(p_journal_.debug())
-
3107 << "getLedger: Request relayed to peer";
-
3108 return ledger;
-
3109 }
-
3110
-
3111 JLOG(p_journal_.trace())
-
3112 << "getLedger: Failed to find peer to relay request";
-
3113 }
-
3114 }
-
3115 }
-
3116 else if (m->has_ledgerseq())
-
3117 {
-
3118 // Attempt to find ledger by sequence
-
3119 if (m->ledgerseq() < app_.getLedgerMaster().getEarliestFetch())
-
3120 {
-
3121 JLOG(p_journal_.debug())
-
3122 << "getLedger: Early ledger sequence request";
-
3123 }
-
3124 else
-
3125 {
-
3126 ledger = app_.getLedgerMaster().getLedgerBySeq(m->ledgerseq());
-
3127 if (!ledger)
-
3128 {
-
3129 JLOG(p_journal_.debug())
-
3130 << "getLedger: Don't have ledger with sequence "
-
3131 << m->ledgerseq();
-
3132 }
-
3133 }
-
3134 }
-
3135 else if (m->has_ltype() && m->ltype() == protocol::ltCLOSED)
-
3136 {
-
3137 ledger = app_.getLedgerMaster().getClosedLedger();
-
3138 }
-
3139
-
3140 if (ledger)
-
3141 {
-
3142 // Validate retrieved ledger sequence
-
3143 auto const ledgerSeq{ledger->info().seq};
-
3144 if (m->has_ledgerseq())
-
3145 {
-
3146 if (ledgerSeq != m->ledgerseq())
-
3147 {
-
3148 // Do not resource charge a peer responding to a relay
-
3149 if (!m->has_requestcookie())
-
3150 charge(
-
3151 Resource::feeMalformedRequest, "get_ledger ledgerSeq");
-
3152
-
3153 ledger.reset();
-
3154 JLOG(p_journal_.warn())
-
3155 << "getLedger: Invalid ledger sequence " << ledgerSeq;
-
3156 }
-
3157 }
-
3158 else if (ledgerSeq < app_.getLedgerMaster().getEarliestFetch())
-
3159 {
-
3160 ledger.reset();
-
3161 JLOG(p_journal_.debug())
-
3162 << "getLedger: Early ledger sequence request " << ledgerSeq;
-
3163 }
-
3164 }
-
3165 else
-
3166 {
-
3167 JLOG(p_journal_.debug()) << "getLedger: Unable to find ledger";
-
3168 }
-
3169
-
3170 return ledger;
-
3171}
-
3172
-
3173std::shared_ptr<SHAMap const>
-
3174PeerImp::getTxSet(std::shared_ptr<protocol::TMGetLedger> const& m) const
-
3175{
-
3176 JLOG(p_journal_.trace()) << "getTxSet: TX set";
-
3177
-
3178 uint256 const txSetHash{m->ledgerhash()};
-
3179 std::shared_ptr<SHAMap> shaMap{
-
3180 app_.getInboundTransactions().getSet(txSetHash, false)};
-
3181 if (!shaMap)
-
3182 {
-
3183 if (m->has_querytype() && !m->has_requestcookie())
-
3184 {
-
3185 // Attempt to relay the request to a peer
-
3186 if (auto const peer = getPeerWithTree(overlay_, txSetHash, this))
-
3187 {
-
3188 m->set_requestcookie(id());
-
3189 peer->send(
-
3190 std::make_shared<Message>(*m, protocol::mtGET_LEDGER));
-
3191 JLOG(p_journal_.debug()) << "getTxSet: Request relayed";
-
3192 }
-
3193 else
-
3194 {
-
3195 JLOG(p_journal_.debug())
-
3196 << "getTxSet: Failed to find relay peer";
-
3197 }
-
3198 }
-
3199 else
-
3200 {
-
3201 JLOG(p_journal_.debug()) << "getTxSet: Failed to find TX set";
-
3202 }
-
3203 }
-
3204
-
3205 return shaMap;
-
3206}
-
3207
-
3208void
-
3209PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
-
3210{
-
3211 // Do not resource charge a peer responding to a relay
-
3212 if (!m->has_requestcookie())
-
3213 charge(
-
3214 Resource::feeModerateBurdenPeer, "received a get ledger request");
+
3048void
+
3049PeerImp::sendLedgerBase(
+
3050 std::shared_ptr<Ledger const> const& ledger,
+
3051 protocol::TMLedgerData& ledgerData)
+
3052{
+
3053 JLOG(p_journal_.trace()) << "sendLedgerBase: Base data";
+
3054
+
3055 Serializer s(sizeof(LedgerInfo));
+
3056 addRaw(ledger->info(), s);
+
3057 ledgerData.add_nodes()->set_nodedata(s.getDataPtr(), s.getLength());
+
3058
+
3059 auto const& stateMap{ledger->stateMap()};
+
3060 if (stateMap.getHash() != beast::zero)
+
3061 {
+
3062 // Return account state root node if possible
+
3063 Serializer root(768);
+
3064
+
3065 stateMap.serializeRoot(root);
+
3066 ledgerData.add_nodes()->set_nodedata(
+
3067 root.getDataPtr(), root.getLength());
+
3068
+
3069 if (ledger->info().txHash != beast::zero)
+
3070 {
+
3071 auto const& txMap{ledger->txMap()};
+
3072 if (txMap.getHash() != beast::zero)
+
3073 {
+
3074 // Return TX root node if possible
+
3075 root.erase();
+
3076 txMap.serializeRoot(root);
+
3077 ledgerData.add_nodes()->set_nodedata(
+
3078 root.getDataPtr(), root.getLength());
+
3079 }
+
3080 }
+
3081 }
+
3082
+
3083 auto message{
+
3084 std::make_shared<Message>(ledgerData, protocol::mtLEDGER_DATA)};
+
3085 send(message);
+
3086}
+
3087
+
3088std::shared_ptr<Ledger const>
+
3089PeerImp::getLedger(std::shared_ptr<protocol::TMGetLedger> const& m)
+
3090{
+
3091 JLOG(p_journal_.trace()) << "getLedger: Ledger";
+
3092
+
3093 std::shared_ptr<Ledger const> ledger;
+
3094
+
3095 if (m->has_ledgerhash())
+
3096 {
+
3097 // Attempt to find ledger by hash
+
3098 uint256 const ledgerHash{m->ledgerhash()};
+
3099 ledger = app_.getLedgerMaster().getLedgerByHash(ledgerHash);
+
3100 if (!ledger)
+
3101 {
+
3102 JLOG(p_journal_.trace())
+
3103 << "getLedger: Don't have ledger with hash " << ledgerHash;
+
3104
+
3105 if (m->has_querytype() && !m->has_requestcookie())
+
3106 {
+
3107 // Attempt to relay the request to a peer
+
3108 if (auto const peer = getPeerWithLedger(
+
3109 overlay_,
+
3110 ledgerHash,
+
3111 m->has_ledgerseq() ? m->ledgerseq() : 0,
+
3112 this))
+
3113 {
+
3114 m->set_requestcookie(id());
+
3115 peer->send(
+
3116 std::make_shared<Message>(*m, protocol::mtGET_LEDGER));
+
3117 JLOG(p_journal_.debug())
+
3118 << "getLedger: Request relayed to peer";
+
3119 return ledger;
+
3120 }
+
3121
+
3122 JLOG(p_journal_.trace())
+
3123 << "getLedger: Failed to find peer to relay request";
+
3124 }
+
3125 }
+
3126 }
+
3127 else if (m->has_ledgerseq())
+
3128 {
+
3129 // Attempt to find ledger by sequence
+
3130 if (m->ledgerseq() < app_.getLedgerMaster().getEarliestFetch())
+
3131 {
+
3132 JLOG(p_journal_.debug())
+
3133 << "getLedger: Early ledger sequence request";
+
3134 }
+
3135 else
+
3136 {
+
3137 ledger = app_.getLedgerMaster().getLedgerBySeq(m->ledgerseq());
+
3138 if (!ledger)
+
3139 {
+
3140 JLOG(p_journal_.debug())
+
3141 << "getLedger: Don't have ledger with sequence "
+
3142 << m->ledgerseq();
+
3143 }
+
3144 }
+
3145 }
+
3146 else if (m->has_ltype() && m->ltype() == protocol::ltCLOSED)
+
3147 {
+
3148 ledger = app_.getLedgerMaster().getClosedLedger();
+
3149 }
+
3150
+
3151 if (ledger)
+
3152 {
+
3153 // Validate retrieved ledger sequence
+
3154 auto const ledgerSeq{ledger->info().seq};
+
3155 if (m->has_ledgerseq())
+
3156 {
+
3157 if (ledgerSeq != m->ledgerseq())
+
3158 {
+
3159 // Do not resource charge a peer responding to a relay
+
3160 if (!m->has_requestcookie())
+
3161 charge(
+
3162 Resource::feeMalformedRequest, "get_ledger ledgerSeq");
+
3163
+
3164 ledger.reset();
+
3165 JLOG(p_journal_.warn())
+
3166 << "getLedger: Invalid ledger sequence " << ledgerSeq;
+
3167 }
+
3168 }
+
3169 else if (ledgerSeq < app_.getLedgerMaster().getEarliestFetch())
+
3170 {
+
3171 ledger.reset();
+
3172 JLOG(p_journal_.debug())
+
3173 << "getLedger: Early ledger sequence request " << ledgerSeq;
+
3174 }
+
3175 }
+
3176 else
+
3177 {
+
3178 JLOG(p_journal_.debug()) << "getLedger: Unable to find ledger";
+
3179 }
+
3180
+
3181 return ledger;
+
3182}
+
3183
+
3184std::shared_ptr<SHAMap const>
+
3185PeerImp::getTxSet(std::shared_ptr<protocol::TMGetLedger> const& m) const
+
3186{
+
3187 JLOG(p_journal_.trace()) << "getTxSet: TX set";
+
3188
+
3189 uint256 const txSetHash{m->ledgerhash()};
+
3190 std::shared_ptr<SHAMap> shaMap{
+
3191 app_.getInboundTransactions().getSet(txSetHash, false)};
+
3192 if (!shaMap)
+
3193 {
+
3194 if (m->has_querytype() && !m->has_requestcookie())
+
3195 {
+
3196 // Attempt to relay the request to a peer
+
3197 if (auto const peer = getPeerWithTree(overlay_, txSetHash, this))
+
3198 {
+
3199 m->set_requestcookie(id());
+
3200 peer->send(
+
3201 std::make_shared<Message>(*m, protocol::mtGET_LEDGER));
+
3202 JLOG(p_journal_.debug()) << "getTxSet: Request relayed";
+
3203 }
+
3204 else
+
3205 {
+
3206 JLOG(p_journal_.debug())
+
3207 << "getTxSet: Failed to find relay peer";
+
3208 }
+
3209 }
+
3210 else
+
3211 {
+
3212 JLOG(p_journal_.debug()) << "getTxSet: Failed to find TX set";
+
3213 }
+
3214 }
3215
-
3216 std::shared_ptr<Ledger const> ledger;
-
3217 std::shared_ptr<SHAMap const> sharedMap;
-
3218 SHAMap const* map{nullptr};
-
3219 protocol::TMLedgerData ledgerData;
-
3220 bool fatLeaves{true};
-
3221 auto const itype{m->itype()};
-
3222
-
3223 if (itype == protocol::liTS_CANDIDATE)
-
3224 {
-
3225 if (sharedMap = getTxSet(m); !sharedMap)
-
3226 return;
-
3227 map = sharedMap.get();
-
3228
-
3229 // Fill out the reply
-
3230 ledgerData.set_ledgerseq(0);
-
3231 ledgerData.set_ledgerhash(m->ledgerhash());
-
3232 ledgerData.set_type(protocol::liTS_CANDIDATE);
-
3233 if (m->has_requestcookie())
-
3234 ledgerData.set_requestcookie(m->requestcookie());
-
3235
-
3236 // We'll already have most transactions
-
3237 fatLeaves = false;
-
3238 }
-
3239 else
-
3240 {
-
3241 if (send_queue_.size() >= Tuning::dropSendQueue)
-
3242 {
-
3243 JLOG(p_journal_.debug())
-
3244 << "processLedgerRequest: Large send queue";
-
3245 return;
-
3246 }
-
3247 if (app_.getFeeTrack().isLoadedLocal() && !cluster())
-
3248 {
-
3249 JLOG(p_journal_.debug()) << "processLedgerRequest: Too busy";
-
3250 return;
-
3251 }
-
3252
-
3253 if (ledger = getLedger(m); !ledger)
-
3254 return;
-
3255
-
3256 // Fill out the reply
-
3257 auto const ledgerHash{ledger->info().hash};
-
3258 ledgerData.set_ledgerhash(ledgerHash.begin(), ledgerHash.size());
-
3259 ledgerData.set_ledgerseq(ledger->info().seq);
-
3260 ledgerData.set_type(itype);
-
3261 if (m->has_requestcookie())
-
3262 ledgerData.set_requestcookie(m->requestcookie());
+
3216 return shaMap;
+
3217}
+
3218
+
3219void
+
3220PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
+
3221{
+
3222 // Do not resource charge a peer responding to a relay
+
3223 if (!m->has_requestcookie())
+
3224 charge(
+
3225 Resource::feeModerateBurdenPeer, "received a get ledger request");
+
3226
+
3227 std::shared_ptr<Ledger const> ledger;
+
3228 std::shared_ptr<SHAMap const> sharedMap;
+
3229 SHAMap const* map{nullptr};
+
3230 protocol::TMLedgerData ledgerData;
+
3231 bool fatLeaves{true};
+
3232 auto const itype{m->itype()};
+
3233
+
3234 if (itype == protocol::liTS_CANDIDATE)
+
3235 {
+
3236 if (sharedMap = getTxSet(m); !sharedMap)
+
3237 return;
+
3238 map = sharedMap.get();
+
3239
+
3240 // Fill out the reply
+
3241 ledgerData.set_ledgerseq(0);
+
3242 ledgerData.set_ledgerhash(m->ledgerhash());
+
3243 ledgerData.set_type(protocol::liTS_CANDIDATE);
+
3244 if (m->has_requestcookie())
+
3245 ledgerData.set_requestcookie(m->requestcookie());
+
3246
+
3247 // We'll already have most transactions
+
3248 fatLeaves = false;
+
3249 }
+
3250 else
+
3251 {
+
3252 if (send_queue_.size() >= Tuning::dropSendQueue)
+
3253 {
+
3254 JLOG(p_journal_.debug())
+
3255 << "processLedgerRequest: Large send queue";
+
3256 return;
+
3257 }
+
3258 if (app_.getFeeTrack().isLoadedLocal() && !cluster())
+
3259 {
+
3260 JLOG(p_journal_.debug()) << "processLedgerRequest: Too busy";
+
3261 return;
+
3262 }
3263
-
3264 switch (itype)
-
3265 {
-
3266 case protocol::liBASE:
-
3267 sendLedgerBase(ledger, ledgerData);
-
3268 return;
-
3269
-
3270 case protocol::liTX_NODE:
-
3271 map = &ledger->txMap();
-
3272 JLOG(p_journal_.trace()) << "processLedgerRequest: TX map hash "
-
3273 << to_string(map->getHash());
-
3274 break;
-
3275
-
3276 case protocol::liAS_NODE:
-
3277 map = &ledger->stateMap();
-
3278 JLOG(p_journal_.trace())
-
3279 << "processLedgerRequest: Account state map hash "
-
3280 << to_string(map->getHash());
-
3281 break;
-
3282
-
3283 default:
-
3284 // This case should not be possible here
-
3285 JLOG(p_journal_.error())
-
3286 << "processLedgerRequest: Invalid ledger info type";
-
3287 return;
-
3288 }
-
3289 }
-
3290
-
3291 if (!map)
-
3292 {
-
3293 JLOG(p_journal_.warn()) << "processLedgerRequest: Unable to find map";
-
3294 return;
-
3295 }
-
3296
-
3297 // Add requested node data to reply
-
3298 if (m->nodeids_size() > 0)
-
3299 {
-
3300 auto const queryDepth{
-
3301 m->has_querydepth() ? m->querydepth() : (isHighLatency() ? 2 : 1)};
-
3302
-
3303 std::vector<std::pair<SHAMapNodeID, Blob>> data;
-
3304
-
3305 for (int i = 0; i < m->nodeids_size() &&
-
3306 ledgerData.nodes_size() < Tuning::softMaxReplyNodes;
-
3307 ++i)
-
3308 {
-
3309 auto const shaMapNodeId{deserializeSHAMapNodeID(m->nodeids(i))};
-
3310
-
3311 data.clear();
-
3312 data.reserve(Tuning::softMaxReplyNodes);
+
3264 if (ledger = getLedger(m); !ledger)
+
3265 return;
+
3266
+
3267 // Fill out the reply
+
3268 auto const ledgerHash{ledger->info().hash};
+
3269 ledgerData.set_ledgerhash(ledgerHash.begin(), ledgerHash.size());
+
3270 ledgerData.set_ledgerseq(ledger->info().seq);
+
3271 ledgerData.set_type(itype);
+
3272 if (m->has_requestcookie())
+
3273 ledgerData.set_requestcookie(m->requestcookie());
+
3274
+
3275 switch (itype)
+
3276 {
+
3277 case protocol::liBASE:
+
3278 sendLedgerBase(ledger, ledgerData);
+
3279 return;
+
3280
+
3281 case protocol::liTX_NODE:
+
3282 map = &ledger->txMap();
+
3283 JLOG(p_journal_.trace()) << "processLedgerRequest: TX map hash "
+
3284 << to_string(map->getHash());
+
3285 break;
+
3286
+
3287 case protocol::liAS_NODE:
+
3288 map = &ledger->stateMap();
+
3289 JLOG(p_journal_.trace())
+
3290 << "processLedgerRequest: Account state map hash "
+
3291 << to_string(map->getHash());
+
3292 break;
+
3293
+
3294 default:
+
3295 // This case should not be possible here
+
3296 JLOG(p_journal_.error())
+
3297 << "processLedgerRequest: Invalid ledger info type";
+
3298 return;
+
3299 }
+
3300 }
+
3301
+
3302 if (!map)
+
3303 {
+
3304 JLOG(p_journal_.warn()) << "processLedgerRequest: Unable to find map";
+
3305 return;
+
3306 }
+
3307
+
3308 // Add requested node data to reply
+
3309 if (m->nodeids_size() > 0)
+
3310 {
+
3311 auto const queryDepth{
+
3312 m->has_querydepth() ? m->querydepth() : (isHighLatency() ? 2 : 1)};
3313
-
3314 try
-
3315 {
-
3316 if (map->getNodeFat(*shaMapNodeId, data, fatLeaves, queryDepth))
-
3317 {
-
3318 JLOG(p_journal_.trace())
-
3319 << "processLedgerRequest: getNodeFat got "
-
3320 << data.size() << " nodes";
+
3314 std::vector<std::pair<SHAMapNodeID, Blob>> data;
+
3315
+
3316 for (int i = 0; i < m->nodeids_size() &&
+
3317 ledgerData.nodes_size() < Tuning::softMaxReplyNodes;
+
3318 ++i)
+
3319 {
+
3320 auto const shaMapNodeId{deserializeSHAMapNodeID(m->nodeids(i))};
3321
-
3322 for (auto const& d : data)
-
3323 {
-
3324 if (ledgerData.nodes_size() >=
-
3325 Tuning::hardMaxReplyNodes)
-
3326 break;
-
3327 protocol::TMLedgerNode* node{ledgerData.add_nodes()};
-
3328 node->set_nodeid(d.first.getRawString());
-
3329 node->set_nodedata(d.second.data(), d.second.size());
-
3330 }
-
3331 }
-
3332 else
-
3333 {
-
3334 JLOG(p_journal_.warn())
-
3335 << "processLedgerRequest: getNodeFat returns false";
-
3336 }
-
3337 }
-
3338 catch (std::exception const& e)
-
3339 {
-
3340 std::string info;
-
3341 switch (itype)
-
3342 {
-
3343 case protocol::liBASE:
-
3344 // This case should not be possible here
-
3345 info = "Ledger base";
-
3346 break;
-
3347
-
3348 case protocol::liTX_NODE:
-
3349 info = "TX node";
-
3350 break;
-
3351
-
3352 case protocol::liAS_NODE:
-
3353 info = "AS node";
-
3354 break;
-
3355
-
3356 case protocol::liTS_CANDIDATE:
-
3357 info = "TS candidate";
-
3358 break;
-
3359
-
3360 default:
-
3361 info = "Invalid";
-
3362 break;
-
3363 }
-
3364
-
3365 if (!m->has_ledgerhash())
-
3366 info += ", no hash specified";
-
3367
-
3368 JLOG(p_journal_.error())
-
3369 << "processLedgerRequest: getNodeFat with nodeId "
-
3370 << *shaMapNodeId << " and ledger info type " << info
-
3371 << " throws exception: " << e.what();
-
3372 }
-
3373 }
-
3374
-
3375 JLOG(p_journal_.info())
-
3376 << "processLedgerRequest: Got request for " << m->nodeids_size()
-
3377 << " nodes at depth " << queryDepth << ", return "
-
3378 << ledgerData.nodes_size() << " nodes";
-
3379 }
-
3380
-
3381 if (ledgerData.nodes_size() == 0)
-
3382 return;
-
3383
-
3384 send(std::make_shared<Message>(ledgerData, protocol::mtLEDGER_DATA));
-
3385}
-
3386
-
3387int
-
3388PeerImp::getScore(bool haveItem) const
-
3389{
-
3390 // Random component of score, used to break ties and avoid
-
3391 // overloading the "best" peer
-
3392 static const int spRandomMax = 9999;
-
3393
-
3394 // Score for being very likely to have the thing we are
-
3395 // look for; should be roughly spRandomMax
-
3396 static const int spHaveItem = 10000;
+
3322 data.clear();
+
3323 data.reserve(Tuning::softMaxReplyNodes);
+
3324
+
3325 try
+
3326 {
+
3327 if (map->getNodeFat(*shaMapNodeId, data, fatLeaves, queryDepth))
+
3328 {
+
3329 JLOG(p_journal_.trace())
+
3330 << "processLedgerRequest: getNodeFat got "
+
3331 << data.size() << " nodes";
+
3332
+
3333 for (auto const& d : data)
+
3334 {
+
3335 if (ledgerData.nodes_size() >=
+
3336 Tuning::hardMaxReplyNodes)
+
3337 break;
+
3338 protocol::TMLedgerNode* node{ledgerData.add_nodes()};
+
3339 node->set_nodeid(d.first.getRawString());
+
3340 node->set_nodedata(d.second.data(), d.second.size());
+
3341 }
+
3342 }
+
3343 else
+
3344 {
+
3345 JLOG(p_journal_.warn())
+
3346 << "processLedgerRequest: getNodeFat returns false";
+
3347 }
+
3348 }
+
3349 catch (std::exception const& e)
+
3350 {
+
3351 std::string info;
+
3352 switch (itype)
+
3353 {
+
3354 case protocol::liBASE:
+
3355 // This case should not be possible here
+
3356 info = "Ledger base";
+
3357 break;
+
3358
+
3359 case protocol::liTX_NODE:
+
3360 info = "TX node";
+
3361 break;
+
3362
+
3363 case protocol::liAS_NODE:
+
3364 info = "AS node";
+
3365 break;
+
3366
+
3367 case protocol::liTS_CANDIDATE:
+
3368 info = "TS candidate";
+
3369 break;
+
3370
+
3371 default:
+
3372 info = "Invalid";
+
3373 break;
+
3374 }
+
3375
+
3376 if (!m->has_ledgerhash())
+
3377 info += ", no hash specified";
+
3378
+
3379 JLOG(p_journal_.error())
+
3380 << "processLedgerRequest: getNodeFat with nodeId "
+
3381 << *shaMapNodeId << " and ledger info type " << info
+
3382 << " throws exception: " << e.what();
+
3383 }
+
3384 }
+
3385
+
3386 JLOG(p_journal_.info())
+
3387 << "processLedgerRequest: Got request for " << m->nodeids_size()
+
3388 << " nodes at depth " << queryDepth << ", return "
+
3389 << ledgerData.nodes_size() << " nodes";
+
3390 }
+
3391
+
3392 if (ledgerData.nodes_size() == 0)
+
3393 return;
+
3394
+
3395 send(std::make_shared<Message>(ledgerData, protocol::mtLEDGER_DATA));
+
3396}
3397
-
3398 // Score reduction for each millisecond of latency; should
-
3399 // be roughly spRandomMax divided by the maximum reasonable
-
3400 // latency
-
3401 static const int spLatency = 30;
-
3402
-
3403 // Penalty for unknown latency; should be roughly spRandomMax
-
3404 static const int spNoLatency = 8000;
-
3405
-
3406 int score = rand_int(spRandomMax);
-
3407
-
3408 if (haveItem)
-
3409 score += spHaveItem;
-
3410
-
3411 std::optional<std::chrono::milliseconds> latency;
-
3412 {
-
3413 std::lock_guard sl(recentLock_);
-
3414 latency = latency_;
-
3415 }
+
3398int
+
3399PeerImp::getScore(bool haveItem) const
+
3400{
+
3401 // Random component of score, used to break ties and avoid
+
3402 // overloading the "best" peer
+
3403 static const int spRandomMax = 9999;
+
3404
+
3405 // Score for being very likely to have the thing we are
+
3406 // look for; should be roughly spRandomMax
+
3407 static const int spHaveItem = 10000;
+
3408
+
3409 // Score reduction for each millisecond of latency; should
+
3410 // be roughly spRandomMax divided by the maximum reasonable
+
3411 // latency
+
3412 static const int spLatency = 30;
+
3413
+
3414 // Penalty for unknown latency; should be roughly spRandomMax
+
3415 static const int spNoLatency = 8000;
3416
-
3417 if (latency)
-
3418 score -= latency->count() * spLatency;
-
3419 else
-
3420 score -= spNoLatency;
+
3417 int score = rand_int(spRandomMax);
+
3418
+
3419 if (haveItem)
+
3420 score += spHaveItem;
3421
-
3422 return score;
-
3423}
-
3424
-
3425bool
-
3426PeerImp::isHighLatency() const
-
3427{
-
3428 std::lock_guard sl(recentLock_);
-
3429 return latency_ >= peerHighLatency;
-
3430}
-
3431
-
3432bool
-
3433PeerImp::reduceRelayReady()
-
3434{
-
3435 if (!reduceRelayReady_)
-
3436 reduceRelayReady_ =
-
3437 reduce_relay::epoch<std::chrono::minutes>(UptimeClock::now()) >
-
3438 reduce_relay::WAIT_ON_BOOTUP;
-
3439 return vpReduceRelayEnabled_ && reduceRelayReady_;
-
3440}
-
3441
-
3442void
-
3443PeerImp::Metrics::add_message(std::uint64_t bytes)
-
3444{
-
3445 using namespace std::chrono_literals;
-
3446 std::unique_lock lock{mutex_};
-
3447
-
3448 totalBytes_ += bytes;
-
3449 accumBytes_ += bytes;
-
3450 auto const timeElapsed = clock_type::now() - intervalStart_;
-
3451 auto const timeElapsedInSecs =
-
3452 std::chrono::duration_cast<std::chrono::seconds>(timeElapsed);
-
3453
-
3454 if (timeElapsedInSecs >= 1s)
-
3455 {
-
3456 auto const avgBytes = accumBytes_ / timeElapsedInSecs.count();
-
3457 rollingAvg_.push_back(avgBytes);
+
3422 std::optional<std::chrono::milliseconds> latency;
+
3423 {
+
3424 std::lock_guard sl(recentLock_);
+
3425 latency = latency_;
+
3426 }
+
3427
+
3428 if (latency)
+
3429 score -= latency->count() * spLatency;
+
3430 else
+
3431 score -= spNoLatency;
+
3432
+
3433 return score;
+
3434}
+
3435
+
3436bool
+
3437PeerImp::isHighLatency() const
+
3438{
+
3439 std::lock_guard sl(recentLock_);
+
3440 return latency_ >= peerHighLatency;
+
3441}
+
3442
+
3443bool
+
3444PeerImp::reduceRelayReady()
+
3445{
+
3446 if (!reduceRelayReady_)
+
3447 reduceRelayReady_ =
+
3448 reduce_relay::epoch<std::chrono::minutes>(UptimeClock::now()) >
+
3449 reduce_relay::WAIT_ON_BOOTUP;
+
3450 return vpReduceRelayEnabled_ && reduceRelayReady_;
+
3451}
+
3452
+
3453void
+
3454PeerImp::Metrics::add_message(std::uint64_t bytes)
+
3455{
+
3456 using namespace std::chrono_literals;
+
3457 std::unique_lock lock{mutex_};
3458
-
3459 auto const totalBytes =
-
3460 std::accumulate(rollingAvg_.begin(), rollingAvg_.end(), 0ull);
-
3461 rollingAvgBytes_ = totalBytes / rollingAvg_.size();
-
3462
-
3463 intervalStart_ = clock_type::now();
-
3464 accumBytes_ = 0;
-
3465 }
-
3466}
-
3467
-
3468std::uint64_t
-
3469PeerImp::Metrics::average_bytes() const
-
3470{
-
3471 std::shared_lock lock{mutex_};
-
3472 return rollingAvgBytes_;
-
3473}
-
3474
-
3475std::uint64_t
-
3476PeerImp::Metrics::total_bytes() const
-
3477{
-
3478 std::shared_lock lock{mutex_};
-
3479 return totalBytes_;
-
3480}
-
3481
-
3482} // namespace ripple
+
3459 totalBytes_ += bytes;
+
3460 accumBytes_ += bytes;
+
3461 auto const timeElapsed = clock_type::now() - intervalStart_;
+
3462 auto const timeElapsedInSecs =
+
3463 std::chrono::duration_cast<std::chrono::seconds>(timeElapsed);
+
3464
+
3465 if (timeElapsedInSecs >= 1s)
+
3466 {
+
3467 auto const avgBytes = accumBytes_ / timeElapsedInSecs.count();
+
3468 rollingAvg_.push_back(avgBytes);
+
3469
+
3470 auto const totalBytes =
+
3471 std::accumulate(rollingAvg_.begin(), rollingAvg_.end(), 0ull);
+
3472 rollingAvgBytes_ = totalBytes / rollingAvg_.size();
+
3473
+
3474 intervalStart_ = clock_type::now();
+
3475 accumBytes_ = 0;
+
3476 }
+
3477}
+
3478
+
3479std::uint64_t
+
3480PeerImp::Metrics::average_bytes() const
+
3481{
+
3482 std::shared_lock lock{mutex_};
+
3483 return rollingAvgBytes_;
+
3484}
+
3485
+
3486std::uint64_t
+
3487PeerImp::Metrics::total_bytes() const
+
3488{
+
3489 std::shared_lock lock{mutex_};
+
3490 return totalBytes_;
+
3491}
+
3492
+
3493} // namespace ripple
T accumulate(T... args)
@@ -3630,16 +3641,16 @@ $(function() {
bool vpReduceRelayEnabled_
Definition: PeerImp.h:194
std::unique_ptr< LoadEvent > load_event_
Definition: PeerImp.h:179
boost::beast::http::fields const & headers_
Definition: PeerImp.h:175
-
void onMessageEnd(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m)
Definition: PeerImp.cpp:1043
-
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
Definition: PeerImp.cpp:517
+
void onMessageEnd(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m)
Definition: PeerImp.cpp:1040
+
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
Definition: PeerImp.cpp:514
clock_type::duration uptime() const
Definition: PeerImp.h:366
-
void removeTxQueue(uint256 const &hash) override
Remove transaction's hash from the transactions' hashes queue.
Definition: PeerImp.cpp:333
+
void removeTxQueue(uint256 const &hash) override
Remove transaction's hash from the transactions' hashes queue.
Definition: PeerImp.cpp:330
protocol::TMStatusChange last_status_
Definition: PeerImp.h:168
boost::shared_mutex nameMutex_
Definition: PeerImp.h:101
std::string name_
Definition: PeerImp.h:100
boost::circular_buffer< uint256 > recentTxSets_
Definition: PeerImp.h:111
std::unique_ptr< stream_type > stream_ptr_
Definition: PeerImp.h:77
-
void onMessage(std::shared_ptr< protocol::TMManifests > const &m)
Definition: PeerImp.cpp:1052
+
void onMessage(std::shared_ptr< protocol::TMManifests > const &m)
Definition: PeerImp.cpp:1049
bool detaching_
Definition: PeerImp.h:97
Tracking
Whether the peer's view of the ledger converges or diverges from ours.
Definition: PeerImp.h:57
@ converged
@@ -3647,77 +3658,77 @@ $(function() {
@ diverged
Compressed compressionEnabled_
Definition: PeerImp.h:184
uint256 closedLedgerHash_
Definition: PeerImp.h:107
-
std::string domain() const
Definition: PeerImp.cpp:835
+
std::string domain() const
Definition: PeerImp.cpp:832
std::optional< std::uint32_t > lastPingSeq_
Definition: PeerImp.h:114
-
void onTimer(boost::system::error_code const &ec)
Definition: PeerImp.cpp:683
+
void onTimer(boost::system::error_code const &ec)
Definition: PeerImp.cpp:680
bool gracefulClose_
Definition: PeerImp.h:177
beast::Journal const journal_
Definition: PeerImp.h:75
-
virtual void run()
Definition: PeerImp.cpp:159
-
void gracefulClose()
Definition: PeerImp.cpp:627
+
virtual void run()
Definition: PeerImp.cpp:156
+
void gracefulClose()
Definition: PeerImp.cpp:624
LedgerIndex maxLedger_
Definition: PeerImp.h:106
beast::Journal const p_journal_
Definition: PeerImp.h:76
-
void cancelTimer()
Definition: PeerImp.cpp:666
+
void cancelTimer()
Definition: PeerImp.cpp:663
bool const inbound_
Definition: PeerImp.h:90
PeerImp(PeerImp const &)=delete
Application & app_
Definition: PeerImp.h:71
-
void stop() override
Definition: PeerImp.cpp:217
-
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
Definition: PeerImp.cpp:559
-
bool hasTxSet(uint256 const &hash) const override
Definition: PeerImp.cpp:541
+
void stop() override
Definition: PeerImp.cpp:214
+
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
Definition: PeerImp.cpp:556
+
bool hasTxSet(uint256 const &hash) const override
Definition: PeerImp.cpp:538
clock_type::time_point lastPingTime_
Definition: PeerImp.h:115
-
void onMessageUnknown(std::uint16_t type)
Definition: PeerImp.cpp:1003
+
void onMessageUnknown(std::uint16_t type)
Definition: PeerImp.cpp:1000
std::shared_ptr< PeerFinder::Slot > const slot_
Definition: PeerImp.h:171
boost::circular_buffer< uint256 > recentLedgers_
Definition: PeerImp.h:110
id_t const id_
Definition: PeerImp.h:72
std::optional< std::chrono::milliseconds > latency_
Definition: PeerImp.h:113
-
void handleTransaction(std::shared_ptr< protocol::TMTransaction > const &m, bool eraseTxQueue, bool batch)
Called from onMessage(TMTransaction(s)).
Definition: PeerImp.cpp:1234
+
void handleTransaction(std::shared_ptr< protocol::TMTransaction > const &m, bool eraseTxQueue, bool batch)
Called from onMessage(TMTransaction(s)).
Definition: PeerImp.cpp:1241
beast::IP::Endpoint const remote_address_
Definition: PeerImp.h:85
-
Json::Value json() override
Definition: PeerImp.cpp:382
+
Json::Value json() override
Definition: PeerImp.cpp:379
PublicKey const publicKey_
Definition: PeerImp.h:99
-
void close()
Definition: PeerImp.cpp:569
+
void close()
Definition: PeerImp.cpp:566
hash_set< uint256 > txQueue_
Definition: PeerImp.h:189
std::mutex recentLock_
Definition: PeerImp.h:167
-
void doAccept()
Definition: PeerImp.cpp:760
-
void onMessageBegin(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m, std::size_t size, std::size_t uncompressed_size, bool isCompressed)
Definition: PeerImp.cpp:1009
+
void doAccept()
Definition: PeerImp.cpp:757
+
void onMessageBegin(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m, std::size_t size, std::size_t uncompressed_size, bool isCompressed)
Definition: PeerImp.cpp:1006
bool txReduceRelayEnabled_
Definition: PeerImp.h:191
clock_type::time_point trackingTime_
Definition: PeerImp.h:96
socket_type & socket_
Definition: PeerImp.h:78
ProtocolVersion protocol_
Definition: PeerImp.h:93
reduce_relay::Squelch< UptimeClock > squelch_
Definition: PeerImp.h:118
-
std::string getVersion() const
Return the version of rippled that the peer is running, if reported.
Definition: PeerImp.cpp:374
+
std::string getVersion() const
Return the version of rippled that the peer is running, if reported.
Definition: PeerImp.cpp:371
struct ripple::PeerImp::@22 metrics_
uint256 previousLedgerHash_
Definition: PeerImp.h:108
-
void charge(Resource::Charge const &fee, std::string const &context) override
Adjust this peer's load balance based on the type of load imposed.
Definition: PeerImp.cpp:345
-
void setTimer()
Definition: PeerImp.cpp:648
-
void send(std::shared_ptr< Message > const &m) override
Definition: PeerImp.cpp:243
-
static std::string makePrefix(id_t id)
Definition: PeerImp.cpp:675
-
std::string name() const
Definition: PeerImp.cpp:828
+
void charge(Resource::Charge const &fee, std::string const &context) override
Adjust this peer's load balance based on the type of load imposed.
Definition: PeerImp.cpp:342
+
void setTimer()
Definition: PeerImp.cpp:645
+
void send(std::shared_ptr< Message > const &m) override
Definition: PeerImp.cpp:240
+
static std::string makePrefix(id_t id)
Definition: PeerImp.cpp:672
+
std::string name() const
Definition: PeerImp.cpp:825
boost::system::error_code error_code
Definition: PeerImp.h:61
-
void onReadMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:883
+
void onReadMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:880
bool ledgerReplayEnabled_
Definition: PeerImp.h:195
boost::asio::basic_waitable_timer< std::chrono::steady_clock > waitable_timer
Definition: PeerImp.h:68
-
bool crawl() const
Returns true if this connection will publicly share its IP address.
Definition: PeerImp.cpp:359
+
bool crawl() const
Returns true if this connection will publicly share its IP address.
Definition: PeerImp.cpp:356
waitable_timer timer_
Definition: PeerImp.h:81
-
void sendTxQueue() override
Send aggregated transactions' hashes.
Definition: PeerImp.cpp:297
+
void sendTxQueue() override
Send aggregated transactions' hashes.
Definition: PeerImp.cpp:294
bool txReduceRelayEnabled() const override
Definition: PeerImp.h:439
-
bool supportsFeature(ProtocolFeature f) const override
Definition: PeerImp.cpp:500
+
bool supportsFeature(ProtocolFeature f) const override
Definition: PeerImp.cpp:497
ChargeWithContext fee_
Definition: PeerImp.h:170
-
void onWriteMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:947
+
void onWriteMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:944
http_request_type request_
Definition: PeerImp.h:173
OverlayImpl & overlay_
Definition: PeerImp.h:89
LedgerIndex minLedger_
Definition: PeerImp.h:105
-
virtual ~PeerImp()
Definition: PeerImp.cpp:136
-
void addTxQueue(uint256 const &hash) override
Add transaction's hash to the transactions' hashes queue.
Definition: PeerImp.cpp:316
+
virtual ~PeerImp()
Definition: PeerImp.cpp:133
+
void addTxQueue(uint256 const &hash) override
Add transaction's hash to the transactions' hashes queue.
Definition: PeerImp.cpp:313
int large_sendq_
Definition: PeerImp.h:178
stream_type & stream_
Definition: PeerImp.h:79
-
bool cluster() const override
Returns true if this connection is a member of the cluster.
Definition: PeerImp.cpp:368
-
void onShutdown(error_code ec)
Definition: PeerImp.cpp:744
+
bool cluster() const override
Returns true if this connection is a member of the cluster.
Definition: PeerImp.cpp:365
+
void onShutdown(error_code ec)
Definition: PeerImp.cpp:741
boost::asio::strand< boost::asio::executor > strand_
Definition: PeerImp.h:80
-
void cycleStatus() override
Definition: PeerImp.cpp:549
+
void cycleStatus() override
Definition: PeerImp.cpp:546
boost::beast::multi_buffer read_buffer_
Definition: PeerImp.h:172
Resource::Consumer usage_
Definition: PeerImp.h:169
-
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
Definition: PeerImp.cpp:532
-
void doProtocolStart()
Definition: PeerImp.cpp:845
-
void fail(std::string const &reason)
Definition: PeerImp.cpp:593
+
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
Definition: PeerImp.cpp:529
+
void doProtocolStart()
Definition: PeerImp.cpp:842
+
void fail(std::string const &reason)
Definition: PeerImp.cpp:590
std::atomic< Tracking > tracking_
Definition: PeerImp.h:95
Represents a peer connection in the overlay.
A public key.
Definition: PublicKey.h:62
@@ -3808,20 +3819,20 @@ $(function() {
std::string base64_decode(std::string_view data)
Definition: base64.cpp:245
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,...
Definition: BasicConfig.h:316
http_response_type makeResponse(bool crawlPublic, http_request_type const &req, beast::IP::Address public_ip, beast::IP::Address remote_ip, uint256 const &sharedValue, std::optional< std::uint32_t > networkID, ProtocolVersion protocol, Application &app)
Make http response.
Definition: Handshake.cpp:389
-
static bool stringIsUint256Sized(std::string const &pBuffStr)
Definition: PeerImp.cpp:153
+
static bool stringIsUint256Sized(std::string const &pBuffStr)
Definition: PeerImp.cpp:150
static constexpr char FEATURE_LEDGER_REPLAY[]
Definition: Handshake.h:148
std::pair< std::size_t, boost::system::error_code > invokeProtocolMessage(Buffers const &buffers, Handler &handler, std::size_t &hint)
Calls the handler for up to one protocol message in the passed buffers.
std::optional< uint256 > makeSharedValue(stream_type &ssl, beast::Journal journal)
Computes a shared value based on the SSL connection state.
Definition: Handshake.cpp:143
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
std::enable_if_t< std::is_integral< Integral >::value &&detail::is_engine< Engine >::value, Integral > rand_int(Engine &engine, Integral min, Integral max)
Return a uniformly distributed random integer.
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
-
static std::shared_ptr< PeerImp > getPeerWithLedger(OverlayImpl &ov, uint256 const &ledgerHash, LedgerIndex ledger, PeerImp const *skip)
Definition: PeerImp.cpp:3013
+
static std::shared_ptr< PeerImp > getPeerWithLedger(OverlayImpl &ov, uint256 const &ledgerHash, LedgerIndex ledger, PeerImp const *skip)
Definition: PeerImp.cpp:3024
@ unknown
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:243
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition: chrono.h:120
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition: Handoff.h:31
NodeID calcNodeID(PublicKey const &)
Calculate the 160-bit node ID from a node public key.
Definition: PublicKey.cpp:303
-
static std::shared_ptr< PeerImp > getPeerWithTree(OverlayImpl &ov, uint256 const &rootHash, PeerImp const *skip)
Definition: PeerImp.cpp:2989
+
static std::shared_ptr< PeerImp > getPeerWithTree(OverlayImpl &ov, uint256 const &rootHash, PeerImp const *skip)
Definition: PeerImp.cpp:3000
bool peerFeatureEnabled(headers const &request, std::string const &feature, std::string value, bool config)
Check if a feature should be enabled for a peer.
Definition: Handshake.h:199
void forceValidity(HashRouter &router, uint256 const &txid, Validity validity)
Sets the validity of a given transaction in the cache.
Definition: apply.cpp:89
static constexpr char FEATURE_TXRR[]
Definition: Handshake.h:146
diff --git a/PeerImp_8h_source.html b/PeerImp_8h_source.html index f23a5195d9..5f069f347a 100644 --- a/PeerImp_8h_source.html +++ b/PeerImp_8h_source.html @@ -803,11 +803,11 @@ $(function() {
std::uint64_t accumBytes_
Definition: PeerImp.h:223
Metrics & operator=(Metrics const &)=delete
Metrics(Metrics &&)=delete
-
std::uint64_t total_bytes() const
Definition: PeerImp.cpp:3476
+
std::uint64_t total_bytes() const
Definition: PeerImp.cpp:3487
std::uint64_t totalBytes_
Definition: PeerImp.h:222
Metrics & operator=(Metrics &&)=delete
-
std::uint64_t average_bytes() const
Definition: PeerImp.cpp:3469
-
void add_message(std::uint64_t bytes)
Definition: PeerImp.cpp:3443
+
std::uint64_t average_bytes() const
Definition: PeerImp.cpp:3480
+
void add_message(std::uint64_t bytes)
Definition: PeerImp.cpp:3454
Metrics(Metrics const &)=delete
boost::shared_mutex mutex_
Definition: PeerImp.h:219
Metrics()=default
@@ -820,19 +820,19 @@ $(function() {
PeerImp & operator=(PeerImp const &)=delete
std::unique_ptr< LoadEvent > load_event_
Definition: PeerImp.h:179
boost::beast::http::fields const & headers_
Definition: PeerImp.h:175
-
void onValidatorListMessage(std::string const &messageType, std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs)
Definition: PeerImp.cpp:1975
-
void onMessageEnd(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m)
Definition: PeerImp.cpp:1043
-
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
Definition: PeerImp.cpp:517
+
void onValidatorListMessage(std::string const &messageType, std::string const &manifest, std::uint32_t version, std::vector< ValidatorBlobInfo > const &blobs)
Definition: PeerImp.cpp:1986
+
void onMessageEnd(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m)
Definition: PeerImp.cpp:1040
+
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
Definition: PeerImp.cpp:514
Metrics sent
Definition: PeerImp.h:229
clock_type::duration uptime() const
Definition: PeerImp.h:366
-
void removeTxQueue(uint256 const &hash) override
Remove transaction's hash from the transactions' hashes queue.
Definition: PeerImp.cpp:333
+
void removeTxQueue(uint256 const &hash) override
Remove transaction's hash from the transactions' hashes queue.
Definition: PeerImp.cpp:330
protocol::TMStatusChange last_status_
Definition: PeerImp.h:168
boost::shared_mutex nameMutex_
Definition: PeerImp.h:101
std::string name_
Definition: PeerImp.h:100
boost::circular_buffer< uint256 > recentTxSets_
Definition: PeerImp.h:111
std::unique_ptr< stream_type > stream_ptr_
Definition: PeerImp.h:77
-
void checkTransaction(int flags, bool checkSignature, std::shared_ptr< STTx const > const &stx, bool batch)
Definition: PeerImp.cpp:2780
-
void onMessage(std::shared_ptr< protocol::TMManifests > const &m)
Definition: PeerImp.cpp:1052
+
void checkTransaction(int flags, bool checkSignature, std::shared_ptr< STTx const > const &stx, bool batch)
Definition: PeerImp.cpp:2791
+
void onMessage(std::shared_ptr< protocol::TMManifests > const &m)
Definition: PeerImp.cpp:1049
bool detaching_
Definition: PeerImp.h:97
Tracking
Whether the peer's view of the ledger converges or diverges from ours.
Definition: PeerImp.h:57
@ converged
@@ -841,112 +841,112 @@ $(function() {
Compressed compressionEnabled_
Definition: PeerImp.h:184
std::optional< std::size_t > publisherListSequence(PublicKey const &pubKey) const override
Definition: PeerImp.h:378
uint256 closedLedgerHash_
Definition: PeerImp.h:107
-
std::string domain() const
Definition: PeerImp.cpp:835
+
std::string domain() const
Definition: PeerImp.cpp:832
std::optional< std::uint32_t > lastPingSeq_
Definition: PeerImp.h:114
std::shared_ptr< PeerFinder::Slot > const & slot()
Definition: PeerImp.h:274
-
void onTimer(boost::system::error_code const &ec)
Definition: PeerImp.cpp:683
+
void onTimer(boost::system::error_code const &ec)
Definition: PeerImp.cpp:680
bool gracefulClose_
Definition: PeerImp.h:177
http_response_type response_
Definition: PeerImp.h:174
void sendEndpoints(FwdIt first, FwdIt last)
Send a set of PeerFinder endpoints as a protocol message.
Definition: PeerImp.h:730
-
void sendLedgerBase(std::shared_ptr< Ledger const > const &ledger, protocol::TMLedgerData &ledgerData)
Definition: PeerImp.cpp:3038
+
void sendLedgerBase(std::shared_ptr< Ledger const > const &ledger, protocol::TMLedgerData &ledgerData)
Definition: PeerImp.cpp:3049
boost::asio::ip::tcp::endpoint endpoint_type
Definition: PeerImp.h:66
beast::Journal const journal_
Definition: PeerImp.h:75
-
virtual void run()
Definition: PeerImp.cpp:159
+
virtual void run()
Definition: PeerImp.cpp:156
boost::asio::ip::address address_type
Definition: PeerImp.h:65
-
void gracefulClose()
Definition: PeerImp.cpp:627
+
void gracefulClose()
Definition: PeerImp.cpp:624
LedgerIndex maxLedger_
Definition: PeerImp.h:106
beast::Journal const p_journal_
Definition: PeerImp.h:76
-
void cancelTimer()
Definition: PeerImp.cpp:666
+
void cancelTimer()
Definition: PeerImp.cpp:663
bool const inbound_
Definition: PeerImp.h:90
PeerImp(PeerImp const &)=delete
-
void processLedgerRequest(std::shared_ptr< protocol::TMGetLedger > const &m)
Definition: PeerImp.cpp:3209
+
void processLedgerRequest(std::shared_ptr< protocol::TMGetLedger > const &m)
Definition: PeerImp.cpp:3220
Application & app_
Definition: PeerImp.h:71
-
std::shared_ptr< SHAMap const > getTxSet(std::shared_ptr< protocol::TMGetLedger > const &m) const
Definition: PeerImp.cpp:3174
-
void stop() override
Definition: PeerImp.cpp:217
-
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
Definition: PeerImp.cpp:559
-
bool hasTxSet(uint256 const &hash) const override
Definition: PeerImp.cpp:541
+
std::shared_ptr< SHAMap const > getTxSet(std::shared_ptr< protocol::TMGetLedger > const &m) const
Definition: PeerImp.cpp:3185
+
void stop() override
Definition: PeerImp.cpp:214
+
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
Definition: PeerImp.cpp:556
+
bool hasTxSet(uint256 const &hash) const override
Definition: PeerImp.cpp:538
clock_type::time_point lastPingTime_
Definition: PeerImp.h:115
-
void onMessageUnknown(std::uint16_t type)
Definition: PeerImp.cpp:1003
+
void onMessageUnknown(std::uint16_t type)
Definition: PeerImp.cpp:1000
std::shared_ptr< PeerFinder::Slot > const slot_
Definition: PeerImp.h:171
boost::circular_buffer< uint256 > recentLedgers_
Definition: PeerImp.h:110
id_t const id_
Definition: PeerImp.h:72
std::optional< std::chrono::milliseconds > latency_
Definition: PeerImp.h:113
-
void handleTransaction(std::shared_ptr< protocol::TMTransaction > const &m, bool eraseTxQueue, bool batch)
Called from onMessage(TMTransaction(s)).
Definition: PeerImp.cpp:1234
+
void handleTransaction(std::shared_ptr< protocol::TMTransaction > const &m, bool eraseTxQueue, bool batch)
Called from onMessage(TMTransaction(s)).
Definition: PeerImp.cpp:1241
beast::IP::Endpoint const remote_address_
Definition: PeerImp.h:85
boost::asio::ip::tcp::socket socket_type
Definition: PeerImp.h:62
-
Json::Value json() override
Definition: PeerImp.cpp:382
+
Json::Value json() override
Definition: PeerImp.cpp:379
PublicKey const publicKey_
Definition: PeerImp.h:99
-
void addLedger(uint256 const &hash, std::lock_guard< std::mutex > const &lockedRecentLock)
Definition: PeerImp.cpp:2675
-
void close()
Definition: PeerImp.cpp:569
+
void addLedger(uint256 const &hash, std::lock_guard< std::mutex > const &lockedRecentLock)
Definition: PeerImp.cpp:2686
+
void close()
Definition: PeerImp.cpp:566
hash_set< uint256 > txQueue_
Definition: PeerImp.h:189
-
std::shared_ptr< Ledger const > getLedger(std::shared_ptr< protocol::TMGetLedger > const &m)
Definition: PeerImp.cpp:3078
+
std::shared_ptr< Ledger const > getLedger(std::shared_ptr< protocol::TMGetLedger > const &m)
Definition: PeerImp.cpp:3089
std::mutex recentLock_
Definition: PeerImp.h:167
-
void doAccept()
Definition: PeerImp.cpp:760
-
void onMessageBegin(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m, std::size_t size, std::size_t uncompressed_size, bool isCompressed)
Definition: PeerImp.cpp:1009
+
void doAccept()
Definition: PeerImp.cpp:757
+
void onMessageBegin(std::uint16_t type, std::shared_ptr<::google::protobuf::Message > const &m, std::size_t size, std::size_t uncompressed_size, bool isCompressed)
Definition: PeerImp.cpp:1006
bool txReduceRelayEnabled_
Definition: PeerImp.h:191
beast::IP::Endpoint getRemoteAddress() const override
Definition: PeerImp.h:320
Metrics recv
Definition: PeerImp.h:230
-
bool reduceRelayReady()
Definition: PeerImp.cpp:3433
+
bool reduceRelayReady()
Definition: PeerImp.cpp:3444
clock_type::time_point trackingTime_
Definition: PeerImp.h:96
socket_type & socket_
Definition: PeerImp.h:78
ProtocolVersion protocol_
Definition: PeerImp.h:93
clock_type::time_point const creationTime_
Definition: PeerImp.h:116
reduce_relay::Squelch< UptimeClock > squelch_
Definition: PeerImp.h:118
hash_map< PublicKey, std::size_t > publisherListSequences_
Definition: PeerImp.h:182
-
std::string getVersion() const
Return the version of rippled that the peer is running, if reported.
Definition: PeerImp.cpp:374
+
std::string getVersion() const
Return the version of rippled that the peer is running, if reported.
Definition: PeerImp.cpp:371
struct ripple::PeerImp::@22 metrics_
uint256 previousLedgerHash_
Definition: PeerImp.h:108
-
void charge(Resource::Charge const &fee, std::string const &context) override
Adjust this peer's load balance based on the type of load imposed.
Definition: PeerImp.cpp:345
-
void setTimer()
Definition: PeerImp.cpp:648
+
void charge(Resource::Charge const &fee, std::string const &context) override
Adjust this peer's load balance based on the type of load imposed.
Definition: PeerImp.cpp:342
+
void setTimer()
Definition: PeerImp.cpp:645
boost::beast::tcp_stream middle_type
Definition: PeerImp.h:63
-
int getScore(bool haveItem) const override
Definition: PeerImp.cpp:3388
-
void send(std::shared_ptr< Message > const &m) override
Definition: PeerImp.cpp:243
-
void doTransactions(std::shared_ptr< protocol::TMGetObjectByHash > const &packet)
Process peer's request to send missing transactions.
Definition: PeerImp.cpp:2725
-
static std::string makePrefix(id_t id)
Definition: PeerImp.cpp:675
-
std::string name() const
Definition: PeerImp.cpp:828
+
int getScore(bool haveItem) const override
Definition: PeerImp.cpp:3399
+
void send(std::shared_ptr< Message > const &m) override
Definition: PeerImp.cpp:240
+
void doTransactions(std::shared_ptr< protocol::TMGetObjectByHash > const &packet)
Process peer's request to send missing transactions.
Definition: PeerImp.cpp:2736
+
static std::string makePrefix(id_t id)
Definition: PeerImp.cpp:672
+
std::string name() const
Definition: PeerImp.cpp:825
boost::system::error_code error_code
Definition: PeerImp.h:61
-
void doFetchPack(const std::shared_ptr< protocol::TMGetObjectByHash > &packet)
Definition: PeerImp.cpp:2691
-
void onReadMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:883
+
void doFetchPack(const std::shared_ptr< protocol::TMGetObjectByHash > &packet)
Definition: PeerImp.cpp:2702
+
void onReadMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:880
bool ledgerReplayEnabled_
Definition: PeerImp.h:195
beast::WrappedSink p_sink_
Definition: PeerImp.h:74
boost::asio::basic_waitable_timer< std::chrono::steady_clock > waitable_timer
Definition: PeerImp.h:68
PublicKey const & getNodePublic() const override
Definition: PeerImp.h:355
static std::atomic_bool reduceRelayReady_
Definition: PeerImp.h:119
-
bool crawl() const
Returns true if this connection will publicly share its IP address.
Definition: PeerImp.cpp:359
+
bool crawl() const
Returns true if this connection will publicly share its IP address.
Definition: PeerImp.cpp:356
waitable_timer timer_
Definition: PeerImp.h:81
beast::Journal const & pjournal() const
Definition: PeerImp.h:268
-
void sendTxQueue() override
Send aggregated transactions' hashes.
Definition: PeerImp.cpp:297
+
void sendTxQueue() override
Send aggregated transactions' hashes.
Definition: PeerImp.cpp:294
bool compressionEnabled() const override
Definition: PeerImp.h:433
bool txReduceRelayEnabled() const override
Definition: PeerImp.h:439
-
bool supportsFeature(ProtocolFeature f) const override
Definition: PeerImp.cpp:500
+
bool supportsFeature(ProtocolFeature f) const override
Definition: PeerImp.cpp:497
uint256 const & getClosedLedgerHash() const override
Definition: PeerImp.h:402
beast::WrappedSink sink_
Definition: PeerImp.h:73
ChargeWithContext fee_
Definition: PeerImp.h:170
-
void onWriteMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:947
+
void onWriteMessage(error_code ec, std::size_t bytes_transferred)
Definition: PeerImp.cpp:944
http_request_type request_
Definition: PeerImp.h:173
OverlayImpl & overlay_
Definition: PeerImp.h:89
LedgerIndex minLedger_
Definition: PeerImp.h:105
-
virtual ~PeerImp()
Definition: PeerImp.cpp:136
+
virtual ~PeerImp()
Definition: PeerImp.cpp:133
Peer::id_t id() const override
Definition: PeerImp.h:333
LedgerReplayMsgHandler ledgerReplayMsgHandler_
Definition: PeerImp.h:196
-
void handleHaveTransactions(std::shared_ptr< protocol::TMHaveTransactions > const &m)
Handle protocol message with hashes of transactions that have not been relayed by an upstream node do...
Definition: PeerImp.cpp:2545
-
void addTxQueue(uint256 const &hash) override
Add transaction's hash to the transactions' hashes queue.
Definition: PeerImp.cpp:316
+
void handleHaveTransactions(std::shared_ptr< protocol::TMHaveTransactions > const &m)
Handle protocol message with hashes of transactions that have not been relayed by an upstream node do...
Definition: PeerImp.cpp:2556
+
void addTxQueue(uint256 const &hash) override
Add transaction's hash to the transactions' hashes queue.
Definition: PeerImp.cpp:313
int large_sendq_
Definition: PeerImp.h:178
stream_type & stream_
Definition: PeerImp.h:79
-
bool cluster() const override
Returns true if this connection is a member of the cluster.
Definition: PeerImp.cpp:368
-
void checkPropose(bool isTrusted, std::shared_ptr< protocol::TMProposeSet > const &packet, RCLCxPeerPos peerPos)
Definition: PeerImp.cpp:2898
-
bool isHighLatency() const override
Definition: PeerImp.cpp:3426
-
void checkTracking(std::uint32_t validationSeq)
Check if the peer is tracking.
Definition: PeerImp.cpp:1908
-
void onShutdown(error_code ec)
Definition: PeerImp.cpp:744
+
bool cluster() const override
Returns true if this connection is a member of the cluster.
Definition: PeerImp.cpp:365
+
void checkPropose(bool isTrusted, std::shared_ptr< protocol::TMProposeSet > const &packet, RCLCxPeerPos peerPos)
Definition: PeerImp.cpp:2909
+
bool isHighLatency() const override
Definition: PeerImp.cpp:3437
+
void checkTracking(std::uint32_t validationSeq)
Check if the peer is tracking.
Definition: PeerImp.cpp:1919
+
void onShutdown(error_code ec)
Definition: PeerImp.cpp:741
boost::asio::strand< boost::asio::executor > strand_
Definition: PeerImp.h:80
-
void cycleStatus() override
Definition: PeerImp.cpp:549
+
void cycleStatus() override
Definition: PeerImp.cpp:546
boost::beast::multi_buffer read_buffer_
Definition: PeerImp.h:172
Resource::Consumer usage_
Definition: PeerImp.h:169
-
void checkValidation(std::shared_ptr< STValidation > const &val, uint256 const &key, std::shared_ptr< protocol::TMValidation > const &packet)
Definition: PeerImp.cpp:2941
+
void checkValidation(std::shared_ptr< STValidation > const &val, uint256 const &key, std::shared_ptr< protocol::TMValidation > const &packet)
Definition: PeerImp.cpp:2952
void setPublisherListSequence(PublicKey const &pubKey, std::size_t const seq) override
Definition: PeerImp.h:389
-
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
Definition: PeerImp.cpp:532
-
void doProtocolStart()
Definition: PeerImp.cpp:845
-
void fail(std::string const &reason)
Definition: PeerImp.cpp:593
+
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
Definition: PeerImp.cpp:529
+
void doProtocolStart()
Definition: PeerImp.cpp:842
+
void fail(std::string const &reason)
Definition: PeerImp.cpp:590
std::atomic< Tracking > tracking_
Definition: PeerImp.h:95
Represents a peer connection in the overlay.
std::uint32_t id_t
Uniquely identifies a peer.
diff --git a/classripple_1_1PeerImp.html b/classripple_1_1PeerImp.html index bd5d2d548d..542015c7a9 100644 --- a/classripple_1_1PeerImp.html +++ b/classripple_1_1PeerImp.html @@ -936,7 +936,7 @@ Friends

Create an active incoming peer from an established ssl connection.

-

Definition at line 68 of file PeerImp.cpp.

+

Definition at line 65 of file PeerImp.cpp.

@@ -1045,7 +1045,7 @@ template<class Buffers >
-

Definition at line 136 of file PeerImp.cpp.

+

Definition at line 133 of file PeerImp.cpp.

@@ -1139,7 +1139,7 @@ template<class Buffers >

Reimplemented in ripple::test::tx_reduce_relay_test::PeerTest.

-

Definition at line 159 of file PeerImp.cpp.

+

Definition at line 156 of file PeerImp.cpp.

@@ -1168,7 +1168,7 @@ template<class Buffers >

Implements ripple::OverlayImpl::Child.

-

Definition at line 217 of file PeerImp.cpp.

+

Definition at line 214 of file PeerImp.cpp.

@@ -1198,7 +1198,7 @@ template<class Buffers >

Implements ripple::Peer.

-

Definition at line 243 of file PeerImp.cpp.

+

Definition at line 240 of file PeerImp.cpp.

@@ -1229,7 +1229,7 @@ template<class Buffers >

Implements ripple::Peer.

-

Definition at line 297 of file PeerImp.cpp.

+

Definition at line 294 of file PeerImp.cpp.

@@ -1267,7 +1267,7 @@ template<class Buffers >

Implements ripple::Peer.

-

Definition at line 316 of file PeerImp.cpp.

+

Definition at line 313 of file PeerImp.cpp.

@@ -1305,7 +1305,7 @@ template<class Buffers >

Implements ripple::Peer.

-

Definition at line 333 of file PeerImp.cpp.

+

Definition at line 330 of file PeerImp.cpp.

@@ -1410,7 +1410,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 345 of file PeerImp.cpp.

+

Definition at line 342 of file PeerImp.cpp.

@@ -1460,7 +1460,7 @@ template<class FwdIt , class >

Returns true if this connection will publicly share its IP address.

-

Definition at line 359 of file PeerImp.cpp.

+

Definition at line 356 of file PeerImp.cpp.

@@ -1491,7 +1491,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 368 of file PeerImp.cpp.

+

Definition at line 365 of file PeerImp.cpp.

@@ -1519,7 +1519,7 @@ template<class FwdIt , class > -

Definition at line 1908 of file PeerImp.cpp.

+

Definition at line 1919 of file PeerImp.cpp.

@@ -1549,7 +1549,7 @@ template<class FwdIt , class >
-

Definition at line 1927 of file PeerImp.cpp.

+

Definition at line 1938 of file PeerImp.cpp.

@@ -1599,7 +1599,7 @@ template<class FwdIt , class >

Return the version of rippled that the peer is running, if reported.

-

Definition at line 374 of file PeerImp.cpp.

+

Definition at line 371 of file PeerImp.cpp.

@@ -1647,7 +1647,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 382 of file PeerImp.cpp.

+

Definition at line 379 of file PeerImp.cpp.

@@ -1677,7 +1677,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 500 of file PeerImp.cpp.

+

Definition at line 497 of file PeerImp.cpp.

@@ -1816,7 +1816,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 517 of file PeerImp.cpp.

+

Definition at line 514 of file PeerImp.cpp.

@@ -1856,7 +1856,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 532 of file PeerImp.cpp.

+

Definition at line 529 of file PeerImp.cpp.

@@ -1886,7 +1886,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 541 of file PeerImp.cpp.

+

Definition at line 538 of file PeerImp.cpp.

@@ -1915,7 +1915,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 549 of file PeerImp.cpp.

+

Definition at line 546 of file PeerImp.cpp.

@@ -1955,7 +1955,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 559 of file PeerImp.cpp.

+

Definition at line 556 of file PeerImp.cpp.

@@ -1985,7 +1985,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 3388 of file PeerImp.cpp.

+

Definition at line 3399 of file PeerImp.cpp.

@@ -2014,7 +2014,7 @@ template<class FwdIt , class >

Implements ripple::Peer.

-

Definition at line 3426 of file PeerImp.cpp.

+

Definition at line 3437 of file PeerImp.cpp.

@@ -2034,7 +2034,7 @@ template<class FwdIt , class >
-

Definition at line 593 of file PeerImp.cpp.

+

Definition at line 590 of file PeerImp.cpp.

@@ -2119,7 +2119,7 @@ template<class FwdIt , class >
-

Definition at line 569 of file PeerImp.cpp.

+

Definition at line 566 of file PeerImp.cpp.

@@ -2157,7 +2157,7 @@ template<class FwdIt , class >
-

Definition at line 612 of file PeerImp.cpp.

+

Definition at line 609 of file PeerImp.cpp.

@@ -2184,7 +2184,7 @@ template<class FwdIt , class >
-

Definition at line 627 of file PeerImp.cpp.

+

Definition at line 624 of file PeerImp.cpp.

@@ -2211,7 +2211,7 @@ template<class FwdIt , class >
-

Definition at line 648 of file PeerImp.cpp.

+

Definition at line 645 of file PeerImp.cpp.

@@ -2238,7 +2238,7 @@ template<class FwdIt , class >
-

Definition at line 666 of file PeerImp.cpp.

+

Definition at line 663 of file PeerImp.cpp.

@@ -2266,7 +2266,7 @@ template<class FwdIt , class >
-

Definition at line 675 of file PeerImp.cpp.

+

Definition at line 672 of file PeerImp.cpp.

@@ -2294,7 +2294,7 @@ template<class FwdIt , class >
-

Definition at line 683 of file PeerImp.cpp.

+

Definition at line 680 of file PeerImp.cpp.

@@ -2322,7 +2322,7 @@ template<class FwdIt , class >
-

Definition at line 744 of file PeerImp.cpp.

+

Definition at line 741 of file PeerImp.cpp.

@@ -2349,7 +2349,7 @@ template<class FwdIt , class >
-

Definition at line 760 of file PeerImp.cpp.

+

Definition at line 757 of file PeerImp.cpp.

@@ -2376,7 +2376,7 @@ template<class FwdIt , class >
-

Definition at line 828 of file PeerImp.cpp.

+

Definition at line 825 of file PeerImp.cpp.

@@ -2403,7 +2403,7 @@ template<class FwdIt , class >
-

Definition at line 835 of file PeerImp.cpp.

+

Definition at line 832 of file PeerImp.cpp.

@@ -2430,7 +2430,7 @@ template<class FwdIt , class >
-

Definition at line 845 of file PeerImp.cpp.

+

Definition at line 842 of file PeerImp.cpp.

@@ -2468,7 +2468,7 @@ template<class FwdIt , class >
-

Definition at line 883 of file PeerImp.cpp.

+

Definition at line 880 of file PeerImp.cpp.

@@ -2506,7 +2506,7 @@ template<class FwdIt , class >
-

Definition at line 947 of file PeerImp.cpp.

+

Definition at line 944 of file PeerImp.cpp.

@@ -2560,7 +2560,7 @@ template<class FwdIt , class > -

Definition at line 1234 of file PeerImp.cpp.

+

Definition at line 1241 of file PeerImp.cpp.

@@ -2596,7 +2596,7 @@ template<class FwdIt , class > -

Definition at line 2545 of file PeerImp.cpp.

+

Definition at line 2556 of file PeerImp.cpp.

@@ -2623,7 +2623,7 @@ template<class FwdIt , class >
-

Definition at line 3433 of file PeerImp.cpp.

+

Definition at line 3444 of file PeerImp.cpp.

@@ -2643,7 +2643,7 @@ template<class FwdIt , class >
-

Definition at line 1003 of file PeerImp.cpp.

+

Definition at line 1000 of file PeerImp.cpp.

@@ -2691,7 +2691,7 @@ template<class FwdIt , class >
-

Definition at line 1009 of file PeerImp.cpp.

+

Definition at line 1006 of file PeerImp.cpp.

@@ -2721,7 +2721,7 @@ template<class FwdIt , class >
-

Definition at line 1043 of file PeerImp.cpp.

+

Definition at line 1040 of file PeerImp.cpp.

@@ -2741,7 +2741,7 @@ template<class FwdIt , class >
-

Definition at line 1052 of file PeerImp.cpp.

+

Definition at line 1049 of file PeerImp.cpp.

@@ -2761,7 +2761,7 @@ template<class FwdIt , class >
-

Definition at line 1072 of file PeerImp.cpp.

+

Definition at line 1069 of file PeerImp.cpp.

@@ -2781,7 +2781,7 @@ template<class FwdIt , class >
-

Definition at line 1109 of file PeerImp.cpp.

+

Definition at line 1106 of file PeerImp.cpp.

@@ -2801,7 +2801,7 @@ template<class FwdIt , class >
-

Definition at line 1181 of file PeerImp.cpp.

+

Definition at line 1178 of file PeerImp.cpp.

@@ -2821,7 +2821,7 @@ template<class FwdIt , class >
-

Definition at line 1228 of file PeerImp.cpp.

+

Definition at line 1235 of file PeerImp.cpp.

@@ -2841,7 +2841,7 @@ template<class FwdIt , class >
-

Definition at line 1340 of file PeerImp.cpp.

+

Definition at line 1347 of file PeerImp.cpp.

@@ -2861,7 +2861,7 @@ template<class FwdIt , class >
-

Definition at line 1535 of file PeerImp.cpp.

+

Definition at line 1546 of file PeerImp.cpp.

@@ -2881,7 +2881,7 @@ template<class FwdIt , class >
-

Definition at line 1626 of file PeerImp.cpp.

+

Definition at line 1637 of file PeerImp.cpp.

@@ -2901,7 +2901,7 @@ template<class FwdIt , class >
-

Definition at line 1733 of file PeerImp.cpp.

+

Definition at line 1744 of file PeerImp.cpp.

@@ -2921,7 +2921,7 @@ template<class FwdIt , class >
-

Definition at line 1949 of file PeerImp.cpp.

+

Definition at line 1960 of file PeerImp.cpp.

@@ -2941,7 +2941,7 @@ template<class FwdIt , class >
-

Definition at line 2189 of file PeerImp.cpp.

+

Definition at line 2200 of file PeerImp.cpp.

@@ -2961,7 +2961,7 @@ template<class FwdIt , class >
-

Definition at line 2218 of file PeerImp.cpp.

+

Definition at line 2229 of file PeerImp.cpp.

@@ -2981,7 +2981,7 @@ template<class FwdIt , class >
-

Definition at line 2258 of file PeerImp.cpp.

+

Definition at line 2269 of file PeerImp.cpp.

@@ -3001,7 +3001,7 @@ template<class FwdIt , class >
-

Definition at line 2370 of file PeerImp.cpp.

+

Definition at line 2381 of file PeerImp.cpp.

@@ -3021,7 +3021,7 @@ template<class FwdIt , class >
-

Definition at line 2526 of file PeerImp.cpp.

+

Definition at line 2537 of file PeerImp.cpp.

@@ -3041,7 +3041,7 @@ template<class FwdIt , class >
-

Definition at line 2595 of file PeerImp.cpp.

+

Definition at line 2606 of file PeerImp.cpp.

@@ -3061,7 +3061,7 @@ template<class FwdIt , class >
-

Definition at line 2619 of file PeerImp.cpp.

+

Definition at line 2630 of file PeerImp.cpp.

@@ -3081,7 +3081,7 @@ template<class FwdIt , class >
-

Definition at line 1429 of file PeerImp.cpp.

+

Definition at line 1436 of file PeerImp.cpp.

@@ -3101,7 +3101,7 @@ template<class FwdIt , class >
-

Definition at line 1467 of file PeerImp.cpp.

+

Definition at line 1475 of file PeerImp.cpp.

@@ -3121,7 +3121,7 @@ template<class FwdIt , class >
-

Definition at line 1482 of file PeerImp.cpp.

+

Definition at line 1491 of file PeerImp.cpp.

@@ -3141,7 +3141,7 @@ template<class FwdIt , class >
-

Definition at line 1520 of file PeerImp.cpp.

+

Definition at line 1530 of file PeerImp.cpp.

@@ -3179,7 +3179,7 @@ template<class FwdIt , class >
-

Definition at line 2675 of file PeerImp.cpp.

+

Definition at line 2686 of file PeerImp.cpp.

@@ -3207,7 +3207,7 @@ template<class FwdIt , class >
-

Definition at line 2691 of file PeerImp.cpp.

+

Definition at line 2702 of file PeerImp.cpp.

@@ -3257,7 +3257,7 @@ template<class FwdIt , class >
-

Definition at line 1975 of file PeerImp.cpp.

+

Definition at line 1986 of file PeerImp.cpp.

@@ -3293,7 +3293,7 @@ template<class FwdIt , class > -

Definition at line 2725 of file PeerImp.cpp.

+

Definition at line 2736 of file PeerImp.cpp.

@@ -3343,7 +3343,7 @@ template<class FwdIt , class >
-

Definition at line 2780 of file PeerImp.cpp.

+

Definition at line 2791 of file PeerImp.cpp.

@@ -3387,7 +3387,7 @@ template<class FwdIt , class >
-

Definition at line 2898 of file PeerImp.cpp.

+

Definition at line 2909 of file PeerImp.cpp.

@@ -3431,7 +3431,7 @@ template<class FwdIt , class >
-

Definition at line 2941 of file PeerImp.cpp.

+

Definition at line 2952 of file PeerImp.cpp.

@@ -3469,7 +3469,7 @@ template<class FwdIt , class >
-

Definition at line 3038 of file PeerImp.cpp.

+

Definition at line 3049 of file PeerImp.cpp.

@@ -3497,7 +3497,7 @@ template<class FwdIt , class >
-

Definition at line 3078 of file PeerImp.cpp.

+

Definition at line 3089 of file PeerImp.cpp.

@@ -3525,7 +3525,7 @@ template<class FwdIt , class >
-

Definition at line 3174 of file PeerImp.cpp.

+

Definition at line 3185 of file PeerImp.cpp.

@@ -3553,7 +3553,7 @@ template<class FwdIt , class >
-

Definition at line 3209 of file PeerImp.cpp.

+

Definition at line 3220 of file PeerImp.cpp.

diff --git a/classripple_1_1PeerImp_1_1Metrics.html b/classripple_1_1PeerImp_1_1Metrics.html index fc8bc604de..d8beb55ac4 100644 --- a/classripple_1_1PeerImp_1_1Metrics.html +++ b/classripple_1_1PeerImp_1_1Metrics.html @@ -274,7 +274,7 @@ Private Attributes
-

Definition at line 3443 of file PeerImp.cpp.

+

Definition at line 3454 of file PeerImp.cpp.

@@ -293,7 +293,7 @@ Private Attributes
-

Definition at line 3469 of file PeerImp.cpp.

+

Definition at line 3480 of file PeerImp.cpp.

@@ -312,7 +312,7 @@ Private Attributes
-

Definition at line 3476 of file PeerImp.cpp.

+

Definition at line 3487 of file PeerImp.cpp.

diff --git a/classripple_1_1Resource_1_1Charge-members.html b/classripple_1_1Resource_1_1Charge-members.html index 2d40b0614e..26c56af293 100644 --- a/classripple_1_1Resource_1_1Charge-members.html +++ b/classripple_1_1Resource_1_1Charge-members.html @@ -85,10 +85,11 @@ $(function() { label() constripple::Resource::Charge m_costripple::Resource::Chargeprivate m_labelripple::Resource::Chargeprivate - operator<=>(Charge const &) constripple::Resource::Charge - operator==(Charge const &) constripple::Resource::Charge - to_string() constripple::Resource::Charge - value_type typedefripple::Resource::Charge + operator*(value_type m) constripple::Resource::Charge + operator<=>(Charge const &) constripple::Resource::Charge + operator==(Charge const &) constripple::Resource::Charge + to_string() constripple::Resource::Charge + value_type typedefripple::Resource::Charge