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 ripple {
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 pass();
57 else
58 fail();
59 }
60 catch (...)
61 {
62 if (success)
63 fail();
64 else
65 pass();
66 }
67 };
68
69 test(true, true, 20, 25);
70 test(false, false, 20, 25);
71 test(false, false, 20, 0, false);
72 test(false, false, 20, 101, false);
73 test(false, false, 9, 10, false);
74 test(false, false, 10, 9, false);
75 });
76 }
77
78 class PeerTest : public PeerImp
79 {
80 public:
82 Application& app,
84 http_request_type&& request,
85 PublicKey const& publicKey,
87 Resource::Consumer consumer,
89 OverlayImpl& overlay)
90 : PeerImp(
91 app,
92 sid_,
93 slot,
94 std::move(request),
95 publicKey,
97 consumer,
98 std::move(stream_ptr),
99 overlay)
100 {
101 sid_++;
102 }
103 ~PeerTest() = default;
104
105 void
106 run() override
107 {
108 }
109 void
111 {
112 sendTx_++;
113 }
114 void
115 addTxQueue(uint256 const& hash) override
116 {
117 queueTx_++;
118 }
119 static void
121 {
122 queueTx_ = 0;
123 sendTx_ = 0;
124 sid_ = 0;
125 }
126 inline static std::size_t sid_ = 0;
127 inline static std::uint16_t queueTx_ = 0;
128 inline static std::uint16_t sendTx_ = 0;
129 };
130
135 boost::beast::multi_buffer read_buf_;
136
137public:
142
143private:
144 void
146 jtx::Env& env,
148 std::uint16_t& nDisabled)
149 {
150 auto& overlay = dynamic_cast<OverlayImpl&>(env.app().overlay());
151 boost::beast::http::request<boost::beast::http::dynamic_body> request;
152 (nDisabled == 0)
153 ? (void)request.insert(
154 "X-Protocol-Ctl",
155 makeFeaturesRequestHeader(false, false, true, false))
156 : (void)nDisabled--;
157 auto stream_ptr = std::make_unique<stream_type>(
159 env.app().getIOContext())),
160 *context_);
162 boost::asio::ip::make_address("172.1.1." + std::to_string(lid_)));
163 beast::IP::Endpoint remote(
164 boost::asio::ip::make_address("172.1.1." + std::to_string(rid_)));
166 auto consumer = overlay.resourceManager().newInboundEndpoint(remote);
167 auto [slot, _] = overlay.peerFinder().new_inbound_slot(local, remote);
168 auto const peer = std::make_shared<PeerTest>(
169 env.app(),
170 slot,
171 std::move(request),
172 key,
174 consumer,
175 std::move(stream_ptr),
176 overlay);
177 BEAST_EXPECT(
178 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().overlay().relay(uint256{0}, m, toSkip);
221 BEAST_EXPECT(
222 PeerTest::sendTx_ == expectRelay &&
223 PeerTest::queueTx_ == expectQueue);
224 }
225 }
226
227 void
228 run() override
229 {
230 bool log = false;
231 std::set<Peer::id_t> skip = {0, 1, 2, 3, 4};
233 // relay to all peers, no hash queue
234 testRelay("feature disabled", false, 10, 0, 10, 25, 10, 0);
235 // relay to nPeers - skip (10-5=5)
236 testRelay("feature disabled & skip", false, 10, 0, 10, 25, 5, 0, skip);
237 // relay to all peers because min is greater than nPeers
238 testRelay("relay all 1", true, 10, 0, 20, 25, 10, 0);
239 // relay to all peers because min + disabled is greater thant nPeers
240 testRelay("relay all 2", true, 20, 15, 10, 25, 20, 0);
241 // relay to minPeers + 25% of nPeers-minPeers (20+0.25*(60-20)=30),
242 // queue the rest (30)
243 testRelay("relay & queue", true, 60, 0, 20, 25, 30, 30);
244 // relay to minPeers + 25% of (nPeers - nPeers) - skip
245 // (20+0.25*(60-20)-5=25), queue the rest, skip counts towards relayed
246 // (60-25-5=30)
247 testRelay("skip", true, 60, 0, 20, 25, 25, 30, skip);
248 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disalbed)
249 // (20+10+0.25*(70-20-10)=40), queue the rest (30)
250 testRelay("disabled", true, 70, 10, 20, 25, 40, 30);
251 // relay to minPeers + disabled-not-in-skip + 25% of (nPeers - minPeers
252 // - disabled) (20+5+0.25*(70-20-10)=35), queue the rest, skip counts
253 // towards relayed (70-35-5=30))
254 testRelay("disabled & skip", true, 70, 10, 20, 25, 35, 30, skip);
255 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
256 // - skip (10+5+0.25*(15-10-5)-10=5), queue the rest, skip counts
257 // towards relayed (15-5-10=0)
258 skip = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
259 testRelay("disabled & skip, no queue", true, 15, 5, 10, 25, 5, 0, skip);
260 // relay to minPeers + disabled + 25% of (nPeers - minPeers - disabled)
261 // - skip (10+2+0.25*(20-10-2)-14=0), queue the rest, skip counts
262 // towards relayed (20-14=6)
263 skip = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
264 testRelay("disabled & skip, no relay", true, 20, 2, 10, 25, 0, 6, skip);
265 }
266};
267
268BEAST_DEFINE_TESTSUITE(tx_reduce_relay, overlay, ripple);
269} // namespace test
270} // namespace ripple
A version-independent IP address and port combination.
Definition IPEndpoint.h:19
A testsuite class.
Definition suite.h:52
log_os< char > log
Logging output stream.
Definition suite.h:149
void pass()
Record a successful test condition.
Definition suite.h:508
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:152
void fail(String const &reason, char const *file, int line)
Record a failure.
Definition suite.h:530
virtual Overlay & overlay()=0
virtual boost::asio::io_context & getIOContext()=0
std::size_t TX_REDUCE_RELAY_MIN_PEERS
Definition Config.h:249
bool TX_REDUCE_RELAY_ENABLE
Definition Config.h:239
bool TX_REDUCE_RELAY_METRICS
Definition Config.h:246
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:460
This class manages established peer-to-peer connections, handles message exchange,...
Definition PeerImp.h:99
std::shared_ptr< PeerFinder::Slot > const & slot()
Definition PeerImp.h:332
A public key.
Definition PublicKey.h:43
An endpoint that consumes resources.
Definition Consumer.h:17
std::size_t size() const noexcept
Definition Serializer.h:53
void const * data() const noexcept
Definition Serializer.h:59
A transaction testing environment.
Definition Env.h:102
Application & app()
Definition Env.h:242
void send(std::shared_ptr< Message > const &) override
void addTxQueue(uint256 const &hash) override
Add transaction's hash to the transactions' hashes queue.
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)
void doTest(std::string const &msg, bool log, std::function< void(bool)> f)
boost::beast::ssl_stream< middle_type > stream_type
void run() override
Runs the suite.
boost::asio::ip::tcp::socket socket_type
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::string makeFeaturesRequestHeader(bool comprEnabled, bool ledgerReplayEnabled, bool txReduceRelayEnabled, bool vpReduceRelayEnabled)
Make request header X-Protocol-Ctl value with supported features.
Definition Handshake.cpp:56
std::shared_ptr< boost::asio::ssl::context > make_SSLContext(std::string const &cipherList)
Create a self-signed SSL context that allows anonymous Diffie Hellman.
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
Definition Handoff.h:14
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
STL namespace.
T str(T... args)
T to_string(T... args)