connect.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_tcp::{ 24 protocols::{Disconnect, Handshake, OnConnect}, 25 P2P, 26 }; 27 use alphavm::prelude::TestRng; 28 29 use core::time::Duration; 30 use deadline::deadline; 31 32 #[tokio::test] 33 async fn test_connect_without_handshake() { 34 let mut rng = TestRng::default(); 35 36 // Create 2 routers. 37 let node0 = validator(0, 2, &[], true, &mut rng).await; 38 let node1 = client(0, 2, &mut rng).await; 39 assert_eq!(node0.number_of_connected_peers(), 0); 40 assert_eq!(node1.number_of_connected_peers(), 0); 41 42 // Start listening. 43 node0.tcp().enable_listener().await.unwrap(); 44 node1.tcp().enable_listener().await.unwrap(); 45 46 { 47 // Connect node0 to node1. 48 node0.connect(node1.local_ip()); 49 // Sleep briefly. 50 tokio::time::sleep(Duration::from_millis(100)).await; 51 52 print_tcp!(node0); 53 print_tcp!(node1); 54 55 assert_eq!(node0.tcp().num_connected(), 1); 56 assert_eq!(node0.tcp().num_connecting(), 0); 57 assert_eq!(node1.tcp().num_connected(), 1); 58 assert_eq!(node1.tcp().num_connecting(), 0); 59 } 60 { 61 // Connect node0 from node1 again. 62 node0.connect(node1.local_ip()); 63 // Sleep briefly. 64 tokio::time::sleep(Duration::from_millis(100)).await; 65 66 print_tcp!(node0); 67 print_tcp!(node1); 68 69 assert_eq!(node0.tcp().num_connected(), 1); 70 assert_eq!(node0.tcp().num_connecting(), 0); 71 assert_eq!(node1.tcp().num_connected(), 1); 72 assert_eq!(node1.tcp().num_connecting(), 0); 73 } 74 { 75 // Connect node1 from node0. 76 node1.connect(node0.local_ip()); 77 // Sleep briefly. 78 tokio::time::sleep(Duration::from_millis(100)).await; 79 80 print_tcp!(node0); 81 print_tcp!(node1); 82 83 assert_eq!(node0.tcp().num_connected(), 2); // node0 has no way of deduping the connection. 84 assert_eq!(node0.tcp().num_connecting(), 0); 85 assert_eq!(node1.tcp().num_connected(), 2); // node1 has no way of deduping the connection. 86 assert_eq!(node1.tcp().num_connecting(), 0); 87 } 88 } 89 90 #[tokio::test] 91 async fn test_connect_with_handshake() { 92 let mut rng = TestRng::default(); 93 94 // Create 2 routers. 95 let node0 = validator(0, 2, &[], true, &mut rng).await; 96 let node1 = client(0, 2, &mut rng).await; 97 assert_eq!(node0.number_of_connected_peers(), 0); 98 assert_eq!(node1.number_of_connected_peers(), 0); 99 100 // Enable handshake protocol. 101 node0.enable_handshake().await; 102 node1.enable_handshake().await; 103 104 // Enable on_connect protocol. 105 node0.enable_on_connect().await; 106 node1.enable_on_connect().await; 107 108 // Start listening. 109 node0.tcp().enable_listener().await.unwrap(); 110 node1.tcp().enable_listener().await.unwrap(); 111 112 { 113 // Connect node0 to node1. 114 node0.connect(node1.local_ip()); 115 // Await for node1 to be connected. 116 let node0_ip = node0.local_ip(); 117 let node1_ = node1.clone(); 118 deadline!(Duration::from_secs(5), move || { node1_.is_connected(node0_ip) }); 119 120 print_tcp!(node0); 121 print_tcp!(node1); 122 123 // Check the TCP level. 124 assert_eq!(node0.tcp().num_connected(), 1); 125 assert_eq!(node0.tcp().num_connecting(), 0); 126 assert_eq!(node1.tcp().num_connected(), 1); 127 assert_eq!(node1.tcp().num_connecting(), 0); 128 129 // Check the router level. 130 assert_eq!(node0.number_of_connected_peers(), 1); 131 assert_eq!(node1.number_of_connected_peers(), 1); 132 } 133 { 134 // Connect node0 to node1 again. 135 node0.connect(node1.local_ip()); 136 // Await for node1 to be connected. 137 let node0_ip = node0.local_ip(); 138 let node1_ = node1.clone(); 139 deadline!(Duration::from_secs(5), move || { node1_.is_connected(node0_ip) }); 140 141 print_tcp!(node0); 142 print_tcp!(node1); 143 144 // Check the TCP level. 145 assert_eq!(node0.tcp().num_connected(), 1); 146 assert_eq!(node0.tcp().num_connecting(), 0); 147 assert_eq!(node1.tcp().num_connected(), 1); 148 assert_eq!(node1.tcp().num_connecting(), 0); 149 150 // Check the router level. 151 assert_eq!(node0.number_of_connected_peers(), 1); 152 assert_eq!(node1.number_of_connected_peers(), 1); 153 } 154 { 155 // Connect node1 to node0. 156 node1.connect(node0.local_ip()); 157 // Await for node0 to be connected. 158 let node1_ip = node1.local_ip(); 159 let node0_ = node0.clone(); 160 deadline!(Duration::from_secs(5), move || { node0_.is_connected(node1_ip) }); 161 162 print_tcp!(node0); 163 print_tcp!(node1); 164 165 // Check the TCP level. 166 assert_eq!(node0.tcp().num_connected(), 1); 167 assert_eq!(node0.tcp().num_connecting(), 0); 168 assert_eq!(node1.tcp().num_connected(), 1); 169 assert_eq!(node1.tcp().num_connecting(), 0); 170 171 // Check the router level. 172 assert_eq!(node0.number_of_connected_peers(), 1); 173 assert_eq!(node1.number_of_connected_peers(), 1); 174 } 175 } 176 177 #[tokio::test] 178 async fn test_validator_connection() { 179 let mut rng = TestRng::default(); 180 181 // Create first router and start listening. 182 let node0 = validator(0, 2, &[], false, &mut rng).await; 183 assert_eq!(node0.number_of_connected_peers(), 0); 184 node0.enable_handshake().await; 185 node0.enable_on_connect().await; 186 node0.enable_disconnect().await; 187 node0.tcp().enable_listener().await.unwrap(); 188 189 // Get the local IP address from the first router. 190 let addr0 = node0.local_ip(); 191 192 // Create second router, trusting the first router, and start listening. 193 let node1 = validator(0, 2, &[addr0], false, &mut rng).await; 194 assert_eq!(node1.number_of_connected_peers(), 0); 195 node1.enable_handshake().await; 196 node1.enable_on_connect().await; 197 node1.enable_disconnect().await; 198 node1.tcp().enable_listener().await.unwrap(); 199 200 { 201 // Connect node0 to node1. 202 node0.connect(node1.local_ip()); 203 // Await for node1 to be connected. 204 let node0_ip = node0.local_ip(); 205 let node1_ = node1.clone(); 206 deadline!(Duration::from_secs(5), move || { node1_.is_connected(node0_ip) }); 207 208 print_tcp!(node0); 209 print_tcp!(node1); 210 211 // Check the TCP level - connection was accepted. 212 assert_eq!(node0.tcp().num_connected(), 1); 213 assert_eq!(node1.tcp().num_connected(), 1); 214 215 // Check the router level - connection was accepted. 216 assert_eq!(node0.number_of_connected_peers(), 1); 217 assert_eq!(node1.number_of_connected_peers(), 1); 218 219 // Disconnect the nodes. 220 node0.disconnect(node1.local_ip()); 221 node1.disconnect(node0.local_ip()); 222 223 // Await for node1 and node0 to be disconnected. 224 let node1_ = node1.clone(); 225 let node0_ = node0.clone(); 226 deadline!(Duration::from_secs(5), move || { 227 !node1_.is_connected(node0_.local_ip()) && !node0_.is_connected(node1_.local_ip()) 228 }); 229 230 // Connect node1 to node0. 231 let Ok(res) = node1.connect(node0.local_ip()).unwrap().await else { 232 panic!("Connection failed for the wrong reasons."); 233 }; 234 assert!(!res, "Connection was accepted when it should not have been."); 235 236 // Check the TCP level - connection was not accepted. 237 assert_eq!(node0.tcp().num_connected(), 0); 238 assert_eq!(node1.tcp().num_connected(), 0); 239 240 // Check the router level - connection was not accepted. 241 assert_eq!(node0.number_of_connected_peers(), 0); 242 assert_eq!(node1.number_of_connected_peers(), 0); 243 } 244 } 245 246 #[ignore] 247 #[tokio::test] 248 async fn test_connect_simultaneously_with_handshake() { 249 let mut rng = TestRng::default(); 250 251 // Create 2 routers. 252 let node0 = validator(0, 2, &[], true, &mut rng).await; 253 let node1 = client(0, 2, &mut rng).await; 254 assert_eq!(node0.number_of_connected_peers(), 0); 255 assert_eq!(node1.number_of_connected_peers(), 0); 256 257 // Enable handshake protocol. 258 node0.enable_handshake().await; 259 node1.enable_handshake().await; 260 261 { 262 // Connect node0 to node1. 263 node0.connect(node1.local_ip()); 264 // Connect node1 to node0. 265 node1.connect(node0.local_ip()); 266 // Sleep briefly. 267 tokio::time::sleep(Duration::from_millis(100)).await; 268 269 print_tcp!(node0); 270 print_tcp!(node1); 271 272 // Check the TCP level. 273 assert_eq!(node0.tcp().num_connected(), 1); 274 assert_eq!(node0.tcp().num_connecting(), 0); 275 assert_eq!(node1.tcp().num_connected(), 1); 276 assert_eq!(node1.tcp().num_connecting(), 0); 277 278 // Check the router level. 279 assert_eq!(node0.number_of_connected_peers(), 1); 280 assert_eq!(node1.number_of_connected_peers(), 1); 281 } 282 }