diff --git a/Cargo.lock b/Cargo.lock index ac64a597..212f8687 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4141,6 +4141,7 @@ dependencies = [ [[package]] name = "relayer-utils" version = "0.3.7" +source = "git+https://github.com/zkemail/relayer-utils.git?rev=94d78d6#94d78d67862b6d6c15bebac66d184c7557f6aff5" dependencies = [ "anyhow", "base64 0.21.7", diff --git a/packages/relayer/src/database.rs b/packages/relayer/src/database.rs index 5dd0fbb9..5ee0e8d2 100644 --- a/packages/relayer/src/database.rs +++ b/packages/relayer/src/database.rs @@ -73,6 +73,31 @@ impl Database { Ok(()) } + // This is a hacky way to make all subsequent uses of "pub static ref DB" work + // Since the DB ref will only be connected to the database after it was used once + // -> The first request always times out + pub(crate) async fn initialize_db_connection(&self) -> Result<()> { + // Try up to 3 times + for i in 1..4 { + match sqlx::query("SELECT 1").execute(&self.db).await { + Ok(_) => { + info!(LOG, "Connected successfully to database"); + return Ok(()); + } + Err(e) => { + error!( + LOG, + "Failed to initialize connection to the database: {:?}. Retrying...", e + ); + tokio::time::sleep(Duration::from_secs(i * i)).await; + } + } + } + Err(anyhow::anyhow!( + "Failed to initialize database connection after 3 attempts" + )) + } + pub(crate) async fn get_credentials(&self, account_code: &str) -> Result> { let row = sqlx::query("SELECT * FROM credentials WHERE account_code = $1") .bind(account_code) @@ -208,14 +233,18 @@ impl Database { &self, request_id: u32, ) -> std::result::Result, DatabaseError> { + println!("attempting to get_request: {:?}", request_id); let row = sqlx::query("SELECT * FROM requests WHERE request_id = $1") .bind(request_id as i64) .fetch_optional(&self.db) .await .map_err(|e| DatabaseError::new("Failed to get request", e))?; + println!("got row"); + match row { Some(row) => { + println!("Row is Some"); let request_id: i64 = row.get("request_id"); let account_eth_addr: String = row.get("account_eth_addr"); let controller_eth_addr: String = row.get("controller_eth_addr"); @@ -241,7 +270,10 @@ impl Database { info!(LOG, "row {:?}", requests_row); Ok(Some(requests_row)) } - None => Ok(None), + None => { + println!("row is node"); + Ok(None) + } } } @@ -326,6 +358,7 @@ impl Database { &self, row: &Request, ) -> std::result::Result<(), DatabaseError> { + let request_id = row.request_id; let row = sqlx::query( "INSERT INTO requests (request_id, account_eth_addr, controller_eth_addr, guardian_email_addr, is_for_recovery, template_idx, is_processed, is_success, email_nullifier, account_salt) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *", ) @@ -342,7 +375,7 @@ impl Database { .fetch_one(&self.db) .await .map_err(|e| DatabaseError::new("Failed to insert request", e))?; - info!(LOG, "Request inserted"); + info!(LOG, "Request inserted with request_id: {}", request_id); Ok(()) } } diff --git a/packages/relayer/src/modules/web_server/server.rs b/packages/relayer/src/modules/web_server/server.rs index fbf85e77..812cd9be 100644 --- a/packages/relayer/src/modules/web_server/server.rs +++ b/packages/relayer/src/modules/web_server/server.rs @@ -6,6 +6,13 @@ use tower_http::cors::{AllowHeaders, AllowMethods, Any, CorsLayer}; pub async fn run_server() -> Result<()> { let addr = WEB_SERVER_ADDRESS.get().unwrap(); + // Force db initialization before server startup + info!(LOG, "Testing connection to database"); + if let Err(e) = DB.initialize_db_connection().await { + error!(LOG, "Failed to initialize db with e: {}", e); + panic!("Forcing panic, since connection to DB could not be established"); + }; + let mut app = Router::new() .route( "/api/echo",