From 33f63eb38c53e80dd586590700fb175eecd5a57e Mon Sep 17 00:00:00 2001 From: Avi Dessauer Date: Thu, 18 Jan 2024 15:29:47 -0600 Subject: [PATCH] Basic server --- kairos-server/Cargo.toml | 5 ++ kairos-server/src/errors.rs | 70 ++++++++++++++++++++++++++++ kairos-server/src/lib.rs | 39 ++++++++++++++++ kairos-server/src/main.rs | 21 ++++++++- kairos-server/src/routes/deposit.rs | 20 ++++++++ kairos-server/src/routes/mod.rs | 7 +++ kairos-server/src/routes/transfer.rs | 27 +++++++++++ kairos-server/src/routes/withdraw.rs | 20 ++++++++ 8 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 kairos-server/src/errors.rs create mode 100644 kairos-server/src/lib.rs create mode 100644 kairos-server/src/routes/deposit.rs create mode 100644 kairos-server/src/routes/mod.rs create mode 100644 kairos-server/src/routes/transfer.rs create mode 100644 kairos-server/src/routes/withdraw.rs diff --git a/kairos-server/Cargo.toml b/kairos-server/Cargo.toml index b4bc9dc2..fd75971d 100644 --- a/kairos-server/Cargo.toml +++ b/kairos-server/Cargo.toml @@ -3,6 +3,11 @@ name = "kairos-server" version.workspace = true edition.workspace = true +[lib] + +[[bin]] +name = "kairos-server" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/kairos-server/src/errors.rs b/kairos-server/src/errors.rs new file mode 100644 index 00000000..9378bfdd --- /dev/null +++ b/kairos-server/src/errors.rs @@ -0,0 +1,70 @@ +use std::{ + fmt, + ops::{Deref, DerefMut}, +}; + +use axum::{ + http::StatusCode, + response::{IntoResponse, Response}, +}; + + + +#[derive(Debug)] +pub struct AppErr { + error: anyhow::Error, + status: Option, +} + +impl AppErr { + pub fn set_status(err: impl Into, status: StatusCode) -> Self { + let mut err = err.into(); + err.status = Some(status); + err + } +} + +impl IntoResponse for AppErr { + fn into_response(self) -> Response { + ( + self.status.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), + format!("{}", self.error), + ) + .into_response() + } +} + +impl Deref for AppErr { + type Target = anyhow::Error; + fn deref(&self) -> &Self::Target { + &self.error + } +} + +impl DerefMut for AppErr { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.error + } +} + +impl fmt::Display for AppErr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}: {}", + self.status.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR), + self.error + ) + } +} + +impl std::error::Error for AppErr {} + +impl From for AppErr { + fn from(error: anyhow::Error) -> Self { + Self { + error, + status: None, + } + } +} diff --git a/kairos-server/src/lib.rs b/kairos-server/src/lib.rs new file mode 100644 index 00000000..8e192b2f --- /dev/null +++ b/kairos-server/src/lib.rs @@ -0,0 +1,39 @@ +pub mod errors; +pub mod routes; + +use std::{ + collections::{HashMap, HashSet}, + sync::Arc, +}; + +use axum::{routing::post, Router}; +use routes::{transfer::Transfer, *}; +use tokio::sync::RwLock; + +pub use errors::AppErr; + +type PublicKey = String; + +pub struct BatchState { + pub balances: HashMap, + pub batch_epoch: u64, + /// The set of transfers that will be batched in the next epoch. + pub batched_transfers: HashSet, +} +impl BatchState { + pub fn new() -> Arc> { + Arc::new(RwLock::new(Self { + balances: HashMap::new(), + batch_epoch: 0, + batched_transfers: HashSet::new(), + })) + } +} + +pub fn app_router(state: Arc>) -> Router { + Router::new() + .route("/api/v1/mock/deposit", post(deposit)) + .route("/api/v1/mock/withdraw", post(withdraw)) + .route("/api/v1/transfer", post(transfer)) + .with_state(state) +} diff --git a/kairos-server/src/main.rs b/kairos-server/src/main.rs index e7a11a96..afce7f8f 100644 --- a/kairos-server/src/main.rs +++ b/kairos-server/src/main.rs @@ -1,3 +1,20 @@ -fn main() { - println!("Hello, world!"); +use std::net::SocketAddr; + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + let axum_port: u16 = std::env::var("SERVER_PORT").map_or(8000, |x| { + x.parse().unwrap_or_else(|e| { + format!("Failed to parse SERVER_PORT: {}", e) + .parse() + .unwrap() + }) + }); + + let app = kairos_server::app_router(kairos_server::BatchState::new()); + + let axum_addr = SocketAddr::from(([127, 0, 0, 1], axum_port)); + tracing::info!("starting http server"); + let listener = tokio::net::TcpListener::bind(axum_addr).await.unwrap(); + axum::serve(listener, app).await.unwrap(); } diff --git a/kairos-server/src/routes/deposit.rs b/kairos-server/src/routes/deposit.rs new file mode 100644 index 00000000..c37cd133 --- /dev/null +++ b/kairos-server/src/routes/deposit.rs @@ -0,0 +1,20 @@ +use std::sync::Arc; + +use axum::{extract::State, Json}; +use serde::{Deserialize, Serialize}; +use tokio::sync::RwLock; + +use crate::{AppErr, BatchState, PublicKey}; + +#[derive(Serialize, Deserialize)] +pub struct DepositRequest { + pub public_key: PublicKey, + pub amount: u64, +} + +pub async fn deposit( + State(pool): State>>, + Json(proof_request): Json, +) -> Result<(), AppErr> { + todo!("deposit") +} diff --git a/kairos-server/src/routes/mod.rs b/kairos-server/src/routes/mod.rs new file mode 100644 index 00000000..bd659de5 --- /dev/null +++ b/kairos-server/src/routes/mod.rs @@ -0,0 +1,7 @@ +pub mod deposit; +pub mod withdraw; +pub mod transfer; + +pub use deposit::deposit; +pub use withdraw::withdraw; +pub use transfer::transfer; diff --git a/kairos-server/src/routes/transfer.rs b/kairos-server/src/routes/transfer.rs new file mode 100644 index 00000000..bc546069 --- /dev/null +++ b/kairos-server/src/routes/transfer.rs @@ -0,0 +1,27 @@ +use std::sync::Arc; + +use axum::{extract::State, Json}; +use serde::{Deserialize, Serialize}; +use tokio::sync::RwLock; + +use crate::{AppErr, BatchState, PublicKey}; + +#[derive(Serialize, Deserialize)] +pub struct Transfer { + pub from: PublicKey, + pub to: PublicKey, + pub amount: u64, +} + +#[derive(Serialize, Deserialize)] +pub struct TransferRequest { + transfer: Transfer, + signature: String, +} + +pub async fn transfer( + State(pool): State>>, + Json(proof_request): Json, +) -> Result<(), AppErr> { + todo!() +} diff --git a/kairos-server/src/routes/withdraw.rs b/kairos-server/src/routes/withdraw.rs new file mode 100644 index 00000000..8cc090fd --- /dev/null +++ b/kairos-server/src/routes/withdraw.rs @@ -0,0 +1,20 @@ +use std::sync::Arc; + +use axum::{extract::State, Json}; +use serde::{Deserialize, Serialize}; +use tokio::sync::RwLock; + +use crate::{AppErr, BatchState, PublicKey}; + +#[derive(Serialize, Deserialize)] +pub struct WithdrawRequest { + pub public_key: PublicKey, + pub amount: u64, +} + +pub async fn withdraw( + State(pool): State>>, + Json(proof_request): Json, +) -> Result<(), AppErr> { + todo!() +}