| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- use crate::{
- consensus::{
- block::{BlockOrder, BlockResponse},
- ValidatorStatePtr,
- },
- net, Result,
- };
- use log::{debug, info, warn};
- /// async task used for block syncing.
- pub async fn block_sync_task(p2p: net::P2pPtr, state: ValidatorStatePtr) -> Result<()> {
- info!("Starting blockchain sync...");
- // we retrieve p2p network connected channels, so we can use it to
- // parallelize downloads.
- // Using len here because is_empty() uses unstable library feature
- // called 'exact_size_is_empty'.
- if p2p.channels().lock().await.values().len() != 0 {
- // Currently we will just use the last channel
- let channel = p2p.channels().lock().await.values().last().unwrap().clone();
- // Communication setup
- let msg_subsystem = channel.get_message_subsystem();
- msg_subsystem.add_dispatch::<BlockResponse>().await;
- let response_sub = channel.subscribe_msg::<BlockResponse>().await?;
- // Node sends the last known block hash of the canonical blockchain
- // and loops until the response is the same block (used to utilize
- // batch requests).
- let mut last = state.read().await.blockchain.last()?;
- info!("Last known block: {:?} - {:?}", last.0, last.1);
- loop {
- // Node creates a `BlockOrder` and sends it
- let order = BlockOrder { slot: last.0, block: last.1 };
- channel.send(order).await?;
- // Node stores response data.
- let resp = response_sub.receive().await?;
- // Verify and store retrieved blocks
- debug!("block_sync_task(): Processing received blocks");
- state.write().await.receive_blocks(&resp.blocks).await?;
- let last_received = state.read().await.blockchain.last()?;
- info!("Last received block: {:?} - {:?}", last_received.0, last_received.1);
- if last == last_received {
- break
- }
- last = last_received;
- }
- } else {
- warn!("Node is not connected to other nodes");
- }
- info!("Blockchain synced!");
- Ok(())
- }
|