Skip to content

Commit

Permalink
dev(better_theoros): supports N datafeeds + returns N calldata
Browse files Browse the repository at this point in the history
!
  • Loading branch information
akhercha committed Nov 2, 2024
1 parent 66b5340 commit 8172260
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 134 deletions.
87 changes: 55 additions & 32 deletions rust/theoros/src/handlers/rest/get_calldata.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,89 @@
use std::str::FromStr;

use alloy::hex;
use axum::extract::{Query, State};
use axum::Json;
use axum::{
extract::{Query, State},
Json,
};
use serde::{Deserialize, Serialize};
use utoipa::{IntoParams, ToResponse, ToSchema};

use crate::configs::evm_config::EvmChainName;
use crate::errors::GetCalldataError;
use crate::extractors::PathExtractor;
use crate::types::calldata::{AsCalldata, Calldata};
use crate::AppState;
use crate::{
configs::evm_config::EvmChainName,
errors::GetCalldataError,
types::calldata::{AsCalldata, Calldata},
AppState,
};

#[derive(Default, Deserialize, IntoParams, ToSchema)]
pub struct GetCalldataQuery {}
#[derive(Deserialize, IntoParams, ToSchema)]
pub struct GetCalldataQuery {
pub chain: String,
#[serde(deserialize_with = "deserialize_feed_ids")]
pub feed_ids: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize, ToResponse, ToSchema)]
pub struct GetCalldataResponse {
pub calldata: Calldata,
pub feed_id: String,
pub encoded_calldata: String,
}

#[utoipa::path(
get,
path = "/v1/calldata/{chain_name}/{feed_id}",
path = "/v1/calldata",
params(
GetCalldataQuery
),
responses(
(
status = 200,
description = "Constructs the calldata used to update the feed id specified",
description = "Constructs the calldata used to update the specified feed IDs",
body = [GetCalldataResponse]
),
(
status = 404,
description = "Unknown Feed Id",
body = [GetCalldataError]
description = "Unknown Feed ID",
body = GetCalldataError
)
),
params(
GetCalldataQuery
),
)]
pub async fn get_calldata(
State(state): State<AppState>,
PathExtractor(path_args): PathExtractor<(String, String)>,
Query(_params): Query<GetCalldataQuery>,
) -> Result<Json<GetCalldataResponse>, GetCalldataError> {
Query(params): Query<GetCalldataQuery>,
) -> Result<Json<Vec<GetCalldataResponse>>, GetCalldataError> {
let started_at = std::time::Instant::now();
let (raw_chain_name, feed_id) = path_args;
let chain_name = EvmChainName::from_str(&raw_chain_name)
.map_err(|_| GetCalldataError::ChainNotSupported(raw_chain_name.clone()))?;

let chain_name =
EvmChainName::from_str(&params.chain).map_err(|_| GetCalldataError::ChainNotSupported(params.chain.clone()))?;

let stored_feed_ids = state.storage.feed_ids();
if !stored_feed_ids.contains(&feed_id).await {
return Err(GetCalldataError::FeedNotFound(feed_id));
};

let calldata = Calldata::build_from(&state, chain_name, feed_id)
.await
.map_err(|e| GetCalldataError::CalldataError(e.to_string()))?;
// Check if all requested feed IDs are supported.
if let Some(missing_id) = stored_feed_ids.contains_vec(&params.feed_ids).await {
return Err(GetCalldataError::FeedNotFound(missing_id));
}

// Build calldata for each feed ID.
let mut responses = Vec::with_capacity(params.feed_ids.len());
for feed_id in &params.feed_ids {
let calldata = Calldata::build_from(&state, chain_name, feed_id.clone())
.await
.map_err(|e| GetCalldataError::CalldataError(e.to_string()))?;

let response =
GetCalldataResponse { feed_id: feed_id.clone(), encoded_calldata: hex::encode(calldata.as_bytes()) };
responses.push(response);
}

let response =
GetCalldataResponse { calldata: calldata.clone(), encoded_calldata: hex::encode(calldata.as_bytes()) };
tracing::info!("🌐 get_calldata - {:?}", started_at.elapsed());
Ok(Json(response))
Ok(Json(responses))
}

/// Deserialize a list of feed ids "A, B, C" into a Vec<String> = [A, B, C].
fn deserialize_feed_ids<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: String = String::deserialize(deserializer)?;
Ok(s.split(',').map(|s| s.trim().to_string()).collect())
}
Loading

0 comments on commit 8172260

Please sign in to comment.