@@ -283,6 +283,179 @@ BOOST_AUTO_TEST_CASE(peer_protection_test)
283
283
/* protected_peer_ids */ {0 , 1 , 2 , 3 , 7 , 8 , 9 , 15 },
284
284
/* unprotected_peer_ids */ {5 , 6 , 10 , 11 , 12 , 13 , 14 },
285
285
random_context));
286
+
287
+ // Combined test: expect having 2 onion and 4 I2P out of 12 peers to protect
288
+ // 2 onion (prioritized for having fewer candidates) and 1 I2P, plus 3
289
+ // others, sorted by longest uptime.
290
+ BOOST_CHECK (IsProtected (
291
+ num_peers, [](NodeEvictionCandidate& c) {
292
+ c.nTimeConnected = c.id ;
293
+ c.m_is_local = false ;
294
+ if (c.id == 8 || c.id == 10 ) {
295
+ c.m_network = NET_ONION;
296
+ } else if (c.id == 6 || c.id == 9 || c.id == 11 || c.id == 12 ) {
297
+ c.m_network = NET_I2P;
298
+ } else {
299
+ c.m_network = NET_IPV4;
300
+ }
301
+ },
302
+ /* protected_peer_ids */ {0 , 1 , 2 , 6 , 8 , 10 },
303
+ /* unprotected_peer_ids */ {3 , 4 , 5 , 7 , 9 , 11 },
304
+ random_context));
305
+
306
+ // Tests with 3 networks...
307
+
308
+ // Combined test: expect having 1 localhost, 1 I2P and 1 onion peer out of 4
309
+ // to protect 1 I2P, 0 localhost, 0 onion and 1 other peer (2 total), sorted
310
+ // by longest uptime; stable sort breaks tie with array order of I2P first.
311
+ BOOST_CHECK (IsProtected (
312
+ 4 , [](NodeEvictionCandidate& c) {
313
+ c.nTimeConnected = c.id ;
314
+ c.m_is_local = (c.id == 3 );
315
+ if (c.id == 4 ) {
316
+ c.m_network = NET_I2P;
317
+ } else if (c.id == 2 ) {
318
+ c.m_network = NET_ONION;
319
+ } else {
320
+ c.m_network = NET_IPV6;
321
+ }
322
+ },
323
+ /* protected_peer_ids */ {0 , 4 },
324
+ /* unprotected_peer_ids */ {1 , 2 },
325
+ random_context));
326
+
327
+ // Combined test: expect having 1 localhost, 1 I2P and 1 onion peer out of 7
328
+ // to protect 1 I2P, 0 localhost, 0 onion and 2 other peers (3 total) sorted
329
+ // by longest uptime; stable sort breaks tie with array order of I2P first.
330
+ BOOST_CHECK (IsProtected (
331
+ 7 , [](NodeEvictionCandidate& c) {
332
+ c.nTimeConnected = c.id ;
333
+ c.m_is_local = (c.id == 4 );
334
+ if (c.id == 6 ) {
335
+ c.m_network = NET_I2P;
336
+ } else if (c.id == 5 ) {
337
+ c.m_network = NET_ONION;
338
+ } else {
339
+ c.m_network = NET_IPV6;
340
+ }
341
+ },
342
+ /* protected_peer_ids */ {0 , 1 , 6 },
343
+ /* unprotected_peer_ids */ {2 , 3 , 4 , 5 },
344
+ random_context));
345
+
346
+ // Combined test: expect having 1 localhost, 1 I2P and 1 onion peer out of 8
347
+ // to protect 1 I2P, 1 localhost, 0 onion and 2 other peers (4 total) sorted
348
+ // by uptime; stable sort breaks tie with array order of I2P then localhost.
349
+ BOOST_CHECK (IsProtected (
350
+ 8 , [](NodeEvictionCandidate& c) {
351
+ c.nTimeConnected = c.id ;
352
+ c.m_is_local = (c.id == 6 );
353
+ if (c.id == 5 ) {
354
+ c.m_network = NET_I2P;
355
+ } else if (c.id == 4 ) {
356
+ c.m_network = NET_ONION;
357
+ } else {
358
+ c.m_network = NET_IPV6;
359
+ }
360
+ },
361
+ /* protected_peer_ids */ {0 , 1 , 5 , 6 },
362
+ /* unprotected_peer_ids */ {2 , 3 , 4 , 7 },
363
+ random_context));
364
+
365
+ // Combined test: expect having 4 localhost, 2 I2P, and 2 onion peers out of
366
+ // 16 to protect 1 localhost, 2 I2P, and 1 onion (4/16 total), plus 4 others
367
+ // for 8 total, sorted by longest uptime.
368
+ BOOST_CHECK (IsProtected (
369
+ 16 , [](NodeEvictionCandidate& c) {
370
+ c.nTimeConnected = c.id ;
371
+ c.m_is_local = (c.id == 6 || c.id > 11 );
372
+ if (c.id == 7 || c.id == 11 ) {
373
+ c.m_network = NET_I2P;
374
+ } else if (c.id == 9 || c.id == 10 ) {
375
+ c.m_network = NET_ONION;
376
+ } else {
377
+ c.m_network = NET_IPV4;
378
+ }
379
+ },
380
+ /* protected_peer_ids */ {0 , 1 , 2 , 3 , 6 , 7 , 9 , 11 },
381
+ /* unprotected_peer_ids */ {4 , 5 , 8 , 10 , 12 , 13 , 14 , 15 },
382
+ random_context));
383
+
384
+ // Combined test: expect having 1 localhost, 8 I2P and 1 onion peer out of
385
+ // 24 to protect 1, 4, and 1 (6 total), plus 6 others for 12/24 total,
386
+ // sorted by longest uptime.
387
+ BOOST_CHECK (IsProtected (
388
+ 24 , [](NodeEvictionCandidate& c) {
389
+ c.nTimeConnected = c.id ;
390
+ c.m_is_local = (c.id == 12 );
391
+ if (c.id > 14 && c.id < 23 ) { // 4 protected instead of usual 2
392
+ c.m_network = NET_I2P;
393
+ } else if (c.id == 23 ) {
394
+ c.m_network = NET_ONION;
395
+ } else {
396
+ c.m_network = NET_IPV6;
397
+ }
398
+ },
399
+ /* protected_peer_ids */ {0 , 1 , 2 , 3 , 4 , 5 , 12 , 15 , 16 , 17 , 18 , 23 },
400
+ /* unprotected_peer_ids */ {6 , 7 , 8 , 9 , 10 , 11 , 13 , 14 , 19 , 20 , 21 , 22 },
401
+ random_context));
402
+
403
+ // Combined test: expect having 1 localhost, 3 I2P and 6 onion peers out of
404
+ // 24 to protect 1, 3, and 2 (6 total, I2P has fewer candidates and so gets the
405
+ // unused localhost slot), plus 6 others for 12/24 total, sorted by longest uptime.
406
+ BOOST_CHECK (IsProtected (
407
+ 24 , [](NodeEvictionCandidate& c) {
408
+ c.nTimeConnected = c.id ;
409
+ c.m_is_local = (c.id == 15 );
410
+ if (c.id == 12 || c.id == 14 || c.id == 17 ) {
411
+ c.m_network = NET_I2P;
412
+ } else if (c.id > 17 ) { // 4 protected instead of usual 2
413
+ c.m_network = NET_ONION;
414
+ } else {
415
+ c.m_network = NET_IPV4;
416
+ }
417
+ },
418
+ /* protected_peer_ids */ {0 , 1 , 2 , 3 , 4 , 5 , 12 , 14 , 15 , 17 , 18 , 19 },
419
+ /* unprotected_peer_ids */ {6 , 7 , 8 , 9 , 10 , 11 , 13 , 16 , 20 , 21 , 22 , 23 },
420
+ random_context));
421
+
422
+ // Combined test: expect having 1 localhost, 7 I2P and 4 onion peers out of
423
+ // 24 to protect 1 localhost, 2 I2P, and 3 onions (6 total), plus 6 others
424
+ // for 12/24 total, sorted by longest uptime.
425
+ BOOST_CHECK (IsProtected (
426
+ 24 , [](NodeEvictionCandidate& c) {
427
+ c.nTimeConnected = c.id ;
428
+ c.m_is_local = (c.id == 13 );
429
+ if (c.id > 16 ) {
430
+ c.m_network = NET_I2P;
431
+ } else if (c.id == 12 || c.id == 14 || c.id == 15 || c.id == 16 ) {
432
+ c.m_network = NET_ONION;
433
+ } else {
434
+ c.m_network = NET_IPV6;
435
+ }
436
+ },
437
+ /* protected_peer_ids */ {0 , 1 , 2 , 3 , 4 , 5 , 12 , 13 , 14 , 15 , 17 , 18 },
438
+ /* unprotected_peer_ids */ {6 , 7 , 8 , 9 , 10 , 11 , 16 , 19 , 20 , 21 , 22 , 23 },
439
+ random_context));
440
+
441
+ // Combined test: expect having 8 localhost, 4 I2P, and 3 onion peers out of
442
+ // 24 to protect 2 of each (6 total), plus 6 others for 12/24 total, sorted
443
+ // by longest uptime.
444
+ BOOST_CHECK (IsProtected (
445
+ 24 , [](NodeEvictionCandidate& c) {
446
+ c.nTimeConnected = c.id ;
447
+ c.m_is_local = (c.id > 15 );
448
+ if (c.id > 10 && c.id < 15 ) {
449
+ c.m_network = NET_I2P;
450
+ } else if (c.id > 6 && c.id < 10 ) {
451
+ c.m_network = NET_ONION;
452
+ } else {
453
+ c.m_network = NET_IPV4;
454
+ }
455
+ },
456
+ /* protected_peer_ids */ {0 , 1 , 2 , 3 , 4 , 5 , 7 , 8 , 11 , 12 , 16 , 17 },
457
+ /* unprotected_peer_ids */ {6 , 9 , 10 , 13 , 14 , 15 , 18 , 19 , 20 , 21 , 22 , 23 },
458
+ random_context));
286
459
}
287
460
288
461
// Returns true if any of the node ids in node_ids are selected for eviction.
0 commit comments