Skip to content

Commit

Permalink
Add max_queued_txs column + minor client improvement (#25)
Browse files Browse the repository at this point in the history
* Add max_queued_txs column

* Implement logic (WIP)

* Serialize errors

* Update errors in client + update logic

* Instrument remaining db methods + fix

* Fix in code condition

* Reenable test

* Fix and refactor tests
  • Loading branch information
Dzejkop authored Mar 19, 2024
1 parent bc538aa commit 3d78aa1
Show file tree
Hide file tree
Showing 12 changed files with 520 additions and 75 deletions.
6 changes: 6 additions & 0 deletions db/migrations/003_relayers_tx_limits.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
ALTER TABLE relayers
ADD COLUMN max_queued_txs BIGINT NOT NULL DEFAULT 20,
ADD CONSTRAINT check_max_queued_txs CHECK (max_queued_txs > max_inflight_txs);

UPDATE relayers
SET max_queued_txs = GREATEST(max_inflight_txs, 20);
68 changes: 54 additions & 14 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use reqwest::Response;
use thiserror::Error;

use crate::api_key::ApiKey;
use crate::server::routes::network::NewNetworkInfo;
Expand All @@ -8,12 +9,29 @@ use crate::server::routes::relayer::{
use crate::server::routes::transaction::{
GetTxResponse, SendTxRequest, SendTxResponse,
};
use crate::server::ApiError;
use crate::types::RelayerUpdate;

pub struct TxSitterClient {
client: reqwest::Client,
url: String,
}

#[derive(Debug, Error)]
pub enum ClientError {
#[error("Reqwest error: {0}")]
Reqwest(#[from] reqwest::Error),

#[error("Serialization error: {0}")]
Serde(#[from] serde_json::Error),

#[error("API error: {0}")]
TxSitter(#[from] ApiError),

#[error("Invalid API key: {0}")]
InvalidApiKey(eyre::Error),
}

impl TxSitterClient {
pub fn new(url: impl ToString) -> Self {
Self {
Expand All @@ -22,7 +40,7 @@ impl TxSitterClient {
}
}

async fn post<R>(&self, url: &str) -> eyre::Result<R>
async fn post<R>(&self, url: &str) -> Result<R, ClientError>
where
R: serde::de::DeserializeOwned,
{
Expand All @@ -33,7 +51,11 @@ impl TxSitterClient {
Ok(response.json().await?)
}

async fn json_post<T, R>(&self, url: &str, body: T) -> eyre::Result<R>
async fn json_post<T, R>(
&self,
url: &str,
body: T,
) -> Result<R, ClientError>
where
T: serde::Serialize,
R: serde::de::DeserializeOwned,
Expand All @@ -45,7 +67,7 @@ impl TxSitterClient {
Ok(response.json().await?)
}

async fn json_get<R>(&self, url: &str) -> eyre::Result<R>
async fn json_get<R>(&self, url: &str) -> Result<R, ClientError>
where
R: serde::de::DeserializeOwned,
{
Expand All @@ -56,38 +78,56 @@ impl TxSitterClient {
Ok(response.json().await?)
}

async fn validate_response(response: Response) -> eyre::Result<Response> {
async fn validate_response(
response: Response,
) -> Result<Response, ClientError> {
if !response.status().is_success() {
let body = response.text().await?;

return Err(eyre::eyre!("{body}"));
let body: ApiError = response.json().await?;
return Err(ClientError::TxSitter(body));
}

Ok(response)
}

pub async fn create_relayer(
&self,
req: &CreateRelayerRequest,
) -> eyre::Result<CreateRelayerResponse> {
) -> Result<CreateRelayerResponse, ClientError> {
self.json_post(&format!("{}/1/admin/relayer", self.url), req)
.await
}

pub async fn create_relayer_api_key(
&self,
relayer_id: &str,
) -> eyre::Result<CreateApiKeyResponse> {
) -> Result<CreateApiKeyResponse, ClientError> {
self.post(&format!("{}/1/admin/relayer/{relayer_id}/key", self.url,))
.await
}

pub async fn update_relayer(
&self,
relayer_id: &str,
relayer_update: RelayerUpdate,
) -> Result<(), ClientError> {
self.json_post(
&format!("{}/1/admin/relayer/{relayer_id}", self.url),
relayer_update,
)
.await
}

pub async fn send_tx(
&self,
api_key: &ApiKey,
req: &SendTxRequest,
) -> eyre::Result<SendTxResponse> {
) -> Result<SendTxResponse, ClientError> {
self.json_post(
&format!("{}/1/api/{}/tx", self.url, api_key.reveal()?),
&format!(
"{}/1/api/{}/tx",
self.url,
api_key.reveal().map_err(ClientError::InvalidApiKey)?
),
req,
)
.await
Expand All @@ -97,11 +137,11 @@ impl TxSitterClient {
&self,
api_key: &ApiKey,
tx_id: &str,
) -> eyre::Result<GetTxResponse> {
) -> Result<GetTxResponse, ClientError> {
self.json_get(&format!(
"{}/1/api/{}/tx/{tx_id}",
self.url,
api_key.reveal()?,
api_key.reveal().map_err(ClientError::InvalidApiKey)?,
tx_id = tx_id
))
.await
Expand All @@ -111,7 +151,7 @@ impl TxSitterClient {
&self,
chain_id: u64,
req: &NewNetworkInfo,
) -> eyre::Result<()> {
) -> Result<(), ClientError> {
let response = self
.client
.post(&format!("{}/1/admin/network/{}", self.url, chain_id))
Expand Down
Loading

0 comments on commit 3d78aa1

Please sign in to comment.