Skip to content

Commit

Permalink
feat(monitoring): add is_ready function to the monitoring gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
OriStarkware committed Nov 13, 2023
1 parent 9990c6a commit 5a6fff4
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions config/default_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@
"privacy": "Public",
"value": "0.0.0.0:8081"
},
"monitoring_gateway.starknet_url": {
"description": "URL for the Starknet gateway and the Starknet feeder gateway.",
"pointer_target": "starknet_url",
"privacy": "Public"
},
"rpc.chain_id": {
"description": "The chain to follow. For more details see https://docs.starknet.io/documentation/architecture_and_concepts/Blocks/transactions/#chain-id.",
"pointer_target": "chain_id",
Expand Down
1 change: 1 addition & 0 deletions crates/papyrus_monitoring_gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ papyrus_config = { path = "../papyrus_config", version = "0.2.0-rc2" }
rand.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = ["arbitrary_precision"]}
starknet_client = { path = "../starknet_client" }
thiserror.workspace = true
tokio = { workspace = true, features = ["full", "sync"] }
tracing.workspace = true
Expand Down
10 changes: 2 additions & 8 deletions crates/papyrus_monitoring_gateway/src/gateway_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const TEST_VERSION: &str = "1.2.3-dev";
fn setup_app() -> Router {
let ((storage_reader, _), _temp_dir) = test_utils::get_test_storage();
app(
String::from("default_url"),
storage_reader,
TEST_VERSION,
serde_json::to_value(TEST_CONFIG_PRESENTATION).unwrap(),
Expand Down Expand Up @@ -112,14 +113,6 @@ async fn alive() {
assert_eq!(response.status(), StatusCode::OK);
}

#[tokio::test]
async fn ready() {
let app = setup_app();
let response = request_app(app, "ready").await;

assert_eq!(response.status(), StatusCode::OK);
}

#[tokio::test]
async fn without_metrics() {
let app = setup_app();
Expand All @@ -136,6 +129,7 @@ async fn with_metrics() {
let ((storage_reader, _), _temp_dir) = test_utils::get_test_storage();
let prometheus_handle = PrometheusBuilder::new().install_recorder().unwrap();
let app = app(
String::from("default_url"),
storage_reader,
TEST_VERSION,
serde_json::Value::default(),
Expand Down
33 changes: 32 additions & 1 deletion crates/papyrus_monitoring_gateway/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ use papyrus_storage::{DbStats, StorageError, StorageReader};
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
use serde::{Deserialize, Serialize};
use starknet_client::reader::StarknetFeederGatewayClient;
use starknet_client::writer::StarknetGatewayClient;
use starknet_client::RetryConfig;
use tracing::{debug, info, instrument};
use validator::Validate;

Expand All @@ -35,6 +38,7 @@ pub struct MonitoringGatewayConfig {
#[validate(length(min = 1))]
#[serde(default = "random_secret")]
pub present_full_config_secret: String,
pub starknet_url: String,
}

fn random_secret() -> String {
Expand All @@ -50,6 +54,7 @@ impl Default for MonitoringGatewayConfig {
collect_metrics: false,
// A constant value for testing purposes.
present_full_config_secret: String::from("qwerty"),
starknet_url: String::from("https://alpha-mainnet.starknet.io/"),
}
}
}
Expand Down Expand Up @@ -138,6 +143,7 @@ impl MonitoringServer {
let server_address = SocketAddr::from_str(&self.config.server_address)
.expect("Configuration value for monitor server address should be valid");
let app = app(
self.config.starknet_url.clone(),
self.storage_reader.clone(),
self.version,
self.full_general_config_presentation.clone(),
Expand All @@ -151,6 +157,7 @@ impl MonitoringServer {
}

fn app(
starknet_url: String,
storage_reader: StorageReader,
version: &'static str,
full_general_config_presentation: serde_json::Value,
Expand Down Expand Up @@ -192,10 +199,34 @@ fn app(
)
.route(
format!("/{MONITORING_PREFIX}/ready").as_str(),
get(move || async { StatusCode::OK.to_string() }),
get(move || is_ready(version, starknet_url.clone())),
)
}

#[instrument(level = "debug", ret)]
async fn is_ready(version: &'static str, starknet_url: String) -> String {
let is_ready_retry_config =
RetryConfig { retry_base_millis: 50, retry_max_delay_millis: 1000, max_retries: 0 };

let starknet_feeder_client = StarknetFeederGatewayClient::new(
starknet_url.as_str(),
None,
version,
is_ready_retry_config,
)
.expect("Failed creating Starknet feeder client.");
let response = starknet_feeder_client.is_alive().await;
assert!(response);

let starknet_client =
StarknetGatewayClient::new(starknet_url.as_str(), version, is_ready_retry_config)
.expect("Failed creating Starknet client.");
let response = starknet_client.is_alive().await;
assert!(response);

StatusCode::OK.to_string()
}

/// Returns DB statistics.
#[instrument(skip(storage_reader), level = "debug", ret)]
async fn db_tables_stats(storage_reader: StorageReader) -> Result<Json<DbStats>, ServerError> {
Expand Down
2 changes: 1 addition & 1 deletion crates/papyrus_node/src/bin/dump_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ lazy_static! {
&ChainId("SN_MAIN".to_string()),
"The chain to follow. For more details see https://docs.starknet.io/documentation/architecture_and_concepts/Blocks/transactions/#chain-id.",
),
vec!["storage.db_config.chain_id".to_owned(), "rpc.chain_id".to_owned()],
vec!["storage.db_config.chain_id".to_owned(), "rpc.chain_id".to_owned(), "monitoring_gateway.starknet_url".to_owned()],
),
(
ser_pointer_target_param(
Expand Down
11 changes: 11 additions & 0 deletions crates/starknet_client/src/reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ struct StarknetUrls {
get_compiled_class_by_class_hash: Url,
get_state_update: Url,
get_pending_data: Url,
feeder_gateway_is_alive: Url,
}

const GET_BLOCK_URL: &str = "feeder_gateway/get_block";
Expand All @@ -123,6 +124,8 @@ const LATEST_BLOCK_NUMBER: &str = "latest";
const CLASS_HASH_QUERY: &str = "classHash";
const PENDING_BLOCK_ID: &str = "pending";
const INCLUDE_BLOCK: &str = "includeBlock";
const FEEDER_GATEWAY_IS_ALIVE: &str = "feeder_gateway/is_alive";
const FEEDER_GATEWAY_ALIVE_RESPONSE: &str = "FeederGateway is alive!";

impl StarknetUrls {
fn new(url_str: &str) -> Result<Self, ClientCreationError> {
Expand All @@ -140,6 +143,7 @@ impl StarknetUrls {
.append_pair(INCLUDE_BLOCK, "true")
.finish()
.clone(),
feeder_gateway_is_alive: base_url.join(FEEDER_GATEWAY_IS_ALIVE)?,
})
}
}
Expand Down Expand Up @@ -180,6 +184,13 @@ impl StarknetFeederGatewayClient {
format!("Failed to get block number {block_number:?} from starknet server."),
)
}

pub async fn is_alive(&self) -> bool {
let url = self.urls.feeder_gateway_is_alive.clone();
let response = self.request_with_retry_url(url).await;
let expected_response = FEEDER_GATEWAY_ALIVE_RESPONSE.to_string();
response.is_ok_and(|response| response == expected_response)
}
}

#[async_trait]
Expand Down
11 changes: 11 additions & 0 deletions crates/starknet_client/src/writer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,15 @@ pub trait StarknetWriter: Sync + Send + 'static {
}

const ADD_TRANSACTION_URL_SUFFIX: &str = "gateway/add_transaction";
const GATEWAY_IS_ALIVE: &str = "gateway/is_alive";
const GATEWAY_ALIVE_RESPONSE: &str = "Gateway is alive!";

/// A client for the [`Starknet`] gateway.
///
/// [`Starknet`]: https://starknet.io/
pub struct StarknetGatewayClient {
add_transaction_url: Url,
is_alive_url: Url,
client: StarknetClient,
}

Expand Down Expand Up @@ -114,6 +117,7 @@ impl StarknetGatewayClient {
) -> Result<Self, ClientCreationError> {
Ok(StarknetGatewayClient {
add_transaction_url: Url::parse(starknet_url)?.join(ADD_TRANSACTION_URL_SUFFIX)?,
is_alive_url: Url::parse(starknet_url)?.join(GATEWAY_IS_ALIVE)?,
client: StarknetClient::new(None, node_version, retry_config)?,
})
}
Expand All @@ -133,4 +137,11 @@ impl StarknetGatewayClient {
.await?;
Ok(serde_json::from_str::<Response>(&response)?)
}

pub async fn is_alive(&self) -> bool {
let url = self.is_alive_url.clone();
let response = self.client.request_with_retry(self.client.internal_client.get(url)).await;
let expected_response = GATEWAY_ALIVE_RESPONSE.to_string();
response.is_ok_and(|response| response == expected_response)
}
}

0 comments on commit 5a6fff4

Please sign in to comment.