diff --git a/eth2near/eth2near-block-relay-rs/src/beacon_rpc_client.rs b/eth2near/eth2near-block-relay-rs/src/beacon_rpc_client.rs index f7598cce6..6d5cce245 100644 --- a/eth2near/eth2near-block-relay-rs/src/beacon_rpc_client.rs +++ b/eth2near/eth2near-block-relay-rs/src/beacon_rpc_client.rs @@ -172,11 +172,16 @@ impl BeaconRPCClient { } pub fn get_checkpoint_root(&self) -> Result> { - let url = format!("{}/eth/v1/beacon/states/finalized/finality_checkpoints", self.endpoint_url); + let url = format!( + "{}/eth/v1/beacon/states/finalized/finality_checkpoints", + self.endpoint_url + ); let checkpoint_json_str = self.get_json_from_raw_request(&url)?; let parsed_json: Value = serde_json::from_str(&checkpoint_json_str)?; - Ok(trim_quotes(parsed_json["data"]["finalized"]["root"].to_string())) + Ok(trim_quotes( + parsed_json["data"]["finalized"]["root"].to_string(), + )) } /// Return the last finalized slot in the Beacon chain diff --git a/eth2near/eth2near-block-relay-rs/src/eth2near_relay.rs b/eth2near/eth2near-block-relay-rs/src/eth2near_relay.rs index 3815a44a1..c7be59093 100644 --- a/eth2near/eth2near-block-relay-rs/src/eth2near_relay.rs +++ b/eth2near/eth2near-block-relay-rs/src/eth2near_relay.rs @@ -1,3 +1,4 @@ +use std::cmp::max; use crate::beacon_rpc_client::BeaconRPCClient; use crate::config::Config; use crate::eth1_rpc_client::Eth1RPCClient; @@ -5,10 +6,7 @@ use crate::hand_made_finality_light_client_update::HandMadeFinalityLightClientUp use crate::last_slot_searcher::LastSlotSearcher; use crate::near_rpc_client::NearRPCClient; use crate::prometheus_metrics; -use crate::prometheus_metrics::{ - FAILS_ON_HEADERS_SUBMISSION, FAILS_ON_UPDATES_SUBMISSION, LAST_ETH_SLOT, LAST_ETH_SLOT_ON_NEAR, - LAST_FINALIZED_ETH_SLOT, LAST_FINALIZED_ETH_SLOT_ON_NEAR, -}; +use crate::prometheus_metrics::{CHAIN_EXECUTION_BLOCK_HEIGHT_ON_ETH, CHAIN_EXECUTION_BLOCK_HEIGHT_ON_NEAR, CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_ETH, CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_NEAR, FAILS_ON_HEADERS_SUBMISSION, FAILS_ON_UPDATES_SUBMISSION, LAST_ETH_SLOT, LAST_ETH_SLOT_ON_NEAR, LAST_FINALIZED_ETH_SLOT, LAST_FINALIZED_ETH_SLOT_ON_NEAR}; use crate::relay_errors::NoBlockForSlotError; use contract_wrapper::eth_client_contract_trait::EthClientContractTrait; use eth_types::eth2::LightClientUpdate; @@ -20,6 +18,7 @@ use std::thread::sleep; use std::thread::spawn; use std::time::Duration; use std::vec::Vec; +use types::Slot; const ONE_EPOCH_IN_SLOTS: u64 = 32; @@ -135,6 +134,62 @@ impl Eth2NearRelay { eth2near_relay } + fn get_max_slot_for_submission(&self) -> Result> { + let last_eth2_slot = self.beacon_rpc_client.get_last_slot_number()?.as_u64(); + LAST_ETH_SLOT.inc_by(max(0, last_eth2_slot as i64 - LAST_ETH_SLOT.get())); + info!(target: "relay", "Last slot on ETH = {}", last_eth2_slot); + + let last_block_number = self.beacon_rpc_client.get_block_number_for_slot(Slot::new(last_eth2_slot))?; + CHAIN_EXECUTION_BLOCK_HEIGHT_ON_ETH.inc_by(max(0, last_block_number as i64 - CHAIN_EXECUTION_BLOCK_HEIGHT_ON_ETH.get())); + + return if self.submit_only_finalized_blocks { + Ok(self.beacon_rpc_client.get_last_finalized_slot_number()?.as_u64()) + } else { + Ok(last_eth2_slot) + } + } + + fn get_last_eth2_slot_on_near(&mut self, max_slot: u64) -> Result> { + let last_eth2_slot_on_near = self.last_slot_searcher.get_last_slot( + max_slot, + &self.beacon_rpc_client, + &self.eth_client_contract + )?; + + LAST_ETH_SLOT_ON_NEAR + .inc_by(max(0,last_eth2_slot_on_near as i64 - LAST_ETH_SLOT_ON_NEAR.get())); + + let last_block_number = self.beacon_rpc_client.get_block_number_for_slot(Slot::new(last_eth2_slot_on_near))?; + CHAIN_EXECUTION_BLOCK_HEIGHT_ON_NEAR.inc_by(max(0, last_block_number as i64 - CHAIN_EXECUTION_BLOCK_HEIGHT_ON_NEAR.get())); + + return Ok(last_eth2_slot_on_near); + } + + fn get_last_finalized_slot_on_near(&self) -> Result> { + let last_finalized_slot_on_near = self.eth_client_contract.get_finalized_beacon_block_slot()?; + LAST_FINALIZED_ETH_SLOT_ON_NEAR + .inc_by(max(0, last_finalized_slot_on_near as i64 - LAST_FINALIZED_ETH_SLOT_ON_NEAR.get())); + + let last_block_number = self.beacon_rpc_client.get_block_number_for_slot(Slot::new(last_finalized_slot_on_near))?; + CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_NEAR.inc_by(max(0, last_block_number as i64 - CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_NEAR.get())); + + Ok(last_finalized_slot_on_near) + } + + fn get_last_finalized_slot_on_eth(&self) -> Result> { + let last_finalized_slot_on_eth = self + .beacon_rpc_client + .get_last_finalized_slot_number()?.as_u64(); + + LAST_FINALIZED_ETH_SLOT + .inc_by(max(0,last_finalized_slot_on_eth as i64 - LAST_FINALIZED_ETH_SLOT.get())); + + let last_block_number = self.beacon_rpc_client.get_block_number_for_slot(Slot::new(last_finalized_slot_on_eth))?; + CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_ETH.inc_by(max(0, last_block_number as i64 - CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_ETH.get())); + + Ok(last_finalized_slot_on_eth) + } + pub fn run(&mut self, max_iterations: Option) { info!(target: "relay", "=== Relay running ==="); let mut iter_id = 0; @@ -150,45 +205,27 @@ impl Eth2NearRelay { info!(target: "relay", "== New relay loop =="); - let last_eth2_slot_on_eth_chain: u64 = if self.submit_only_finalized_blocks { - skip_fail!( - self.beacon_rpc_client.get_last_finalized_slot_number(), - "Fail to get last finalized slot on Eth", - self.sleep_time_on_sync_secs - ) - .as_u64() - } else { - skip_fail!( - self.beacon_rpc_client.get_last_slot_number(), - "Fail to get last slot on Eth", - self.sleep_time_on_sync_secs - ) - .as_u64() - }; + let max_slot_for_submission: u64 = skip_fail!( + self.get_max_slot_for_submission(), + "Fail to get last slot on Eth", + self.sleep_time_on_sync_secs); + let mut last_eth2_slot_on_near: u64 = skip_fail!( - self.last_slot_searcher.get_last_slot( - last_eth2_slot_on_eth_chain, - &self.beacon_rpc_client, - &self.eth_client_contract - ), + self.get_last_eth2_slot_on_near(max_slot_for_submission), "Fail to get last slot on NEAR", self.sleep_time_on_sync_secs ); - LAST_ETH_SLOT.inc_by(last_eth2_slot_on_eth_chain as i64 - LAST_ETH_SLOT.get()); - LAST_ETH_SLOT_ON_NEAR - .inc_by(last_eth2_slot_on_near as i64 - LAST_ETH_SLOT_ON_NEAR.get()); - - info!(target: "relay", "Last slot on near = {}; last slot on eth = {}", - last_eth2_slot_on_near, last_eth2_slot_on_eth_chain); + info!(target: "relay", "Last slot on near = {}; max slot for submission = {}", + last_eth2_slot_on_near, max_slot_for_submission); - if last_eth2_slot_on_near < last_eth2_slot_on_eth_chain { + if last_eth2_slot_on_near < max_slot_for_submission { info!(target: "relay", "= Creating headers batch ="); let (headers, current_slot) = skip_fail!( self.get_execution_blocks_between( last_eth2_slot_on_near + 1, - last_eth2_slot_on_eth_chain, + max_slot_for_submission, ), "Network problems during fetching execution blocks", self.sleep_time_on_sync_secs @@ -198,20 +235,15 @@ impl Eth2NearRelay { } let last_finalized_slot_on_near: u64 = skip_fail!( - self.eth_client_contract.get_finalized_beacon_block_slot(), - "Error on getting finalized block hash. Skipping sending light client update", + self.get_last_finalized_slot_on_near(), + "Error on getting finalized block slot on NEAR. Skipping sending light client update", + self.sleep_time_on_sync_secs + ); + + let last_finalized_slot_on_eth: u64 = skip_fail!( + self.get_last_finalized_slot_on_eth(), + "Error on getting last finalized slot on Ethereum. Skipping sending light client update", self.sleep_time_on_sync_secs); - - let last_finalized_slot_on_eth: u64 = skip_fail!(self - .beacon_rpc_client - .get_last_finalized_slot_number(), - "Error on getting last finalized slot number on Ethereum. Skipping sending light client update", - self.sleep_time_on_sync_secs).as_u64(); - - LAST_FINALIZED_ETH_SLOT_ON_NEAR - .inc_by(last_finalized_slot_on_near as i64 - LAST_FINALIZED_ETH_SLOT_ON_NEAR.get()); - LAST_FINALIZED_ETH_SLOT - .inc_by(last_finalized_slot_on_eth as i64 - LAST_FINALIZED_ETH_SLOT.get()); trace!(target: "relay", "last_finalized_slot on near/eth {}/{}", last_finalized_slot_on_near, last_finalized_slot_on_eth); diff --git a/eth2near/eth2near-block-relay-rs/src/prometheus_metrics.rs b/eth2near/eth2near-block-relay-rs/src/prometheus_metrics.rs index a1157e82e..160ab8c4a 100644 --- a/eth2near/eth2near-block-relay-rs/src/prometheus_metrics.rs +++ b/eth2near/eth2near-block-relay-rs/src/prometheus_metrics.rs @@ -9,54 +9,86 @@ use warp::Reply; lazy_static! { pub static ref REGISTRY: Registry = Registry::new(); pub static ref LAST_ETH_SLOT: IntCounter = - IntCounter::new("last_eth_slot", "Last Ethereum Slot").expect("metric can be created"); + IntCounter::new("last_eth_slot", "Last Ethereum Slot").expect("metric can't be created"); pub static ref LAST_ETH_SLOT_ON_NEAR: IntCounter = IntCounter::new("last_eth_slot_on_near", "Last Ethereum Slot on NEAR") - .expect("metric can be created"); + .expect("metric can't be created"); pub static ref LAST_FINALIZED_ETH_SLOT: IntCounter = IntCounter::new("last_finalized_eth_slot", "Last Finalized Ethereum Slot") - .expect("metric can be created"); + .expect("metric can't be created"); pub static ref LAST_FINALIZED_ETH_SLOT_ON_NEAR: IntCounter = IntCounter::new( "last_finalized_eth_slot_on_near", "Last Finalized Ethereum Slot on NEAR" ) - .expect("metric can be created"); + .expect("metric can't be created"); pub static ref FAILS_ON_HEADERS_SUBMISSION: IntCounter = IntCounter::new( "fails_on_headers_submission", "Fails number on Headers Submission" ) - .expect("metric can be created"); + .expect("metric can't be created"); pub static ref FAILS_ON_UPDATES_SUBMISSION: IntCounter = IntCounter::new( "fails_on_updates_submission", "Fails number on Light Client Updates Submission" ) - .expect("metric can be created"); + .expect("metric can't be created"); + + pub static ref CHAIN_EXECUTION_BLOCK_HEIGHT_ON_ETH: IntCounter = + IntCounter::new("chain_execution_block_height_on_eth", + "Chain execution block height on eth").expect("metric can't be created"); + + pub static ref CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_ETH: IntCounter = + IntCounter::new("chain_finalized_execution_block_height_on_eth", + "Chain finalized execution block height on eth").expect("metric cann't be created"); + + pub static ref CHAIN_EXECUTION_BLOCK_HEIGHT_ON_NEAR: IntCounter = + IntCounter::new("chain_execution_block_height_on_near", + "Chain execution block height on near").expect("metric can't be created"); + + pub static ref CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_NEAR: IntCounter = + IntCounter::new("chain_finalized_execution_block_height_on_near", + "Chain finalized execution block height on near").expect("metric can't be created"); } fn register_custom_metrics() { REGISTRY .register(Box::new(LAST_ETH_SLOT.clone())) - .expect("collector can be registered"); + .expect("last_eth_slot can't be registered"); REGISTRY .register(Box::new(LAST_ETH_SLOT_ON_NEAR.clone())) - .expect("collector can be registered"); + .expect("last_eth_slot_on_near can't be registered"); REGISTRY .register(Box::new(LAST_FINALIZED_ETH_SLOT.clone())) - .expect("collector can be registered"); + .expect("last_finalized_eth_slot can't be registered"); REGISTRY .register(Box::new(LAST_FINALIZED_ETH_SLOT_ON_NEAR.clone())) - .expect("collector can be registered"); + .expect("last_finalized_eth_slot_on_near can't be registered"); REGISTRY .register(Box::new(FAILS_ON_HEADERS_SUBMISSION.clone())) - .expect("collector can be registered"); + .expect("fails_on_header_submission can't be registered"); REGISTRY .register(Box::new(FAILS_ON_UPDATES_SUBMISSION.clone())) - .expect("collector can be registered"); + .expect("fails_on_updates_submission can't be registered"); + + REGISTRY + .register(Box::new(CHAIN_EXECUTION_BLOCK_HEIGHT_ON_ETH.clone())) + .expect("chain_execution_block_height_on_eth can't be registered"); + + REGISTRY + .register(Box::new(CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_ETH.clone())) + .expect("chain_finalized_execution_block_height_on_eth can't be registered"); + + REGISTRY + .register(Box::new(CHAIN_EXECUTION_BLOCK_HEIGHT_ON_NEAR.clone())) + .expect("chain_execution_block_height_on_near can't be registered"); + + REGISTRY + .register(Box::new(CHAIN_FINALIZED_EXECUTION_BLOCK_HEIGHT_ON_NEAR.clone())) + .expect("chain_finalized_execution_block_height_on_near can't be registered"); } async fn metrics_handler() -> Result { @@ -65,7 +97,7 @@ async fn metrics_handler() -> Result { let mut buffer = Vec::new(); if let Err(e) = encoder.encode(®ISTRY.gather(), &mut buffer) { - eprintln!("could not encode custom metrics: {}", e); + eprintln!("could not encode custom metrics: {:?}", e); }; let mut res = match String::from_utf8(buffer.clone()) { Ok(v) => v, @@ -77,7 +109,7 @@ async fn metrics_handler() -> Result { buffer.clear(); if let Err(e) = encoder.encode(&prometheus::gather(), &mut buffer) { - eprintln!("could not encode prometheus metrics: {}", e); + eprintln!("could not encode prometheus metrics: {:?}", e); }; let res_custom = match String::from_utf8(buffer.clone()) { Ok(v) => v,