Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update engine spec and api validation #10

Merged
merged 2 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
resolver = "2"

members = [
"crates/config",
Expand Down
1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y libssl-dev ca-certificates
COPY --from=builder /usr/local/cargo/bin/reflux /app/reflux

24 changes: 22 additions & 2 deletions bin/reflux/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;

Expand Down Expand Up @@ -98,6 +99,8 @@ async fn run_solver(config: Config) {

// Initialize routing engine
let buckets = config.buckets.clone();
let chain_configs = config.chains.clone();
let token_configs = config.tokens.clone();
let redis_client = RedisClient::build(&config.infra.redis_url)
.await
.expect("Failed to instantiate redis client");
Expand All @@ -106,6 +109,8 @@ async fn run_solver(config: Config) {
buckets,
redis_client.clone(),
config.solver_config,
chain_configs,
token_configs,
));

// Subscribe to cache update messages
Expand All @@ -131,8 +136,22 @@ async fn run_solver(config: Config) {
let _ = shutdown_rx.recv().await;
});

let token_chain_supported: HashMap<String, HashMap<u32, bool>> = config
.tokens
.iter()
.map(|(token, token_config)| {
let chain_supported = token_config
.by_chain
.iter()
.map(|(chain_id, chain_config)| (*chain_id, chain_config.is_enabled))
.collect();
(token.clone(), chain_supported)
})
.collect();

// API service controller
let service_controller = ServiceController::new(account_service, routing_engine);
let service_controller =
ServiceController::new(account_service, routing_engine, token_chain_supported);

let cors = CorsLayer::new().allow_origin(Any).allow_methods([
Method::GET,
Expand All @@ -146,8 +165,9 @@ async fn run_solver(config: Config) {
.await
.expect("Failed to bind port");

// todo: fix the graceful shutdown
axum::serve(listener, app.into_make_service())
.with_graceful_shutdown(shutdown_signal(shutdown_tx.clone()))
// .with_graceful_shutdown(shutdown_signal(shutdown_tx.clone()))
.await
.unwrap();

Expand Down
53 changes: 37 additions & 16 deletions crates/api/src/service_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,62 @@ use account_aggregation::{service::AccountAggregationService, types};
use axum::{extract::Query, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
use routing_engine::engine::RoutingEngine;
use serde_json::json;
use std::sync::Arc;
use std::{collections::HashMap, sync::Arc};

pub struct ServiceController {
account_service: Arc<AccountAggregationService>,
routing_engine: Arc<RoutingEngine>,
token_supported: HashMap<String, HashMap<u32, bool>>,
}

impl ServiceController {
pub fn new(
account_service: AccountAggregationService,
routing_engine: Arc<RoutingEngine>,
token_supported: HashMap<String, HashMap<u32, bool>>,
) -> Self {
Self { account_service: Arc::new(account_service), routing_engine }
Self { account_service: Arc::new(account_service), routing_engine, token_supported }
}

pub fn router(self) -> Router {
let account_service = self.account_service.clone();
let routing_engine = self.routing_engine.clone();

pub fn router(&self) -> Router {
Router::new()
.route("/", get(ServiceController::status))
.route("/api/health", get(ServiceController::status))
.route(
"/api/account",
get({
let account_service = account_service.clone();
let account_service = self.account_service.clone();
move |Query(query): Query<types::UserAccountMappingQuery>| async move {
ServiceController::get_account(account_service.clone(), query).await
ServiceController::get_account(account_service, query).await
}
}),
)
.route(
"/api/register_account",
axum::routing::post({
let account_service = account_service.clone();
let account_service = self.account_service.clone();
move |Json(payload): Json<types::RegisterAccountPayload>| async move {
ServiceController::register_user_account(account_service.clone(), payload)
.await
ServiceController::register_user_account(account_service, payload).await
}
}),
)
.route(
"/api/add_account",
axum::routing::post({
let account_service = account_service.clone();
let account_service = self.account_service.clone();
move |Json(payload): Json<types::AddAccountPayload>| async move {
ServiceController::add_account(account_service.clone(), payload).await
ServiceController::add_account(account_service, payload).await
}
}),
)
.route(
"/api/get_best_path",
get({
let routing_engine = routing_engine.clone();
let routing_engine = self.routing_engine.clone();
let token_supported = self.token_supported.clone();
move |Query(query): Query<types::PathQuery>| async move {
ServiceController::get_best_path(routing_engine.clone(), query).await
ServiceController::get_best_path(routing_engine, token_supported, query)
.await
}
}),
)
Expand Down Expand Up @@ -134,14 +134,35 @@ impl ServiceController {
/// Get best cost path for asset consolidation
pub async fn get_best_path(
routing_engine: Arc<RoutingEngine>,
token_supported: HashMap<String, HashMap<u32, bool>>,
query: types::PathQuery,
) -> impl IntoResponse {
// Check for the supported chain and token
match token_supported.get(&query.to_token) {
Some(chain_supported) => match chain_supported.get(&query.to_chain) {
Some(supported) => {
if !supported {
let response = json!({ "error": "Token not supported on chain" });
return (StatusCode::BAD_REQUEST, Json(response));
}
}
None => {
let response = json!({ "error": "Chain not supported for token" });
return (StatusCode::BAD_REQUEST, Json(response));
}
},
None => {
let response = json!({ "error": "Token not supported" });
return (StatusCode::BAD_REQUEST, Json(response));
}
}

match routing_engine
.get_best_cost_path(&query.account, query.to_chain, &query.to_token, query.to_value)
.await
{
Ok(routes) => {
let response = json!({ "routes": routes });
let response = json!({ "routes": "routes" });
(StatusCode::OK, Json(response))
}
Err(err) => {
Expand Down
10 changes: 5 additions & 5 deletions crates/config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ impl PartialEq<Self> for BucketConfig {

impl Eq for BucketConfig {}

#[derive(Debug, Deserialize, Validate)]
#[derive(Debug, Deserialize, Validate, Clone)]
pub struct ChainConfig {
// The chain id
#[validate(minimum = 1)]
Expand All @@ -313,7 +313,7 @@ pub struct ChainConfig {
pub covalent_name: String,
}

#[derive(Debug, Deserialize, Validate)]
#[derive(Debug, Deserialize, Validate, Clone)]
pub struct TokenConfig {
// The token symbol
#[validate(min_length = 1)]
Expand All @@ -328,8 +328,8 @@ pub struct TokenConfig {
pub by_chain: TokenConfigByChainConfigs,
}

#[derive(Debug, Deserialize, Validate, Into, From)]
pub struct TokenConfigByChainConfigs(HashMap<u32, ChainSpecificTokenConfig>);
#[derive(Debug, Deserialize, Validate, Into, From, Clone)]
pub struct TokenConfigByChainConfigs(pub HashMap<u32, ChainSpecificTokenConfig>);

impl ValidateUniqueItems for TokenConfigByChainConfigs {
fn validate_unique_items(&self) -> Result<(), UniqueItemsError> {
Expand All @@ -345,7 +345,7 @@ impl Deref for TokenConfigByChainConfigs {
}
}

#[derive(Debug, Deserialize, Validate)]
#[derive(Debug, Deserialize, Validate, Clone)]
pub struct ChainSpecificTokenConfig {
// The number of decimals the token has
#[validate(minimum = 1)]
Expand Down
Loading
Loading