protocol_proposal.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. use async_executor::Executor;
  2. use async_trait::async_trait;
  3. use darkfi::{
  4. consensus::{block::BlockProposal, state::StatePtr},
  5. net::{
  6. ChannelPtr, MessageSubscription, P2pPtr, ProtocolBase, ProtocolBasePtr,
  7. ProtocolJobsManager, ProtocolJobsManagerPtr,
  8. },
  9. Result,
  10. };
  11. use log::debug;
  12. use std::sync::Arc;
  13. pub struct ProtocolProposal {
  14. proposal_sub: MessageSubscription<BlockProposal>,
  15. jobsman: ProtocolJobsManagerPtr,
  16. state: StatePtr,
  17. p2p: P2pPtr,
  18. }
  19. impl ProtocolProposal {
  20. pub async fn init(channel: ChannelPtr, state: StatePtr, p2p: P2pPtr) -> ProtocolBasePtr {
  21. let message_subsytem = channel.get_message_subsystem();
  22. message_subsytem.add_dispatch::<BlockProposal>().await;
  23. let proposal_sub =
  24. channel.subscribe_msg::<BlockProposal>().await.expect("Missing Proposal dispatcher!");
  25. Arc::new(Self {
  26. proposal_sub,
  27. jobsman: ProtocolJobsManager::new("ProposalProtocol", channel),
  28. state,
  29. p2p,
  30. })
  31. }
  32. async fn handle_receive_proposal(self: Arc<Self>) -> Result<()> {
  33. debug!(target: "ircd", "ProtocolBlock::handle_receive_proposal() [START]");
  34. loop {
  35. let proposal = self.proposal_sub.receive().await?;
  36. debug!(
  37. target: "ircd",
  38. "ProtocolProposal::handle_receive_proposal() received {:?}",
  39. proposal
  40. );
  41. let proposal_copy = (*proposal).clone();
  42. let vote = self.state.write().unwrap().receive_proposal(&proposal_copy);
  43. match vote {
  44. Ok(x) => {
  45. if x.is_none() {
  46. debug!("Node did not vote for the proposed block.");
  47. } else {
  48. let vote = x.unwrap();
  49. self.state.write().unwrap().receive_vote(&vote);
  50. // Broadcasting block to rest nodes
  51. self.p2p.broadcast(proposal_copy).await?;
  52. // Broadcasting vote
  53. self.p2p.broadcast(vote).await?;
  54. }
  55. }
  56. Err(e) => {
  57. debug!(target: "ircd", "ProtocolBlock::handle_receive_proposal() error prosessing proposal: {:?}", e)
  58. }
  59. }
  60. }
  61. }
  62. }
  63. #[async_trait]
  64. impl ProtocolBase for ProtocolProposal {
  65. async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  66. debug!(target: "ircd", "ProtocolProposal::start() [START]");
  67. self.jobsman.clone().start(executor.clone());
  68. self.jobsman.clone().spawn(self.clone().handle_receive_proposal(), executor.clone()).await;
  69. debug!(target: "ircd", "ProtocolProposal::start() [END]");
  70. Ok(())
  71. }
  72. fn name(&self) -> &'static str {
  73. "ProtocolProposal"
  74. }
  75. }