Skip to content

Commit

Permalink
feat(db): separate ledger/protocol_param logic from collections (#677)
Browse files Browse the repository at this point in the history
* Separate ledger/protocol param logic from collections.

* ßßßßßßßß

* Add helper fn for ledger index. Convert response milestone types. Remove ledger index from db results.
  • Loading branch information
Alexandcoats authored Sep 15, 2022
1 parent 6507ee7 commit 81178c8
Show file tree
Hide file tree
Showing 9 changed files with 479 additions and 519 deletions.
8 changes: 4 additions & 4 deletions src/bin/inx-chronicle/api/stardust/analytics/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::ops::Range;

use bee_api_types_stardust::responses::RentStructureResponse;
use chronicle::db::collections::DistributionStat;
use chronicle::{db::collections::DistributionStat, types::tangle::MilestoneIndex};
use serde::{Deserialize, Serialize};

use crate::api::responses::impl_success_response;
Expand Down Expand Up @@ -37,7 +37,7 @@ pub struct StorageDepositAnalyticsResponse {
pub total_key_bytes: String,
pub total_data_bytes: String,
pub total_byte_cost: String,
pub ledger_index: u32,
pub ledger_index: MilestoneIndex,
pub rent_structure: RentStructureResponse,
}

Expand All @@ -57,7 +57,7 @@ impl_success_response!(OutputDiffAnalyticsResponse);
#[serde(rename_all = "camelCase")]
pub struct RichestAddressesResponse {
pub top: Vec<AddressStatDto>,
pub ledger_index: u32,
pub ledger_index: MilestoneIndex,
}

impl_success_response!(RichestAddressesResponse);
Expand All @@ -72,7 +72,7 @@ pub struct AddressStatDto {
#[serde(rename_all = "camelCase")]
pub struct TokenDistributionResponse {
pub distribution: Vec<DistributionStatDto>,
pub ledger_index: u32,
pub ledger_index: MilestoneIndex,
}

impl_success_response!(TokenDistributionResponse);
Expand Down
46 changes: 33 additions & 13 deletions src/bin/inx-chronicle/api/stardust/analytics/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use chronicle::{
types::{
stardust::block::{
output::{AliasOutput, BasicOutput, FoundryOutput, NftOutput},
payload::milestone::MilestoneId,
payload::MilestoneId,
},
tangle::MilestoneIndex,
},
Expand Down Expand Up @@ -165,7 +165,7 @@ async fn unspent_output_ledger_analytics<O: OutputKind>(
) -> ApiResult<OutputAnalyticsResponse> {
let res = database
.collection::<OutputCollection>()
.get_unspent_output_analytics::<O>(ledger_index)
.get_unspent_output_analytics::<O>(resolve_ledger_index(&database, ledger_index).await?)
.await?
.ok_or(ApiError::NoResults)?;

Expand All @@ -179,11 +179,17 @@ async fn storage_deposit_ledger_analytics(
database: Extension<MongoDb>,
LedgerIndex { ledger_index }: LedgerIndex,
) -> ApiResult<StorageDepositAnalyticsResponse> {
let ledger_index = resolve_ledger_index(&database, ledger_index).await?;
let protocol_params = database
.collection::<ProtocolUpdateCollection>()
.get_protocol_parameters_for_ledger_index(ledger_index)
.await?
.ok_or(InternalApiError::CorruptState("no protocol parameters"))?
.parameters;
let res = database
.collection::<OutputCollection>()
.get_storage_deposit_analytics(ledger_index)
.await?
.ok_or(ApiError::NoResults)?;
.get_storage_deposit_analytics(ledger_index, protocol_params)
.await?;

Ok(StorageDepositAnalyticsResponse {
output_count: res.output_count.to_string(),
Expand All @@ -192,7 +198,7 @@ async fn storage_deposit_ledger_analytics(
total_key_bytes: res.total_key_bytes,
total_data_bytes: res.total_data_bytes,
total_byte_cost: res.total_byte_cost,
ledger_index: res.ledger_index.0,
ledger_index,
rent_structure: RentStructureResponse {
v_byte_cost: res.rent_structure.v_byte_cost,
v_byte_factor_key: res.rent_structure.v_byte_factor_key,
Expand Down Expand Up @@ -237,15 +243,15 @@ async fn richest_addresses_ledger_analytics(
database: Extension<MongoDb>,
RichestAddressesQuery { top, ledger_index }: RichestAddressesQuery,
) -> ApiResult<RichestAddressesResponse> {
let ledger_index = resolve_ledger_index(&database, ledger_index).await?;
let res = database
.collection::<OutputCollection>()
.get_richest_addresses(ledger_index, top)
.await?
.ok_or(ApiError::NoResults)?;
.await?;

let hrp = database
.collection::<ProtocolUpdateCollection>()
.get_protocol_parameters_for_ledger_index(res.ledger_index)
.get_protocol_parameters_for_ledger_index(ledger_index)
.await?
.ok_or(InternalApiError::CorruptState("no protocol parameters"))?
.parameters
Expand All @@ -260,22 +266,36 @@ async fn richest_addresses_ledger_analytics(
balance: stat.balance,
})
.collect(),
ledger_index: res.ledger_index.0,
ledger_index,
})
}

async fn token_distribution_ledger_analytics(
database: Extension<MongoDb>,
LedgerIndex { ledger_index }: LedgerIndex,
) -> ApiResult<TokenDistributionResponse> {
let ledger_index = resolve_ledger_index(&database, ledger_index).await?;
let res = database
.collection::<OutputCollection>()
.get_token_distribution(ledger_index)
.await?
.ok_or(ApiError::NoResults)?;
.await?;

Ok(TokenDistributionResponse {
distribution: res.distribution.into_iter().map(Into::into).collect(),
ledger_index: res.ledger_index.0,
ledger_index,
})
}

/// This is just a helper fn to either unwrap an optional ledger index param or fetch the latest
/// index from the database.
async fn resolve_ledger_index(database: &MongoDb, ledger_index: Option<MilestoneIndex>) -> ApiResult<MilestoneIndex> {
Ok(if let Some(ledger_index) = ledger_index {
ledger_index
} else {
database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?
})
}
32 changes: 25 additions & 7 deletions src/bin/inx-chronicle/api/stardust/core/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,10 @@ async fn block_metadata(
})
}

fn create_output_metadata_response(metadata: OutputMetadataResult) -> OutputMetadataResponse {
fn create_output_metadata_response(
metadata: OutputMetadataResult,
ledger_index: MilestoneIndex,
) -> OutputMetadataResponse {
OutputMetadataResponse {
block_id: metadata.block_id.to_hex(),
transaction_id: metadata.output_id.transaction_id.to_hex(),
Expand All @@ -250,19 +253,24 @@ fn create_output_metadata_response(metadata: OutputMetadataResult) -> OutputMeta
.map(|spent_md| spent_md.transaction_id.to_hex()),
milestone_index_booked: *metadata.booked.milestone_index,
milestone_timestamp_booked: *metadata.booked.milestone_timestamp,
ledger_index: metadata.ledger_index.0,
ledger_index: ledger_index.0,
}
}

async fn output(database: Extension<MongoDb>, Path(output_id): Path<String>) -> ApiResult<OutputResponse> {
let ledger_index = database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?;
let output_id = OutputId::from_str(&output_id).map_err(ApiError::bad_parse)?;
let OutputWithMetadataResult { output, metadata } = database
.collection::<OutputCollection>()
.get_output_with_metadata(&output_id)
.get_output_with_metadata(&output_id, ledger_index)
.await?
.ok_or(ApiError::NoResults)?;

let metadata = create_output_metadata_response(metadata);
let metadata = create_output_metadata_response(metadata, ledger_index);

Ok(OutputResponse {
metadata,
Expand All @@ -274,14 +282,19 @@ async fn output_metadata(
database: Extension<MongoDb>,
Path(output_id): Path<String>,
) -> ApiResult<OutputMetadataResponse> {
let ledger_index = database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?;
let output_id = OutputId::from_str(&output_id).map_err(ApiError::bad_parse)?;
let metadata = database
.collection::<OutputCollection>()
.get_output_metadata(&output_id)
.get_output_metadata(&output_id, ledger_index)
.await?
.ok_or(ApiError::NoResults)?;

Ok(create_output_metadata_response(metadata))
Ok(create_output_metadata_response(metadata, ledger_index))
}

async fn transaction_included_block(
Expand Down Expand Up @@ -424,12 +437,17 @@ async fn utxo_changes_by_index(
}

async fn collect_utxo_changes(database: &MongoDb, milestone_index: MilestoneIndex) -> ApiResult<UtxoChangesResponse> {
let ledger_index = database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?;
let UtxoChangesResult {
created_outputs,
consumed_outputs,
} = database
.collection::<OutputCollection>()
.get_utxo_changes(milestone_index)
.get_utxo_changes(milestone_index, ledger_index)
.await?
.ok_or(ApiError::NoResults)?;

Expand Down
9 changes: 7 additions & 2 deletions src/bin/inx-chronicle/api/stardust/explorer/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,22 @@ async fn ledger_updates_by_milestone(
}

async fn balance(database: Extension<MongoDb>, Path(address): Path<String>) -> ApiResult<BalanceResponse> {
let ledger_index = database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?;
let address = Address::from_str(&address).map_err(ApiError::bad_parse)?;
let res = database
.collection::<OutputCollection>()
.get_address_balance(address)
.get_address_balance(address, ledger_index)
.await?
.ok_or(ApiError::NoResults)?;

Ok(BalanceResponse {
total_balance: res.total_balance,
sig_locked_balance: res.sig_locked_balance,
ledger_index: res.ledger_index,
ledger_index,
})
}

Expand Down
3 changes: 2 additions & 1 deletion src/bin/inx-chronicle/api/stardust/indexer/responses.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
// Copyright 2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use chronicle::types::tangle::MilestoneIndex;
use serde::{Deserialize, Serialize};

use crate::api::responses::impl_success_response;

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct IndexerOutputsResponse {
pub ledger_index: u32,
pub ledger_index: MilestoneIndex,
pub items: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
Expand Down
23 changes: 17 additions & 6 deletions src/bin/inx-chronicle/api/stardust/indexer/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use axum::{extract::Path, routing::get, Extension};
use chronicle::{
db::{
collections::{
AliasOutputsQuery, BasicOutputsQuery, FoundryOutputsQuery, IndexedId, NftOutputsQuery, OutputCollection,
AliasOutputsQuery, BasicOutputsQuery, FoundryOutputsQuery, IndexedId, MilestoneCollection, NftOutputsQuery,
OutputCollection,
},
MongoDb,
},
Expand Down Expand Up @@ -54,14 +55,19 @@ where
ID: Into<IndexedId> + FromStr,
ParseError: From<ID::Err>,
{
let ledger_index = database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?;
let id = ID::from_str(&id).map_err(ApiError::bad_parse)?;
let res = database
.collection::<OutputCollection>()
.get_indexed_output_by_id(id)
.get_indexed_output_by_id(id, ledger_index)
.await?
.ok_or(ApiError::NoResults)?;
Ok(IndexerOutputsResponse {
ledger_index: res.ledger_index.0,
ledger_index,
items: vec![res.output_id.to_hex()],
cursor: None,
})
Expand All @@ -80,6 +86,11 @@ async fn indexed_outputs<Q>(
where
bson::Document: From<Q>,
{
let ledger_index = database
.collection::<MilestoneCollection>()
.get_ledger_index()
.await?
.ok_or(ApiError::NoResults)?;
let res = database
.collection::<OutputCollection>()
.get_indexed_outputs(
Expand All @@ -89,9 +100,9 @@ where
cursor,
sort,
include_spent,
ledger_index,
)
.await?
.ok_or(ApiError::NoResults)?;
.await?;

let mut iter = res.outputs.iter();

Expand All @@ -109,7 +120,7 @@ where
});

Ok(IndexerOutputsResponse {
ledger_index: res.ledger_index.0,
ledger_index,
items,
cursor,
})
Expand Down
Loading

0 comments on commit 81178c8

Please sign in to comment.