diff --git a/src/api_key.rs b/src/api_key.rs index c497ace..286e0f5 100644 --- a/src/api_key.rs +++ b/src/api_key.rs @@ -3,7 +3,9 @@ use std::str::FromStr; use base64::Engine; use poem_openapi::registry::{MetaSchema, MetaSchemaRef}; -use poem_openapi::types::{ParseFromJSON, ParseFromParameter, ToJSON}; +use poem_openapi::types::{ + ParseError, ParseFromJSON, ParseFromParameter, ToJSON, +}; use rand::rngs::OsRng; use rand::Rng; use serde::Serialize; @@ -161,12 +163,9 @@ impl ParseFromJSON for ApiKey { fn parse_from_json( value: Option, ) -> poem_openapi::types::ParseResult { - // TODO: Better error handling - let value = value - .ok_or_else(|| poem_openapi::types::ParseError::expected_input())?; + let value = value.ok_or_else(ParseError::expected_input)?; - serde_json::from_value(value) - .map_err(|_| poem_openapi::types::ParseError::expected_input()) + serde_json::from_value(value).map_err(ParseError::custom) } } @@ -177,8 +176,10 @@ impl ToJSON for ApiKey { } impl ParseFromParameter for ApiKey { - fn parse_from_parameter(value: &str) -> poem_openapi::types::ParseResult { - value.parse().map_err(|_| poem_openapi::types::ParseError::expected_input()) + fn parse_from_parameter( + value: &str, + ) -> poem_openapi::types::ParseResult { + value.parse().map_err(|_| ParseError::expected_input()) } } diff --git a/src/client.rs b/src/client.rs index 6efcd76..75e8581 100644 --- a/src/client.rs +++ b/src/client.rs @@ -48,16 +48,18 @@ impl TxSitterClient { self } + fn creds(&self) -> (&str, &str) { + self.credentials + .as_ref() + .map(|(u, p)| (u.as_str(), p.as_str())) + .unwrap_or_default() + } + async fn post(&self, url: &str) -> Result where R: serde::de::DeserializeOwned, { - let (username, password) = self - .credentials - .as_ref() - .map(|(u, p)| (u.as_str(), p.as_str())) - .unwrap_or_default() - .clone(); + let (username, password) = self.creds(); let response = self .client @@ -80,12 +82,7 @@ impl TxSitterClient { T: serde::Serialize, R: serde::de::DeserializeOwned, { - let (username, password) = self - .credentials - .as_ref() - .map(|(u, p)| (u.as_str(), p.as_str())) - .unwrap_or_default() - .clone(); + let (username, password) = self.creds(); let response = self .client @@ -104,12 +101,7 @@ impl TxSitterClient { where R: serde::de::DeserializeOwned, { - let (username, password) = self - .credentials - .as_ref() - .map(|(u, p)| (u.as_str(), p.as_str())) - .unwrap_or_default() - .clone(); + let (username, password) = self.creds(); let response = self .client @@ -155,17 +147,11 @@ impl TxSitterClient { relayer_id: &str, relayer_update: RelayerUpdate, ) -> Result<(), ClientError> { - let this = &self; let url: &str = &format!("{}/1/admin/relayer/{relayer_id}", self.url); - let (username, password) = this - .credentials - .as_ref() - .map(|(u, p)| (u.as_str(), p.as_str())) - .unwrap_or_default() - .clone(); + let (username, password) = self.creds(); - let response = this + let response = self .client .post(url) .json(&relayer_update) diff --git a/src/db.rs b/src/db.rs index 25574ee..4d4fcb1 100644 --- a/src/db.rs +++ b/src/db.rs @@ -12,7 +12,9 @@ use tracing::instrument; use crate::broadcast_utils::gas_estimation::FeesEstimate; use crate::config::DatabaseConfig; use crate::types::wrappers::h256::H256Wrapper; -use crate::types::{NetworkInfo, RelayerInfo, RelayerUpdate, TransactionPriority, TxStatus}; +use crate::types::{ + NetworkInfo, RelayerInfo, RelayerUpdate, TransactionPriority, TxStatus, +}; pub mod data; diff --git a/src/lib.rs b/src/lib.rs index 00643f9..fb183d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,8 +6,8 @@ pub mod client; pub mod config; pub mod db; pub mod keys; -pub mod serde_utils; pub mod new_server; +pub mod serde_utils; pub mod service; pub mod shutdown; pub mod task_runner; diff --git a/src/new_server.rs b/src/new_server.rs index fe44e54..8c6798c 100644 --- a/src/new_server.rs +++ b/src/new_server.rs @@ -41,26 +41,14 @@ impl AdminApi { ) -> Result> { basic_auth.validate(app).await?; - let (key_id, signer) = match app.keys_source.new_signer(&req.name).await - { - Ok(signer) => signer, - Err(e) => { - tracing::error!("Failed to create signer: {:?}", e); - - return Err(poem::error::Error::from_string( - "Failed to create signer".to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - )); - } - }; + let (key_id, signer) = app.keys_source.new_signer(&req.name).await?; let address = signer.address(); let relayer_id = uuid::Uuid::new_v4(); let relayer_id = relayer_id.to_string(); - let result = app - .db + app.db .create_relayer( &relayer_id, &req.name, @@ -68,19 +56,7 @@ impl AdminApi { &key_id, address, ) - .await; - - match result { - Ok(()) => {} - Err(e) => { - tracing::error!("Failed to create relayer: {:?}", e); - - return Err(poem::error::Error::from_string( - "Failed to create relayer".to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - )); - } - } + .await?; Ok(Json(CreateRelayerResponse { relayer_id, @@ -112,13 +88,7 @@ impl AdminApi { ) -> Result> { basic_auth.validate(app).await?; - let relayer_info = - app.db.get_relayer(&relayer_id).await.map_err(|err| { - poem::error::Error::from_string( - err.to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ) - })?; + let relayer_info = app.db.get_relayer(&relayer_id).await?; Ok(Json(relayer_info)) } @@ -134,15 +104,7 @@ impl AdminApi { ) -> Result<()> { basic_auth.validate(app).await?; - app.db - .update_relayer(&relayer_id, &req) - .await - .map_err(|err| { - poem::error::Error::from_string( - err.to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ) - })?; + app.db.update_relayer(&relayer_id, &req).await?; Ok(()) } @@ -159,12 +121,7 @@ impl AdminApi { ) -> Result<()> { basic_auth.validate(app).await?; - app.db.purge_unsent_txs(&relayer_id).await.map_err(|err| { - poem::error::Error::from_string( - err.to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ) - })?; + app.db.purge_unsent_txs(&relayer_id).await?; Ok(()) } @@ -202,12 +159,12 @@ impl AdminApi { let http_url: Url = network .http_rpc .parse::() - .map_err(|err| poem::error::BadRequest(err))?; + .map_err(poem::error::BadRequest)?; let ws_url: Url = network .ws_rpc .parse::() - .map_err(|err| poem::error::BadRequest(err))?; + .map_err(poem::error::BadRequest)?; app.db .upsert_network( @@ -216,21 +173,10 @@ impl AdminApi { http_url.as_str(), ws_url.as_str(), ) - .await - .map_err(|err| { - poem::error::Error::from_string( - err.to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ) - })?; + .await?; let task_runner = TaskRunner::new(app.clone()); - Service::spawn_chain_tasks(&task_runner, chain_id).map_err(|err| { - poem::error::Error::from_string( - err.to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ) - })?; + Service::spawn_chain_tasks(&task_runner, chain_id)?; Ok(()) } @@ -244,12 +190,7 @@ impl AdminApi { ) -> Result>> { basic_auth.validate(app).await?; - let networks = app.db.get_networks().await.map_err(|err| { - poem::error::Error::from_string( - err.to_string(), - StatusCode::INTERNAL_SERVER_ERROR, - ) - })?; + let networks = app.db.get_networks().await?; Ok(Json(networks)) } diff --git a/src/types/wrappers/address.rs b/src/types/wrappers/address.rs index 3599060..a0eccd5 100644 --- a/src/types/wrappers/address.rs +++ b/src/types/wrappers/address.rs @@ -1,6 +1,6 @@ use ethers::types::Address; use poem_openapi::registry::{MetaSchema, MetaSchemaRef}; -use poem_openapi::types::{ParseFromJSON, ToJSON}; +use poem_openapi::types::{ParseError, ParseFromJSON, ToJSON}; use serde::{Deserialize, Serialize}; use sqlx::database::HasValueRef; use sqlx::Database; @@ -56,11 +56,11 @@ impl poem_openapi::types::Type for AddressWrapper { } fn schema_ref() -> MetaSchemaRef { - let mut schema_ref = MetaSchema::new_with_format( - "string", "address", - ); + let mut schema_ref = MetaSchema::new_with_format("string", "address"); - schema_ref.example = Some(serde_json::Value::String("0x000000000000000000000000000000000000000f".to_string())); + schema_ref.example = Some(serde_json::Value::String( + "0x000000000000000000000000000000000000000f".to_string(), + )); schema_ref.title = Some("Address".to_string()); schema_ref.description = Some("Hex encoded ethereum address"); @@ -82,12 +82,10 @@ impl ParseFromJSON for AddressWrapper { fn parse_from_json( value: Option, ) -> poem_openapi::types::ParseResult { - // TODO: Better error handling - let value = value - .ok_or_else(|| poem_openapi::types::ParseError::expected_input())?; + let value = value.ok_or_else(ParseError::expected_input)?; - let value = serde_json::from_value(value) - .map_err(|_| poem_openapi::types::ParseError::expected_input())?; + let value = + serde_json::from_value(value).map_err(ParseError::custom)?; Ok(value) } @@ -108,10 +106,13 @@ mod tests { #[test] fn deserialize() { - let address: AddressWrapper = serde_json::from_str(r#""1Ed53d680B8890DAe2a63f673a85fFDE1FD5C7a2""#).unwrap(); + let address: AddressWrapper = serde_json::from_str( + r#""1Ed53d680B8890DAe2a63f673a85fFDE1FD5C7a2""#, + ) + .unwrap(); let expected = H160(hex!("1Ed53d680B8890DAe2a63f673a85fFDE1FD5C7a2")); assert_eq!(address.0, expected); } -} \ No newline at end of file +} diff --git a/src/types/wrappers/decimal_u256.rs b/src/types/wrappers/decimal_u256.rs index d9cc114..d32aa65 100644 --- a/src/types/wrappers/decimal_u256.rs +++ b/src/types/wrappers/decimal_u256.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use ethers::types::U256; use poem_openapi::registry::{MetaSchema, MetaSchemaRef}; -use poem_openapi::types::{ParseFromJSON, ToJSON}; +use poem_openapi::types::{ParseError, ParseFromJSON, ToJSON}; use serde::{Deserialize, Serialize}; use sqlx::database::{HasArguments, HasValueRef}; use sqlx::Database; @@ -122,15 +122,10 @@ impl ParseFromJSON for DecimalU256 { fn parse_from_json( value: Option, ) -> poem_openapi::types::ParseResult { - // TODO: Better error handling - let value = value - .ok_or_else(|| poem_openapi::types::ParseError::expected_input())?; + let value = value.ok_or_else(ParseError::expected_input)?; - let value = serde_json::from_value(value).map_err(|err| { - tracing::error!("Error deserializing DecimalU256: {:?}", err); - - poem_openapi::types::ParseError::expected_input() - })?; + let value = + serde_json::from_value(value).map_err(ParseError::custom)?; Ok(value) } diff --git a/src/types/wrappers/h256.rs b/src/types/wrappers/h256.rs index 0052996..069f536 100644 --- a/src/types/wrappers/h256.rs +++ b/src/types/wrappers/h256.rs @@ -1,6 +1,6 @@ use ethers::types::H256; use poem_openapi::registry::{MetaSchema, MetaSchemaRef}; -use poem_openapi::types::{ParseFromJSON, ToJSON}; +use poem_openapi::types::{ParseError, ParseFromJSON, ToJSON}; use serde::{Deserialize, Serialize}; use sqlx::database::{HasArguments, HasValueRef}; use sqlx::postgres::{PgHasArrayType, PgTypeInfo}; @@ -100,11 +100,10 @@ impl ParseFromJSON for H256Wrapper { value: Option, ) -> poem_openapi::types::ParseResult { // TODO: Better error handling - let value = value - .ok_or_else(|| poem_openapi::types::ParseError::expected_input())?; + let value = value.ok_or_else(ParseError::expected_input)?; - let inner = serde_json::from_value(value) - .map_err(|_| poem_openapi::types::ParseError::expected_input())?; + let inner = + serde_json::from_value(value).map_err(ParseError::custom)?; Ok(Self(inner)) } @@ -114,4 +113,4 @@ impl ToJSON for H256Wrapper { fn to_json(&self) -> Option { serde_json::to_value(self.0).ok() } -} \ No newline at end of file +} diff --git a/src/types/wrappers/hex_bytes.rs b/src/types/wrappers/hex_bytes.rs index 1e1d4f6..02dbbe8 100644 --- a/src/types/wrappers/hex_bytes.rs +++ b/src/types/wrappers/hex_bytes.rs @@ -1,7 +1,7 @@ use ethers::types::Bytes; -use serde::{Deserialize, Serialize}; use poem_openapi::registry::{MetaSchema, MetaSchemaRef}; -use poem_openapi::types::{ParseFromJSON, ToJSON}; +use poem_openapi::types::{ParseError, ParseFromJSON, ToJSON}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(transparent)] @@ -33,9 +33,8 @@ impl poem_openapi::types::Type for HexBytes { fn schema_ref() -> MetaSchemaRef { let mut schema_ref = MetaSchema::new_with_format("string", "bytes"); - schema_ref.example = Some(serde_json::Value::String( - "0xffffff".to_string(), - )); + schema_ref.example = + Some(serde_json::Value::String("0xffffff".to_string())); schema_ref.title = Some("Bytes".to_string()); schema_ref.description = Some("Hex encoded binary blob"); @@ -59,12 +58,10 @@ impl ParseFromJSON for HexBytes { fn parse_from_json( value: Option, ) -> poem_openapi::types::ParseResult { - // TODO: Better error handling - let value = value - .ok_or_else(|| poem_openapi::types::ParseError::expected_input())?; + let value = value.ok_or_else(ParseError::expected_input)?; - let inner = serde_json::from_value(value) - .map_err(|_| poem_openapi::types::ParseError::expected_input())?; + let inner = + serde_json::from_value(value).map_err(ParseError::custom)?; Ok(Self(inner)) } @@ -78,9 +75,10 @@ impl ToJSON for HexBytes { #[cfg(test)] mod tests { - use super::*; use test_case::test_case; + use super::*; + #[test_case("0xff", vec![255])] #[test_case("0xffff", vec![255, 255])] #[test_case("0x0101", vec![1, 1])] diff --git a/src/types/wrappers/hex_u256.rs b/src/types/wrappers/hex_u256.rs index c93424b..63f4a5f 100644 --- a/src/types/wrappers/hex_u256.rs +++ b/src/types/wrappers/hex_u256.rs @@ -1,6 +1,6 @@ use ethers::types::U256; use poem_openapi::registry::{MetaSchema, MetaSchemaRef}; -use poem_openapi::types::{ParseFromJSON, ToJSON}; +use poem_openapi::types::{ParseError, ParseFromJSON, ToJSON}; use serde::{Deserialize, Serialize}; use sqlx::database::{HasArguments, HasValueRef}; use sqlx::Database; @@ -74,12 +74,9 @@ impl poem_openapi::types::Type for HexU256 { fn schema_ref() -> MetaSchemaRef { let mut schema_ref = MetaSchema::new_with_format("string", "hex-u256"); - schema_ref.example = Some(serde_json::Value::String( - "0xff".to_string(), - )); - schema_ref.default = Some(serde_json::Value::String( - "0x0".to_string(), - )); + schema_ref.example = + Some(serde_json::Value::String("0xff".to_string())); + schema_ref.default = Some(serde_json::Value::String("0x0".to_string())); schema_ref.title = Some("Hex U256".to_string()); schema_ref.description = Some("A hex encoded 256-bit unsigned integer"); @@ -101,12 +98,10 @@ impl ParseFromJSON for HexU256 { fn parse_from_json( value: Option, ) -> poem_openapi::types::ParseResult { - // TODO: Better error handling - let value = value - .ok_or_else(|| poem_openapi::types::ParseError::expected_input())?; + let value = value.ok_or_else(ParseError::expected_input)?; - let value = serde_json::from_value(value) - .map_err(|_| poem_openapi::types::ParseError::expected_input())?; + let value = + serde_json::from_value(value).map_err(ParseError::custom)?; Ok(value) } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 423e6cc..b6e007f 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -113,7 +113,12 @@ pub async fn await_balance( for _ in 0..50 { let balance = provider.get_balance(address, None).await?; - tracing::info!(?address, ?balance, ?expected_balance, "Checking balance"); + tracing::info!( + ?address, + ?balance, + ?expected_balance, + "Checking balance" + ); if balance >= expected_balance { return Ok(());