ferveo_nucypher/
validator.rs1use std::{collections::HashSet, fmt::Display, str::FromStr};
2
3use ark_ec::pairing::Pairing;
4use ferveo_common::PublicKey as ValidatorPublicKey;
5use serde::{Deserialize, Serialize};
6use thiserror::Error;
7
8use crate::Error;
9
10const ETHEREUM_ADDRESS_LEN: usize = 42;
11
12#[derive(
13 Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize, Hash,
14)]
15pub struct EthereumAddress(String);
16
17#[derive(Debug, Error, Clone, PartialEq, Eq)]
18pub enum EthereumAddressParseError {
19 #[error("Invalid Ethereum address length.")]
20 InvalidLength,
21
22 #[error("Invalid hex value in Ethereum address.")]
23 InvalidHex,
24}
25
26impl FromStr for EthereumAddress {
27 type Err = EthereumAddressParseError;
28
29 fn from_str(s: &str) -> Result<EthereumAddress, EthereumAddressParseError> {
30 if s.len() != ETHEREUM_ADDRESS_LEN {
31 return Err(EthereumAddressParseError::InvalidLength);
32 }
33 let prefix_len = "0x".len();
34 hex::decode(&s[prefix_len..])
35 .map_err(|_| EthereumAddressParseError::InvalidHex)?;
36 Ok(EthereumAddress(s.to_string()))
37 }
38}
39
40impl Display for EthereumAddress {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 write!(f, "{}", self.0)
43 }
44}
45
46#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
47pub struct Validator<E: Pairing> {
49 pub address: EthereumAddress,
51 pub public_key: ValidatorPublicKey<E>,
53 pub share_index: u32,
55}
56
57impl<E: Pairing> Validator<E> {
58 pub fn new(
59 address: String,
60 public_key: ValidatorPublicKey<E>,
61 share_index: u32,
62 ) -> Result<Self, EthereumAddressParseError> {
63 Ok(Self {
64 address: EthereumAddress::from_str(&address)?,
65 public_key,
66 share_index,
67 })
68 }
69}
70
71pub fn assert_no_share_duplicates<E: Pairing>(
72 validators: &[Validator<E>],
73) -> Result<(), Error> {
74 let mut set = HashSet::new();
75 for validator in validators {
76 if set.contains(&validator.share_index) {
77 return Err(Error::DuplicatedShareIndex(validator.share_index));
78 } else {
79 set.insert(validator.share_index);
80 }
81 }
82 Ok(())
83}