mod.rs
Overview
This file implements core functionality for monitoring and managing a set of blockchain nodes (peers) and their associated accounts. It provides traits for accessing blockchain data, an asynchronous watcher function to continuously update node subscriptions and peer information, and utility functions to process and format peer data. The main purpose is to maintain an up-to-date view of the blockchain network topology with respect to active peers and their reachable addresses.
The file heavily relies on data structures such as sets and maps to track peers and their connection endpoints. It interacts with blockchain account abstractions and a node database module, facilitating dynamic subscription updates for network communication layers.
Modules and Imports
accountsandnode_dbmodules are declared internally.Uses collections (
HashMap,HashSet), formatting traits (Display), and network address types (SocketAddr).External crates: itertools for iterator utilities.
Imports blockchain account and type definitions from
tvm_blockandtvm_types.Imports helper functions and types from
accountsmodule within the same resolver::blockchain namespace.
Traits
BkSetProvider
pub trait BkSetProvider {
fn get_bk_set(&self) -> Vec<UInt256>;
}
Purpose: Provides a set of blockchain key identifiers (
UInt256values) used to identify accounts relevant for monitoring.Method:
get_bk_set(): Returns a vector of blockchain keys to track.
Usage: Implemented by components that can supply the current list of blockchain keys to be observed.
AccountProvider
pub trait AccountProvider {
fn get_account(&self, id: &UInt256) -> Option<Account>;
}
Purpose: Abstracts access to blockchain accounts by their identifiers.
Method:
get_account(id: &UInt256): Fetches anAccountobject for the given blockchain key if it exists.
Usage: Used to retrieve account data for blockchain keys provided by
BkSetProvider.
Asynchronous Functions
watch_blockchain
pub async fn watch_blockchain<PeerId, B, A>(
bk_set_provider: B,
account_provider: A,
self_peer_id: PeerId,
subscribe_tx: tokio::sync::watch::Sender<Vec<Vec<SocketAddr>>>,
peers_tx: tokio::sync::watch::Sender<HashMap<PeerId, SocketAddr>>,
) where
B: BkSetProvider + Send + Sync + 'static,
A: AccountProvider + Send + Sync + 'static,
PeerId: Display + Clone + Hash + Eq + From<UInt256>,
Purpose: Continuously monitors blockchain state changes and updates subscribed peers and peer connection information.
Parameters:
bk_set_provider: An implementation ofBkSetProvidersupplying blockchain keys.account_provider: An implementation ofAccountProviderto retrieve accounts.self_peer_id: Identifier for the current node (peer) running this watcher.subscribe_tx: Tokio watch channel sender to broadcast updated subscription address lists.peers_tx: Tokio watch channel sender to broadcast updated peer address maps.
Functionality:
Enters an infinite loop with a 60-second delay.
Calls
refreshto compute new subscriptions and peer maps.Sends updated data over the watch channels to notify subscribers.
Logs a trace message after each update cycle.
Usage Example:
let (subscribe_tx, mut subscribe_rx) = tokio::sync::watch::channel(Vec::new());
let (peers_tx, mut peers_rx) = tokio::sync::watch::channel(HashMap::new());
tokio::spawn(async move {
watch_blockchain(bk_set_provider, account_provider, self_peer_id, subscribe_tx, peers_tx).await;
});
refresh
async fn refresh<PeerId, B, A>(
self_peer_id: &PeerId,
bk_set_provider: &B,
account_provider: &A,
_old_subscribe: Vec<Vec<SocketAddr>>,
old_peers: HashMap<PeerId, SocketAddr>,
) -> (Vec<Vec<SocketAddr>>, HashMap<PeerId, SocketAddr>)
where
B: BkSetProvider + Send + Sync + 'static,
A: AccountProvider + Send + Sync + 'static,
PeerId: Display + Clone + Hash + Eq + From<UInt256>,
Purpose: Recomputes the current set of peer subscription endpoints and peer address mappings.
Parameters:
self_peer_id: The current node's peer identifier.bk_set_provider: Supplies blockchain keys to monitor.account_provider: Retrieves account data by blockchain key._old_subscribe: Previous subscription lists (unused in current implementation).old_peers: Previously known peer to address mappings.
Returns:
Tuple of:
Vec<Vec<SocketAddr>>: Updated subscription lists grouped by peer.HashMap<PeerId, SocketAddr>: Updated mapping of peers to their socket addresses.
Implementation Details:
Initializes an empty map
bk_setkeyed byPeerIdto aggregate peer addresses and proxies.For each blockchain key from
bk_set_provider:Attempts to get the account from
account_provider.Wraps the account in
Bkstruct.Calls
collect_bk_set(from accounts module) to populatebk_setwith publishers (peers).Logs errors if collection fails.
Constructs the
peersmap, filtering entries where address exists.Builds
subscribelists for each peer (except self).Compares new peer info string with old to log updates.
Usage: Internally called by
watch_blockchainto update network topology.
Helper Functions
peer_subscribe
fn peer_subscribe(peer_addr: Option<SocketAddr>, proxies: HashSet<SocketAddr>) -> Vec<SocketAddr>
Purpose: Generates a subscription list of socket addresses for a peer.
Parameters:
peer_addr: Optional primary address of the peer.proxies: Set of proxy addresses for the peer.
Returns: Vector of socket addresses to subscribe to.
Behavior:
If proxies are available, returns them as a vector.
Otherwise, if the primary address exists, returns a vector with it.
Returns an empty vector if neither is available.
Usage: Used by
refreshto determine addresses to subscribe for each peer.
peers_info
fn peers_info<PeerId>(nodes: &HashMap<PeerId, SocketAddr>) -> String
where
PeerId: Display,
Purpose: Creates a formatted string summarizing peer IDs and their addresses.
Parameters:
nodes: Map of peer identifiers to socket addresses.
Returns: String with comma-separated entries showing first 4 characters of peer ID and the address.
Usage: Utilized in
refreshto detect and log changes in peer set.
Interactions with Other Parts of the System
Uses
NodeDbfromnode_dbmodule (re-exported for external usage).Relies on
collect_bk_setandBkfrom theaccountsmodule to gather peer information from blockchain accounts.Depends on the blockchain account and identity abstractions from
tvm_block::Accountandtvm_types::UInt256.Communicates asynchronously via Tokio watch channels, allowing other components to react to peer and subscription updates.
The
PeerIdtype is generic but constrained to be convertible from a blockchain key (UInt256), clonable, hashable, and displayable.
Implementation Details and Algorithms
Uses a periodic polling loop with a fixed 60-second interval to refresh blockchain peer state.
Aggregates peer addresses and subscription proxies by traversing account data associated with blockchain keys.
Filtering and mapping logic ensures that the node does not subscribe to itself.
Employs string formatting and hashing to detect changes in peers for logging purposes.
The
collect_bk_setfunction (defined in theaccountsmodule) performs recursive or iterative collection of peer publishers from account data; this file depends on its output to build the network topology.
Visual Diagram
flowchart TD
A[watch_blockchain] -->|calls periodically| B[refresh]
B --> C[collect_bk_set]
B --> D[peer_subscribe]
B --> E[peers_info]
A -->|sends updates| F["subscribe_tx (watch channel)"]
A -->|sends updates| G["peers_tx (watch channel)"]
C -->|uses| H[AccountProvider]
C -->|uses| I[BkSetProvider]
D --> J[Vec<SocketAddr>]
E --> K[String summary]
Explanation:
watch_blockchainorchestrates the update cycle, invokingrefreshasynchronously.refreshinteracts with account and key providers to build peer sets.Helper functions
peer_subscribeandpeers_infoassist in formatting and filtering data.Changes detected are sent through Tokio watch channels to external listeners.
The diagram highlights the flow from data providers through processing to notification channels.