diff --git a/src/test/overlay/base_squelch_test.cpp b/src/test/overlay/base_squelch_test.cpp index f18ea4deaf..b69bfb8324 100644 --- a/src/test/overlay/base_squelch_test.cpp +++ b/src/test/overlay/base_squelch_test.cpp @@ -450,7 +450,7 @@ public: Slots::slots_map const& getSlots() const { - return slots_; + return trustedSlots_; } }; diff --git a/src/test/overlay/enhanced_squelch_test.cpp b/src/test/overlay/enhanced_squelch_test.cpp index 600832286f..5c6636103c 100644 --- a/src/test/overlay/enhanced_squelch_test.cpp +++ b/src/test/overlay/enhanced_squelch_test.cpp @@ -104,7 +104,7 @@ public: getSlots(bool trusted) const { if (trusted) - return slots_; + return trustedSlots_; return untrustedSlots_; } diff --git a/src/xrpld/overlay/Slot.h b/src/xrpld/overlay/Slot.h index a1e864ef20..6262923173 100644 --- a/src/xrpld/overlay/Slot.h +++ b/src/xrpld/overlay/Slot.h @@ -482,7 +482,14 @@ protected: std::atomic_bool reduceRelayReady_{false}; - slots_map slots_; + // Maintain an open number of slots for trusted validators to reduce + // duplicate traffic from trusted validators. + slots_map trustedSlots_; + + // Maintain slots for untrusted validators to reduce duplicate traffic from + // untrusted validators. If enhanced squelching is enabled, the number of + // untrustedSlots_ is capped at reduce_relay::MAX_UNTRUSTED_SLOTS. + // Otherwise, there is no limit. slots_map untrustedSlots_; SquelchHandler& handler_; // squelch/unsquelch handler diff --git a/src/xrpld/overlay/detail/OverlayImpl.cpp b/src/xrpld/overlay/detail/OverlayImpl.cpp index 33f6ffbaf1..05bfaedcd8 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.cpp +++ b/src/xrpld/overlay/detail/OverlayImpl.cpp @@ -1481,7 +1481,7 @@ OverlayImpl::updateSlotAndSquelch( } void -OverlayImpl::updateValidatorSlot( +OverlayImpl::updateUntrustedValidatorSlot( uint256 const& key, PublicKey const& validator, Peer::id_t peer) @@ -1491,7 +1491,7 @@ OverlayImpl::updateValidatorSlot( if (!strand_.running_in_this_thread()) return post(strand_, [this, key, validator, peer]() { - updateValidatorSlot(key, validator, peer); + updateUntrustedValidatorSlot(key, validator, peer); }); slots_.updateUntrustedValidatorSlot(key, validator, peer, [&]() { diff --git a/src/xrpld/overlay/detail/OverlayImpl.h b/src/xrpld/overlay/detail/OverlayImpl.h index 3911d1b63b..863451585e 100644 --- a/src/xrpld/overlay/detail/OverlayImpl.h +++ b/src/xrpld/overlay/detail/OverlayImpl.h @@ -427,7 +427,7 @@ public: * @param peer Peer's id to update the slot for */ void - updateValidatorSlot( + updateUntrustedValidatorSlot( uint256 const& key, PublicKey const& validator, Peer::id_t peer); diff --git a/src/xrpld/overlay/detail/PeerImp.cpp b/src/xrpld/overlay/detail/PeerImp.cpp index 696e691a26..129175a7f2 100644 --- a/src/xrpld/overlay/detail/PeerImp.cpp +++ b/src/xrpld/overlay/detail/PeerImp.cpp @@ -2386,7 +2386,8 @@ PeerImp::onMessage(std::shared_ptr const& m) TrafficCount::category::validation_untrusted, Message::messageSize(*m)); - overlay_.updateValidatorSlot(key, val->getSignerPublic(), id_); + overlay_.updateUntrustedValidatorSlot( + key, val->getSignerPublic(), id_); // If the operator has specified that untrusted validations be // dropped then this happens here I.e. before further wasting CPU diff --git a/src/xrpld/overlay/detail/Slot.cpp b/src/xrpld/overlay/detail/Slot.cpp index 4fb83d781f..09ead75fc5 100644 --- a/src/xrpld/overlay/detail/Slot.cpp +++ b/src/xrpld/overlay/detail/Slot.cpp @@ -410,7 +410,10 @@ Slots::updateSlotAndSquelch( { JLOG(journal_.trace()) << "updateSlotAndSquelch: new slot " << Slice(validator); - auto it = slots_ + + // if enhanced squelching is disabled, keep untrusted validator slots + // separately from trusted ones + auto it = (isTrusted ? trustedSlots_ : untrustedSlots_) .emplace(std::make_pair( validator, Slot( @@ -420,6 +423,7 @@ Slots::updateSlotAndSquelch( isTrusted, clock_))) .first; + it->second.update(validator, id, callback); } else @@ -511,21 +515,23 @@ Slots::updateConsideredValidator(PublicKey const& validator, Peer::id_t peer) .peers = {peer}, })); - return {}; + return std::nullopt; } // the validator idled. Don't update it, it will be cleaned later if (now - it->second.lastMessage > IDLED) - return {}; + return std::nullopt; it->second.peers.insert(peer); - it->second.lastMessage = now; ++it->second.count; + // if the validator has not met selection criteria yet if (it->second.count < MAX_MESSAGE_THRESHOLD || it->second.peers.size() < reduce_relay::MAX_SELECTED_PEERS) - return {}; + { + return std::nullopt; + } auto const key = it->first; consideredValidators_.erase(it); @@ -541,7 +547,7 @@ Slots::deletePeer(Peer::id_t id, bool erase) slot.deletePeer(validator, id, erase); }; - f(slots_); + f(trustedSlots_); f(untrustedSlots_); } @@ -573,7 +579,7 @@ Slots::deleteIdlePeers() } }; - f(slots_); + f(trustedSlots_); f(untrustedSlots_); // remove and squelch all validators that the selector deemed unsuitable @@ -621,7 +627,7 @@ Slots::onWrite(beast::PropertyStream::Map& stream) const { beast::PropertyStream::Set set("trusted", slots); - writeSlot(set, slots_); + writeSlot(set, trustedSlots_); } {