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