1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
1819use std::{collections::HashMap, sync::Arc};
2021use darkfi::{
22 net::{P2p, P2pPtr, Settings},
23 rpc::jsonrpc::JsonSubscriber,
24 system::ExecutorPtr,
25 validator::ValidatorPtr,
26Result,
27};
28use log::info;
2930/// Block proposal broadcast protocol
31mod protocol_proposal;
32pub use protocol_proposal::{ProposalMessage, ProtocolProposalHandler, ProtocolProposalHandlerPtr};
3334/// Validator blockchain sync protocol
35mod protocol_sync;
36pub use protocol_sync::{
37 ForkHeaderHashRequest, ForkHeaderHashResponse, ForkHeadersRequest, ForkHeadersResponse,
38 ForkProposalsRequest, ForkProposalsResponse, ForkSyncRequest, ForkSyncResponse,
39 HeaderSyncRequest, HeaderSyncResponse, ProtocolSyncHandler, ProtocolSyncHandlerPtr,
40 SyncRequest, SyncResponse, TipRequest, TipResponse, BATCH,
41};
4243/// Transaction broadcast protocol
44mod protocol_tx;
45pub use protocol_tx::{ProtocolTxHandler, ProtocolTxHandlerPtr};
4647/// Atomic pointer to the Darkfid P2P protocols handler.
48pub type DarkfidP2pHandlerPtr = Arc<DarkfidP2pHandler>;
4950/// Darkfid P2P protocols handler.
51pub struct DarkfidP2pHandler {
52/// P2P network pointer
53pub p2p: P2pPtr,
54/// `ProtocolProposal` messages handler
55proposals: ProtocolProposalHandlerPtr,
56/// `ProtocolSync` messages handler
57sync: ProtocolSyncHandlerPtr,
58/// `ProtocolTx` messages handler
59txs: ProtocolTxHandlerPtr,
60}
6162impl DarkfidP2pHandler {
63/// Initialize a Darkfid P2P protocols handler.
64 ///
65 /// A new P2P instance is generated using provided settings and all
66 /// corresponding protocols are registered.
67pub async fn init(settings: &Settings, executor: &ExecutorPtr) -> Result<DarkfidP2pHandlerPtr> {
68info!(
69 target: "darkfid::proto::mod::DarkfidP2pHandler::init",
70"Initializing a new Darkfid P2P handler..."
71);
7273// Generate a new P2P instance
74let p2p = P2p::new(settings.clone(), executor.clone()).await?;
7576// Generate a new `ProtocolProposal` messages handler
77let proposals = ProtocolProposalHandler::init(&p2p).await;
7879// Generate a new `ProtocolSync` messages handler
80let sync = ProtocolSyncHandler::init(&p2p).await;
8182// Generate a new `ProtocolTx` messages handler
83let txs = ProtocolTxHandler::init(&p2p).await;
8485info!(
86 target: "darkfid::proto::mod::DarkfidP2pHandler::init",
87"Darkfid P2P handler generated successfully!"
88);
8990Ok(Arc::new(Self { p2p, proposals, sync, txs }))
91 }
9293/// Start the Darkfid P2P protocols handler for provided validator.
94pub async fn start(
95&self,
96 executor: &ExecutorPtr,
97 validator: &ValidatorPtr,
98 subscribers: &HashMap<&'static str, JsonSubscriber>,
99 ) -> Result<()> {
100info!(
101 target: "darkfid::proto::mod::DarkfidP2pHandler::start",
102"Starting the Darkfid P2P handler..."
103);
104105// Start the `ProtocolProposal` messages handler
106let proposals_sub = subscribers.get("proposals").unwrap().clone();
107let blocks_sub = subscribers.get("blocks").unwrap().clone();
108self.proposals.start(executor, validator, &self.p2p, proposals_sub, blocks_sub).await?;
109110// Start the `ProtocolSync` messages handler
111self.sync.start(executor, validator).await?;
112113// Start the `ProtocolTx` messages handler
114let subscriber = subscribers.get("txs").unwrap().clone();
115self.txs.start(executor, validator, subscriber).await?;
116117// Start the P2P instance
118self.p2p.clone().start().await?;
119120info!(
121 target: "darkfid::proto::mod::DarkfidP2pHandler::start",
122"Darkfid P2P handler started successfully!"
123);
124125Ok(())
126 }
127128/// Stop the Darkfid P2P protocols handler.
129pub async fn stop(&self) {
130info!(target: "darkfid::proto::mod::DarkfidP2pHandler::stop", "Terminating Darkfid P2P handler...");
131132// Stop the P2P instance
133self.p2p.stop().await;
134135// Start the `ProtocolTx` messages handler
136self.txs.stop().await;
137138// Start the `ProtocolSync` messages handler
139self.sync.stop().await;
140141// Start the `ProtocolProposal` messages handler
142self.proposals.stop().await;
143144info!(target: "darkfid::proto::mod::DarkfidP2pHandler::stop", "Darkfid P2P handler terminated successfully!");
145 }
146}