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, bool metrics, std::uint16_t min, std::uint16_t pct, bool success = true) {
36 std::stringstream str("[reduce_relay]");
37 str << "[reduce_relay]\n"
38 << "tx_enable=" << static_cast<int>(enable) << "\n"
39 << "tx_metrics=" << static_cast<int>(metrics) << "\n"
40 << "tx_min_peers=" << min << "\n"
41 << "tx_relay_percentage=" << pct << "\n";
42 Config c;
43 try
44 {
45 c.loadFromString(str.str());
46
47 BEAST_EXPECT(c.TX_REDUCE_RELAY_ENABLE == enable);
48 BEAST_EXPECT(c.TX_REDUCE_RELAY_METRICS == metrics);
49 BEAST_EXPECT(c.TX_REDUCE_RELAY_MIN_PEERS == min);
50 BEAST_EXPECT(c.TX_RELAY_PERCENTAGE == pct);
51 if (success)
52 pass();
53 else
54 fail();
55 }
56 catch (...)
57 {
58 if (success)
59 fail();
60 else
61 pass();
62 }
63 };
64
65 test(true, true, 20, 25);
66 test(false, false, 20, 25);
67 test(false, false, 20, 0, false);
68 test(false, false, 20, 101, false);
69 test(false, false, 9, 10, false);
70 test(false, false, 10, 9, false);
71 });
72 }
73
74 class PeerTest : public PeerImp
75 {
76 public:
78 Application& app,
80 http_request_type&& request,
81 PublicKey const& publicKey,
83 Resource::Consumer consumer,
85 OverlayImpl& overlay)
86 : PeerImp(
87 app,
88 sid_,
89 slot,
90 std::move(request),
91 publicKey,
93 consumer,
94 std::move(stream_ptr),
95 overlay)
96 {
97 sid_++;
98 }
99 ~PeerTest() = default;
100
101 void
102 run() override
103 {
104 }
105 void
107 {
108 sendTx_++;
109 }
110 void
111 addTxQueue(uint256 const& hash) override
112 {
113 queueTx_++;
114 }
115 static void
117 {
118 queueTx_ = 0;
119 sendTx_ = 0;
120 sid_ = 0;
121 }
122 inline static std::size_t sid_ = 0;
123 inline static std::uint16_t queueTx_ = 0;
124 inline static std::uint16_t sendTx_ = 0;
125 };
126
131 boost::beast::multi_buffer read_buf_;
132
133public:
137
138private:
139 void
141 {
142 auto& overlay = dynamic_cast<OverlayImpl&>(env.app().overlay());
143 boost::beast::http::request<boost::beast::http::dynamic_body> request;
144 (nDisabled == 0) ? (void)request.insert("X-Protocol-Ctl", makeFeaturesRequestHeader(false, false, true, false))
145 : (void)nDisabled--;
146 auto stream_ptr = std::make_unique<stream_type>(
148 beast::IP::Endpoint local(boost::asio::ip::make_address("172.1.1." + std::to_string(lid_)));
149 beast::IP::Endpoint remote(boost::asio::ip::make_address("172.1.1." + std::to_string(rid_)));
151 auto consumer = overlay.resourceManager().newInboundEndpoint(remote);
152 auto [slot, _] = overlay.peerFinder().new_inbound_slot(local, remote);
153 auto const peer = std::make_shared<PeerTest>(
154 env.app(), slot, std::move(request), key, protocolVersion_, consumer, std::move(stream_ptr), overlay);
155 BEAST_EXPECT(overlay.findPeerByPublicKey(key) == std::shared_ptr<PeerImp>{});
156 overlay.add_active(peer);
157 BEAST_EXPECT(overlay.findPeerByPublicKey(key) == peer);
158 peers.emplace_back(peer); // overlay stores week ptr to PeerImp
159 lid_ += 2;
160 rid_ += 2;
161 assert(lid_ <= 254);
162 }
163
164 void
166 std::string const& test,
167 bool txRREnabled,
168 std::uint16_t nPeers,
169 std::uint16_t nDisabled,
170 std::uint16_t minPeers,
171 std::uint16_t relayPercentage,
172 std::uint16_t expectRelay,
173 std::uint16_t expectQueue,
174 std::set<Peer::id_t> const& toSkip = {})
175 {
176 testcase(test);
177 jtx::Env env(*this);
179 env.app().config().TX_REDUCE_RELAY_ENABLE = txRREnabled;
180 env.app().config().TX_REDUCE_RELAY_MIN_PEERS = minPeers;
181 env.app().config().TX_RELAY_PERCENTAGE = relayPercentage;
183 lid_ = 0;
184 rid_ = 0;
185 for (int i = 0; i < nPeers; i++)
186 addPeer(env, peers, nDisabled);
187
188 auto const jtx = env.jt(noop(env.master));
189 if (BEAST_EXPECT(jtx.stx))
190 {
191 protocol::TMTransaction m;
192 Serializer s;
193 jtx.stx->add(s);
194 m.set_rawtransaction(s.data(), s.size());
195 m.set_deferred(false);
196 m.set_status(protocol::TransactionStatus::tsNEW);
197 env.app().overlay().relay(uint256{0}, m, toSkip);
198 BEAST_EXPECT(PeerTest::sendTx_ == expectRelay && PeerTest::queueTx_ == expectQueue);
199 }
200 }
201
202 void
203 run() override
204 {
205 bool log = false;
206 std::set<Peer::id_t> skip = {0, 1, 2, 3, 4};
208 // relay to all peers, no hash queue
209 testRelay("feature disabled", false, 10, 0, 10, 25, 10, 0);
210 // relay to nPeers - skip (10-5=5)
211 testRelay("feature disabled & skip", false, 10, 0, 10, 25, 5, 0, skip);
212 // relay to all peers because min is greater than nPeers
213 testRelay("relay all 1", true, 10, 0, 20, 25, 10, 0);
214 // relay to all peers because min + disabled is greater thant nPeers
215 testRelay("relay all 2", true, 20, 15, 10, 25, 20, 0);
216 // relay to minPeers + 25% of nPeers-minPeers (20+0.25*(60-20)=30),
217 // queue the rest (30)
218 testRelay("relay & queue", true, 60, 0, 20, 25, 30, 30);
219 // relay to minPeers + 25% of (nPeers - nPeers) - skip
220 // (20+0.25*(60-20)-5=25), queue the rest, skip counts towards relayed
221 // (60-25-5=30)
222 testRelay("skip", true, 60, 0, 20, 25, 25, 30, skip);
223 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
224 // (20+10+0.25*(70-20-10)=40), queue the rest (30)
225 testRelay("disabled", true, 70, 10, 20, 25, 40, 30);
226 // relay to minPeers + disabled-not-in-skip + 25% of (nPeers - minPeers
227 // - disabled) (20+5+0.25*(70-20-10)=35), queue the rest, skip counts
228 // towards relayed (70-35-5=30))
229 testRelay("disabled & skip", true, 70, 10, 20, 25, 35, 30, skip);
230 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
231 // - skip (10+5+0.25*(15-10-5)-10=5), queue the rest, skip counts
232 // towards relayed (15-5-10=0)
233 skip = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
234 testRelay("disabled & skip, no queue", true, 15, 5, 10, 25, 5, 0, skip);
235 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
236 // - skip (10+2+0.25*(20-10-2)-14=0), queue the rest, skip counts
237 // towards relayed (20-14=6)
238 skip = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
239 testRelay("disabled & skip, no relay", true, 20, 2, 10, 25, 0, 6, skip);
240 }
241};
242
243BEAST_DEFINE_TESTSUITE(tx_reduce_relay, overlay, xrpl);
244} // namespace test
245} // 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:144
void pass()
Record a successful test condition.
Definition suite.h:494
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:147
void fail(String const &reason, char const *file, int line)
Record a failure.
Definition suite.h:516
bool TX_REDUCE_RELAY_ENABLE
Definition Config.h:239
std::size_t TX_RELAY_PERCENTAGE
Definition Config.h:252
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Definition Config.cpp:440
bool TX_REDUCE_RELAY_METRICS
Definition Config.h:246
std::size_t TX_REDUCE_RELAY_MIN_PEERS
Definition Config.h:249
This class manages established peer-to-peer connections, handles message exchange,...
Definition PeerImp.h:96
std::shared_ptr< PeerFinder::Slot > const & slot()
Definition PeerImp.h:326
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 Overlay & overlay()=0
virtual boost::asio::io_context & getIOContext()=0
A transaction testing environment.
Definition Env.h:119
Application & app()
Definition Env.h:251
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:49
T str(T... args)
T to_string(T... args)