1#include <test/unit_test/SuiteJournal.h>
3#include <xrpld/core/Config.h>
4#include <xrpld/peerfinder/PeerfinderManager.h>
5#include <xrpld/peerfinder/detail/Counts.h>
6#include <xrpld/peerfinder/detail/Logic.h>
7#include <xrpld/peerfinder/detail/Store.h>
9#include <xrpl/basics/chrono.h>
10#include <xrpl/beast/net/IPEndpoint.h>
11#include <xrpl/beast/unit_test/suite.h>
12#include <xrpl/protocol/KeyType.h>
13#include <xrpl/protocol/PublicKey.h>
14#include <xrpl/protocol/SecretKey.h>
16#include <boost/system/detail/error_code.hpp>
63 template <
class Handler>
67 boost::system::error_code ec;
75 auto const seconds = 10000;
94 BEAST_EXPECT(list.size() == 1);
105 BEAST_EXPECT(n < 20);
112 auto const seconds = 10000;
134 BEAST_EXPECT(list.size() == 1);
139 if (!BEAST_EXPECT(logic.
activate(slot, pk,
false) == PeerFinder::Result::Success))
148 BEAST_EXPECT(n <= (seconds + 59) / 60);
170 BEAST_EXPECT(slot1 !=
nullptr);
171 BEAST_EXPECT(r == Result::Success);
177 BEAST_EXPECT(r2 == Result::DuplicatePeer);
179 if (!BEAST_EXPECT(slot2 ==
nullptr))
206 BEAST_EXPECT(slot1 !=
nullptr);
207 BEAST_EXPECT(r == Result::Success);
211 BEAST_EXPECT(r2 == Result::DuplicatePeer);
213 if (!BEAST_EXPECT(slot2 ==
nullptr))
235 auto const [slot, r] =
237 BEAST_EXPECT(slot !=
nullptr);
238 BEAST_EXPECT(r == Result::Success);
240 auto const [slot1, r1] =
242 BEAST_EXPECT(slot1 !=
nullptr);
243 BEAST_EXPECT(r1 == Result::Success);
245 auto const [slot2, r2] =
247 BEAST_EXPECT(r2 == Result::IpLimitExceeded);
249 if (!BEAST_EXPECT(slot2 ==
nullptr))
258 testcase(
"test activate duplicate peer");
275 auto const [slot, rSlot] =
277 BEAST_EXPECT(slot !=
nullptr);
278 BEAST_EXPECT(rSlot == Result::Success);
280 auto const [slot2, r2Slot] =
282 BEAST_EXPECT(slot2 !=
nullptr);
283 BEAST_EXPECT(r2Slot == Result::Success);
288 BEAST_EXPECT(logic.
activate(slot, pk1,
false) == Result::Success);
291 BEAST_EXPECT(logic.
activate(slot2, pk1,
false) == Result::DuplicatePeer);
296 BEAST_EXPECT(logic.
activate(slot2, pk1,
false) == Result::Success);
303 testcase(
"test activate inbound disabled");
319 auto const [slot, rSlot] =
321 BEAST_EXPECT(slot !=
nullptr);
322 BEAST_EXPECT(rSlot == Result::Success);
324 BEAST_EXPECT(logic.
activate(slot, pk1,
false) == Result::InboundDisabled);
335 BEAST_EXPECT(logic.
activate(slot, pk1,
false) == Result::Success);
338 auto const [slot2, r2Slot] =
340 BEAST_EXPECT(slot2 !=
nullptr);
341 BEAST_EXPECT(r2Slot == Result::Success);
346 BEAST_EXPECT(logic.
activate(slot2, pk2,
false) == Result::Full);
355 testcase(
"test addFixedPeer no port");
363 fail(
"invalid endpoint successfully added");
374 testcase(
"test onConnected self connection");
382 BEAST_EXPECT(slot !=
nullptr);
383 BEAST_EXPECT(r == Result::Success);
411 max = maxPeers.value();
412 toLoad +=
"[peers_max]\n" +
std::to_string(max) +
"\n" +
"[peers_in_max]\n" +
416 else if (maxIn && maxOut)
418 toLoad +=
"[peers_in_max]\n" +
std::to_string(*maxIn) +
"\n" +
"[peers_out_max]\n" +
432 counts.
outMax() == expectOut && counts.
inMax() == expectIn &&
433 config.
ipLimit == expectIpLimit);
441 BEAST_EXPECT(logic.
config() == config);
455 run(
"legacy no config", {}, {}, {}, 4000, 10, 11, 2);
456 run(
"legacy max_peers 0", 0, 100, 10, 4000, 10, 11, 2);
457 run(
"legacy max_peers 5", 5, 100, 10, 4000, 10, 0, 1);
458 run(
"legacy max_peers 20", 20, 100, 10, 4000, 10, 10, 2);
459 run(
"legacy max_peers 100", 100, 100, 10, 4000, 15, 85, 6);
460 run(
"legacy max_peers 20, private", 20, 100, 10, 0, 20, 0, 1);
463 run(
"new in 100/out 10", {}, 100, 10, 4000, 10, 100, 6);
464 run(
"new in 0/out 10", {}, 0, 10, 4000, 10, 0, 1);
465 run(
"new in 100/out 10, private", {}, 100, 10, 0, 10, 0, 6);
A version-independent IP address and port combination.
static Endpoint fromString(std::string const &s)
void pass()
Record a successful test condition.
void fail(String const &reason, char const *file, int line)
Record a failure.
TestcaseT testcase
Memberspace for declaring test cases.
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Manages the count of available connections for the various slots.
int outMax() const
Returns the total number of outbound slots.
int inMax() const
Returns the total number of inbound slots.
void onConfig(Config const &config)
Called when the config is set or changed.
The Logic for maintaining the list of Slot addresses.
void addFixedPeer(std::string_view name, beast::IP::Endpoint const &ep)
void config(Config const &c)
std::pair< SlotImp::ptr, Result > newOutboundSlot(beast::IP::Endpoint const &remoteEndpoint)
std::pair< SlotImp::ptr, Result > newInboundSlot(beast::IP::Endpoint const &localEndpoint, beast::IP::Endpoint const &remoteEndpoint)
Result activate(SlotImp::ptr const &slot, PublicKey const &key, bool reserved)
std::multiset< beast::IP::Address > connectedAddresses
std::vector< beast::IP::Endpoint > autoconnect()
Create new outbound connection attempts as needed.
void onClosed(SlotImp::ptr const &slot)
bool onConnected(SlotImp::ptr const &slot, beast::IP::Endpoint const &localEndpoint)
test::SuiteJournal journal_
void testAddFixedPeerNoPort()
void testDuplicateOutIn()
void testDuplicateInOut()
void testOnConnectedSelfConnection()
void testActivateDuplicatePeer()
void testPeerLimitExceeded()
void testActivateInboundDisabled()
void run() override
Runs the suite.
Abstract persistence for PeerFinder data.
std::function< void(beast::IP::Endpoint, int)> load_callback
BEAST_DEFINE_TESTSUITE(Livecache, peerfinder, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
beast::ManualClock< std::chrono::steady_clock > TestStopwatch
A manual Stopwatch for unit tests.
PeerFinder configuration settings.
int ipLimit
Limit how many incoming connections we allow per IP.
bool autoConnect
true if we want to establish connections automatically
std::size_t inPeers
The number of automatic inbound connections to maintain.
std::uint16_t listeningPort
The listening port number.
static Config makeConfig(xrpl::Config const &config, std::uint16_t port, bool validationPublicKey, int ipLimit, bool verifyEndpoints)
Make PeerFinder::Config from configuration parameters.
void asyncConnect(beast::IP::Endpoint const &ep, Handler &&handler)
void save(std::vector< Entry > const &) override
std::size_t load(load_callback const &cb) override