outbound.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 use crate::{PeerPoolHandling, Router, messages::Message}; 17 use alphavm::prelude::Network; 18 19 use std::net::SocketAddr; 20 21 pub trait Outbound<N: Network> { 22 /// Returns a reference to the router. 23 fn router(&self) -> &Router<N>; 24 25 /// Returns `true` if the node is synced up to the latest block (within the given tolerance). 26 fn is_block_synced(&self) -> bool; 27 28 /// Returns the number of blocks this node is behind the greatest peer height, 29 /// or `None` if not connected to peers yet. 30 fn num_blocks_behind(&self) -> Option<u32>; 31 32 /// Returns the current sync speed in blocks per second. 33 fn get_sync_speed(&self) -> f64; 34 35 /// Sends the given message to every connected peer, excluding the sender and any specified peer IPs. 36 fn propagate(&self, message: Message<N>, excluded_peers: &[SocketAddr]) { 37 // TODO (howardwu): Serialize large messages once only. 38 // // Perform ahead-of-time, non-blocking serialization just once for applicable objects. 39 // if let Message::UnconfirmedSolution(ref mut message) = message { 40 // if let Ok(serialized_solution) = Data::serialize(message.solution.clone()).await { 41 // let _ = std::mem::replace(&mut message.solution, Data::Buffer(serialized_solution)); 42 // } else { 43 // error!("Solution serialization is bugged"); 44 // } 45 // } else if let Message::UnconfirmedTransaction(ref mut message) = message { 46 // if let Ok(serialized_transaction) = Data::serialize(message.transaction.clone()).await { 47 // let _ = std::mem::replace(&mut message.transaction, Data::Buffer(serialized_transaction)); 48 // } else { 49 // error!("Transaction serialization is bugged"); 50 // } 51 // } 52 53 // Prepare the peers to send to. 54 let connected_peers = 55 self.router().filter_connected_peers(|peer| !excluded_peers.contains(&peer.listener_addr)); 56 57 // Iterate through all peers that are not the sender and excluded peers. 58 for addr in connected_peers.iter().map(|peer| peer.listener_addr) { 59 self.router().send(addr, message.clone()); 60 } 61 } 62 63 /// Sends the given message to every connected validator, excluding the sender and any specified IPs. 64 fn propagate_to_validators(&self, message: Message<N>, excluded_peers: &[SocketAddr]) { 65 // TODO (howardwu): Serialize large messages once only. 66 // // Perform ahead-of-time, non-blocking serialization just once for applicable objects. 67 // if let Message::UnconfirmedSolution(ref mut message) = message { 68 // if let Ok(serialized_solution) = Data::serialize(message.solution.clone()).await { 69 // let _ = std::mem::replace(&mut message.solution, Data::Buffer(serialized_solution)); 70 // } else { 71 // error!("Solution serialization is bugged"); 72 // } 73 // } else if let Message::UnconfirmedTransaction(ref mut message) = message { 74 // if let Ok(serialized_transaction) = Data::serialize(message.transaction.clone()).await { 75 // let _ = std::mem::replace(&mut message.transaction, Data::Buffer(serialized_transaction)); 76 // } else { 77 // error!("Transaction serialization is bugged"); 78 // } 79 // } 80 81 // Prepare the peers to send to. 82 let connected_validators = self.router().filter_connected_peers(|peer| { 83 peer.node_type.is_validator() && !excluded_peers.contains(&peer.listener_addr) 84 }); 85 86 // Iterate through all validators that are not the sender and excluded validators. 87 for listener_addr in connected_validators.iter().map(|peer| peer.listener_addr) { 88 self.router().send(listener_addr, message.clone()); 89 } 90 } 91 }