diff --git a/swagger.yml b/swagger.yml index 7a4ae1ea..e41fa38c 100644 --- a/swagger.yml +++ b/swagger.yml @@ -1295,6 +1295,12 @@ components: type: string proposer: type: string + transactions: + type: array + items: + type: string + parentHash: + type: string epoch: type: string TransactionHistory: diff --git a/webserver/src/repository/tranasaction.rs b/webserver/src/repository/tranasaction.rs index 03646501..a82a5cc3 100644 --- a/webserver/src/repository/tranasaction.rs +++ b/webserver/src/repository/tranasaction.rs @@ -41,6 +41,10 @@ pub trait TransactionRepositoryTrait { PaginatedResponseDb<(TransactionHistoryDb, InnerTransactionDb, i32)>, String, >; + async fn find_txs_by_block_height( + &self, + block_height: i32, + ) -> Result, String>; } #[async_trait] @@ -124,4 +128,23 @@ impl TransactionRepositoryTrait for TransactionRepository { .map_err(|e| e.to_string())? .map_err(|e| e.to_string()) } + + async fn find_txs_by_block_height( + &self, + block_height: i32, + ) -> Result, String> { + let conn = self.app_state.get_db_connection().await; + + conn.interact(move |conn| { + wrapper_transactions::table + .filter( + wrapper_transactions::dsl::block_height.eq(block_height), + ) + .select(WrapperTransactionDb::as_select()) + .get_results(conn) + }) + .await + .map_err(|e| e.to_string())? + .map_err(|e| e.to_string()) + } } diff --git a/webserver/src/response/block.rs b/webserver/src/response/block.rs index 3ab9b51c..4d9b2c15 100644 --- a/webserver/src/response/block.rs +++ b/webserver/src/response/block.rs @@ -1,4 +1,5 @@ use orm::blocks::BlockDb; +use orm::transactions::WrapperTransactionDb; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -9,11 +10,17 @@ pub struct Block { pub app_hash: Option, pub timestamp: Option, pub proposer: Option, + pub transactions: Vec, + pub parent_hash: Option, pub epoch: Option, } -impl From for Block { - fn from(block_db: BlockDb) -> Self { +impl Block { + pub fn from( + block_db: BlockDb, + prev_block_db: Option, + transactions: Vec, + ) -> Self { Self { height: block_db.height, hash: block_db.hash, @@ -22,6 +29,13 @@ impl From for Block { .timestamp .map(|t| t.and_utc().timestamp().to_string()), proposer: block_db.proposer, + transactions: transactions + .into_iter() + .map(|wrapper| wrapper.id.to_lowercase()) + .collect(), + parent_hash: prev_block_db + .map(|block| block.app_hash) + .unwrap_or(None), epoch: block_db.epoch.map(|e| e.to_string()), } } diff --git a/webserver/src/service/block.rs b/webserver/src/service/block.rs index 54c7d73e..1bc02def 100644 --- a/webserver/src/service/block.rs +++ b/webserver/src/service/block.rs @@ -1,17 +1,22 @@ use crate::appstate::AppState; use crate::error::block::BlockError; use crate::repository::block::{BlockRepository, BlockRepositoryTrait}; +use crate::repository::tranasaction::{ + TransactionRepository, TransactionRepositoryTrait, +}; use crate::response::block::Block; #[derive(Clone)] pub struct BlockService { block_repo: BlockRepository, + transaction_repo: TransactionRepository, } impl BlockService { pub fn new(app_state: AppState) -> Self { Self { - block_repo: BlockRepository::new(app_state), + block_repo: BlockRepository::new(app_state.clone()), + transaction_repo: TransactionRepository::new(app_state), } } @@ -28,8 +33,23 @@ impl BlockService { "height".to_string(), height.to_string(), ))?; + let prev_block = if let Some(block_height) = block.height.checked_sub(1) + { + self.block_repo + .find_block_by_height(block_height) + .await + .map_err(BlockError::Database)? + } else { + None + }; - Ok(Block::from(block)) + let transactions = self + .transaction_repo + .find_txs_by_block_height(block.height) + .await + .map_err(BlockError::Database)?; + + Ok(Block::from(block, prev_block, transactions)) } pub async fn get_block_by_timestamp( @@ -46,7 +66,22 @@ impl BlockService { "timestamp".to_string(), timestamp.to_string(), ))?; + let prev_block = if let Some(block_height) = block.height.checked_sub(1) + { + self.block_repo + .find_block_by_height(block_height) + .await + .map_err(BlockError::Database)? + } else { + None + }; + + let transactions = self + .transaction_repo + .find_txs_by_block_height(block.height) + .await + .map_err(BlockError::Database)?; - Ok(Block::from(block)) + Ok(Block::from(block, prev_block, transactions)) } }