From 36cb9378d9124825957b7ec90155e6609a818049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E7=AE=80=E8=88=9F?= Date: Mon, 8 Apr 2024 12:38:47 +0800 Subject: [PATCH] Optimize: prism e2n. (#256) --- explorer/src/main.rs | 7 +- .../src/service/v2/prism_evm_to_native.rs | 189 +++++++++++------- .../src/service/v2/prism_native_to_evm.rs | 2 +- 3 files changed, 127 insertions(+), 71 deletions(-) diff --git a/explorer/src/main.rs b/explorer/src/main.rs index 37e76c1..77049c0 100644 --- a/explorer/src/main.rs +++ b/explorer/src/main.rs @@ -4,7 +4,8 @@ use crate::service::v2::asset::get_assets; use crate::service::v2::block::{get_block_by_hash, get_block_by_num, get_blocks}; use crate::service::v2::claim::{get_claim_by_tx_hash, get_claims}; use crate::service::v2::delegation::{get_delegation_by_tx_hash, get_delegations}; -use crate::service::v2::prism_native_to_evm::{get_n2e_tx_by_tx_hash, get_n2e_txs}; +use crate::service::v2::prism_evm_to_native::{get_e2n_by_tx_hash, get_e2n_txs}; +use crate::service::v2::prism_native_to_evm::{get_n2e_by_tx_hash, get_n2e_txs}; use crate::service::v2::transaction::{get_tx_by_hash, get_txs}; use crate::service::v2::undelegation::{get_undelegation_by_tx_hash, get_undelegations}; use anyhow::Result; @@ -66,8 +67,10 @@ async fn main() -> Result<()> { get(get_undelegation_by_tx_hash), ) .route("/api/v2/undelegations", get(get_undelegations)) - .route("/api/v2/hash/n2e", get(get_n2e_tx_by_tx_hash)) + .route("/api/v2/hash/n2e", get(get_n2e_by_tx_hash)) .route("/api/v2/n2es", get(get_n2e_txs)) + .route("/api/v2/hash/e2n", get(get_e2n_by_tx_hash)) + .route("/api/v2/e2ns", get(get_e2n_txs)) .layer(cors) .with_state(app_state); let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); diff --git a/explorer/src/service/v2/prism_evm_to_native.rs b/explorer/src/service/v2/prism_evm_to_native.rs index a19b3e5..e265262 100644 --- a/explorer/src/service/v2/prism_evm_to_native.rs +++ b/explorer/src/service/v2/prism_evm_to_native.rs @@ -1,38 +1,16 @@ -use crate::service::api::Api; -use poem_openapi::param::Query; -use poem_openapi::payload::Json; -use poem_openapi::{ApiResponse, Object}; +use crate::service::v2::error::{internal_error, Result}; +use crate::service::v2::QueryResult; +use crate::AppState; +use axum::extract::{Query, State}; +use axum::Json; use serde::{Deserialize, Serialize}; use serde_json::Value; use sqlx::Row; +use std::ops::Add; +use std::sync::Arc; -#[derive(ApiResponse)] -pub enum V2EvmToNativeTxsResponse { - #[oai(status = 200)] - Ok(Json), - #[oai(status = 404)] - NotFound, - #[oai(status = 500)] - InternalError, -} - -#[derive(Serialize, Deserialize, Debug, Object)] -pub struct V2EvmToNativeTxsResult { - pub code: u16, - pub message: String, - pub data: V2EvmToNativeTxsData, -} - -#[derive(Serialize, Deserialize, Debug, Object)] -pub struct V2EvmToNativeTxsData { - pub total: i64, - pub page: i32, - pub page_size: i32, - pub txs: Vec, -} - -#[derive(Serialize, Deserialize, Debug, Object)] -pub struct V2EvmToNativeTx { +#[derive(Serialize, Deserialize)] +pub struct E2NTxResponse { pub tx_hash: String, pub block_hash: String, pub from: String, @@ -44,37 +22,116 @@ pub struct V2EvmToNativeTx { pub timestamp: i64, pub value: Value, } -#[allow(dead_code)] -pub async fn v2_get_e2n_txs( - api: &Api, - page: Query>, - page_size: Query>, -) -> anyhow::Result { - let mut conn = api.storage.lock().await.acquire().await?; - let page = page.0.unwrap_or(1); - let page_size = page_size.0.unwrap_or(10); - let sql_total = "SELECT count(*) FROM e2n"; - let row = sqlx::query(sql_total).fetch_one(&mut *conn).await?; - let total: i64 = row.try_get("count")?; +#[derive(Serialize, Deserialize)] +pub struct GetE2NByTxHashParams { + pub hash: String, +} + +pub async fn get_e2n_by_tx_hash( + State(state): State>, + Query(params): Query, +) -> Result> { + let mut conn = state.pool.acquire().await.map_err(internal_error)?; + let sql_query = r#"SELECT tx_hash,block_hash,sender,receiver,asset,amount,decimal,height,timestamp,value FROM e2n WHERE tx_hash=$1"#; + let row = sqlx::query(sql_query) + .bind(params.hash) + .fetch_one(&mut *conn) + .await + .map_err(internal_error)?; + + let tx_hash: String = row.try_get("tx_hash").map_err(internal_error)?; + let block_hash: String = row.try_get("block_hash").map_err(internal_error)?; + let from: String = row.try_get("sender").map_err(internal_error)?; + let to: String = row.try_get("receiver").map_err(internal_error)?; + let asset: String = row.try_get("asset").map_err(internal_error)?; + let decimal: i32 = row.try_get("decimal").map_err(internal_error)?; + let amount: String = row.try_get("amount").map_err(internal_error)?; + let height: i64 = row.try_get("height").map_err(internal_error)?; + let timestamp: i64 = row.try_get("timestamp").map_err(internal_error)?; + let value: Value = row.try_get("value").map_err(internal_error)?; + let tx = E2NTxResponse { + tx_hash, + block_hash, + from, + to, + asset, + amount, + decimal, + height, + timestamp, + value, + }; + + Ok(Json(tx)) +} + +#[derive(Serialize, Deserialize)] +pub struct GetE2NTxsParams { + pub from: Option, + pub to: Option, + pub page: Option, + pub page_size: Option, +} + +pub async fn get_e2n_txs( + State(state): State>, + Query(params): Query, +) -> Result>>> { + let mut conn = state.pool.acquire().await.map_err(internal_error)?; + let page = params.page.unwrap_or(1); + let page_size = params.page_size.unwrap_or(10); - let sql_query = format!("SELECT tx_hash,block_hash,sender,receiver,asset,amount,decimal,height,timestamp,value FROM e2n ORDER BY timestamp DESC LIMIT {} OFFSET {}", page_size, (page-1)*page_size); - let mut res: Vec = vec![]; - let rows = sqlx::query(sql_query.as_str()) + let mut sql_total = "SELECT count(*) FROM e2n ".to_string(); + let mut sql_query = "SELECT tx_hash,block_hash,sender,receiver,asset,amount,decimal,height,timestamp,value FROM e2n ".to_string(); + + let mut query_params: Vec = vec![]; + if let Some(from) = params.from { + query_params.push(format!("sender='{}'", from)); + } + if let Some(to) = params.to { + query_params.push(format!("receiver='{}'", to)); + } + if !query_params.is_empty() { + sql_total = sql_total + .add("WHERE ") + .add(query_params.join("AND ").as_str()); + sql_query = sql_query + .add("WHERE ") + .add(query_params.join("AND ").as_str()); + } + sql_query = sql_query.add( + format!( + "ORDER BY timestamp DESC LIMIT {} OFFSET {} ", + page_size, + (page - 1) * page_size + ) + .as_str(), + ); + + let row = sqlx::query(&sql_total) + .fetch_one(&mut *conn) + .await + .map_err(internal_error)?; + let total: i64 = row.try_get("count").map_err(internal_error)?; + + let mut txs: Vec = vec![]; + let rows = sqlx::query(&sql_query) .fetch_all(&mut *conn) - .await?; + .await + .map_err(internal_error)?; for row in rows { - let tx_hash: String = row.try_get("tx_hash")?; - let block_hash: String = row.try_get("block_hash")?; - let from: String = row.try_get("sender")?; - let to: String = row.try_get("receiver")?; - let asset: String = row.try_get("asset")?; - let decimal: i32 = row.try_get("decimal")?; - let amount: String = row.try_get("amount")?; - let height: i64 = row.try_get("height")?; - let timestamp: i64 = row.try_get("timestamp")?; - let value: Value = row.try_get("value")?; - res.push(V2EvmToNativeTx { + let tx_hash: String = row.try_get("tx_hash").map_err(internal_error)?; + let block_hash: String = row.try_get("block_hash").map_err(internal_error)?; + let from: String = row.try_get("sender").map_err(internal_error)?; + let to: String = row.try_get("receiver").map_err(internal_error)?; + let asset: String = row.try_get("asset").map_err(internal_error)?; + let decimal: i32 = row.try_get("decimal").map_err(internal_error)?; + let amount: String = row.try_get("amount").map_err(internal_error)?; + let height: i64 = row.try_get("height").map_err(internal_error)?; + let timestamp: i64 = row.try_get("timestamp").map_err(internal_error)?; + let value: Value = row.try_get("value").map_err(internal_error)?; + txs.push(E2NTxResponse { tx_hash, block_hash, from, @@ -88,14 +145,10 @@ pub async fn v2_get_e2n_txs( }) } - Ok(V2EvmToNativeTxsResponse::Ok(Json(V2EvmToNativeTxsResult { - code: 200, - message: "".to_string(), - data: V2EvmToNativeTxsData { - total, - page, - page_size, - txs: res, - }, - }))) + Ok(Json(QueryResult { + total, + page, + page_size, + data: txs, + })) } diff --git a/explorer/src/service/v2/prism_native_to_evm.rs b/explorer/src/service/v2/prism_native_to_evm.rs index 485be33..7657f62 100644 --- a/explorer/src/service/v2/prism_native_to_evm.rs +++ b/explorer/src/service/v2/prism_native_to_evm.rs @@ -113,7 +113,7 @@ pub struct GetN2ETxByTxHashParams { } #[allow(dead_code)] -pub async fn get_n2e_tx_by_tx_hash( +pub async fn get_n2e_by_tx_hash( State(state): State>, Query(params): Query, ) -> Result> {