Skip to content

Commit 012f3ed

Browse files
committed
Put block timestamp lag next to other tracking tasks
1 parent 69db8a4 commit 012f3ed

File tree

4 files changed

+67
-104
lines changed

4 files changed

+67
-104
lines changed

apps/fortuna/src/command/run.rs

Lines changed: 4 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,24 @@ use {
44
chain::ethereum::InstrumentedPythContract,
55
command::register_provider::CommitmentMetadata,
66
config::{Commitment, Config, EthereumConfig, RunOptions},
7-
eth_utils::traced_client::{RpcMetrics, TracedClient},
7+
eth_utils::traced_client::RpcMetrics,
88
keeper::{self, keeper_metrics::KeeperMetrics},
99
state::{HashChainState, PebbleHashChain},
1010
},
1111
anyhow::{anyhow, Error, Result},
1212
axum::Router,
13-
ethers::{
14-
middleware::Middleware,
15-
types::{Address, BlockNumber},
16-
},
17-
prometheus_client::{
18-
encoding::EncodeLabelSet,
19-
metrics::{family::Family, gauge::Gauge},
20-
registry::Registry,
21-
},
22-
std::{
23-
collections::HashMap,
24-
net::SocketAddr,
25-
sync::Arc,
26-
time::{Duration, SystemTime, UNIX_EPOCH},
27-
},
13+
ethers::types::Address,
14+
prometheus_client::{encoding::EncodeLabelSet, registry::Registry},
15+
std::{collections::HashMap, net::SocketAddr, sync::Arc},
2816
tokio::{
2917
spawn,
3018
sync::{watch, RwLock},
31-
time,
3219
},
3320
tower_http::cors::CorsLayer,
3421
utoipa::OpenApi,
3522
utoipa_swagger_ui::SwaggerUi,
3623
};
3724

38-
/// Track metrics in this interval
39-
const TRACK_INTERVAL: Duration = Duration::from_secs(10);
40-
4125
pub async fn run_api(
4226
socket_addr: SocketAddr,
4327
chains: Arc<RwLock<HashMap<String, api::BlockchainState>>>,
@@ -158,16 +142,7 @@ pub async fn run(opts: &RunOptions) -> Result<()> {
158142
Ok::<(), Error>(())
159143
});
160144

161-
// Spawn a thread to track latest block lag. This helps us know if the rpc is up and updated with the latest block.
162-
//TODO: only run this after the chain is setup
163-
spawn(track_block_timestamp_lag(
164-
config,
165-
metrics_registry.clone(),
166-
rpc_metrics.clone(),
167-
));
168-
169145
run_api(opts.addr, chains.clone(), metrics_registry.clone(), rx_exit).await?;
170-
tracing::info!("Shut down server");
171146
Ok(())
172147
}
173148

@@ -271,74 +246,3 @@ async fn setup_chain_state(
271246
pub struct ChainLabel {
272247
pub chain_id: String,
273248
}
274-
275-
#[tracing::instrument(name = "block_timestamp_lag", skip_all, fields(chain_id = chain_id))]
276-
pub async fn check_block_timestamp_lag(
277-
chain_id: String,
278-
chain_config: EthereumConfig,
279-
metrics: Family<ChainLabel, Gauge>,
280-
rpc_metrics: Arc<RpcMetrics>,
281-
) {
282-
let provider =
283-
match TracedClient::new(chain_id.clone(), &chain_config.geth_rpc_addr, rpc_metrics) {
284-
Ok(r) => r,
285-
Err(e) => {
286-
tracing::error!("Failed to create provider for chain id - {:?}", e);
287-
return;
288-
}
289-
};
290-
291-
const INF_LAG: i64 = 1000000; // value that definitely triggers an alert
292-
let lag = match provider.get_block(BlockNumber::Latest).await {
293-
Ok(block) => match block {
294-
Some(block) => {
295-
let block_timestamp = block.timestamp;
296-
let server_timestamp = SystemTime::now()
297-
.duration_since(UNIX_EPOCH)
298-
.unwrap()
299-
.as_secs();
300-
let lag: i64 = (server_timestamp as i64) - (block_timestamp.as_u64() as i64);
301-
lag
302-
}
303-
None => {
304-
tracing::error!("Block is None");
305-
INF_LAG
306-
}
307-
},
308-
Err(e) => {
309-
tracing::error!("Failed to get block - {:?}", e);
310-
INF_LAG
311-
}
312-
};
313-
metrics
314-
.get_or_create(&ChainLabel {
315-
chain_id: chain_id.clone(),
316-
})
317-
.set(lag);
318-
}
319-
320-
/// Tracks the difference between the server timestamp and the latest block timestamp for each chain
321-
pub async fn track_block_timestamp_lag(
322-
config: Config,
323-
metrics_registry: Arc<RwLock<Registry>>,
324-
rpc_metrics: Arc<RpcMetrics>,
325-
) {
326-
let metrics = Family::<ChainLabel, Gauge>::default();
327-
metrics_registry.write().await.register(
328-
"block_timestamp_lag",
329-
"The difference between server timestamp and latest block timestamp",
330-
metrics.clone(),
331-
);
332-
loop {
333-
for (chain_id, chain_config) in &config.chains {
334-
spawn(check_block_timestamp_lag(
335-
chain_id.clone(),
336-
chain_config.clone(),
337-
metrics.clone(),
338-
rpc_metrics.clone(),
339-
));
340-
}
341-
342-
time::sleep(TRACK_INTERVAL).await;
343-
}
344-
}

apps/fortuna/src/keeper.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::keeper::track::track_block_timestamp_lag;
12
use {
23
crate::{
34
api::{BlockchainState, ChainId},
@@ -215,6 +216,14 @@ pub async fn run_keeper_threads(
215216
)
216217
.in_current_span(),
217218
);
219+
spawn(
220+
track_block_timestamp_lag(
221+
chain_id.clone(),
222+
contract.client(),
223+
keeper_metrics.clone(),
224+
)
225+
.in_current_span(),
226+
);
218227

219228
time::sleep(TRACK_INTERVAL).await;
220229
}

apps/fortuna/src/keeper/keeper_metrics.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub struct KeeperMetrics {
4242
pub final_fee_multiplier: Family<AccountLabel, Histogram>,
4343
pub gas_price_estimate: Family<AccountLabel, Gauge<f64, AtomicU64>>,
4444
pub accrued_pyth_fees: Family<ChainIdLabel, Gauge<f64, AtomicU64>>,
45+
pub block_timestamp_lag: Family<ChainIdLabel, Gauge>,
4546
}
4647

4748
impl Default for KeeperMetrics {
@@ -83,6 +84,7 @@ impl Default for KeeperMetrics {
8384
}),
8485
gas_price_estimate: Family::default(),
8586
accrued_pyth_fees: Family::default(),
87+
block_timestamp_lag: Family::default(),
8688
}
8789
}
8890
}
@@ -212,6 +214,12 @@ impl KeeperMetrics {
212214
keeper_metrics.accrued_pyth_fees.clone(),
213215
);
214216

