use async_executor::Executor; use async_trait::async_trait; use darkfi::{ consensus::{state::StatePtr, vote::Vote}, net::{ ChannelPtr, MessageSubscription, ProtocolBase, ProtocolBasePtr, ProtocolJobsManager, ProtocolJobsManagerPtr, }, Result, }; use log::debug; use std::sync::Arc; pub struct ProtocolVote { vote_sub: MessageSubscription, jobsman: ProtocolJobsManagerPtr, state: StatePtr, } impl ProtocolVote { pub async fn init(channel: ChannelPtr, state: StatePtr) -> ProtocolBasePtr { let message_subsytem = channel.get_message_subsystem(); message_subsytem.add_dispatch::().await; let vote_sub = channel.subscribe_msg::().await.expect("Missing Vote dispatcher!"); Arc::new(Self { vote_sub, jobsman: ProtocolJobsManager::new("VoteProtocol", channel), state, }) } // TODO: 1. Nodes count not hardcoded. async fn handle_receive_vote(self: Arc) -> Result<()> { debug!(target: "ircd", "ProtocolVote::handle_receive_vote() [START]"); loop { let vote = self.vote_sub.receive().await?; debug!( target: "ircd", "ProtocolVote::handle_receive_vote() received {:?}", vote ); let vote_copy = (*vote).clone(); let nodes_count = 4; self.state.write().unwrap().receive_vote(&vote_copy, nodes_count); } } } #[async_trait] impl ProtocolBase for ProtocolVote { async fn start(self: Arc, executor: Arc>) -> Result<()> { debug!(target: "ircd", "ProtocolVote::start() [START]"); self.jobsman.clone().start(executor.clone()); self.jobsman.clone().spawn(self.clone().handle_receive_vote(), executor.clone()).await; debug!(target: "ircd", "ProtocolVote::start() [END]"); Ok(()) } fn name(&self) -> &'static str { "ProtocolVote" } }