/ node / router / src / outbound.rs
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  }