mithril_common/messages/message_parts/
signer.rs1#[cfg(any(test, feature = "test_tools"))]
2use crate::test_utils::fake_keys;
3use crate::{
4 crypto_helper::{KesPeriod, ProtocolOpCert, ProtocolSignerVerificationKeySignature},
5 entities::{
6 HexEncodedOpCert, HexEncodedVerificationKey, HexEncodedVerificationKeySignature, PartyId,
7 Signer, SignerWithStake, Stake,
8 },
9 StdError, StdResult,
10};
11use anyhow::Context;
12use serde::{Deserialize, Serialize};
13use std::fmt::{Debug, Formatter};
14
15#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
17pub struct SignerWithStakeMessagePart {
18 pub party_id: PartyId,
22
23 pub verification_key: HexEncodedVerificationKey,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
31 pub verification_key_signature: Option<HexEncodedVerificationKeySignature>,
32
33 #[serde(skip_serializing_if = "Option::is_none")]
38 pub operational_certificate: Option<HexEncodedOpCert>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
44 pub kes_period: Option<KesPeriod>,
45
46 pub stake: Stake,
48}
49
50impl SignerWithStakeMessagePart {
51 cfg_test_tools! {
52 pub fn dummy() -> Self {
54 Self {
55 party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx".to_string(),
56 verification_key: fake_keys::signer_verification_key()[0].to_string(),
57 verification_key_signature: Some(
58 fake_keys::signer_verification_key_signature()[0].to_string(),
59 ),
60 operational_certificate: Some(fake_keys::operational_certificate()[0].to_string()),
61 kes_period: Some(6),
62 stake: 234,
63 }
64 }
65 }
66
67 pub fn from_signers(signers: Vec<SignerWithStake>) -> Vec<Self> {
69 signers.into_iter().map(|signer| signer.into()).collect()
70 }
71
72 pub fn try_into_signers(messages: Vec<Self>) -> StdResult<Vec<SignerWithStake>> {
74 messages
75 .into_iter()
76 .map(SignerWithStakeMessagePart::try_into)
77 .collect()
78 }
79}
80
81impl TryInto<SignerWithStake> for SignerWithStakeMessagePart {
82 type Error = StdError;
83
84 fn try_into(self) -> Result<SignerWithStake, Self::Error> {
85 let verification_key_signature: Option<ProtocolSignerVerificationKeySignature> = self
86 .verification_key_signature
87 .map(|f| f.try_into())
88 .transpose()
89 .with_context(|| {
90 format!(
91 "Error while parsing verification key signature message, party_id = '{}'",
92 self.party_id
93 )
94 })?;
95 let operational_certificate: Option<ProtocolOpCert> = self
96 .operational_certificate
97 .map(|f| f.try_into())
98 .transpose()
99 .with_context(|| {
100 format!(
101 "Error while parsing operational certificate message, party_id = '{}'.",
102 self.party_id
103 )
104 })?;
105 let value = SignerWithStake {
106 party_id: self.party_id,
107 verification_key: self.verification_key.try_into()?,
108 verification_key_signature,
109 kes_period: self.kes_period,
110 operational_certificate,
111 stake: self.stake,
112 };
113 Ok(value)
114 }
115}
116
117impl From<SignerWithStake> for SignerWithStakeMessagePart {
118 fn from(value: SignerWithStake) -> Self {
119 Self {
120 party_id: value.party_id,
121 verification_key: value.verification_key.try_into().unwrap(),
122 verification_key_signature: value
123 .verification_key_signature
124 .map(|k| k.try_into().unwrap()),
125 operational_certificate: value
126 .operational_certificate
127 .map(|op_cert| (op_cert.try_into().unwrap())),
128 kes_period: value.kes_period,
129 stake: value.stake,
130 }
131 }
132}
133
134impl Debug for SignerWithStakeMessagePart {
135 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
136 let should_be_exhaustive = f.alternate();
137 let mut debug = f.debug_struct("Signer");
138 debug
139 .field("party_id", &self.party_id)
140 .field("stake", &self.stake);
141
142 match should_be_exhaustive {
143 true => debug
144 .field(
145 "verification_key",
146 &format_args!("{:?}", self.verification_key),
147 )
148 .field(
149 "verification_key_signature",
150 &format_args!("{:?}", self.verification_key_signature),
151 )
152 .field(
153 "operational_certificate",
154 &format_args!("{:?}", self.operational_certificate),
155 )
156 .field("kes_period", &format_args!("{:?}", self.kes_period))
157 .finish(),
158 false => debug.finish_non_exhaustive(),
159 }
160 }
161}
162
163#[derive(Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
165pub struct SignerMessagePart {
166 pub party_id: PartyId,
170
171 pub verification_key: HexEncodedVerificationKey,
173
174 #[serde(skip_serializing_if = "Option::is_none")]
179 pub verification_key_signature: Option<HexEncodedVerificationKeySignature>,
180
181 #[serde(skip_serializing_if = "Option::is_none")]
186 pub operational_certificate: Option<HexEncodedOpCert>,
187
188 #[serde(skip_serializing_if = "Option::is_none")]
192 pub kes_period: Option<KesPeriod>,
193}
194
195impl SignerMessagePart {
196 pub fn try_into_signers(messages: Vec<Self>) -> StdResult<Vec<Signer>> {
198 messages
199 .into_iter()
200 .map(SignerMessagePart::try_into)
201 .collect()
202 }
203
204 pub fn from_signers(signers: Vec<Signer>) -> Vec<Self> {
206 signers.into_iter().map(|signer| signer.into()).collect()
207 }
208
209 cfg_test_tools! {
210 pub fn dummy() -> Self {
212 Self {
213 party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx".to_string(),
214 verification_key: fake_keys::signer_verification_key()[0].to_string(),
215 verification_key_signature: Some(
216 fake_keys::signer_verification_key_signature()[0].to_string(),
217 ),
218 operational_certificate: Some(fake_keys::operational_certificate()[0].to_string()),
219 kes_period: Some(6),
220 }
221 }
222 }
223}
224
225impl TryInto<Signer> for SignerMessagePart {
226 type Error = StdError;
227
228 fn try_into(self) -> Result<Signer, Self::Error> {
229 let verification_key_signature: Option<ProtocolSignerVerificationKeySignature> = self
230 .verification_key_signature
231 .map(|f| f.try_into())
232 .transpose()
233 .with_context(|| {
234 format!(
235 "Error while parsing verification key signature message, party_id = '{}'",
236 self.party_id
237 )
238 })?;
239 let operational_certificate: Option<ProtocolOpCert> = self
240 .operational_certificate
241 .map(|f| f.try_into())
242 .transpose()
243 .with_context(|| {
244 format!(
245 "Error while parsing operational certificate message, party_id = '{}'.",
246 self.party_id
247 )
248 })?;
249 let value = Signer {
250 party_id: self.party_id,
251 verification_key: self.verification_key.try_into()?,
252 verification_key_signature,
253 kes_period: self.kes_period,
254 operational_certificate,
255 };
256 Ok(value)
257 }
258}
259
260impl From<Signer> for SignerMessagePart {
261 fn from(value: Signer) -> Self {
262 Self {
263 party_id: value.party_id,
264 verification_key: value.verification_key.try_into().unwrap(),
265 verification_key_signature: value
266 .verification_key_signature
267 .map(|k| k.try_into().unwrap()),
268 operational_certificate: value
269 .operational_certificate
270 .map(|op_cert| (op_cert.try_into().unwrap())),
271 kes_period: value.kes_period,
272 }
273 }
274}
275
276impl Debug for SignerMessagePart {
277 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
278 let should_be_exhaustive = f.alternate();
279 let mut debug = f.debug_struct("Signer");
280 debug.field("party_id", &self.party_id);
281
282 match should_be_exhaustive {
283 true => debug
284 .field(
285 "verification_key",
286 &format_args!("{:?}", self.verification_key),
287 )
288 .field(
289 "verification_key_signature",
290 &format_args!("{:?}", self.verification_key_signature),
291 )
292 .field(
293 "operational_certificate",
294 &format_args!("{:?}", self.operational_certificate),
295 )
296 .field("kes_period", &format_args!("{:?}", self.kes_period))
297 .finish(),
298 false => debug.finish_non_exhaustive(),
299 }
300 }
301}
302#[cfg(test)]
303mod tests {
304 use super::*;
305
306 mod golden_protocol_key_encodings {
307 use super::*;
308
309 fn golden_signer_message_part_with_json_hex_encoding() -> SignerMessagePart {
310 SignerMessagePart {
311 party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx"
312 .to_string(),
313 verification_key: "7b22766b223a5b3138342c3134352c3230382c3138382c31342c342c3230342c3135392c33322c3234332c37352c3137392c38322c3133352c3235342c3135372c33312c35392c33382c3131302c3133362c3232352c3233342c3132332c34372c3130322c34322c3132352c3138392c31372c3136322c3234342c37352c3234382c3139352c3232372c3131362c3139322c3135322c39302c34312c32372c3235312c3137322c35332c3137382c3231342c35362c32302c3232372c3139372c31392c3234322c3138362c3130312c322c37332c3234332c31342c3230342c3136342c3133342c3136322c3233332c32392c3131342c33302c3136372c3230372c3137332c36382c362c37362c38302c3233342c36352c36342c3137332c3231372c3232392c34382c3133342c31322c39352c3138362c3233382c3135302c3139322c3138302c3139322c31302c312c3136322c3131372c3131322c3132325d2c22706f70223a5b3137382c3231342c3231342c3139332c3137382c3134372c34332c3132362c31362c3231362c3231352c3133322c3136342c3134362c382c3233382c3234352c38322c3232342c3233372c3234392c3134322c3135372c3232392c32372c3135392c3132312c3233312c3234382c3131312c38352c38352c35302c3139382c3233362c39312c3133302c3133352c36322c3133302c3132352c3134372c3136392c3134352c39352c33352c37382c3235332c3135302c3232352c3232352c3232372c38332c3132352c32382c3137332c3130382c3234312c3230302c37332c3134342c36322c31322c3232392c3134332c3134332c37352c37342c3133352c3135382c3139362c3139362c3232342c3232382c38382c3130352c3132342c34372c37362c3234382c3234342c38362c3136332c3232312c3134372c3134382c36352c3232382c31352c37392c3138352c39302c39362c3139322c3138392c3233365d7d".to_string(),
314 verification_key_signature: Some(
315 "7b227369676d61223a7b227369676d61223a7b227369676d61223a7b227369676d61223a7b227369676d61223a7b227369676d61223a5b32312c3131392c302c3232382c3130322c3231362c3137372c3133302c34362c3131362c3132302c3235322c3232342c31322c34332c3139302c32322c3131372c3231362c3132342c3234302c3137332c31392c3234312c3138342c3230392c36342c3130352c39392c3233342c36312c31302c37312c36302c33392c3133392c39382c3133342c3133322c3135372c3133382c33372c3232322c3130362c3131312c37382c3132302c37382c39332c39382c32382c35332c3231322c3138332c3135322c37312c3135312c36332c3136382c3138372c33372c3232372c3133352c31345d2c226c68735f706b223a5b3135372c32312c33362c32392c32302c33342c31372c3233392c31332c38392c33372c3132302c32312c3135352c3233362c3234302c39352c3138392c3136362c3131332c3231332c39302c3138382c34312c3137312c33372c3131312c3138302c3234332c33312c35322c36385d2c227268735f706b223a5b3136302c3234332c39382c34352c342c3232312c36342c3131372c34382c3230332c3138362c34312c39352c31342c3135382c3232382c3137352c3232322c3131362c34342c38342c39372c3136372c3132372c38302c3139372c3234352c3136372c3139332c3139362c3135372c3137375d7d2c226c68735f706b223a5b3138332c3135352c36352c3234322c3233342c34332c3136372c3139322c31362c38322c3130322c39382c3133372c3139362c32382c38312c3232312c38312c36352c322c39332c37302c38342c3136382c3137392c3138372c3130322c32382c3234342c3138322c3132332c3134385d2c227268735f706b223a5b3135352c36392c3134302c32382c3137342c33382c3134392c36302c3137382c3232372c35342c3231312c3130362c3133312c36382c3135362c35392c3138302c35332c382c3138382c3233312c3137332c312c3137312c3131392c33322c3134372c3233342c34322c3136332c3131305d7d2c226c68735f706b223a5b3134312c3137322c3137372c38352c39302c3131312c3135332c3234362c3233332c3139362c3130352c3138342c35342c3234372c3133342c3135382c3232362c3230372c32392c3136332c31392c33342c312c3230372c3232322c37322c3136362c32332c31382c3137342c31362c39365d2c227268735f706b223a5b31322c3231322c3139372c3130382c3233302c38332c33372c3139342c3135382c3135362c38362c3138362c33322c3234352c3234342c34302c3234342c3138302c3136382c3233302c362c3137382c3138362c32322c36382c33392c3230322c35352c3130302c3232392c3138392c3232315d7d2c226c68735f706b223a5b33362c3235302c322c3232392c3233342c3136352c32372c36332c3132302c3137382c342c3138302c3235312c3134372c35302c3134382c3233372c3135342c33382c3134352c3131342c37342c3231312c34382c3133362c3231332c31382c3138322c3230332c3233302c31352c3133345d2c227268735f706b223a5b3139332c3134342c3231332c362c3235352c3137372c3131302c3131302c3231332c3137352c332c32382c3135382c3231362c3137332c32362c3232352c38392c34362c3133382c34392c37342c36332c34332c3134342c34382c34392c39352c35372c31392c3132392c34335d7d2c226c68735f706b223a5b3135362c38312c3130352c3134312c3230392c322c3137352c38332c38332c37342c3138332c3130312c3131362c3137362c31382c3233362c31382c3232332c3233372c3233332c3139332c35342c32382c3231332c302c3133352c3135372c33342c37352c3230352c34382c3133385d2c227268735f706b223a5b33382c3234382c35322c32302c35352c3131382c3138372c33392c3137362c3231332c33342c332c3231342c322c33312c3131382c3232342c3132392c34322c3136332c39342c3130382c3131362c35352c3231332c36372c3133322c39362c3232392c3132322c39362c3136385d7d2c226c68735f706b223a5b3132312c3134342c33312c3131302c3234392c3234342c3139382c3235342c3139312c36322c39312c31372c3135322c3135312c3233322c3130302c3130392c39362c3230322c3234392c3139382c3230342c39332c372c3131372c3233362c3132382c36362c38392c3231342c3133392c3134375d2c227268735f706b223a5b3234362c3136362c3230342c3135302c3139362c39312c3135382c3133312c3133382c3130332c3234352c34392c3134352c3133302c32322c3132362c3134372c39352c32332c39332c31332c3230392c3133312c34392c3138322c34362c3135332c35372c33372c3130332c3235332c3234325d7d".to_string(),
316 ),
317 operational_certificate: Some(
318 "5b5b5b35312c36322c392c3230302c3230392c34312c3234352c3230372c3135392c3139392c31342c372c38322c3230332c3234302c312c3132392c3138372c3131392c3232312c3133362c3234372c38392c3132382c3232382c3133332c302c39382c31322c3232382c3137382c3233345d2c31362c313139302c5b3231302c3134382c37332c3136332c3232322c3233332c3138302c33372c3133312c3235342c392c3230352c3135382c3134392c31342c37302c39322c372c3233352c3231342c3131312c35322c3131362c34312c3131382c362c3132392c312c3130362c312c39342c3233332c3131352c3137332c3130302c3133392c3131342c3130392c31352c31342c3233332c34332c3137392c3137342c35302c31302c3135302c39372c3132372c3138322c31362c372c3131322c3234352c34382c3134312c38342c3130322c342c32352c3231312c3134342c3230322c345d5d2c5b3133312c3135352c37322c35372c3134372c3231382c3137332c36382c3139312c3234322c3138392c3234372c32372c3235342c3134382c3232352c35332c31312c36392c3135372c3138322c38302c3233342c3133312c3233342c33392c3130322c32312c322c332c36352c3139305d5d".to_string(),
319 ),
320 kes_period: Some(6)
321 }
322 }
323
324 fn golden_signer_message_part_with_bytes_hex_encoding() -> SignerMessagePart {
325 SignerMessagePart {
326 party_id: "pool1m8crhnqj5k2kyszf5j2scshupystyxc887zdfrpzh6ty6eun4fx"
327 .to_string(),
328 verification_key: "b891d0bc0e04cc9f20f34bb35287fe9d1f3b266e88e1ea7b2f662a7dbd11a2f44bf8c3e374c0985a291bfbac35b2d63814e3c513f2ba650249f30ecca486a2e91d721ea7cfad44064c50ea4140add9e530860c5fbaee96c0b4c00a01a275707ab2d6d6c1b2932b7e10d8d784a49208eef552e0edf98e9de51b9f79e7f86f555532c6ec5b82873e827d93a9915f234efd96e1e1e3537d1cad6cf1c849903e0ce58f8f4b4a879ec4c4e0e458697c2f4cf8f456a3dd939441e40f4fb95a60c0bdec".to_string(),
329 verification_key_signature: Some(
330 "157700e466d8b1822e7478fce00c2bbe1675d87cf0ad13f1b8d1406963ea3d0a473c278b6286849d8a25de6a6f4e784e5d621c35d4b79847973fa8bb25e3870e9d15241d142211ef0d592578159becf05fbda671d55abc29ab256fb4f31f3444a0f3622d04dd407530cbba295f0e9ee4afde742c5461a77f50c5f5a7c1c49db1b79b41f2ea2ba7c01052666289c41c51dd5141025d4654a8b3bb661cf4b67b949b458c1cae26953cb2e336d36a83449c3bb43508bce7ad01ab772093ea2aa36e8dacb1555a6f99f6e9c469b836f7869ee2cf1da3132201cfde48a61712ae10600cd4c56ce65325c29e9c56ba20f5f428f4b4a8e606b2ba164427ca3764e5bddd24fa02e5eaa51b3f78b204b4fb933294ed9a2691724ad33088d512b6cbe60f86c190d506ffb16e6ed5af031c9ed8ad1ae1592e8a314a3f2b9030315f3913812b9c51698dd102af53534ab76574b012ec12dfede9c1361cd500879d224bcd308a26f834143776bb27b0d52203d6021f76e0812aa35e6c7437d5438460e57a60a879901f6ef9f4c6febf3e5b119897e8646d60caf9c6cc5d0775ec804259d68b93f6a6cc96c45b9e838a67f5319182167e935f175d0dd18331b62e99392567fdf2".to_string(),
331 ),
332 operational_certificate: Some(
333 "82845820333e09c8d129f5cf9fc70e0752cbf00181bb77dd88f75980e48500620ce4b2ea101904a65840d29449a3dee9b42583fe09cd9e950e465c07ebd66f347429760681016a015ee973ad648b726d0f0ee92bb3ae320a96617fb6100770f5308d54660419d390ca045820839b483993daad44bff2bdf71bfe94e1350b459db650ea83ea276615020341be".to_string(),
334 ),
335 kes_period: Some(6)
336 }
337 }
338
339 mod signer {
340 use super::*;
341
342 fn golden_message_with_json_hex_encoding() -> SignerMessagePart {
343 golden_signer_message_part_with_json_hex_encoding()
344 }
345
346 fn golden_message_with_bytes_hex_encoding() -> SignerMessagePart {
347 golden_signer_message_part_with_bytes_hex_encoding()
348 }
349
350 #[test]
351 fn restorations_from_json_hex_and_bytes_hex_give_same_signer() {
352 let signer_from_json_hex: Signer =
353 golden_message_with_json_hex_encoding().try_into().unwrap();
354
355 let signer_from_bytes_hex: Signer =
356 golden_message_with_bytes_hex_encoding().try_into().unwrap();
357
358 assert_eq!(signer_from_json_hex, signer_from_bytes_hex);
359 }
360 }
361
362 mod signer_with_stake {
363 use super::*;
364
365 fn golden_message_with_json_hex_encoding() -> SignerWithStakeMessagePart {
366 let signer_message_part = golden_signer_message_part_with_json_hex_encoding();
367
368 SignerWithStakeMessagePart {
369 party_id: signer_message_part.party_id,
370 verification_key: signer_message_part.verification_key,
371 verification_key_signature: signer_message_part.verification_key_signature,
372 operational_certificate: signer_message_part.operational_certificate,
373 kes_period: signer_message_part.kes_period,
374 stake: 123,
375 }
376 }
377
378 fn golden_message_with_bytes_hex_encoding() -> SignerWithStakeMessagePart {
379 let signer_message_part = golden_signer_message_part_with_bytes_hex_encoding();
380
381 SignerWithStakeMessagePart {
382 party_id: signer_message_part.party_id,
383 verification_key: signer_message_part.verification_key,
384 verification_key_signature: signer_message_part.verification_key_signature,
385 operational_certificate: signer_message_part.operational_certificate,
386 kes_period: signer_message_part.kes_period,
387 stake: 123,
388 }
389 }
390
391 #[test]
392 fn restorations_from_json_hex_and_bytes_hex_give_same_signer() {
393 let signer_from_json_hex: SignerWithStake =
394 golden_message_with_json_hex_encoding().try_into().unwrap();
395
396 let signer_from_bytes_hex: SignerWithStake =
397 golden_message_with_bytes_hex_encoding().try_into().unwrap();
398
399 assert_eq!(signer_from_json_hex, signer_from_bytes_hex);
400 }
401 }
402 }
403}