karyon_p2p/protocol.rs
1use std::sync::Arc;
2
3use async_trait::async_trait;
4
5use karyon_core::event::EventValue;
6
7use crate::{peer::Peer, version::Version, Result};
8
9pub type ProtocolConstructor = dyn Fn(Arc<Peer>) -> Arc<dyn Protocol> + Send + Sync;
10
11pub type ProtocolID = String;
12
13/// Protocol event
14#[derive(Debug, Clone)]
15pub enum ProtocolEvent {
16 /// Message event, contains a vector of bytes.
17 Message(Vec<u8>),
18 /// Shutdown event signals the protocol to gracefully shut down.
19 Shutdown,
20}
21
22impl EventValue for ProtocolEvent {
23 fn id() -> &'static str {
24 "ProtocolEvent"
25 }
26}
27
28/// The Protocol trait defines the interface for core protocols
29/// and custom protocols.
30///
31/// # Example
32/// ```
33/// use std::sync::Arc;
34///
35/// use async_trait::async_trait;
36/// use smol::Executor;
37///
38/// use karyon_p2p::{
39/// protocol::{Protocol, ProtocolID, ProtocolEvent},
40/// Backend, PeerID, Config, Version, Error, Peer,
41/// keypair::{KeyPair, KeyPairType},
42/// };
43///
44/// pub struct NewProtocol {
45/// peer: Arc<Peer>,
46/// }
47///
48/// impl NewProtocol {
49/// fn new(peer: Arc<Peer>) -> Arc<dyn Protocol> {
50/// Arc::new(Self {
51/// peer,
52/// })
53/// }
54/// }
55///
56/// #[async_trait]
57/// impl Protocol for NewProtocol {
58/// async fn start(self: Arc<Self>) -> Result<(), Error> {
59/// loop {
60/// match self.peer.recv::<Self>().await.expect("Receive msg") {
61/// ProtocolEvent::Message(msg) => {
62/// println!("{:?}", msg);
63/// }
64/// ProtocolEvent::Shutdown => {
65/// break;
66/// }
67/// }
68/// }
69/// Ok(())
70/// }
71///
72/// fn version() -> Result<Version, Error> {
73/// "0.2.0, >0.1.0".parse()
74/// }
75///
76/// fn id() -> ProtocolID {
77/// "NEWPROTOCOLID".into()
78/// }
79/// }
80///
81/// async {
82/// let key_pair = KeyPair::generate(&KeyPairType::Ed25519);
83/// let config = Config::default();
84///
85/// // Create a new Executor
86/// let ex = Arc::new(Executor::new());
87///
88/// // Create a new Backend
89/// let backend = Backend::new(&key_pair, config, ex.into());
90///
91/// // Attach the NewProtocol
92/// let c = move |peer| NewProtocol::new(peer);
93/// backend.attach_protocol::<NewProtocol>(c).await.unwrap();
94/// };
95///
96/// ```
97#[async_trait]
98pub trait Protocol: Send + Sync {
99 /// Start the protocol
100 async fn start(self: Arc<Self>) -> Result<()>;
101
102 /// Returns the version of the protocol.
103 fn version() -> Result<Version>
104 where
105 Self: Sized;
106
107 /// Returns the unique ProtocolID associated with the protocol.
108 fn id() -> ProtocolID
109 where
110 Self: Sized;
111}
112
113#[async_trait]
114pub(crate) trait InitProtocol: Send + Sync {
115 type T;
116 /// Initialize the protocol
117 async fn init(self: Arc<Self>) -> Self::T;
118}