/ node / router / tests / cleanups.rs
cleanups.rs
  1  // Copyright (c) 2025-2026 ACDC Network
  2  // This file is part of the alphaos library.
  3  //
  4  // Alpha Chain | Delta Chain Protocol
  5  // International Monetary Graphite.
  6  //
  7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
  8  // They built world-class ZK infrastructure. We installed the EASY button.
  9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
 10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
 11  //
 12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
 13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
 14  // No rights reserved. No permission required. No warranty. No refunds.
 15  //
 16  // https://creativecommons.org/publicdomain/zero/1.0/
 17  // SPDX-License-Identifier: CC0-1.0
 18  
 19  mod common;
 20  use common::*;
 21  
 22  use alphaos_node_network::PeerPoolHandling;
 23  use alphaos_node_router::{Outbound, Routing};
 24  use alphaos_node_tcp::protocols::{Disconnect, Handshake, OnConnect};
 25  use alphavm::{prelude::Rng, utilities::TestRng};
 26  use deadline::deadline;
 27  use peak_alloc::PeakAlloc;
 28  
 29  use core::time::Duration;
 30  
 31  #[global_allocator]
 32  static PEAK_ALLOC: PeakAlloc = PeakAlloc;
 33  
 34  #[tokio::test]
 35  async fn test_connection_cleanups() {
 36      // The number of connections to start and close.
 37      const NUM_CONNECTIONS: usize = 10;
 38  
 39      // Initialize an Rng.
 40      let mut rng = TestRng::default();
 41  
 42      // Create 2 routers of random types.
 43      let mut nodes = Vec::with_capacity(2);
 44      for _ in 0..2 {
 45          let node = match rng.gen_range(0..=1) {
 46              0 => client(0, 1, &mut rng).await,
 47              1 => prover(0, 1, &mut rng).await,
 48              // TODO => validator(0, 1, &[], false, &mut rng).await,
 49              _ => unreachable!(),
 50          };
 51  
 52          nodes.push(node);
 53      }
 54  
 55      // Enable handshake handling.
 56      nodes[0].enable_handshake().await;
 57      nodes[1].enable_handshake().await;
 58  
 59      nodes[0].enable_disconnect().await;
 60      nodes[1].enable_disconnect().await;
 61  
 62      nodes[0].enable_on_connect().await;
 63      nodes[1].enable_on_connect().await;
 64  
 65      nodes[0].enable_listener().await;
 66      nodes[1].enable_listener().await;
 67  
 68      // We'll want to register heap use after a single connection, after the related collections are initialized.
 69      let mut heap_after_one_conn = None;
 70  
 71      // Connect and disconnect in a loop.
 72      for i in 0..NUM_CONNECTIONS {
 73          // Connect one of the nodes to the other one.
 74          nodes[1].connect(nodes[0].local_ip());
 75  
 76          // Wait until the connection is complete.
 77          let node0 = nodes[0].clone();
 78          let node1 = nodes[1].clone();
 79          deadline!(Duration::from_secs(3), move || node0.router().number_of_connected_peers() == 1
 80              && node1.router().number_of_connected_peers() == 1);
 81  
 82          // Since the connectee doesn't read from the connector, it can't tell that the connector disconnected
 83          // from it, so it needs to disconnect from it manually.
 84          nodes[0].disconnect(nodes[1].local_ip());
 85          nodes[1].disconnect(nodes[0].local_ip());
 86  
 87          // Wait until the disconnect is complete.
 88          let node0 = nodes[0].clone();
 89          let node1 = nodes[1].clone();
 90          deadline!(Duration::from_secs(3), move || node0.router().number_of_connected_peers() == 0
 91              && node1.router().number_of_connected_peers() == 0);
 92  
 93          // Register heap use after a single connection.
 94          if i == 0 {
 95              heap_after_one_conn = Some(PEAK_ALLOC.current_usage());
 96          }
 97      }
 98  
 99      // Register final heap use.
100      let heap_after_loop = PEAK_ALLOC.current_usage();
101  
102      // Final heap use should equal that after the first connection.
103      assert_eq!(heap_after_one_conn.unwrap(), heap_after_loop);
104  }