/* This file is part of DarkFi (https://dark.fi) * * Copyright (C) 2020-2024 Dyne.org foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ use std::{collections::HashMap, sync::Arc}; use darkfi::{ net::{P2p, P2pPtr, Settings}, rpc::jsonrpc::JsonSubscriber, system::ExecutorPtr, validator::ValidatorPtr, Result, }; use log::info; // TODO: Protocal functions need to be protected so peers can't spam us. /// Block proposal broadcast protocol mod protocol_proposal; pub use protocol_proposal::{ProposalMessage, ProtocolProposalHandler, ProtocolProposalHandlerPtr}; /// Validator blockchain sync protocol mod protocol_sync; pub use protocol_sync::{ ForkSyncRequest, ForkSyncResponse, HeaderSyncRequest, HeaderSyncResponse, ProtocolSyncHandler, ProtocolSyncHandlerPtr, SyncRequest, SyncResponse, TipRequest, TipResponse, BATCH, }; /// Transaction broadcast protocol mod protocol_tx; pub use protocol_tx::{ProtocolTxHandler, ProtocolTxHandlerPtr}; /// Atomic pointer to the Darkfid P2P protocols handler. pub type DarkfidP2pHandlerPtr = Arc; /// Darkfid P2P protocols handler. pub struct DarkfidP2pHandler { /// P2P network pointer pub p2p: P2pPtr, /// `ProtocolProposal` messages handler proposals: ProtocolProposalHandlerPtr, /// `ProtocolSync` messages handler sync: ProtocolSyncHandlerPtr, /// `ProtocolTx` messages handler txs: ProtocolTxHandlerPtr, } impl DarkfidP2pHandler { /// Initialize a Darkfid P2P protocols handler. /// /// A new P2P instance is generated using provided settings and all /// corresponding protocols are registered. pub async fn init(settings: &Settings, executor: &ExecutorPtr) -> Result { info!( target: "darkfid::proto::mod::DarkfidP2pHandler::init", "Initializing a new Darkfid P2P handler..." ); // Generate a new P2P instance let p2p = P2p::new(settings.clone(), executor.clone()).await?; // Generate a new `ProtocolProposal` messages handler let proposals = ProtocolProposalHandler::init(&p2p).await; // Generate a new `ProtocolSync` messages handler let sync = ProtocolSyncHandler::init(&p2p).await; // Generate a new `ProtocolTx` messages handler let txs = ProtocolTxHandler::init(&p2p).await; info!( target: "darkfid::proto::mod::DarkfidP2pHandler::init", "Darkfid P2P handler generated successfully!" ); Ok(Arc::new(Self { p2p, proposals, sync, txs })) } /// Start the Darkfid P2P protocols handler for provided validator. pub async fn start( &self, executor: &ExecutorPtr, validator: &ValidatorPtr, subscribers: &HashMap<&'static str, JsonSubscriber>, ) -> Result<()> { info!( target: "darkfid::proto::mod::DarkfidP2pHandler::start", "Starting the Darkfid P2P handler..." ); // Start the `ProtocolProposal` messages handler let subscriber = subscribers.get("proposals").unwrap().clone(); self.proposals.start(executor, validator, &self.p2p, subscriber).await?; // Start the `ProtocolSync` messages handler self.sync.start(executor, validator).await?; // Start the `ProtocolTx` messages handler let subscriber = subscribers.get("txs").unwrap().clone(); self.txs.start(executor, validator, subscriber).await?; // Start the P2P instance self.p2p.clone().start().await?; info!( target: "darkfid::proto::mod::DarkfidP2pHandler::start", "Darkfid P2P handler started successfully!" ); Ok(()) } /// Stop the Darkfid P2P protocols handler. pub async fn stop(&self) { info!(target: "darkfid::proto::mod::DarkfidP2pHandler::stop", "Terminating Darkfid P2P handler..."); // Stop the P2P instance self.p2p.stop().await; // Start the `ProtocolTx` messages handler self.txs.stop().await; // Start the `ProtocolSync` messages handler self.sync.stop().await; // Start the `ProtocolProposal` messages handler self.proposals.stop().await; info!(target: "darkfid::proto::mod::DarkfidP2pHandler::stop", "Darkfid P2P handler terminated successfully!"); } }