tempo_commonware_node_config/
lib.rs1#![cfg_attr(not(test), warn(unused_crate_dependencies))]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6use std::{fmt::Display, net::SocketAddr, path::Path};
7
8use commonware_codec::{DecodeExt as _, Encode as _, FixedSize, Read};
9use commonware_cryptography::{
10 Signer,
11 bls12381::primitives::{
12 group::Share,
13 poly::Public,
14 variant::{MinSig, Variant},
15 },
16 ed25519::{PrivateKey, PublicKey},
17};
18use commonware_utils::set::{Ordered, OrderedAssociated};
19use indexmap::IndexMap;
20use serde::{
21 Deserialize,
22 Deserializer,
23 Serialize,
24 ser::{SerializeMap as _, Serializer}, };
26
27#[cfg(test)]
28mod tests;
29
30#[derive(Clone, Debug, PartialEq, Eq)]
31pub struct Peers {
32 inner: OrderedAssociated<PublicKey, SocketAddr>,
33}
34
35impl Peers {
36 pub fn empty() -> Self {
37 Self {
38 inner: OrderedAssociated::from(vec![]),
39 }
40 }
41
42 pub fn into_inner(self) -> OrderedAssociated<PublicKey, SocketAddr> {
43 self.inner
44 }
45
46 pub fn public_keys(&self) -> &Ordered<PublicKey> {
47 self.inner.keys()
48 }
49
50 pub fn socket_addresses(&self) -> &[SocketAddr] {
51 self.inner.values()
52 }
53}
54
55impl From<OrderedAssociated<PublicKey, SocketAddr>> for Peers {
56 fn from(inner: OrderedAssociated<PublicKey, SocketAddr>) -> Self {
57 Self { inner }
58 }
59}
60
61impl Serialize for Peers {
62 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 struct Helper<'a>(&'a PublicKey);
68 impl<'a> Serialize for Helper<'a> {
69 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: serde::Serializer,
72 {
73 use commonware_codec::Encode as _;
74
75 let bytes = self.0.encode();
76 const_hex::serde::serialize(&bytes, serializer)
77 }
78 }
79 let mut map = serializer.serialize_map(Some(self.inner.len()))?;
80 for (key, addr) in &self.inner {
81 map.serialize_entry(&Helper(key), addr)?;
82 }
83 map.end()
84 }
85}
86
87impl<'de> Deserialize<'de> for Peers {
88 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
89 where
90 D: Deserializer<'de>,
91 {
92 struct Helper(PublicKey);
94 impl<'de> Deserialize<'de> for Helper {
95 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96 where
97 D: Deserializer<'de>,
98 {
99 let bytes: Vec<u8> = const_hex::serde::deserialize(deserializer)?;
100 let key = PublicKey::decode(&bytes[..]).map_err(|err| {
101 serde::de::Error::custom(format!(
102 "failed decoding hex-formatted bytes as public key: {err:?}"
103 ))
104 })?;
105 Ok(Self(key))
106 }
107 }
108 struct PeersVisitor;
109
110 impl<'de> serde::de::Visitor<'de> for PeersVisitor {
111 type Value = IndexMap<crate::PublicKey, SocketAddr>;
112
113 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114 formatter
115 .write_str("a map of hex-formatted ed25519 public keys to <ip>:<port> entries")
116 }
117
118 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
119 where
120 A: serde::de::MapAccess<'de>,
121 {
122 let mut peers = IndexMap::with_capacity(map.size_hint().unwrap_or(0));
123 while let Some((key, addr)) = map.next_entry::<Helper, _>()? {
124 let key = key.0;
125 if peers.insert(key.clone(), addr).is_some() {
126 return Err(serde::de::Error::custom(format!(
127 "peers must not have duplicate entries; duplicate key: `{key}`",
128 )))?;
129 }
130 }
131 Ok(peers)
132 }
133 }
134
135 let peers = deserializer.deserialize_map(PeersVisitor)?;
136 Ok(Self {
137 inner: peers.into_iter().collect(),
138 })
139 }
140}
141
142#[derive(Clone, Debug, PartialEq, Eq)]
143pub struct PublicPolynomial {
144 inner: Public<MinSig>,
145}
146
147impl PublicPolynomial {
148 pub fn into_inner(self) -> Public<MinSig> {
149 self.inner
150 }
151}
152
153impl From<Public<MinSig>> for PublicPolynomial {
154 fn from(inner: Public<MinSig>) -> Self {
155 Self { inner }
156 }
157}
158
159impl Serialize for PublicPolynomial {
160 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
161 where
162 S: Serializer,
163 {
164 let bytes = self.inner.encode();
165 const_hex::serde::serialize(&bytes, serializer)
166 }
167}
168
169impl<'de> Deserialize<'de> for PublicPolynomial {
170 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
171 where
172 D: Deserializer<'de>,
173 {
174 let bytes: Vec<u8> = const_hex::serde::deserialize(deserializer)?;
175 let degree_of_public_polynomial = degree_of_public_polynomial_from_bytes(&bytes);
176 let inner = Public::<MinSig>::read_cfg(&mut &bytes[..], °ree_of_public_polynomial)
177 .map_err(serde::de::Error::custom)?;
178 Ok(Self { inner })
179 }
180}
181
182#[derive(Clone, PartialEq, Eq, derive_more::Debug)]
183pub struct SigningKey {
184 #[debug(skip)]
185 inner: PrivateKey,
186}
187
188impl SigningKey {
189 pub fn into_inner(self) -> PrivateKey {
190 self.inner
191 }
192
193 pub fn read_from_file<P: AsRef<Path>>(path: P) -> Result<Self, SigningKeyError> {
194 let hex = std::fs::read_to_string(path).map_err(SigningKeyErrorKind::Read)?;
195 Self::try_from_hex(&hex)
196 }
197
198 pub fn try_from_hex(hex: &str) -> Result<Self, SigningKeyError> {
199 let bytes = const_hex::decode(hex).map_err(SigningKeyErrorKind::Hex)?;
200 let inner = PrivateKey::decode(&bytes[..]).map_err(SigningKeyErrorKind::Parse)?;
201 Ok(Self { inner })
202 }
203
204 pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), SigningKeyError> {
205 std::fs::write(path, self.to_string()).map_err(SigningKeyErrorKind::Write)?;
206 Ok(())
207 }
208
209 pub fn public_key(&self) -> PublicKey {
210 self.inner.public_key()
211 }
212}
213
214impl Display for SigningKey {
215 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216 f.write_str(&const_hex::encode_prefixed(self.inner.encode().as_ref()))
217 }
218}
219
220impl From<PrivateKey> for SigningKey {
221 fn from(inner: PrivateKey) -> Self {
222 Self { inner }
223 }
224}
225
226#[derive(Debug, thiserror::Error)]
227#[error(transparent)]
228pub struct SigningKeyError {
229 #[from]
230 inner: SigningKeyErrorKind,
231}
232
233#[derive(Debug, thiserror::Error)]
234enum SigningKeyErrorKind {
235 #[error("failed decoding file contents as hex-encoded bytes")]
236 Hex(#[source] const_hex::FromHexError),
237 #[error("failed parsing hex-decoded bytes as ed25519 private key")]
238 Parse(#[source] commonware_codec::Error),
239 #[error("failed reading file")]
240 Read(#[source] std::io::Error),
241 #[error("failed writing to file")]
242 Write(#[source] std::io::Error),
243}
244
245#[derive(Clone, Debug, PartialEq, Eq)]
246pub struct SigningShare {
247 inner: Share,
248}
249
250impl SigningShare {
251 pub fn into_inner(self) -> Share {
252 self.inner
253 }
254
255 pub fn read_from_file<P: AsRef<Path>>(path: P) -> Result<Self, SigningShareError> {
256 let hex = std::fs::read_to_string(path).map_err(SigningShareErrorKind::Read)?;
257 Self::try_from_hex(&hex)
258 }
259
260 pub fn try_from_hex(hex: &str) -> Result<Self, SigningShareError> {
261 let bytes = const_hex::decode(hex).map_err(SigningShareErrorKind::Hex)?;
262 let inner = Share::decode(&bytes[..]).map_err(SigningShareErrorKind::Parse)?;
263 Ok(Self { inner })
264 }
265
266 pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), SigningShareError> {
267 std::fs::write(path, self.to_string()).map_err(SigningShareErrorKind::Write)?;
268 Ok(())
269 }
270}
271
272impl Display for SigningShare {
273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274 f.write_str(&const_hex::encode_prefixed(self.inner.encode().as_ref()))
275 }
276}
277
278impl From<Share> for SigningShare {
279 fn from(inner: Share) -> Self {
280 Self { inner }
281 }
282}
283
284#[derive(Debug, thiserror::Error)]
285#[error(transparent)]
286pub struct SigningShareError {
287 #[from]
288 inner: SigningShareErrorKind,
289}
290
291#[derive(Debug, thiserror::Error)]
292enum SigningShareErrorKind {
293 #[error("failed decoding file contents as hex-encoded bytes")]
294 Hex(#[source] const_hex::FromHexError),
295 #[error("failed parsing hex-decoded bytes as bls12381 private share")]
296 Parse(#[source] commonware_codec::Error),
297 #[error("failed reading file")]
298 Read(#[source] std::io::Error),
299 #[error("failed writing to file")]
300 Write(#[source] std::io::Error),
301}
302
303fn degree_of_public_polynomial_from_bytes(bytes: &[u8]) -> usize {
306 bytes.len() / <<MinSig as Variant>::Public as FixedSize>::SIZE
307}