1use std::marker::PhantomData;
3
4use bincode::Options;
5use cdn_broker::reexports::{
6 connection::protocols::{Quic, Tcp, TcpTls},
7 crypto::signature::{Serializable, SignatureScheme},
8 def::{hook::NoMessageHook, ConnectionDef, RunDef, Topic as TopicTrait},
9 discovery::{Embedded, Redis},
10};
11use hotshot::types::SignatureKey;
12use hotshot_types::{
13 traits::{network::Topic as HotShotTopic, node_implementation::NodeType},
14 utils::bincode_opts,
15};
16use num_enum::{IntoPrimitive, TryFromPrimitive};
17use static_assertions::const_assert_eq;
18
19#[repr(u8)]
21#[derive(IntoPrimitive, TryFromPrimitive, Clone, PartialEq, Eq)]
22pub enum Topic {
23 Global = 0,
25 Da = 1,
27}
28
29pub enum Namespace {}
30
31const_assert_eq!(Topic::Global as u8, HotShotTopic::Global as u8);
33const_assert_eq!(Topic::Da as u8, HotShotTopic::Da as u8);
34
35impl TopicTrait for Topic {}
38
39#[derive(Clone, Eq, PartialEq)]
42pub struct WrappedSignatureKey<T: SignatureKey + 'static>(pub T);
43impl<T: SignatureKey> SignatureScheme for WrappedSignatureKey<T> {
44 type PrivateKey = T::PrivateKey;
45 type PublicKey = Self;
46
47 fn sign(
52 private_key: &Self::PrivateKey,
53 namespace: &str,
54 message: &[u8],
55 ) -> anyhow::Result<Vec<u8>> {
56 let message = [namespace.as_bytes(), message].concat();
58
59 let signature = T::sign(private_key, &message)?;
60 Ok(bincode_opts().serialize(&signature)?)
61 }
62
63 fn verify(
68 public_key: &Self::PublicKey,
69 namespace: &str,
70 message: &[u8],
71 signature: &[u8],
72 ) -> bool {
73 let namespaced_message = [namespace.as_bytes(), message].concat();
75
76 let signature: T::PureAssembledSignatureType = match bincode_opts().deserialize(signature) {
77 Ok(key) => key,
78 Err(_) => return false,
79 };
80
81 public_key.0.validate(&signature, message)
82 || public_key.0.validate(&signature, &namespaced_message)
83 }
84}
85
86impl<T: SignatureKey> Serializable for WrappedSignatureKey<T> {
89 fn serialize(&self) -> anyhow::Result<Vec<u8>> {
90 Ok(self.0.to_bytes())
91 }
92
93 fn deserialize(serialized: &[u8]) -> anyhow::Result<Self> {
94 Ok(WrappedSignatureKey(T::from_bytes(serialized)?))
95 }
96}
97
98pub struct ProductionDef<TYPES: NodeType>(PhantomData<TYPES>);
101impl<TYPES: NodeType> RunDef for ProductionDef<TYPES> {
102 type User = UserDefQuic<TYPES>;
103 type User2 = UserDefTcp<TYPES>;
104 type Broker = BrokerDef<TYPES>;
105 type DiscoveryClientType = Redis;
106 type Topic = Topic;
107}
108
109pub struct UserDefQuic<TYPES: NodeType>(PhantomData<TYPES>);
113impl<TYPES: NodeType> ConnectionDef for UserDefQuic<TYPES> {
114 type Scheme = WrappedSignatureKey<TYPES::SignatureKey>;
115 type Protocol = Quic;
116 type MessageHook = NoMessageHook;
117}
118
119pub struct UserDefTcp<TYPES: NodeType>(PhantomData<TYPES>);
122impl<TYPES: NodeType> ConnectionDef for UserDefTcp<TYPES> {
123 type Scheme = WrappedSignatureKey<TYPES::SignatureKey>;
124 type Protocol = TcpTls;
125 type MessageHook = NoMessageHook;
126}
127
128pub struct BrokerDef<TYPES: NodeType>(PhantomData<TYPES>);
131impl<TYPES: NodeType> ConnectionDef for BrokerDef<TYPES> {
132 type Scheme = WrappedSignatureKey<TYPES::SignatureKey>;
133 type Protocol = Tcp;
134 type MessageHook = NoMessageHook;
135}
136
137#[derive(Clone)]
141pub struct ClientDef<TYPES: NodeType>(PhantomData<TYPES>);
142impl<TYPES: NodeType> ConnectionDef for ClientDef<TYPES> {
143 type Scheme = WrappedSignatureKey<TYPES::SignatureKey>;
144 type Protocol = Quic;
145 type MessageHook = NoMessageHook;
146}
147
148pub struct TestingDef<TYPES: NodeType>(PhantomData<TYPES>);
151impl<TYPES: NodeType> RunDef for TestingDef<TYPES> {
152 type User = UserDefQuic<TYPES>;
153 type User2 = UserDefTcp<TYPES>;
154 type Broker = BrokerDef<TYPES>;
155 type DiscoveryClientType = Embedded;
156 type Topic = Topic;
157}