Skip to content

Commit

Permalink
Get tx
Browse files Browse the repository at this point in the history
  • Loading branch information
Dzejkop committed Jun 4, 2024
1 parent fd018e2 commit d525328
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 88 deletions.
7 changes: 4 additions & 3 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ use tracing::instrument;

use crate::broadcast_utils::gas_estimation::FeesEstimate;

Check warning on line 12 in src/db.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/tx-sitter-monolith/tx-sitter-monolith/src/db.rs
use crate::config::DatabaseConfig;
use crate::types::{RelayerInfo, NetworkInfo, RelayerUpdate, TransactionPriority};
use crate::types::wrappers::h256::H256Wrapper;
use crate::types::{NetworkInfo, RelayerInfo, RelayerUpdate, TransactionPriority, TxStatus};

pub mod data;

use self::data::{BlockFees, H256Wrapper, NetworkStats, ReadTxData, RpcKind};
pub use self::data::{TxForEscalation, TxStatus, UnsentTx};
use self::data::{BlockFees, NetworkStats, ReadTxData, RpcKind};
pub use self::data::{TxForEscalation, UnsentTx};

// Statically link in migration files
static MIGRATOR: Migrator = sqlx::migrate!("db/migrations");
Expand Down
81 changes: 3 additions & 78 deletions src/db/data.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
use ethers::types::{H256, U256};
use ethers::types::U256;
use serde::{Deserialize, Serialize};
use sqlx::database::{HasArguments, HasValueRef};
use sqlx::postgres::{PgHasArrayType, PgTypeInfo};
use sqlx::prelude::FromRow;
use sqlx::Database;

use crate::broadcast_utils::gas_estimation::FeesEstimate;
use crate::types::wrappers::address::AddressWrapper;
use crate::types::wrappers::h256::H256Wrapper;
use crate::types::wrappers::hex_u256::HexU256;
use crate::types::TransactionPriority;
use crate::types::{TransactionPriority, TxStatus};

#[derive(Debug, Clone, FromRow)]
pub struct UnsentTx {
Expand Down Expand Up @@ -78,79 +76,6 @@ pub struct BlockFees {
pub gas_price: U256,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct H256Wrapper(pub H256);

impl<'r, DB> sqlx::Decode<'r, DB> for H256Wrapper
where
DB: Database,
[u8; 32]: sqlx::Decode<'r, DB>,
{
fn decode(
value: <DB as HasValueRef<'r>>::ValueRef,
) -> Result<Self, sqlx::error::BoxDynError> {
let bytes = <[u8; 32] as sqlx::Decode<DB>>::decode(value)?;

let value = H256::from_slice(&bytes);

Ok(Self(value))
}
}

impl<'q, DB> sqlx::Encode<'q, DB> for H256Wrapper
where
DB: Database,
[u8; 32]: sqlx::Encode<'q, DB>,
{
fn encode_by_ref(
&self,
buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer,
) -> sqlx::encode::IsNull {
<[u8; 32] as sqlx::Encode<DB>>::encode_by_ref(&self.0 .0, buf)
}
}

impl PgHasArrayType for H256Wrapper {
fn array_type_info() -> PgTypeInfo {
<[u8; 32] as PgHasArrayType>::array_type_info()
}
}

impl<DB: Database> sqlx::Type<DB> for H256Wrapper
where
[u8; 32]: sqlx::Type<DB>,
{
fn type_info() -> DB::TypeInfo {
<[u8; 32] as sqlx::Type<DB>>::type_info()
}

fn compatible(ty: &DB::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

#[derive(
Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, sqlx::Type,
)]
#[sqlx(rename_all = "camelCase")]
#[sqlx(type_name = "tx_status")]
#[serde(rename_all = "camelCase")]
pub enum TxStatus {
Pending,
Mined,
Finalized,
}

impl TxStatus {
pub fn previous(self) -> Self {
match self {
Self::Pending => Self::Pending,
Self::Mined => Self::Pending,
Self::Finalized => Self::Mined,
}
}
}

#[derive(
Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, sqlx::Type,
)]
Expand Down
30 changes: 26 additions & 4 deletions src/new_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use crate::server::routes::relayer::CreateApiKeyResponse;
use crate::service::Service;
use crate::task_runner::TaskRunner;
use crate::types::{
CreateRelayerRequest, CreateRelayerResponse, NetworkInfo, NewNetworkInfo,
RelayerInfo, RelayerUpdate, SendTxRequest, SendTxResponse,
CreateRelayerRequest, CreateRelayerResponse, GetTxResponse, NetworkInfo,
NewNetworkInfo, RelayerInfo, RelayerUpdate, SendTxRequest, SendTxResponse,
};

