rippled
Loading...
Searching...
No Matches
tx_reduce_relay_test.cpp
1#include <test/jtx.h>
2#include <test/jtx/Env.h>
3
4#include <xrpld/overlay/detail/OverlayImpl.h>
5#include <xrpld/overlay/detail/PeerImp.h>
6#include <xrpld/peerfinder/detail/SlotImp.h>
7
8#include <xrpl/basics/make_SSLContext.h>
9#include <xrpl/beast/unit_test.h>
10
11namespace xrpl {
12
13namespace test {
14
16{
17public:
18 using socket_type = boost::asio::ip::tcp::socket;
19 using middle_type = boost::beast::tcp_stream;
20 using stream_type = boost::beast::ssl_stream<middle_type>;
22
23private:
24 void
25 doTest(std::string const& msg, bool log, std::function<void(bool)> f)
26 {
27 testcase(msg);
28 f(log);
29 }
30
31 void
33 {
34 doTest("Config Test", log, [&](bool log) {
35 auto test = [&](bool enable,
36 bool metrics,
37 std::uint16_t min,
38 std::uint16_t pct,
39 bool success = true) {
40 std::stringstream str("[reduce_relay]");
41 str << "[reduce_relay]\n"
42 << "tx_enable=" << static_cast<int>(enable) << "\n"
43 << "tx_metrics=" << static_cast<int>(metrics) << "\n"
44 << "tx_min_peers=" << min << "\n"
45 << "tx_relay_percentage=" << pct << "\n";
46 Config c;
47 try
48 {
49 c.loadFromString(str.str());
50
51 BEAST_EXPECT(c.TX_REDUCE_RELAY_ENABLE == enable);
52 BEAST_EXPECT(c.TX_REDUCE_RELAY_METRICS == metrics);
53 BEAST_EXPECT(c.TX_REDUCE_RELAY_MIN_PEERS == min);
54 BEAST_EXPECT(c.TX_RELAY_PERCENTAGE == pct);
55 if (success)
56 {
57 pass();
58 }
59 else
60 {
61 fail();
62 }
63 }
64 catch (...)
65 {
66 if (success)
67 {
68 fail();
69 }
70 else
71 {
72 pass();
73 }
74 }
75 };
76
77 test(true, true, 20, 25);
78 test(false, false, 20, 25);
79 test(false, false, 20, 0, false);
80 test(false, false, 20, 101, false);
81 test(false, false, 9, 10, false);
82 test(false, false, 10, 9, false);
83 });
84 }
85
86 class PeerTest : public PeerImp
87 {
88 public:
90 Application& app,
92 http_request_type&& request,
93 PublicKey const& publicKey,
95 Resource::Consumer consumer,
97 OverlayImpl& overlay)
98 : PeerImp(
99 app,
100 sid_,
101 slot,
102 std::move(request),
103 publicKey,
104 protocol,
105 consumer,
106 std::move(stream_ptr),
107 overlay)
108 {
109 sid_++;
110 }
111 ~PeerTest() = default;
112
113 void
114 run() override
115 {
116 }
117 void
119 {
120 sendTx_++;
121 }
122 void
123 addTxQueue(uint256 const& hash) override
124 {
125 queueTx_++;
126 }
127 static void
129 {
130 queueTx_ = 0;
131 sendTx_ = 0;
132 sid_ = 0;
133 }
134 inline static std::size_t sid_ = 0;
135 inline static std::uint16_t queueTx_ = 0;
136 inline static std::uint16_t sendTx_ = 0;
137 };
138
143 boost::beast::multi_buffer read_buf_;
144
145public:
149
150private:
151 void
153 {
154 auto& overlay = dynamic_cast<OverlayImpl&>(env.app().getOverlay());
155 boost::beast::http::request<boost::beast::http::dynamic_body> request;
156 (nDisabled == 0)
157 ? request.insert("X-Protocol-Ctl", makeFeaturesRequestHeader(false, false, true, false))
158 : (void)nDisabled--;
159 auto stream_ptr = std::make_unique<stream_type>(
161 *context_);
162 beast::IP::Endpoint const local(
163 boost::asio::ip::make_address("172.1.1." + std::to_string(lid_)));
164 beast::IP::Endpoint const remote(
165 boost::asio::ip::make_address("172.1.1." + std::to_string(rid_)));
167 auto consumer = overlay.resourceManager().newInboundEndpoint(remote);
168 auto [slot, _] = overlay.peerFinder().new_inbound_slot(local, remote);
169 auto const peer = std::make_shared<PeerTest>(
170 env.app(),
171 slot,
172 std::move(request),
173 key,
175 consumer,
176 std::move(stream_ptr),
177 overlay);
178 BEAST_EXPECT(overlay.findPeerByPublicKey(key) == std::shared_ptr<PeerImp>{});
179 overlay.add_active(peer);
180 BEAST_EXPECT(overlay.findPeerByPublicKey(key) == peer);
181 peers.emplace_back(peer); // overlay stores week ptr to PeerImp
182 lid_ += 2;
183 rid_ += 2;
184 assert(lid_ <= 254);
185 }
186
187 void
189 std::string const& test,
190 bool txRREnabled,
191 std::uint16_t nPeers,
192 std::uint16_t nDisabled,
193 std::uint16_t minPeers,
194 std::uint16_t relayPercentage,
195 std::uint16_t expectRelay,
196 std::uint16_t expectQueue,
197 std::set<Peer::id_t> const& toSkip = {})
198 {
199 testcase(test);
200 jtx::Env env(*this);
202 env.app().config().TX_REDUCE_RELAY_ENABLE = txRREnabled;
203 env.app().config().TX_REDUCE_RELAY_MIN_PEERS = minPeers;
204 env.app().config().TX_RELAY_PERCENTAGE = relayPercentage;
206 lid_ = 0;
207 rid_ = 0;
208 for (int i = 0; i < nPeers; i++)
209 addPeer(env, peers, nDisabled);
210
211 auto const jtx = env.jt(noop(env.master));
212 if (BEAST_EXPECT(jtx.stx))
213 {
214 protocol::TMTransaction m;
215 Serializer s;
216 jtx.stx->add(s);
217 m.set_rawtransaction(s.data(), s.size());
218 m.set_deferred(false);
219 m.set_status(protocol::TransactionStatus::tsNEW);
220 env.app().getOverlay().relay(uint256{0}, m, toSkip);
221 BEAST_EXPECT(PeerTest::sendTx_ == expectRelay && PeerTest::queueTx_ == expectQueue);
222 }
223 }
224
225 void
226 run() override
227 {
228 bool const log = false;
229 std::set<Peer::id_t> skip = {0, 1, 2, 3, 4};
231 // relay to all peers, no hash queue
232 testRelay("feature disabled", false, 10, 0, 10, 25, 10, 0);
233 // relay to nPeers - skip (10-5=5)
234 testRelay("feature disabled & skip", false, 10, 0, 10, 25, 5, 0, skip);
235 // relay to all peers because min is greater than nPeers
236 testRelay("relay all 1", true, 10, 0, 20, 25, 10, 0);
237 // relay to all peers because min + disabled is greater thant nPeers
238 testRelay("relay all 2", true, 20, 15, 10, 25, 20, 0);
239 // relay to minPeers + 25% of nPeers-minPeers (20+0.25*(60-20)=30),
240 // queue the rest (30)
241 testRelay("relay & queue", true, 60, 0, 20, 25, 30, 30);
242 // relay to minPeers + 25% of (nPeers - nPeers) - skip
243 // (20+0.25*(60-20)-5=25), queue the rest, skip counts towards relayed
244 // (60-25-5=30)
245 testRelay("skip", true, 60, 0, 20, 25, 25, 30, skip);
246 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
247 // (20+10+0.25*(70-20-10)=40), queue the rest (30)
248 testRelay("disabled", true, 70, 10, 20, 25, 40, 30);
249 // relay to minPeers + disabled-not-in-skip + 25% of (nPeers - minPeers
250 // - disabled) (20+5+0.25*(70-20-10)=35), queue the rest, skip counts
251 // towards relayed (70-35-5=30))
252 testRelay("disabled & skip", true, 70, 10, 20, 25, 35, 30, skip);
253 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
254 // - skip (10+5+0.25*(15-10-5)-10=5), queue the rest, skip counts
255 // towards relayed (15-5-10=0)
256 skip = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
257 testRelay("disabled & skip, no queue", true, 15, 5, 10, 25, 5, 0, skip);
258 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
259 // - skip (10+2+0.25*(20-10-2)-14=0), queue the rest, skip counts
260 // towards relayed (20-14=6)
261 skip = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
262 testRelay("disabled & skip, no relay", true, 20, 2, 10, 25, 0, 6, skip);
263 }
264};
265
266BEAST_DEFINE_TESTSUITE(tx_reduce_relay, overlay, xrpl);
267} // namespace test
268} // namespace xrpl
A version-independent IP address and port combination.
Definition IPEndpoint.h:18
A testsuite class.
Definition suite.h:51
log_os< char > log
Logging output stream.
Definition suite.h:147
void pass()
Record a successful test condition.
Definition suite.h:497
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:150
void fail(String const &reason, char const *file, int line)
Record a failure.
Definition suite.h:519
bool TX_REDUCE_RELAY_ENABLE
Definition Config.h:243
std::size_t TX_RELAY_PERCENTAGE
Definition Config.h:256
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition Config.cpp:452
bool TX_REDUCE_RELAY_METRICS
Definition Config.h:250
std::size_t TX_REDUCE_RELAY_MIN_PEERS
Definition Config.h:253
This class manages established peer-to-peer connections, handles message exchange,...
Definition PeerImp.h:95
std::shared_ptr< PeerFinder::Slot > const & slot()
Definition PeerImp.h:325
A public key.
Definition PublicKey.h:42
An endpoint that consumes resources.
Definition Consumer.h:16
std::size_t size() const noexcept
Definition Serializer.h:50
void const * data() const noexcept
Definition Serializer.h:56
virtual boost::asio::io_context & getIOContext()=0
virtual Overlay & getOverlay()=0
A transaction testing environment.
Definition Env.h:122
Application & app()
Definition Env.h:259
void addTxQueue(uint256 const &hash) override
Add transaction's hash to the transactions' hashes queue.
void send(std::shared_ptr< Message > const &) override
PeerTest(Application &app, std::shared_ptr< PeerFinder::Slot > const &slot, http_request_type &&request, PublicKey const &publicKey, ProtocolVersion protocol, Resource::Consumer consumer, std::unique_ptr< tx_reduce_relay_test::stream_type > &&stream_ptr, OverlayImpl &overlay)
void testRelay(std::string const &test, bool txRREnabled, std::uint16_t nPeers, std::uint16_t nDisabled, std::uint16_t minPeers, std::uint16_t relayPercentage, std::uint16_t expectRelay, std::uint16_t expectQueue, std::set< Peer::id_t > const &toSkip={})
void addPeer(jtx::Env &env, std::vector< std::shared_ptr< PeerTest > > &peers, std::uint16_t &nDisabled)
boost::asio::ip::tcp::socket socket_type
void run() override
Runs the suite.
boost::beast::ssl_stream< middle_type > stream_type
void doTest(std::string const &msg, bool log, std::function< void(bool)> f)
T is_same_v
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition Handoff.h:12
std::shared_ptr< boost::asio::ssl::context > make_SSLContext(std::string const &cipherList)
Create a self-signed SSL context that allows anonymous Diffie Hellman.
std::string makeFeaturesRequestHeader(bool comprEnabled, bool ledgerReplayEnabled, bool txReduceRelayEnabled, bool vpReduceRelayEnabled)
Make request header X-Protocol-Ctl value with supported features.
Definition Handshake.cpp:52
T str(T... args)
T to_string(T... args)