consensus_sync.rs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. use log::{info, warn};
  2. use crate::{
  3. consensus::{
  4. state::{ConsensusRequest, ConsensusResponse},
  5. ValidatorStatePtr,
  6. },
  7. net::P2pPtr,
  8. Result,
  9. };
  10. /// async task used for consensus state syncing.
  11. pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Result<()> {
  12. info!("Starting consensus state sync...");
  13. let channels_map = p2p.channels().lock().await;
  14. let values = channels_map.values();
  15. // Using len here because is_empty() uses unstable library feature
  16. // called 'exact_size_is_empty'.
  17. if values.len() != 0 {
  18. // Node iterates the channel peers to ask for their consensus state
  19. for channel in values {
  20. // Communication setup
  21. let msg_subsystem = channel.get_message_subsystem();
  22. msg_subsystem.add_dispatch::<ConsensusResponse>().await;
  23. let response_sub = channel.subscribe_msg::<ConsensusResponse>().await?;
  24. // Node creates a `ConsensusRequest` and sends it
  25. let request = ConsensusRequest { address: state.read().await.address };
  26. channel.send(request).await?;
  27. // Node verifies response came from a participating node.
  28. // Extra validations can be added here.
  29. let response = response_sub.receive().await?;
  30. if response.participants.is_empty() {
  31. warn!("Retrieved consensus state from a new node, retrying...");
  32. continue
  33. }
  34. // Node stores response data.
  35. let mut lock = state.write().await;
  36. lock.consensus.proposals = response.proposals.clone();
  37. lock.consensus.participants = response.participants.clone();
  38. break
  39. }
  40. } else {
  41. warn!("Node is not connected to other nodes, resetting consensus state.");
  42. state.write().await.reset_consensus_state()?;
  43. }
  44. info!("Consensus state synced!");
  45. Ok(())
  46. }