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