Skip to content

Commit 7ce3b7e

Browse files
committed
[unit test] basic TxOrphanage eviction and protection
1 parent 4d23d1d commit 7ce3b7e

File tree

1 file changed

+359
-0
lines changed

1 file changed

+359
-0
lines changed

src/test/orphanage_tests.cpp

Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,365 @@ static bool EqualTxns(const std::set<CTransactionRef>& set_txns, const std::vect
7272
return true;
7373
}
7474

75+
unsigned int CheckNumEvictions(node::TxOrphanage& orphanage)
76+
{
77+
const auto original_total_count{orphanage.CountAnnouncements()};
78+
orphanage.LimitOrphans();
79+
assert(orphanage.TotalLatencyScore() <= orphanage.MaxGlobalLatencyScore());
80+
assert(orphanage.TotalOrphanUsage() <= orphanage.MaxGlobalUsage());
81+
return original_total_count - orphanage.CountAnnouncements();
82+
}
83+
84+
BOOST_AUTO_TEST_CASE(peer_dos_limits)
85+
{
86+
FastRandomContext det_rand{true};
87+
88+
// Construct transactions to use. They must all be the same size.
89+
static constexpr unsigned int NUM_TXNS_CREATED = 100;
90+
static constexpr int64_t TX_SIZE{469};
91+
static constexpr int64_t TOTAL_SIZE = NUM_TXNS_CREATED * TX_SIZE;
92+
93+
std::vector<CTransactionRef> txns;
94+
txns.reserve(NUM_TXNS_CREATED);
95+
// All transactions are the same size.
96+
for (unsigned int i{0}; i < NUM_TXNS_CREATED; ++i) {
97+
auto ptx = MakeTransactionSpending({}, det_rand);
98+
txns.emplace_back(ptx);
99+
BOOST_CHECK_EQUAL(TX_SIZE, GetTransactionWeight(*ptx));
100+
}
101+
102+
// Single peer: eviction is triggered if either limit is hit
103+
{
104+
// Test announcement limits
105+
NodeId peer{8};
106+
auto orphanage_low_ann = node::MakeTxOrphanage(/*max_global_ann=*/1, /*reserved_peer_usage=*/TX_SIZE * 10);
107+
auto orphanage_low_mem = node::MakeTxOrphanage(/*max_global_ann=*/10, /*reserved_peer_usage=*/TX_SIZE);
108+
109+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage_low_mem), 0);
110+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage_low_ann), 0);
111+
112+
// Add the first transaction
113+
orphanage_low_ann->AddTx(txns.at(0), peer);
114+
orphanage_low_mem->AddTx(txns.at(0), peer);
115+
116+
// Add more. One of the limits is exceeded, so LimitOrphans evicts 1.
117+
orphanage_low_ann->AddTx(txns.at(1), peer);
118+
BOOST_CHECK(orphanage_low_ann->TotalLatencyScore() > orphanage_low_ann->MaxGlobalLatencyScore());
119+
BOOST_CHECK(orphanage_low_ann->TotalOrphanUsage() <= orphanage_low_ann->MaxGlobalUsage());
120+
121+
orphanage_low_mem->AddTx(txns.at(1), peer);
122+
BOOST_CHECK(orphanage_low_mem->TotalLatencyScore() <= orphanage_low_mem->MaxGlobalLatencyScore());
123+
BOOST_CHECK(orphanage_low_mem->TotalOrphanUsage() > orphanage_low_mem->MaxGlobalUsage());
124+
125+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage_low_mem), 1);
126+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage_low_ann), 1);
127+
128+
// The older transaction is evicted.
129+
BOOST_CHECK(!orphanage_low_ann->HaveTx(txns.at(0)->GetWitnessHash()));
130+
BOOST_CHECK(!orphanage_low_mem->HaveTx(txns.at(0)->GetWitnessHash()));
131+
BOOST_CHECK(orphanage_low_ann->HaveTx(txns.at(1)->GetWitnessHash()));
132+
BOOST_CHECK(orphanage_low_mem->HaveTx(txns.at(1)->GetWitnessHash()));
133+
}
134+
135+
// Single peer: latency score includes inputs
136+
{
137+
// Test latency score limits
138+
NodeId peer{10};
139+
auto orphanage_low_ann = node::MakeTxOrphanage(/*max_global_ann=*/5, /*reserved_peer_usage=*/TX_SIZE * 1000);
140+
141+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage_low_ann), 0);
142+
143+
// Add the first transaction
144+
orphanage_low_ann->AddTx(txns.at(0), peer);
145+
146+
// Add 1 more transaction with 45 inputs. Even though there are only 2 announcements, this pushes the orphanage above its maximum latency score.
147+
std::vector<COutPoint> outpoints_45;
148+
for (unsigned int j{0}; j < 45; ++j) {
149+
outpoints_45.emplace_back(Txid::FromUint256(det_rand.rand256()), j);
150+
}
151+
auto ptx = MakeTransactionSpending(outpoints_45, det_rand);
152+
orphanage_low_ann->AddTx(ptx, peer);
153+
154+
BOOST_CHECK(orphanage_low_ann->TotalLatencyScore() > orphanage_low_ann->MaxGlobalLatencyScore());
155+
BOOST_CHECK(orphanage_low_ann->LatencyScoreFromPeer(peer) > orphanage_low_ann->MaxPeerLatencyScore());
156+
157+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage_low_ann), 1);
158+
159+
// The older transaction is evicted.
160+
BOOST_CHECK(!orphanage_low_ann->HaveTx(txns.at(0)->GetWitnessHash()));
161+
BOOST_CHECK(orphanage_low_ann->HaveTx(ptx->GetWitnessHash()));
162+
}
163+
164+
// Single peer: eviction order is FIFO on non-reconsiderable, then reconsiderable orphans.
165+
{
166+
// Construct parent + child pairs
167+
std::vector<CTransactionRef> parents;
168+
std::vector<CTransactionRef> children;
169+
for (unsigned int i{0}; i < 10; ++i) {
170+
CTransactionRef parent = MakeTransactionSpending({}, det_rand);
171+
CTransactionRef child = MakeTransactionSpending({{parent->GetHash(), 0}}, det_rand);
172+
parents.emplace_back(parent);
173+
children.emplace_back(child);
174+
}
175+
176+
// Test announcement limits
177+
NodeId peer{9};
178+
auto orphanage = node::MakeTxOrphanage(/*max_global_ann=*/3, /*reserved_peer_usage=*/TX_SIZE * 10);
179+
180+
// First add a tx which will be made reconsiderable.
181+
orphanage->AddTx(children.at(0), peer);
182+
183+
// Then add 2 more orphans... not oversize yet.
184+
orphanage->AddTx(children.at(1), peer);
185+
orphanage->AddTx(children.at(2), peer);
186+
187+
// Make child0 ready to reconsider
188+
orphanage->AddChildrenToWorkSet(*parents.at(0), det_rand);
189+
BOOST_CHECK(orphanage->HaveTxToReconsider(peer));
190+
191+
// Add 1 more orphan, causing the orphanage to be oversize. child1 is evicted.
192+
orphanage->AddTx(children.at(3), peer);
193+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
194+
BOOST_CHECK(orphanage->HaveTx(children.at(0)->GetWitnessHash()));
195+
BOOST_CHECK(!orphanage->HaveTx(children.at(1)->GetWitnessHash()));
196+
BOOST_CHECK(orphanage->HaveTx(children.at(2)->GetWitnessHash()));
197+
BOOST_CHECK(orphanage->HaveTx(children.at(3)->GetWitnessHash()));
198+
199+
// Add 1 more... child2 is evicted.
200+
orphanage->AddTx(children.at(4), peer);
201+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
202+
BOOST_CHECK(orphanage->HaveTx(children.at(0)->GetWitnessHash()));
203+
BOOST_CHECK(!orphanage->HaveTx(children.at(2)->GetWitnessHash()));
204+
BOOST_CHECK(orphanage->HaveTx(children.at(3)->GetWitnessHash()));
205+
BOOST_CHECK(orphanage->HaveTx(children.at(4)->GetWitnessHash()));
206+
207+
// Eviction order is FIFO within the orphans that are ready to be reconsidered.
208+
orphanage->AddChildrenToWorkSet(*parents.at(4), det_rand);
209+
orphanage->AddChildrenToWorkSet(*parents.at(3), det_rand);
210+
211+
// child5 is evicted immediately because it is the only non-reconsiderable orphan.
212+
orphanage->AddTx(children.at(5), peer);
213+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
214+
BOOST_CHECK(orphanage->HaveTx(children.at(0)->GetWitnessHash()));
215+
BOOST_CHECK(orphanage->HaveTx(children.at(3)->GetWitnessHash()));
216+
BOOST_CHECK(orphanage->HaveTx(children.at(4)->GetWitnessHash()));
217+
BOOST_CHECK(!orphanage->HaveTx(children.at(5)->GetWitnessHash()));
218+
219+
// Transactions are marked non-reconsiderable again when returned through GetTxToReconsider
220+
BOOST_CHECK_EQUAL(orphanage->GetTxToReconsider(peer), children.at(0));
221+
orphanage->AddTx(children.at(6), peer);
222+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
223+
BOOST_CHECK(!orphanage->HaveTx(children.at(0)->GetWitnessHash()));
224+
BOOST_CHECK(orphanage->HaveTx(children.at(3)->GetWitnessHash()));
225+
BOOST_CHECK(orphanage->HaveTx(children.at(4)->GetWitnessHash()));
226+
BOOST_CHECK(orphanage->HaveTx(children.at(6)->GetWitnessHash()));
227+
228+
// The first transaction returned from GetTxToReconsider is the older one, not the one that was marked for
229+
// reconsideration earlier.
230+
BOOST_CHECK_EQUAL(orphanage->GetTxToReconsider(peer), children.at(3));
231+
BOOST_CHECK_EQUAL(orphanage->GetTxToReconsider(peer), children.at(4));
232+
}
233+
234+
// Multiple peers: when limit is exceeded, we choose the DoSiest peer and evict their oldest transaction.
235+
{
236+
NodeId peer_dosy{0};
237+
NodeId peer1{1};
238+
NodeId peer2{2};
239+
240+
unsigned int max_announcements = 60;
241+
// Set a high per-peer reservation so announcement limit is always hit first.
242+
auto orphanage = node::MakeTxOrphanage(max_announcements, TOTAL_SIZE * 10);
243+
244+
// No evictions happen before the global limit is reached.
245+
for (unsigned int i{0}; i < max_announcements; ++i) {
246+
orphanage->AddTx(txns.at(i), peer_dosy);
247+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 0);
248+
}
249+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer_dosy), max_announcements);
250+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer1), 0);
251+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer2), 0);
252+
253+
// Add 10 unique transactions from peer1.
254+
// LimitOrphans should evict from peer_dosy, because that's the one exceeding announcement limits.
255+
unsigned int num_from_peer1 = 10;
256+
for (unsigned int i{0}; i < num_from_peer1; ++i) {
257+
orphanage->AddTx(txns.at(max_announcements + i), peer1);
258+
// The announcement limit per peer has halved, but LimitOrphans does not evict beyond what is necessary to
259+
// bring the total announcements within its global limit.
260+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
261+
BOOST_CHECK(orphanage->AnnouncementsFromPeer(peer_dosy) > orphanage->MaxPeerLatencyScore());
262+
263+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer1), i + 1);
264+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer_dosy), max_announcements - i - 1);
265+
266+
// Evictions are FIFO within a peer, so the ith transaction sent by peer_dosy is the one that was evicted.
267+
BOOST_CHECK(!orphanage->HaveTx(txns.at(i)->GetWitnessHash()));
268+
}
269+
// Add 10 transactions that are duplicates of the ones sent by peer_dosy. We need to add 10 because the first 10
270+
// were just evicted in the previous block additions.
271+
for (unsigned int i{num_from_peer1}; i < num_from_peer1 + 10; ++i) {
272+
// Tx has already been sent by peer_dosy
273+
BOOST_CHECK(orphanage->HaveTxFromPeer(txns.at(i)->GetWitnessHash(), peer_dosy));
274+
orphanage->AddTx(txns.at(i), peer2);
275+
276+
// Announcement limit is by entry, not by unique orphans
277+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
278+
279+
// peer_dosy is still the only one getting evicted
280+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer_dosy), max_announcements - i - 1);
281+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer1), num_from_peer1);
282+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer2), i + 1 - num_from_peer1);
283+
284+
// Evictions are FIFO within a peer, so the ith transaction sent by peer_dosy is the one that was evicted.
285+
BOOST_CHECK(!orphanage->HaveTxFromPeer(txns.at(i)->GetWitnessHash(), peer_dosy));
286+
BOOST_CHECK(orphanage->HaveTx(txns.at(i)->GetWitnessHash()));
287+
}
288+
289+
// With 6 peers, each can add 10, and still only peer_dosy's orphans are evicted.
290+
const unsigned int max_per_peer{max_announcements / 6};
291+
for (NodeId peer{3}; peer < 6; ++peer) {
292+
for (unsigned int i{0}; i < max_per_peer; ++i) {
293+
orphanage->AddTx(txns.at(peer * max_per_peer + i), peer);
294+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 1);
295+
}
296+
}
297+
for (NodeId peer{0}; peer < 6; ++peer) {
298+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer), max_per_peer);
299+
}
300+
}
301+
302+
// Limits change as more peers are added.
303+
{
304+
auto orphanage{node::MakeTxOrphanage()};
305+
// These stay the same regardless of number of peers
306+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
307+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
308+
309+
// These change with number of peers
310+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
311+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
312+
313+
// Number of peers = 1
314+
orphanage->AddTx(txns.at(0), 0);
315+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
316+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
317+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
318+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
319+
320+
// Number of peers = 2
321+
orphanage->AddTx(txns.at(1), 1);
322+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
323+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
324+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER * 2);
325+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE / 2);
326+
327+
// Number of peers = 3
328+
orphanage->AddTx(txns.at(2), 2);
329+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
330+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
331+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER * 3);
332+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE / 3);
333+
334+
// Number of peers didn't change.
335+
orphanage->AddTx(txns.at(3), 2);
336+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
337+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
338+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER * 3);
339+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE / 3);
340+
341+
// Once a peer has no orphans, it is not considered in the limits.
342+
// Number of peers = 2
343+
orphanage->EraseForPeer(2);
344+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
345+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
346+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER * 2);
347+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE / 2);
348+
349+
// Number of peers = 1
350+
orphanage->EraseTx(txns.at(0)->GetWitnessHash());
351+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
352+
BOOST_CHECK_EQUAL(orphanage->ReservedPeerUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
353+
BOOST_CHECK_EQUAL(orphanage->MaxGlobalUsage(), node::DEFAULT_RESERVED_ORPHAN_WEIGHT_PER_PEER);
354+
BOOST_CHECK_EQUAL(orphanage->MaxPeerLatencyScore(), node::DEFAULT_MAX_ORPHANAGE_LATENCY_SCORE);
355+
}
356+
357+
// Test eviction of multiple transactions at a time
358+
{
359+
// Create a large transaction that is 10 times larger than the normal size transaction.
360+
CMutableTransaction tx_large;
361+
tx_large.vin.resize(1);
362+
BulkTransaction(tx_large, 10 * TX_SIZE);
363+
auto ptx_large = MakeTransactionRef(tx_large);
364+
365+
const auto large_tx_size = GetTransactionWeight(*ptx_large);
366+
BOOST_CHECK(large_tx_size > 10 * TX_SIZE);
367+
BOOST_CHECK(large_tx_size < 11 * TX_SIZE);
368+
369+
auto orphanage = node::MakeTxOrphanage(20, large_tx_size);
370+
// One peer sends 10 normal size transactions. The other peer sends 10 normal transactions and 1 very large one
371+
NodeId peer_normal{0};
372+
NodeId peer_large{1};
373+
for (unsigned int i = 0; i < 20; i++) {
374+
orphanage->AddTx(txns.at(i), i < 10 ? peer_normal : peer_large);
375+
}
376+
BOOST_CHECK(orphanage->TotalLatencyScore() <= orphanage->MaxGlobalLatencyScore());
377+
BOOST_CHECK(orphanage->TotalOrphanUsage() <= orphanage->MaxGlobalUsage());
378+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 0);
379+
380+
// Add the large transaction. This should cause evictions of all the previous 10 transactions from that peer.
381+
orphanage->AddTx(ptx_large, peer_large);
382+
BOOST_CHECK_EQUAL(CheckNumEvictions(*orphanage), 10);
383+
384+
// peer_normal should still have 10 transactions, and peer_large should have 1.
385+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer_normal), 10);
386+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(peer_large), 1);
387+
BOOST_CHECK(orphanage->HaveTxFromPeer(ptx_large->GetWitnessHash(), peer_large));
388+
BOOST_CHECK_EQUAL(orphanage->CountAnnouncements(), 11);
389+
}
390+
391+
// Test that latency score includes number of inputs.
392+
{
393+
auto orphanage = node::MakeTxOrphanage();
394+
395+
// Add 10 transactions with 9 inputs each.
396+
std::vector<COutPoint> outpoints_9;
397+
for (unsigned int j{0}; j < 9; ++j) {
398+
outpoints_9.emplace_back(Txid::FromUint256(m_rng.rand256()), j);
399+
}
400+
for (unsigned int i{0}; i < 10; ++i) {
401+
auto ptx = MakeTransactionSpending(outpoints_9, m_rng);
402+
orphanage->AddTx(ptx, 0);
403+
}
404+
BOOST_CHECK_EQUAL(orphanage->CountAnnouncements(), 10);
405+
BOOST_CHECK_EQUAL(orphanage->TotalLatencyScore(), 10);
406+
407+
// Add 10 transactions with 50 inputs each.
408+
std::vector<COutPoint> outpoints_50;
409+
for (unsigned int j{0}; j < 50; ++j) {
410+
outpoints_50.emplace_back(Txid::FromUint256(m_rng.rand256()), j);
411+
}
412+
413+
for (unsigned int i{0}; i < 10; ++i) {
414+
CMutableTransaction tx;
415+
std::shuffle(outpoints_50.begin(), outpoints_50.end(), m_rng);
416+
auto ptx = MakeTransactionSpending(outpoints_50, m_rng);
417+
BOOST_CHECK(orphanage->AddTx(ptx, 0));
418+
if (i < 5) BOOST_CHECK(!orphanage->AddTx(ptx, 1));
419+
}
420+
// 10 of the 9-input transactions + 10 of the 50-input transactions + 5 more announcements of the 50-input transactions
421+
BOOST_CHECK_EQUAL(orphanage->CountAnnouncements(), 25);
422+
// Base of 25 announcements, plus 10 * 5 for the 50-input transactions (counted just once)
423+
BOOST_CHECK_EQUAL(orphanage->TotalLatencyScore(), 25 + 50);
424+
425+
// Peer 0 sent all 20 transactions
426+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(0), 20);
427+
BOOST_CHECK_EQUAL(orphanage->LatencyScoreFromPeer(0), 20 + 10 * 5);
428+
429+
// Peer 1 sent 5 of the 10 transactions with many inputs
430+
BOOST_CHECK_EQUAL(orphanage->AnnouncementsFromPeer(1), 5);
431+
BOOST_CHECK_EQUAL(orphanage->LatencyScoreFromPeer(1), 5 + 5 * 5);
432+
}
433+
}
75434
BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
76435
{
77436
// This test had non-deterministic coverage due to

0 commit comments

Comments
 (0)