mod security;
Expand Down Expand Up @@ -318,10 +318,32 @@ impl RelayerApi {
Data(app): Data<&Arc<App>>,
Path(api_token): Path<ApiKey>,
Path(tx_id): Path<String>,
) -> Result<Json<SendTxResponse>> {
) -> Result<Json<GetTxResponse>> {
api_token.validate(app).await?;

todo!()
let tx = app.db.read_tx(&tx_id).await?.ok_or_else(|| {
poem::error::Error::from_string(
"Transaction not found".to_string(),
StatusCode::NOT_FOUND,
)
})?;

let get_tx_response = GetTxResponse {
tx_id: tx.tx_id,
to: tx.to,
data: if tx.data.is_empty() {
None
} else {
Some(tx.data.into())
},
value: tx.value.into(),
gas_limit: tx.gas_limit.into(),
nonce: tx.nonce,
tx_hash: tx.tx_hash,
status: tx.status,
};

Ok(Json(get_tx_response))
}

/// Get Transactions
Expand Down
5 changes: 2 additions & 3 deletions src/server/routes/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use std::sync::Arc;

use axum::extract::{Json, Path, Query, State};
use ethers::types::{Address, Bytes, H256, U256};
use ethers::types::{Address, Bytes, H256};
use eyre::Result;
use serde::{Deserialize, Serialize};

use crate::api_key::ApiKey;
use crate::app::App;
use crate::db::TxStatus;
use crate::server::ApiError;
use crate::types::wrappers::decimal_u256::DecimalU256;
use crate::types::TransactionPriority;
use crate::types::{TransactionPriority, TxStatus};

#[derive(Debug, Default, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down
44 changes: 44 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
use sqlx::prelude::FromRow;
use wrappers::address::AddressWrapper;
use wrappers::decimal_u256::DecimalU256;
use wrappers::h256::H256Wrapper;
use wrappers::hex_bytes::HexBytes;
use wrappers::hex_u256::HexU256;

Expand Down Expand Up @@ -151,6 +152,49 @@ pub struct SendTxResponse {
pub tx_id: String,
}

#[derive(Debug, Clone, Serialize, Deserialize, Object)]
#[serde(rename_all = "camelCase")]
#[oai(rename_all = "camelCase")]
pub struct GetTxResponse {
pub tx_id: String,
pub to: AddressWrapper,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub data: Option<HexBytes>,
pub value: DecimalU256,
pub gas_limit: DecimalU256,
pub nonce: u64,

// Sent tx data
#[serde(default, skip_serializing_if = "Option::is_none")]
pub tx_hash: Option<H256Wrapper>,
#[serde(default)]
#[oai(default)]
pub status: Option<TxStatus>,
}

#[derive(
Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, sqlx::Type, Enum
)]
#[sqlx(rename_all = "camelCase")]
#[sqlx(type_name = "tx_status")]
#[serde(rename_all = "camelCase")]
#[oai(rename_all = "camelCase")]
pub enum TxStatus {
Pending,
Mined,
Finalized,
}

impl TxStatus {
pub fn previous(self) -> Self {
match self {
Self::Pending => Self::Pending,
Self::Mined => Self::Pending,
Self::Finalized => Self::Mined,
}
}
}