217+
writable_registry.register(
218+
"block_timestamp_lag",
219+
"The difference between server timestamp and latest block timestamp",
220+
keeper_metrics.block_timestamp_lag.clone(),
221+
);
222+
215223
// *Important*: When adding a new metric:
216224
// 1. Register it above using `writable_registry.register(...)`
217225
// 2. Add a get_or_create call in the add_chain function below to initialize it for each chain/provider pair
@@ -220,9 +228,11 @@ impl KeeperMetrics {
220228
}
221229

222230
pub fn add_chain(&self, chain_id: String, provider_address: Address) {
223-
let _ = self.accrued_pyth_fees.get_or_create(&ChainIdLabel {
231+
let chain_id_label = ChainIdLabel {
224232
chain_id: chain_id.clone(),
225-
});
233+
};
234+
let _ = self.accrued_pyth_fees.get_or_create(&chain_id_label);
235+
let _ = self.block_timestamp_lag.get_or_create(&chain_id_label);
226236

227237
let account_label = AccountLabel {
228238
chain_id,

apps/fortuna/src/keeper/track.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ use {
55
eth_utils::traced_client::TracedClient,
66
},
77
ethers::middleware::Middleware,
8-
ethers::{providers::Provider, types::Address},
9-
std::sync::Arc,
8+
ethers::{prelude::BlockNumber, providers::Provider, types::Address},
9+
std::{
10+
sync::Arc,
11+
time::{SystemTime, UNIX_EPOCH},
12+
},
1013
tracing,
1114
};
1215

@@ -41,6 +44,43 @@ pub async fn track_balance(
4144
.set(balance);
4245
}
4346

47+
/// Tracks the difference between the server timestamp and the latest block timestamp for each chain
48+
#[tracing::instrument(skip_all)]
49+
pub async fn track_block_timestamp_lag(
50+
chain_id: String,
51+
provider: Arc<Provider<TracedClient>>,
52+
metrics: Arc<KeeperMetrics>,
53+
) {
54+
const INF_LAG: i64 = 1000000; // value that definitely triggers an alert
55+
let lag = match provider.get_block(BlockNumber::Latest).await {
56+
Ok(block) => match block {
57+
Some(block) => {
58+
let block_timestamp = block.timestamp;
59+
let server_timestamp = SystemTime::now()
60+
.duration_since(UNIX_EPOCH)
61+
.unwrap()
62+
.as_secs();
63+
let lag: i64 = (server_timestamp as i64) - (block_timestamp.as_u64() as i64);
64+
lag
65+
}
66+
None => {
67+
tracing::error!("Block is None");
68+
INF_LAG
69+
}
70+
},
71+
Err(e) => {
72+
tracing::error!("Failed to get block - {:?}", e);
73+
INF_LAG
74+
}
75+
};
76+
metrics
77+
.block_timestamp_lag
78+
.get_or_create(&ChainIdLabel {
79+
chain_id: chain_id.clone(),
80+
})
81+
.set(lag);
82+
}
83+
4484
/// tracks the collected fees and the hashchain data of the given provider address on the given chain
4585
/// if there is a error the function will just return
4686
#[tracing::instrument(skip_all)]

0 commit comments

Comments
 (0)