1use alloy::primitives::{aliases::U192, Address, FixedBytes, U256};
2use eigen_crypto_bls::{convert_to_g1_point, error::BlsError, BlsG1Point, BlsKeyPair};
3use eigen_utils::common::get_url_content;
4use ethers::utils::keccak256;
5use num_bigint::BigUint;
6use thiserror::Error;
7use url::Url;
8
9pub use crate::operator_metadata::OperatorMetadata;
10use crate::operator_metadata::OperatorMetadataError;
11pub use crate::operator_pubkeys::OperatorPubKeys;
12
13#[derive(Debug, Error)]
14pub enum OperatorTypesError {
15 #[error("Operator id from pub key conversion failed")]
16 OperatorIdFromPubKey(#[from] BlsError),
17 #[error("Invalid Metadata URL")]
18 InvalidMetadataUrl,
19 #[error("Metadata Not Found")]
20 MetadataNotFound,
21 #[error("Metadata Parse Error")]
22 MetadataParseError,
23 #[error("Metadata Validation Error")]
24 MetadataValidationError(#[from] OperatorMetadataError),
25 #[error("Invalid Address")]
26 InvalidAddress,
27 #[error("Invalid Delegation Approver Address")]
28 InvalidDelegationApproverAddress,
29}
30
31const MAX_NUMBER_OF_QUORUMS: u8 = 192;
32
33pub type OperatorId = FixedBytes<32>;
34
35pub fn bitmap_to_quorum_ids(quorum_bitmaps: U256) -> Vec<u8> {
36 let bytes = quorum_bitmaps.to_be_bytes::<32>();
37
38 let mut quorum_ids: Vec<u8> = Vec::with_capacity(usize::from(MAX_NUMBER_OF_QUORUMS));
39
40 for i in 0..MAX_NUMBER_OF_QUORUMS {
41 let bitmap = BigUint::from_bytes_be(&bytes);
42 if bitmap.bit(u64::from(i)) {
43 quorum_ids.push(i);
44 }
45 }
46 quorum_ids
47}
48
49pub fn bitmap_to_quorum_ids_from_u192(quorum_bitmaps: U192) -> Vec<u8> {
50 let bytes = quorum_bitmaps.to_be_bytes::<24>();
51
52 let mut quorum_ids: Vec<u8> = Vec::with_capacity(usize::from(MAX_NUMBER_OF_QUORUMS));
53
54 for i in 0..MAX_NUMBER_OF_QUORUMS {
55 let bitmap = BigUint::from_bytes_be(&bytes);
56 if bitmap.bit(u64::from(i)) {
57 quorum_ids.push(i);
58 }
59 }
60 quorum_ids
61}
62
63pub struct Operator {
65 pub address: Address,
67
68 pub delegation_approver_address: Address,
70
71 pub metadata_url: String,
73
74 pub allocation_delay: Option<u32>,
77
78 pub _deprecated_earnings_receiver_address: Option<Address>,
79
80 pub staker_opt_out_window_blocks: Option<u32>,
81}
82
83impl Operator {
84 pub fn new(
85 address: &str,
86 delegation_approver_address: &str,
87 metadata_url: String,
88 allocation_delay: Option<u32>,
89 _deprecated_earnings_receiver_address: Option<Address>,
90 staker_opt_out_window_blocks: Option<u32>,
91 ) -> Result<Self, OperatorTypesError> {
92 let address = Address::try_from(address.as_bytes())
93 .map_err(|_| OperatorTypesError::InvalidAddress)?;
94 let delegation_approver_address = Address::try_from(delegation_approver_address.as_bytes())
95 .map_err(|_| OperatorTypesError::InvalidDelegationApproverAddress)?;
96
97 Ok(Self {
98 address,
99 delegation_approver_address,
100 metadata_url,
101 allocation_delay,
102 _deprecated_earnings_receiver_address,
103 staker_opt_out_window_blocks,
104 })
105 }
106
107 pub async fn validate(&self) -> Result<(), OperatorTypesError> {
108 Url::parse(&self.metadata_url).map_err(|_| OperatorTypesError::InvalidMetadataUrl)?;
110
111 let body = get_url_content(&self.metadata_url)
113 .await
114 .map_err(|_| OperatorTypesError::MetadataNotFound)?;
115
116 let operator_metadata: OperatorMetadata =
117 serde_json::from_str(&body).map_err(|_| OperatorTypesError::MetadataParseError)?;
118
119 operator_metadata
120 .validate()
121 .await
122 .map_err(OperatorTypesError::MetadataValidationError)
123 }
124
125 pub fn operator_id_from_key_pair(
126 keypair: BlsKeyPair,
127 ) -> Result<OperatorId, OperatorTypesError> {
128 operator_id_from_g1_pub_key(keypair.public_key())
129 }
130}
131
132pub type Socket = String;
133
134pub type QuorumNum = u8;
135
136#[derive(Clone, Debug, PartialEq, Eq)]
137pub struct OperatorInfo {
138 pub pub_keys: Option<OperatorPubKeys>,
139}
140
141pub fn operator_id_from_g1_pub_key(pub_key: BlsG1Point) -> Result<OperatorId, OperatorTypesError> {
142 let x: [u8; 32] = convert_to_g1_point(pub_key.g1())?.X.to_be_bytes();
143 let y: [u8; 32] = convert_to_g1_point(pub_key.g1())?.Y.to_be_bytes();
144 let mut bytes = [0_u8; 64];
145 bytes[..32].copy_from_slice(&x);
146 bytes[32..].copy_from_slice(&y);
147 Ok(keccak256(bytes).into())
148}
149
150pub type QuorumThresholdPercentage = u8;
151
152pub type QuorumThresholdPercentages = Vec<QuorumThresholdPercentage>;