minting state
implement 1 minting at a time to prevent ddos enhanced json response
This commit is contained in:
		
							parent
							
								
									5514f7b794
								
							
						
					
					
						commit
						f67146aa13
					
				| @ -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() })), | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user