From f0d832ff4ded061d850f0d2955cad9a5b59d88b2 Mon Sep 17 00:00:00 2001 From: Yurii Koba Date: Thu, 22 Feb 2024 16:54:22 +0200 Subject: [PATCH] add metrics to calculate proxy calls to archival nodes (#177) --- CHANGELOG.md | 2 +- rpc-server/src/config.rs | 36 ++++++++++++++++------- rpc-server/src/metrics.rs | 8 +++++ rpc-server/src/modules/queries/methods.rs | 21 ++++++++++--- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aca28cf..603ab055 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for `SyncCheckpoint` in the `block` method for better block handling and synchronization. - +- Added `ARCHIVAL_PROXY_QUERY_VIEW_STATE_WITH_INCLUDE_PROOFS` metric to track the number of archival proxy requests for view state with include proofs. ### Changed - Enhanced the tx method to show in-progress transaction status, avoiding `UNKNOWN_TRANSACTION` responses and providing more accurate feedback. diff --git a/rpc-server/src/config.rs b/rpc-server/src/config.rs index 10b156af..8fbe7b57 100644 --- a/rpc-server/src/config.rs +++ b/rpc-server/src/config.rs @@ -10,7 +10,11 @@ pub struct GenesisInfo { } impl GenesisInfo { - pub async fn get(near_rpc_client: &crate::utils::JsonRpcClient) -> Self { + pub async fn get( + near_rpc_client: &crate::utils::JsonRpcClient, + s3_client: &near_lake_framework::s3_fetchers::LakeS3Client, + s3_bucket_name: &str, + ) -> Self { tracing::info!("Get genesis config..."); let genesis_config = near_rpc_client .call( @@ -18,14 +22,15 @@ impl GenesisInfo { ) .await .expect("Error to get genesis config"); - let genesis_block = near_rpc_client - .archival_call(near_jsonrpc_client::methods::block::RpcBlockRequest { - block_reference: near_primitives::types::BlockReference::BlockId( - near_primitives::types::BlockId::Height(genesis_config.genesis_height), - ), - }) - .await - .expect("Error to get genesis block"); + + let genesis_block = near_lake_framework::s3_fetchers::fetch_block( + s3_client, + s3_bucket_name, + genesis_config.genesis_height, + ) + .await + .expect("Error to get genesis block"); + Self { genesis_config, genesis_block_cache: genesis_block.into(), @@ -93,6 +98,8 @@ impl ServerContext { FinalBlockInfo::new(&near_rpc_client, &blocks_cache).await, )); + let s3_client = rpc_server_config.lake_config.lake_s3_client().await; + #[cfg(feature = "scylla_db")] let db_manager = database::prepare_db_manager::< database::scylladb::rpc_server::ScyllaDBManager, @@ -105,10 +112,17 @@ impl ServerContext { >(&rpc_server_config.database) .await?; + let genesis_info = GenesisInfo::get( + &near_rpc_client, + &s3_client, + &rpc_server_config.lake_config.aws_bucket_name, + ) + .await; + Ok(Self { - s3_client: rpc_server_config.lake_config.lake_s3_client().await, + s3_client, db_manager: std::sync::Arc::new(Box::new(db_manager)), - genesis_info: GenesisInfo::get(&near_rpc_client).await, + genesis_info, near_rpc_client, s3_bucket_name: rpc_server_config.lake_config.aws_bucket_name.clone(), blocks_cache, diff --git a/rpc-server/src/metrics.rs b/rpc-server/src/metrics.rs index 7b8229d8..9dafd533 100644 --- a/rpc-server/src/metrics.rs +++ b/rpc-server/src/metrics.rs @@ -578,6 +578,14 @@ lazy_static! { // end RECEIPT } +lazy_static! { + // ARCHIVAL PROXY CALL COUNTERS + pub(crate) static ref ARCHIVAL_PROXY_QUERY_VIEW_STATE_WITH_INCLUDE_PROOFS: IntCounter = try_create_int_counter( + "archive_proxy_query_view_state_with_include_proofs", + "Total number of the request to the archive nodes query_view_state with include_proofs" + ).unwrap(); +} + /// Exposes prometheus metrics #[get("/metrics")] pub(crate) async fn get_metrics() -> impl Responder { diff --git a/rpc-server/src/modules/queries/methods.rs b/rpc-server/src/modules/queries/methods.rs index 217bf521..f9cc6e4c 100644 --- a/rpc-server/src/modules/queries/methods.rs +++ b/rpc-server/src/modules/queries/methods.rs @@ -65,10 +65,23 @@ async fn query_call( crate::metrics::QUERY_VIEW_STATE_REQUESTS_TOTAL.inc(); if include_proof { // TODO: We can calculate the proof for state only on regular or archival nodes. - // After indexing the epochs and validators, - // we will be able to separate proxies queries to regular and archival nodes. - // For now we will proxy all requests with `include_proof` to archival nodes. - return Ok(data.near_rpc_client.archival_call(params).await?); + let final_block_info = data.final_block_info.read().await; + // `expected_earliest_available_block` calculated by formula: + // `final_block_height` - `node_epoch_count` * `epoch_length` + // Now near store 5 epochs, it can be changed in the future + // epoch_length = 43200 blocks + let expected_earliest_available_block = + final_block_info.final_block_cache.block_height + - 5 * data.genesis_info.genesis_config.epoch_length; + return if block.block_height > expected_earliest_available_block { + // Proxy to regular rpc if the block is available + Ok(data.near_rpc_client.call(params).await?) + } else { + // Increase the QUERY_VIEW_STATE_INCLUDE_PROOFS metric if we proxy to archival rpc + crate::metrics::ARCHIVAL_PROXY_QUERY_VIEW_STATE_WITH_INCLUDE_PROOFS.inc(); + // Proxy to archival rpc if the block garbage collected + Ok(data.near_rpc_client.archival_call(params).await?) + }; } else { view_state(&data, block, &account_id, prefix.as_ref()).await }