Skip to content

Commit

Permalink
NDEV-2184: Report error when requested too early slot (#195)
Browse files Browse the repository at this point in the history
* Remove #[allow(dead_code)]

* NDEV-2184: Report error when requested too early slot
  • Loading branch information
andreisilviudragnea authored Sep 15, 2023
1 parent 3800125 commit 95d5c75
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 21 deletions.
2 changes: 1 addition & 1 deletion evm_loader/api/src/api_server/handlers/emulate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub async fn emulate(
) -> (StatusCode, Json<serde_json::Value>) {
let tx = emulate_request.tx_params.into();

let rpc_client = match context::build_rpc_client(&state.config, emulate_request.slot) {
let rpc_client = match context::build_rpc_client(&state.config, emulate_request.slot).await {
Ok(rpc_client) => rpc_client,
Err(e) => return process_error(StatusCode::BAD_REQUEST, &e),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub async fn get_ether_account_data(
Query(req_params): Query<GetEtherRequest>,
State(state): State<NeonApiState>,
) -> (StatusCode, Json<serde_json::Value>) {
let rpc_client = match context::build_rpc_client(&state.config, req_params.slot) {
let rpc_client = match context::build_rpc_client(&state.config, req_params.slot).await {
Ok(rpc_client) => rpc_client,
Err(e) => return process_error(StatusCode::BAD_REQUEST, &e),
};
Expand Down
2 changes: 1 addition & 1 deletion evm_loader/api/src/api_server/handlers/get_storage_at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub async fn get_storage_at(
Query(req_params): Query<GetStorageAtRequest>,
State(state): State<NeonApiState>,
) -> (StatusCode, Json<serde_json::Value>) {
let rpc_client = match context::build_rpc_client(&state.config, req_params.slot) {
let rpc_client = match context::build_rpc_client(&state.config, req_params.slot).await {
Ok(rpc_client) => rpc_client,
Err(e) => return process_error(StatusCode::BAD_REQUEST, &e),
};
Expand Down
2 changes: 2 additions & 0 deletions evm_loader/api/src/api_server/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{Config, Context, NeonApiResult};
use crate::types::request_models::EmulationParamsRequestModel;
use std::net::AddrParseError;
use std::str::FromStr;
use tracing::error;

pub mod emulate;
pub mod emulate_hash;
Expand Down Expand Up @@ -133,6 +134,7 @@ fn process_result<T: Serialize>(
}

fn process_error(status_code: StatusCode, e: &NeonError) -> (StatusCode, Json<Value>) {
error!("NeonError: {e}");
(
status_code,
Json(json!({
Expand Down
2 changes: 1 addition & 1 deletion evm_loader/api/src/api_server/handlers/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub async fn trace(
let tx = trace_request.emulate_request.tx_params.into();

let rpc_client =
match context::build_rpc_client(&state.config, trace_request.emulate_request.slot) {
match context::build_rpc_client(&state.config, trace_request.emulate_request.slot).await {
Ok(rpc_client) => rpc_client,
Err(e) => return process_error(StatusCode::BAD_REQUEST, &e),
};
Expand Down
4 changes: 2 additions & 2 deletions evm_loader/api/src/api_server/handlers/trace_next_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub async fn trace_next_block(
Json(trace_next_block_request): Json<TraceNextBlockRequestModel>,
) -> (StatusCode, Json<serde_json::Value>) {
let rpc_client =
match context::build_call_db_client(&state.config, trace_next_block_request.slot) {
match context::build_call_db_client(&state.config, trace_next_block_request.slot).await {
Ok(rpc_client) => rpc_client,
Err(e) => return process_error(StatusCode::BAD_REQUEST, &e),
};
Expand Down Expand Up @@ -49,7 +49,7 @@ pub async fn trace_next_block(
Err(e) => {
return process_error(
StatusCode::INTERNAL_SERVER_ERROR,
&errors::NeonError::PostgreError(e),
&errors::NeonError::PostgresError(e),
)
}
};
Expand Down
11 changes: 7 additions & 4 deletions evm_loader/cli/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ pub async fn create_from_config_and_options<'a>(
}
_ => {
if let Some(slot) = slot {
Arc::new(CallDbClient::new(
config.db_config.as_ref().expect("db-config not found"),
*slot,
))
Arc::new(
CallDbClient::new(
config.db_config.as_ref().expect("db-config not found"),
*slot,
)
.await?,
)
} else {
Arc::new(RpcClient::new_with_commitment(
config.json_rpc_url.clone(),
Expand Down
11 changes: 7 additions & 4 deletions evm_loader/lib/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ pub fn build_signer(config: &Config) -> Result<Box<dyn Signer>, NeonError> {
}

/// # Errors
pub fn build_rpc_client(
pub async fn build_rpc_client(
config: &Config,
slot: Option<u64>,
) -> Result<Arc<dyn rpc::Rpc>, NeonError> {
if let Some(slot) = slot {
return build_call_db_client(config, slot);
return build_call_db_client(config, slot).await;
}

Ok(Arc::new(RpcClient::new_with_commitment(
Expand All @@ -84,10 +84,13 @@ pub fn build_rpc_client(
}

/// # Errors
pub fn build_call_db_client(config: &Config, slot: u64) -> Result<Arc<dyn rpc::Rpc>, NeonError> {
pub async fn build_call_db_client(
config: &Config,
slot: u64,
) -> Result<Arc<dyn rpc::Rpc>, NeonError> {
let config = config
.db_config
.clone()
.ok_or(NeonError::InvalidChDbConfig)?;
Ok(Arc::new(CallDbClient::new(&config, slot)))
Ok(Arc::new(CallDbClient::new(&config, slot).await?))
}
12 changes: 9 additions & 3 deletions evm_loader/lib/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use solana_sdk::signer::SignerError as SolanaSignerError;
use thiserror::Error;

use crate::commands::init_environment::EnvironmentError;
use crate::types::PgError;
use crate::types::{ChError, PgError};

/// Errors that may be returned by the neon-cli program.
#[derive(Debug, Error)]
Expand Down Expand Up @@ -94,9 +94,13 @@ pub enum NeonError {
#[error("Hex Error. {0}")]
FromHexError(#[from] hex::FromHexError),
#[error("PostgreSQL Error: {0}")]
PostgreError(#[from] PgError),
PostgresError(#[from] PgError),
#[error("Panic: {0}")]
Panic(String),
#[error("ClickHouse: {0}")]
ClickHouse(ChError),
#[error("Slot {0} is less than earliest_rooted_slot={1}")]
EarlySlot(u64, u64),
}

impl NeonError {
Expand Down Expand Up @@ -131,7 +135,9 @@ impl NeonError {
NeonError::IncorrectAddress(_) => 248,
NeonError::IncorrectIndex(_) => 249,
NeonError::TxParametersParsingError(_) => 250,
NeonError::PostgreError(_) => 251,
NeonError::PostgresError(_) => 251,
NeonError::ClickHouse(_) => 252,
NeonError::EarlySlot(_, _) => 253,
}
}
}
Expand Down
16 changes: 13 additions & 3 deletions evm_loader/lib/src/rpc/db_call_client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{e, Rpc};
use crate::types::{ChDbConfig, TracerDb, TxParams};
use crate::NeonError;
use async_trait::async_trait;
use solana_client::{
client_error::Result as ClientResult,
Expand Down Expand Up @@ -27,12 +28,21 @@ pub struct CallDbClient {
}

impl CallDbClient {
pub fn new(config: &ChDbConfig, slot: u64) -> Self {
pub async fn new(config: &ChDbConfig, slot: u64) -> Result<Self, NeonError> {
let db = TracerDb::new(config);
Self {

let earliest_rooted_slot = db
.get_earliest_rooted_slot()
.await
.map_err(NeonError::ClickHouse)?;
if slot < earliest_rooted_slot {
return Err(NeonError::EarlySlot(slot, earliest_rooted_slot));
}

Ok(Self {
slot,
tracer_db: db,
}
})
}
}

Expand Down
18 changes: 17 additions & 1 deletion evm_loader/lib/src/types/tracer_ch_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ impl TryInto<Account> for AccountRow {
}
}

#[allow(dead_code)]
impl ClickHouseDb {
pub fn new(config: &ChDbConfig) -> Self {
let url_id = rand::thread_rng().gen_range(0..config.clickhouse_url.len());
Expand Down Expand Up @@ -169,6 +168,23 @@ impl ClickHouseDb {
result
}

pub async fn get_earliest_rooted_slot(&self) -> ChResult<u64> {
let time_start = Instant::now();
let query = "SELECT min(slot) FROM events.rooted_slots";
let result = self
.client
.query(query)
.fetch_one::<u64>()
.await
.map_err(std::convert::Into::into);
let execution_time = Instant::now().duration_since(time_start);
info!(
"get_earliest_rooted_slot sql returned {result:?}, time: {} sec",
execution_time.as_secs_f64()
);
result
}

pub async fn get_latest_block(&self) -> ChResult<u64> {
let time_start = Instant::now();
let query = "SELECT max(slot) FROM events.update_slot";
Expand Down

0 comments on commit 95d5c75

Please sign in to comment.