improved minting #3

Merged
valy merged 2 commits from noormohammedb/hacker-challenge-sgx-general:enhance_minting into main 2025-01-02 13:19:40 +00:00
2 changed files with 28 additions and 4 deletions
Showing only changes of commit f67146aa13 - Show all commits

@ -2,6 +2,7 @@ use crate::persistence::{SealError, SealedFile};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_with::{serde_as, TimestampSeconds}; use serde_with::{serde_as, TimestampSeconds};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, SystemTime, UNIX_EPOCH}; use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::sync::RwLock; use tokio::sync::RwLock;
@ -95,6 +96,7 @@ pub struct State {
nodes: RwLock<HashMap<IP, NodeInfo>>, nodes: RwLock<HashMap<IP, NodeInfo>>,
conns: RwLock<HashSet<IP>>, conns: RwLock<HashSet<IP>>,
timeout: u64, timeout: u64,
is_minting: AtomicBool,
} }
impl State { impl State {
@ -102,7 +104,13 @@ impl State {
let mut nodes = HashMap::new(); let mut nodes = HashMap::new();
let my_info = NodeInfo::load(); let my_info = NodeInfo::load();
nodes.insert(my_ip.clone(), my_info); nodes.insert(my_ip.clone(), my_info);
Self { my_ip, timeout, nodes: RwLock::new(nodes), conns: RwLock::new(HashSet::new()) } Self {
my_ip,
timeout,
nodes: RwLock::new(nodes),
conns: RwLock::new(HashSet::new()),
is_minting: AtomicBool::new(false),
}
} }
pub async fn add_conn(&self, ip: &str) { pub async fn add_conn(&self, ip: &str) {
@ -203,6 +211,14 @@ impl State {
Duration::from_secs(self.timeout) Duration::from_secs(self.timeout)
} }
pub fn is_minting(&self) -> bool {
self.is_minting.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst).is_err()
}
pub fn release_minting(&self) {
self.is_minting.store(false, Ordering::SeqCst);
}
pub async fn get_my_info(&self) -> NodeInfo { pub async fn get_my_info(&self) -> NodeInfo {
let nodes = self.nodes.read().await; let nodes = self.nodes.read().await;
nodes.get(&self.my_ip).cloned().unwrap_or(NodeInfo::new_empty()) nodes.get(&self.my_ip).cloned().unwrap_or(NodeInfo::new_empty())

@ -2,6 +2,7 @@ use crate::{datastore, datastore::State, solana::SolClient};
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder}; use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::json;
use std::sync::Arc; use std::sync::Arc;
const HOMEPAGE: &str = include_str!("HOMEPAGE.md"); const HOMEPAGE: &str = include_str!("HOMEPAGE.md");
@ -67,12 +68,19 @@ async fn mint(
let recipient = req.into_inner().wallet; let recipient = req.into_inner().wallet;
state.increase_mint_requests().await; state.increase_mint_requests().await;
match sol_client.mint(&recipient).await { if state.is_minting() {
return HttpResponse::TooManyRequests().json(json!({ "error": "already mint processing" }));
}
let mint_res = sol_client.mint(&recipient).await;
state.release_minting();
match mint_res {
Ok(s) => { Ok(s) => {
state.increase_mints().await; state.increase_mints().await;
HttpResponse::Ok().body(format!(r#"{{" signature": "{s} "}}"#)) HttpResponse::Ok().json(json!({"signature": s}))
} }
Err(e) => HttpResponse::InternalServerError().body(format!(r#"{{ "error": "{e}" }}"#)), Err(e) => HttpResponse::InternalServerError().json(json!({ "error": e.to_string() })),
} }
} }