diff --git a/Cargo.lock b/Cargo.lock index 25efdfea..d2fba402 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2475,6 +2475,7 @@ dependencies = [ "eigen-client-elcontracts", "eigen-crypto-bls", "eigen-logging", + "eigen-telemetry", "eigen-testing-utils", "eigen-types", "eigen-utils", @@ -2709,7 +2710,6 @@ dependencies = [ "alloy", "alloy-primitives", "alloy-signer-local", - "anyhow", "ark-bn254 0.5.0", "ark-ff 0.5.0", "ark-std 0.4.0", @@ -2753,6 +2753,13 @@ dependencies = [ "url", ] +[[package]] +name = "eigen-telemetry" +version = "0.1.0" +dependencies = [ + "posthog-rs", +] + [[package]] name = "eigen-testing-utils" version = "0.1.0" @@ -2773,7 +2780,6 @@ name = "eigen-types" version = "0.1.0" dependencies = [ "alloy-primitives", - "ark-serialize 0.5.0", "eigen-crypto-bls", "ethers", "num-bigint 0.4.6", @@ -5314,6 +5320,18 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +[[package]] +name = "posthog-rs" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad1b35ffe50419992615288c40ee90fbf30da4c6faf251414675ea64e1cdfa3" +dependencies = [ + "chrono", + "reqwest 0.11.27", + "serde", + "serde_json", +] + [[package]] name = "powerfmt" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 755da1f3..4dbc366f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,7 @@ eigen-services-blsaggregation = { path = "crates/services/bls_aggregation" } eigen-services-operatorsinfo = { path = "crates/services/operatorsinfo" } eigen-signer = { path = "crates/signer/" } eigen-testing-utils = { path = "testing/testing-utils" } +eigen-telemetry = { path = "crates/telemetry/" } eigen-types = { path = "crates/types/" } eigen-utils = { path = "crates/utils/" } eigen-nodeapi = { path = "crates/nodeapi/" } @@ -112,7 +113,9 @@ tracing-subscriber = { version = "0.3.18", features = ["json"] } url = "2.5.2" #misc -rust-bls-bn254 = { git = "https://github.com/Layr-Labs/rust-bls-bn254", rev = "ce3313f" ,features = ["std"] } +rust-bls-bn254 = { git = "https://github.com/Layr-Labs/rust-bls-bn254", rev = "ce3313f", features = [ + "std", +] } uuid = { version = "1.11.0", features = ["v4"] } @@ -145,7 +148,15 @@ alloy-transport-http = { version = "0.5.3", features = [ ], default-features = false } alloy-transport-ipc = { version = "0.5.3", default-features = false } alloy-transport-ws = { version = "0.5.3", default-features = false } -alloy = { version = "0.5.3", features = ["sol-types", "contract","full","signer-aws"] } +alloy = { version = "0.5.3", features = [ + "sol-types", + "contract", + "full", + "signer-aws", +] } + anvil-utils = { path = "examples/anvil-utils" } avsregistry-read = { path = "examples/avsregistry-read" } avsregistry-write = { path = "examples/avsregistry-write" } + +posthog-rs = "0.2.0" diff --git a/crates/chainio/clients/avsregistry/Cargo.toml b/crates/chainio/clients/avsregistry/Cargo.toml index 7ff33bea..c810a108 100644 --- a/crates/chainio/clients/avsregistry/Cargo.toml +++ b/crates/chainio/clients/avsregistry/Cargo.toml @@ -13,15 +13,17 @@ alloy.workspace = true alloy-primitives.workspace = true alloy-signer.workspace = true alloy-signer-local.workspace = true +ark-ff.workspace = true async-trait.workspace = true -num-bigint = "0.4.4" eigen-types.workspace = true eigen-crypto-bls.workspace = true -ark-ff.workspace = true +eigen-telemetry = { workspace = true, optional = true } eigen-client-elcontracts.workspace = true eigen-utils.workspace = true eigen-logging.workspace = true +num-bigint = "0.4.4" thiserror.workspace = true +tokio = { workspace = true, optional = true } tracing.workspace = true @@ -34,3 +36,6 @@ eigen-testing-utils.workspace = true hex = "0.4.3" once_cell.workspace = true tokio = { version = "1.37.0", features = ["test-util", "full", "sync"] } + +[features] +telemetry = ["dep:eigen-telemetry", "dep:tokio"] diff --git a/crates/chainio/clients/avsregistry/src/error.rs b/crates/chainio/clients/avsregistry/src/error.rs index 69ffb393..96ccd1c1 100644 --- a/crates/chainio/clients/avsregistry/src/error.rs +++ b/crates/chainio/clients/avsregistry/src/error.rs @@ -157,9 +157,14 @@ pub enum AvsRegistryError { /// Invalid Signature #[error("Invalid signature")] InvalidSignature, + /// Parse BigInt #[error("big int error")] ParseBigIntError, + + /// Telemetry error + #[error("Telemetry error")] + TelemetryError(String), } impl From for AvsRegistryError { diff --git a/crates/chainio/clients/avsregistry/src/reader.rs b/crates/chainio/clients/avsregistry/src/reader.rs index 19471547..7b4b180c 100644 --- a/crates/chainio/clients/avsregistry/src/reader.rs +++ b/crates/chainio/clients/avsregistry/src/reader.rs @@ -105,6 +105,17 @@ impl AvsRegistryReader for AvsRegistryChainReader { .map_err(|_| AvsRegistryError::GetOperatorState)?; let OperatorStateRetriever::getOperatorState_0Return { _0: quorum } = operator_state; + + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "get_operators_stake_in_quorums_at_block", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } Ok(quorum) } @@ -114,6 +125,17 @@ impl AvsRegistryReader for AvsRegistryChainReader { quorum_numbers: Vec, non_signer_operator_ids: Vec>, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_check_signatures_indices", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_operator_state_retriever = @@ -137,6 +159,17 @@ impl AvsRegistryReader for AvsRegistryChainReader { &self, operator_id: [u8; 32], ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operator_from_id", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_registry_coordinator = @@ -169,6 +202,16 @@ impl AvsRegistryChainReader { operator_state_retriever_addr: Address, http_provider_url: String, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = + eigen_telemetry::telemetry::Telemetry::capture_event("avsregistryreader.new") + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&http_provider_url); let contract_registry_coordinator = @@ -209,6 +252,17 @@ impl AvsRegistryChainReader { /// /// The total quorum count read from the RegistryCoordinator. pub async fn get_quorum_count(&self) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_quorum_count", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_registry_coordinator = @@ -241,6 +295,17 @@ impl AvsRegistryChainReader { block_number: u32, operator_id: B256, ) -> Result<(U256, Vec>), AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operators_stake_in_quorums_at_block_operator_id", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_operator_state_retriever = @@ -276,6 +341,17 @@ impl AvsRegistryChainReader { &self, quorum_numbers: Bytes, ) -> Result>, AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operators_stake_in_quorums_at_current_block", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let current_block_number = provider @@ -310,6 +386,17 @@ impl AvsRegistryChainReader { operator_id: B256, block_number: u32, ) -> Result<(Vec, Vec>), AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operators_stake_in_quorums_of_operator_at_block", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let (quorum_bitmaps, operator_stakes) = self .get_operators_stake_in_quorums_at_block_operator_id(block_number, operator_id) .await @@ -335,6 +422,17 @@ impl AvsRegistryChainReader { &self, operator_id: B256, ) -> Result<(Vec, Vec>), AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operators_stake_in_quorums_of_operator_at_current_block", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let current_block_number = provider.get_block_number().await.map_err(|e| { @@ -366,6 +464,17 @@ impl AvsRegistryChainReader { &self, operator_id: B256, ) -> Result, AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operator_stake_in_quorums_of_operator_at_current_block", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let registry_coordinator = @@ -412,6 +521,17 @@ impl AvsRegistryChainReader { &self, operator_address: Address, ) -> Result, AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.get_operator_id", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_registry_coordinator = @@ -438,6 +558,17 @@ impl AvsRegistryChainReader { &self, operator_address: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.is_operator_registered", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_registry_coordinator = @@ -473,6 +604,17 @@ impl AvsRegistryChainReader { mut stop_block: u64, ws_url: String, ) -> Result<(Vec
, Vec), AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.query_existing_registered_operator_pub_keys", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_ws_provider(&ws_url).await.map_err(|e| { AvsRegistryError::AlloyContractError(alloy::contract::Error::TransportError(e)) })?; @@ -545,6 +687,17 @@ impl AvsRegistryChainReader { start_block: u64, stop_block: u64, ) -> Result, String>, AvsRegistryError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistryreader.query_existing_registered_operator_sockets", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let mut operator_id_to_socket = HashMap::new(); diff --git a/crates/chainio/clients/avsregistry/src/writer.rs b/crates/chainio/clients/avsregistry/src/writer.rs index c3d93b3a..fd0219f1 100644 --- a/crates/chainio/clients/avsregistry/src/writer.rs +++ b/crates/chainio/clients/avsregistry/src/writer.rs @@ -60,6 +60,17 @@ impl AvsRegistryChainWriter { registry_coordinator_addr: Address, operator_state_retriever_addr: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistrychainwriter.build_avs_registry_chain_writer", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let fill_provider = get_provider(&provider); let contract_registry_coordinator = @@ -142,6 +153,17 @@ impl AvsRegistryChainWriter { quorum_numbers: Bytes, socket: String, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistrychainwriter.register_operator_in_quorum_with_avs_registry_coordinator", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_signer(&self.signer.clone(), &self.provider); let wallet = PrivateKeySigner::from_str(&self.signer) .map_err(|_| AvsRegistryError::InvalidPrivateKey)?; @@ -222,6 +244,7 @@ impl AvsRegistryChainWriter { .map_err(AvsRegistryError::AlloyContractError)?; info!(tx_hash = ?tx,"Sent transaction to register operator in the AVS's registry coordinator" ); + Ok(*tx.tx_hash()) } @@ -246,6 +269,17 @@ impl AvsRegistryChainWriter { operators_per_quorum: Vec>, quorum_number: Bytes, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistrychainwriter.update_stakes_of_entire_operator_set_for_quorums", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + info!(quorum_numbers = %quorum_number, "updating stakes for entire operator set"); let provider = get_signer(&self.signer.clone(), &self.provider); let contract_registry_coordinator = @@ -277,6 +311,17 @@ impl AvsRegistryChainWriter { &self, operators: Vec
, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistrychainwriter.update_stakes_of_operator_subset_for_all_quorums", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + info!(operators = ?operators, "updating stakes of operator subset for all quorums"); let provider = get_signer(&self.signer.clone(), &self.provider); @@ -310,6 +355,17 @@ impl AvsRegistryChainWriter { &self, quorum_numbers: Bytes, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "avsregistrychainwriter.deregister_operator", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + info!("deregistering operator with the AVS's registry coordinator"); let provider = get_signer(&self.signer.clone(), &self.provider); diff --git a/crates/chainio/clients/elcontracts/Cargo.toml b/crates/chainio/clients/elcontracts/Cargo.toml index 841f16d7..d3789ab4 100644 --- a/crates/chainio/clients/elcontracts/Cargo.toml +++ b/crates/chainio/clients/elcontracts/Cargo.toml @@ -12,6 +12,7 @@ license-file.workspace = true alloy.workspace = true alloy-primitives.workspace = true eigen-logging.workspace = true +eigen-telemetry = { workspace = true, optional = true } eigen-types.workspace = true eigen-utils.workspace = true thiserror.workspace = true @@ -26,3 +27,6 @@ eigen-utils.workspace = true once_cell.workspace = true serial_test.workspace = true tokio.workspace = true + +[features] +telemetry = ["dep:eigen-telemetry", "dep:tokio"] diff --git a/crates/chainio/clients/elcontracts/src/reader.rs b/crates/chainio/clients/elcontracts/src/reader.rs index b2b89f80..ff71b3af 100644 --- a/crates/chainio/clients/elcontracts/src/reader.rs +++ b/crates/chainio/clients/elcontracts/src/reader.rs @@ -40,6 +40,15 @@ impl ELChainReader { avs_directory: Address, provider: String, ) -> Self { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event("elchainreader.new") + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + ELChainReader { _logger, slasher, @@ -70,6 +79,15 @@ impl ELChainReader { avs_directory: Address, client: &String, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event("elchainreader.build") + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(client); let contract_delegation_manager = DelegationManager::new(delegation_manager, provider); @@ -116,6 +134,17 @@ impl ELChainReader { approve_salt: FixedBytes<32>, expiry: U256, ) -> Result, ElContractsError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.calculate_delegation_approval_digest_hash", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_delegation_manager = DelegationManager::new(self.delegation_manager, provider); let delegation_approval_digest_hash = contract_delegation_manager @@ -159,6 +188,17 @@ impl ELChainReader { salt: FixedBytes<32>, expiry: U256, ) -> Result, ElContractsError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.calculate_operator_avs_registration_digest_hash", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_avs_directory = AVSDirectory::new(self.avs_directory, provider); @@ -194,6 +234,17 @@ impl ELChainReader { operator_addr: Address, strategy_addr: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.get_operator_shares_in_strategy", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_delegation_manager = DelegationManager::new(self.delegation_manager, provider); @@ -223,6 +274,17 @@ impl ELChainReader { &self, operator_addr: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.operator_is_frozen", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_slasher = ISlasher::new(self.slasher, provider); @@ -256,6 +318,17 @@ impl ELChainReader { operator_addr: Address, service_manager_addr: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.service_manager_can_slash_operator_until_block", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_slasher = ISlasher::new(self.slasher, provider); @@ -291,6 +364,17 @@ impl ELChainReader { &self, strategy_addr: Address, ) -> Result<(Address, Address, Address), ElContractsError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.get_strategy_and_underlying_erc20_token", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_strategy = IStrategy::new(strategy_addr, &provider); @@ -331,6 +415,17 @@ impl ELChainReader { &self, operator: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.get_operator_details", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_delegation_manager = @@ -372,6 +467,17 @@ impl ELChainReader { &self, operator: Address, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainreader.is_operator_registered", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_provider(&self.provider); let contract_delegation_manager = DelegationManager::new(self.delegation_manager, provider); diff --git a/crates/chainio/clients/elcontracts/src/writer.rs b/crates/chainio/clients/elcontracts/src/writer.rs index cd94ca15..325cdeb1 100644 --- a/crates/chainio/clients/elcontracts/src/writer.rs +++ b/crates/chainio/clients/elcontracts/src/writer.rs @@ -38,6 +38,15 @@ impl ELChainWriter { provider: String, signer: String, ) -> Self { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event("elchainwriter.new") + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + Self { delegation_manager, strategy_manager, @@ -65,6 +74,17 @@ impl ELChainWriter { &self, operator: Operator, ) -> Result, ElContractsError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainwriter.register_as_operator", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + info!("registering operator {:?} to EigenLayer", operator.address); let op_details = OperatorDetails { __deprecated_earningsReceiver: operator.earnings_receiver_address, @@ -118,6 +138,17 @@ impl ELChainWriter { &self, operator: Operator, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainwriter.update_operator_details", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + info!( "updating operator detils of operator {:?} to EigenLayer", operator.address @@ -168,6 +199,17 @@ impl ELChainWriter { strategy_addr: Address, amount: U256, ) -> Result { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainwriter.deposit_erc20_into_strategy", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + info!("depositing {amount:?} tokens into strategy {strategy_addr:?}"); let tokens = self .el_chain_reader @@ -210,6 +252,17 @@ impl ELChainWriter { &self, claimer: Address, ) -> Result, ElContractsError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainwriter.set_claimer_for", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_signer(&self.signer, &self.provider); let contract_rewards_coordinator = @@ -241,6 +294,17 @@ impl ELChainWriter { earner_address: Address, claim: RewardsMerkleClaim, ) -> Result, ElContractsError> { + #[cfg(feature = "telemetry")] + { + let _ = tokio::task::spawn_blocking(move || { + let _ = eigen_telemetry::telemetry::Telemetry::capture_event( + "elchainwriter.process_claim", + ) + .map_err(|e| AvsRegistryError::TelemetryError(e.to_string())); + }) + .await; + } + let provider = get_signer(&self.signer, &self.provider); let contract_rewards_coordinator = diff --git a/crates/chainio/txmanager/src/fake_backend.rs b/crates/chainio/txmanager/src/fake_backend.rs index 31189fcc..9ff07da3 100644 --- a/crates/chainio/txmanager/src/fake_backend.rs +++ b/crates/chainio/txmanager/src/fake_backend.rs @@ -123,7 +123,6 @@ impl EthBackend for FakeEthBackend { from: Address::default(), to: None, contract_address: None, - state_root: None, authorization_list: None, }) } diff --git a/crates/telemetry/Cargo.toml b/crates/telemetry/Cargo.toml new file mode 100644 index 00000000..4111b6b0 --- /dev/null +++ b/crates/telemetry/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "eigen-telemetry" +description = "Eigen Layer telemetry" + +version.workspace = true +edition.workspace = true +rust-version.workspace = true +repository.workspace = true +license-file.workspace = true + +[dependencies] +posthog-rs.workspace = true diff --git a/crates/telemetry/README.md b/crates/telemetry/README.md new file mode 100644 index 00000000..396512d6 --- /dev/null +++ b/crates/telemetry/README.md @@ -0,0 +1,18 @@ +# Eigen-telemetry + +To enable and use telemetry in your avs/code, you need to include `eigen-telemetry` crate and the rest of the SDK crates with the feature telemetry enabled. To do so, in your `Cargo.toml` file put: + +``` toml +eigen-telemetry = "*" +eigen-client-avsregistry = { version = "*", features = "telemetry" } +``` + +In the main function the code must set the config of the telemetry with the given parameters: + +``` rust +fn main() { + let _ = eigen_telemetry::telemetry::Telemetry::set_config("YOUR_TELEMETRY_KEY", "YOUR_USER_ID"); + + // ... the rest of the code ... +} +``` diff --git a/crates/telemetry/src/lib.rs b/crates/telemetry/src/lib.rs new file mode 100644 index 00000000..96bb08ec --- /dev/null +++ b/crates/telemetry/src/lib.rs @@ -0,0 +1,7 @@ +pub mod telemetry; +pub mod telemetry_config; + +use std::sync::OnceLock; +use telemetry_config::TelemetryConfig; + +static TELEMETRY_CELL: OnceLock = OnceLock::new(); diff --git a/crates/telemetry/src/telemetry.rs b/crates/telemetry/src/telemetry.rs new file mode 100644 index 00000000..ed4d8ee6 --- /dev/null +++ b/crates/telemetry/src/telemetry.rs @@ -0,0 +1,18 @@ +use super::telemetry_config::TelemetryConfig; +use posthog_rs::{Error, Event}; + +pub struct Telemetry {} + +impl Telemetry { + pub fn set_config(key: &str, user_id: &str) -> Result<(), TelemetryConfig> { + let config = TelemetryConfig::new(key, user_id); + crate::TELEMETRY_CELL.set(config)?; + Ok(()) + } + + pub fn capture_event(event: &str) -> Result<(), Error> { + let cell = crate::TELEMETRY_CELL.get().unwrap(); + let event = Event::new(event, &cell.user_id); + cell.client.capture(event) + } +} diff --git a/crates/telemetry/src/telemetry_config.rs b/crates/telemetry/src/telemetry_config.rs new file mode 100644 index 00000000..95216987 --- /dev/null +++ b/crates/telemetry/src/telemetry_config.rs @@ -0,0 +1,19 @@ +use posthog_rs::{client, Client}; + +pub struct TelemetryConfig { + pub key: String, + pub user_id: String, + pub(crate) client: Client, +} + +impl TelemetryConfig { + pub(crate) fn new(key: &str, user_id: &str) -> Self { + let client = client(key); + + Self { + key: key.to_owned(), + user_id: user_id.to_owned(), + client, + } + } +}