lib.rs
1 // Copyright (c) 2025 ADnet Contributors 2 // This file is part of the AlphaOS library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 #![forbid(unsafe_code)] 17 18 pub mod node_type; 19 pub use node_type::*; 20 21 pub mod peer; 22 pub use peer::*; 23 24 pub mod peering; 25 pub use peering::*; 26 27 pub mod resolver; 28 pub use resolver::*; 29 30 use alphavm::prelude::Network; 31 32 use std::{net::SocketAddr, str::FromStr}; 33 use tracing::*; 34 35 // Include the generated build information. 36 pub mod built_info { 37 include!(concat!(env!("OUT_DIR"), "/built.rs")); 38 } 39 40 /// Returns the list of bootstrap peers for the ALPHA network. 41 /// 42 /// Bootstrap peers can also be configured via environment variables: 43 /// - ALPHA_BOOTSTRAP_PEERS: Comma-separated list of peer addresses (e.g., "1.2.3.4:4130,5.6.7.8:4130") 44 #[allow(clippy::if_same_then_else)] 45 pub fn bootstrap_peers<N: Network>(is_dev: bool) -> Vec<SocketAddr> { 46 if cfg!(feature = "test") || is_dev { 47 // Development testing contains optional bootstrap peers loaded from the environment. 48 match std::env::var("TEST_BOOTSTRAP_PEERS") { 49 Ok(peers) => peers.split(',').map(|peer| SocketAddr::from_str(peer).unwrap()).collect(), 50 Err(err) => { 51 warn!("Failed to load bootstrap peers from environment: {err}"); 52 vec![] 53 } 54 } 55 } else if let Ok(peers) = std::env::var("ALPHA_BOOTSTRAP_PEERS") { 56 // Allow runtime configuration of bootstrap peers via environment variable. 57 peers.split(',').filter_map(|peer| SocketAddr::from_str(peer.trim()).ok()).collect() 58 } else if N::ID == alphavm::console::network::MainnetV0::ID { 59 // ALPHA Mainnet bootstrap peers (ADnet infrastructure). 60 // TODO: Replace with actual ADnet mainnet bootstrap node IPs when deployed. 61 vec![ 62 // Placeholder: ADnet mainnet bootstrap nodes 63 // SocketAddr::from_str("alpha-boot-1.adnet.io:4130").unwrap(), 64 // SocketAddr::from_str("alpha-boot-2.adnet.io:4130").unwrap(), 65 ] 66 } else if N::ID == alphavm::console::network::TestnetV0::ID { 67 // ALPHA Testnet bootstrap peers (ADnet infrastructure). 68 // TODO: Replace with actual ADnet testnet bootstrap node IPs when deployed. 69 vec![ 70 // Placeholder: ADnet testnet bootstrap nodes 71 // SocketAddr::from_str("alpha-test-1.adnet.io:4130").unwrap(), 72 // SocketAddr::from_str("alpha-test-2.adnet.io:4130").unwrap(), 73 ] 74 } else if N::ID == alphavm::console::network::CanaryV0::ID { 75 // ALPHA Canary bootstrap peers (ADnet infrastructure). 76 // TODO: Replace with actual ADnet canary bootstrap node IPs when deployed. 77 vec![ 78 // Placeholder: ADnet canary bootstrap nodes 79 // SocketAddr::from_str("alpha-canary-1.adnet.io:4130").unwrap(), 80 // SocketAddr::from_str("alpha-canary-2.adnet.io:4130").unwrap(), 81 ] 82 } else { 83 // Unrecognized networks contain no bootstrap peers. 84 vec![] 85 } 86 } 87 88 /// Get our SHA from the build information (or None if it is not set or does not 40 bytes long). 89 pub fn get_repo_commit_hash() -> Option<[u8; 40]> { 90 built_info::GIT_COMMIT_HASH.and_then(|sha| sha.as_bytes().try_into().ok()) 91 } 92 93 /// Logs the peer's AlphaOS repo SHA and how it compares to ours. 94 pub fn log_repo_sha_comparison(peer_addr: SocketAddr, peer_sha: &Option<[u8; 40]>, ctx: &str) { 95 let our_sha = get_repo_commit_hash(); 96 97 // Generate a string representation for the peers hash. 98 let peer_sha_str: Option<&str> = peer_sha.as_ref().and_then(|h| str::from_utf8(h).ok()); 99 100 let sha_cmp = match (&our_sha, peer_sha, peer_sha_str) { 101 // They sent no hash, or an invalid string. 102 (_, _, None) | (_, None, _) => " with an unknown repo SHA".to_owned(), 103 // Our hash cannot be retrieved. 104 (None, _, Some(theirs_str)) => format!("@{theirs_str} (potentially different than us)"), 105 // Both hashes are valid. Compare. 106 (Some(ours), Some(theirs), Some(theirs_str)) => { 107 if ours == theirs { 108 format!("@{theirs_str} (same as us)") 109 } else { 110 format!("@{theirs_str} (different than us)") 111 } 112 } 113 }; 114 115 debug!("{ctx} Peer '{peer_addr}' uses AlphaOS{sha_cmp}"); 116 }