impl RelayerUpdate {
pub fn with_relayer_name(mut self, relayer_name: String) -> Self {
self.relayer_name = Some(relayer_name);
Expand Down
117 changes: 117 additions & 0 deletions src/types/wrappers/h256.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
use ethers::types::H256;
use poem_openapi::registry::{MetaSchema, MetaSchemaRef};
use poem_openapi::types::{ParseFromJSON, ToJSON};
use serde::{Deserialize, Serialize};
use sqlx::database::{HasArguments, HasValueRef};
use sqlx::postgres::{PgHasArrayType, PgTypeInfo};
use sqlx::Database;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct H256Wrapper(pub H256);

impl<'r, DB> sqlx::Decode<'r, DB> for H256Wrapper
where
DB: Database,
[u8; 32]: sqlx::Decode<'r, DB>,
{
fn decode(
value: <DB as HasValueRef<'r>>::ValueRef,
) -> Result<Self, sqlx::error::BoxDynError> {
let bytes = <[u8; 32] as sqlx::Decode<DB>>::decode(value)?;

let value = H256::from_slice(&bytes);

Ok(Self(value))
}
}

impl<'q, DB> sqlx::Encode<'q, DB> for H256Wrapper
where
DB: Database,
[u8; 32]: sqlx::Encode<'q, DB>,
{
fn encode_by_ref(
&self,
buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer,
) -> sqlx::encode::IsNull {
<[u8; 32] as sqlx::Encode<DB>>::encode_by_ref(&self.0 .0, buf)
}
}

impl PgHasArrayType for H256Wrapper {
fn array_type_info() -> PgTypeInfo {
<[u8; 32] as PgHasArrayType>::array_type_info()
}
}

impl<DB: Database> sqlx::Type<DB> for H256Wrapper
where
[u8; 32]: sqlx::Type<DB>,
{
fn type_info() -> DB::TypeInfo {
<[u8; 32] as sqlx::Type<DB>>::type_info()
}

fn compatible(ty: &DB::TypeInfo) -> bool {
*ty == Self::type_info()
}
}

impl poem_openapi::types::Type for H256Wrapper {
const IS_REQUIRED: bool = true;

type RawValueType = Self;

type RawElementValueType = Self;

fn name() -> std::borrow::Cow<'static, str> {
"string(h256)".into()
}

fn schema_ref() -> MetaSchemaRef {
let mut schema_ref = MetaSchema::new_with_format("string", "h256");

schema_ref.example = Some(serde_json::Value::String(
"0x46239dbfe5502b9f82c3dff992927d8d9b3168e732b4fd5771288569f5a1813d".to_string(),
));
schema_ref.default = Some(serde_json::Value::String(
"0x0000000000000000000000000000000000000000000000000000000000000000".to_string(),
));
schema_ref.title = Some("H256".to_string());
schema_ref.description = Some("A hex encoded 256-bit hash");

MetaSchemaRef::Inline(Box::new(schema_ref))
}

fn as_raw_value(&self) -> Option<&Self::RawValueType> {
Some(self)
}

fn raw_element_iter<'a>(
&'a self,
) -> Box<dyn Iterator<Item = &'a Self::RawElementValueType> + 'a> {
Box::new(self.as_raw_value().into_iter())
}
}

impl ParseFromJSON for H256Wrapper {
fn parse_from_json(
value: Option<serde_json::Value>,
) -> poem_openapi::types::ParseResult<Self> {
// TODO: Better error handling
let value = value
.ok_or_else(|| poem_openapi::types::ParseError::expected_input())?;

let inner = serde_json::from_value(value)
.map_err(|_| poem_openapi::types::ParseError::expected_input())?;

Ok(Self(inner))
}
}

impl ToJSON for H256Wrapper {
fn to_json(&self) -> Option<serde_json::Value> {
serde_json::to_value(self.0).ok()

Check warning on line 115 in src/types/wrappers/h256.rs

View workflow job for this annotation

GitHub Actions / cargo fmt

Diff in /home/runner/work/tx-sitter-monolith/tx-sitter-monolith/src/types/wrappers/h256.rs
}
}
6 changes: 6 additions & 0 deletions src/types/wrappers/hex_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ impl From<Bytes> for HexBytes {
}
}

impl From<Vec<u8>> for HexBytes {
fn from(value: Vec<u8>) -> Self {
Self(Bytes::from(value))
}
}

impl poem_openapi::types::Type for HexBytes {
const IS_REQUIRED: bool = true;

Expand Down

0 comments on commit d525328

Please sign in to comment.