diff --git a/src/db.rs b/src/db.rs index cf9adad..df84750 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1023,6 +1023,39 @@ impl Database { block_txs: block_txs as u64, }) } + + pub async fn purge_unsent_txs(&self, relayer_id: &str) -> eyre::Result<()> { + let unsent_txs = self.get_unsent_txs().await?; + + let unsent_tx_ids: Vec<_> = unsent_txs + .into_iter() + .filter(|tx| tx.relayer_id == relayer_id) + .map(|tx| tx.id) + .collect(); + + sqlx::query( + r#" + DELETE FROM transactions + WHERE id = ANY($1::TEXT[]) + "#, + ) + .bind(&unsent_tx_ids) + .execute(&self.pool) + .await?; + + sqlx::query( + r#" + UPDATE relayers + SET nonce = current_nonce + WHERE id = $1 + "#, + ) + .bind(relayer_id) + .execute(&self.pool) + .await?; + + Ok(()) + } } #[cfg(test)] diff --git a/src/server.rs b/src/server.rs index 247a604..11803d1 100644 --- a/src/server.rs +++ b/src/server.rs @@ -10,7 +10,7 @@ use tower_http::validate_request::ValidateRequestHeaderLayer; use self::routes::relayer::{ create_relayer, create_relayer_api_key, get_relayer, get_relayers, - relayer_rpc, update_relayer, + purge_unsent_txs, relayer_rpc, update_relayer, }; use self::routes::transaction::{get_tx, get_txs, send_tx}; use crate::app::App; @@ -77,6 +77,7 @@ pub async fn spawn_server( let mut admin_routes = Router::new() .route("/relayer", post(create_relayer)) + .route("/relayer/:relayer_id/reset", post(purge_unsent_txs)) .route("/relayers", get(get_relayers)) .route( "/relayer/:relayer_id", diff --git a/src/server/routes/relayer.rs b/src/server/routes/relayer.rs index 306c6c4..d262cdc 100644 --- a/src/server/routes/relayer.rs +++ b/src/server/routes/relayer.rs @@ -108,6 +108,19 @@ pub async fn get_relayer( Ok(Json(relayer_info)) } +/// Resets the relayer +/// deletes all unsent txs +/// and resets nonce to the current confirmed nonce +#[tracing::instrument(skip(app))] +pub async fn purge_unsent_txs( + State(app): State>, + Path(relayer_id): Path, +) -> Result<(), ApiError> { + app.db.purge_unsent_txs(&relayer_id).await?; + + Ok(()) +} + #[tracing::instrument(skip(app))] pub async fn relayer_rpc( State(app): State>,