Skip to content

Commit

Permalink
feat(api): add block metadata route for included transactions (#1033)
Browse files Browse the repository at this point in the history
* Add block metadata route for included transactions

* Format and simplifications

* Duh

* Add helper fn
  • Loading branch information
Alex6323 authored Jan 16, 2023
1 parent 2969fc1 commit b02ad42
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 18 deletions.
56 changes: 40 additions & 16 deletions src/bin/inx-chronicle/api/stardust/core/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use chronicle::{
},
types::{
context::TryFromWithContext,
ledger::BlockMetadata,
stardust::block::{
output::OutputId,
payload::{milestone::MilestoneId, transaction::TransactionId},
Expand Down Expand Up @@ -81,7 +82,9 @@ pub fn routes() -> Router {
.route("/treasury", get(treasury))
.nest(
"/transactions",
Router::new().route("/:transaction_id/included-block", get(transaction_included_block)),
Router::new()
.route("/:transaction_id/included-block", get(included_block))
.route("/:transaction_id/included-block/metadata", get(included_block_metadata)),
)
.nest(
"/milestones",
Expand Down Expand Up @@ -214,6 +217,21 @@ async fn block(
Ok(IotaRawResponse::Json(block.into()))
}

fn create_block_metadata_response(block_id: BlockId, metadata: BlockMetadata) -> iota::BlockMetadataResponse {
iota::BlockMetadataResponse {
block_id: block_id.to_hex(),
parents: metadata.parents.iter().map(BlockId::to_hex).collect(),
is_solid: metadata.is_solid,
referenced_by_milestone_index: Some(*metadata.referenced_by_milestone_index),
milestone_index: Some(*metadata.milestone_index),
ledger_inclusion_state: Some(metadata.inclusion_state.into()),
conflict_reason: Some(metadata.conflict_reason as u8),
should_promote: Some(metadata.should_promote),
should_reattach: Some(metadata.should_reattach),
white_flag_index: Some(metadata.white_flag_index),
}
}

async fn block_metadata(
database: Extension<MongoDb>,
Path(block_id_str): Path<String>,
Expand All @@ -225,19 +243,7 @@ async fn block_metadata(
.await?
.ok_or(MissingError::NoResults)?;

Ok(BlockMetadataResponse {
block_id: block_id_str,
parents: metadata.parents.iter().map(BlockId::to_hex).collect(),
is_solid: metadata.is_solid,
referenced_by_milestone_index: Some(*metadata.referenced_by_milestone_index),
milestone_index: Some(*metadata.milestone_index),
ledger_inclusion_state: Some(metadata.inclusion_state.into()),
conflict_reason: Some(metadata.conflict_reason as u8),
should_promote: Some(metadata.should_promote),
should_reattach: Some(metadata.should_reattach),
white_flag_index: Some(metadata.white_flag_index),
}
.into())
Ok(create_block_metadata_response(block_id, metadata).into())
}

fn create_output_metadata_response(
Expand Down Expand Up @@ -323,7 +329,7 @@ async fn output_metadata(
Ok(create_output_metadata_response(metadata, ledger_index).into())
}

async fn transaction_included_block(
async fn included_block(
database: Extension<MongoDb>,
Path(transaction_id): Path<String>,
headers: HeaderMap,
Expand All @@ -344,11 +350,29 @@ async fn transaction_included_block(
.collection::<BlockCollection>()
.get_block_for_transaction(&transaction_id)
.await?
.ok_or(MissingError::NoResults)?;
.ok_or(MissingError::NoResults)?
.block;

Ok(IotaRawResponse::Json(block.into()))
}

async fn included_block_metadata(
database: Extension<MongoDb>,
Path(transaction_id): Path<String>,
) -> ApiResult<IotaResponse<BlockMetadataResponse>> {
let transaction_id = TransactionId::from_str(&transaction_id).map_err(RequestError::from)?;

let res = database
.collection::<BlockCollection>()
.get_block_metadata_for_transaction(&transaction_id)
.await?
.ok_or(MissingError::NoResults)?;
let block_id = res.block_id;
let metadata = res.metadata;

Ok(create_block_metadata_response(block_id, metadata).into())
}

async fn receipts(database: Extension<MongoDb>) -> ApiResult<IotaResponse<ReceiptsResponse>> {
let mut receipts_at = database.collection::<MilestoneCollection>().get_all_receipts().await?;
let mut receipts = Vec::new();
Expand Down
45 changes: 43 additions & 2 deletions src/db/collections/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ impl MongoDbCollection for BlockCollection {
}
}

#[derive(Deserialize, Debug, Clone)]
pub struct IncludedBlockResult {
pub block_id: BlockId,
pub block: Block,
}

#[derive(Deserialize, Debug, Clone)]
pub struct IncludedBlockMetadataResult {
pub block_id: BlockId,
pub metadata: BlockMetadata,
}

/// Implements the queries for the core API.
impl BlockCollection {
/// Get a [`Block`] by its [`BlockId`].
Expand Down Expand Up @@ -270,7 +282,10 @@ impl BlockCollection {
}

/// Finds the [`Block`] that included a transaction by [`TransactionId`].
pub async fn get_block_for_transaction(&self, transaction_id: &TransactionId) -> Result<Option<Block>, Error> {
pub async fn get_block_for_transaction(
&self,
transaction_id: &TransactionId,
) -> Result<Option<IncludedBlockResult>, Error> {
self.aggregate(
vec![
doc! { "$match": {
Expand All @@ -295,7 +310,10 @@ impl BlockCollection {
"$$REMOVE",
"$block.payload",
] } } },
doc! { "$replaceWith": "$block" },
doc! { "$replaceWith": {
"block_id": "$_id",
"block": "$block",
} },
],
None,
)
Expand Down Expand Up @@ -332,6 +350,29 @@ impl BlockCollection {
.map(|RawResult { data }| data))
}

/// Finds the [`BlockMetadata`] that included a transaction by [`TransactionId`].
pub async fn get_block_metadata_for_transaction(
&self,
transaction_id: &TransactionId,
) -> Result<Option<IncludedBlockMetadataResult>, Error> {
self.aggregate(
vec![
doc! { "$match": {
"metadata.inclusion_state": LedgerInclusionState::Included,
"block.payload.transaction_id": transaction_id,
} },
doc! { "$replaceWith": {
"block_id": "$_id",
"metadata": "$metadata",
} },
],
None,
)
.await?
.try_next()
.await
}

/// Gets the spending transaction of an [`Output`](crate::types::stardust::block::Output) by [`OutputId`].
pub async fn get_spending_transaction(&self, output_id: &OutputId) -> Result<Option<Block>, Error> {
self.aggregate(
Expand Down
1 change: 1 addition & 0 deletions tests/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ mod test_rand {
.get_block_for_transaction(&transaction_id)
.await
.unwrap()
.map(|res| res.block)
.as_ref(),
Some(block),
);
Expand Down

0 comments on commit b02ad42

Please sign in to comment.