From c6dcb11d294b8dd4ea0870329e7ce4a6d1048357 Mon Sep 17 00:00:00 2001 From: Alex Coats Date: Fri, 8 Mar 2024 11:52:42 -0500 Subject: [PATCH] Update dependencies --- Cargo.lock | 112 ++++++++++---------- src/analytics/influx.rs | 6 +- src/analytics/ledger/active_addresses.rs | 6 +- src/analytics/ledger/address_balance.rs | 2 + src/analytics/ledger/base_token.rs | 6 +- src/analytics/ledger/features.rs | 3 +- src/analytics/ledger/ledger_outputs.rs | 6 +- src/analytics/ledger/ledger_size.rs | 6 +- src/analytics/ledger/output_activity.rs | 6 +- src/analytics/ledger/transaction_size.rs | 6 +- src/analytics/ledger/unlock_conditions.rs | 6 +- src/analytics/mod.rs | 120 +++++++++++++--------- src/analytics/tangle/block_activity.rs | 60 +++++++---- src/analytics/tangle/mana_activity.rs | 3 +- src/bin/inx-chronicle/api/core/routes.rs | 38 +++---- src/bin/inx-chronicle/inx/mod.rs | 4 +- src/db/mongodb/collections/block.rs | 108 +++++++++---------- src/inx/client.rs | 31 ++++-- src/inx/ledger.rs | 46 ++------- src/inx/responses.rs | 22 ++-- src/model/block_metadata.rs | 94 ++++++----------- src/tangle/slot_stream.rs | 30 +++++- src/tangle/sources/inx.rs | 13 ++- src/tangle/sources/memory.rs | 26 ++++- src/tangle/sources/mod.rs | 11 +- src/tangle/sources/mongodb.rs | 19 +++- 26 files changed, 433 insertions(+), 357 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bbe4ac794..0a87fbf37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,7 +182,7 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", "itoa", @@ -210,7 +210,7 @@ dependencies = [ "axum-macros", "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "hyper 1.2.0", @@ -242,7 +242,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "mime", "rustversion", @@ -259,7 +259,7 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "mime", @@ -281,7 +281,7 @@ dependencies = [ "bytes", "futures-util", "headers", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "mime", @@ -443,9 +443,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byte-slice-cast" @@ -473,9 +473,9 @@ checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] name = "cc" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" @@ -562,9 +562,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", @@ -586,9 +586,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -596,9 +596,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstyle", "clap_lex", @@ -1321,7 +1321,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.11", + "http 0.2.12", "indexmap 2.2.5", "slab", "tokio", @@ -1340,7 +1340,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 1.0.0", + "http 1.1.0", "indexmap 2.2.5", "slab", "tokio", @@ -1374,7 +1374,7 @@ dependencies = [ "base64 0.21.7", "bytes", "headers-core", - "http 1.0.0", + "http 1.1.0", "httpdate", "mime", "sha1", @@ -1386,7 +1386,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.0.0", + "http 1.1.0", ] [[package]] @@ -1447,9 +1447,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1458,9 +1458,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1474,7 +1474,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.11", + "http 0.2.12", "pin-project-lite", ] @@ -1485,7 +1485,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http 1.0.0", + "http 1.1.0", ] [[package]] @@ -1496,7 +1496,7 @@ checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" dependencies = [ "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "pin-project-lite", ] @@ -1540,7 +1540,7 @@ dependencies = [ "futures-core", "futures-util", "h2 0.3.24", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "httparse", "httpdate", @@ -1563,7 +1563,7 @@ dependencies = [ "futures-channel", "futures-util", "h2 0.4.2", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "httparse", "httpdate", @@ -1580,7 +1580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.11", + "http 0.2.12", "hyper 0.14.28", "rustls", "tokio", @@ -1607,7 +1607,7 @@ checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "hyper 1.2.0", "pin-project-lite", @@ -1728,7 +1728,7 @@ checksum = "601aa12a5876c044ea2a94a9443d0f086e6fc1f7bb4264bd7120e63c1462d1c8" dependencies = [ "chrono", "futures-util", - "http 0.2.11", + "http 0.2.12", "influxdb_derive", "lazy_static", "regex", @@ -1762,7 +1762,7 @@ dependencies = [ [[package]] name = "inx" version = "2.0.0" -source = "git+https://github.com/iotaledger/inx#6d5f4ef12ac514f5b267ae73764fb596d57d7371" +source = "git+https://github.com/iotaledger/inx#2d3509413fe2f427cbddfcc76c6f58adb4518f88" dependencies = [ "prost", "tonic", @@ -1806,7 +1806,7 @@ dependencies = [ [[package]] name = "iota-sdk" version = "1.1.4" -source = "git+https://github.com/iotaledger/iota-sdk?branch=2.0#d2dc74d0d4250bc0ed71a618e3e3607f84679dad" +source = "git+https://github.com/iotaledger/iota-sdk?branch=2.0#67ea8cb3426225f84c617b2c35f2959079d36574" dependencies = [ "bech32", "bitflags 2.4.2", @@ -1899,9 +1899,9 @@ checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2344,18 +2344,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", @@ -2704,7 +2704,7 @@ dependencies = [ "futures-core", "futures-util", "h2 0.3.24", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", "hyper-rustls", @@ -3590,7 +3590,7 @@ dependencies = [ "base64 0.21.7", "bytes", "h2 0.3.24", - "http 0.2.11", + "http 0.2.12", "http-body 0.4.6", "hyper 0.14.28", "hyper-timeout", @@ -3647,7 +3647,7 @@ dependencies = [ "bitflags 2.4.2", "bytes", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body 1.0.0", "http-body-util", "pin-project-lite", @@ -3913,9 +3913,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3923,9 +3923,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", @@ -3938,9 +3938,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3950,9 +3950,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3960,9 +3960,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", @@ -3973,15 +3973,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/src/analytics/influx.rs b/src/analytics/influx.rs index 7960ccbb5..4e80e2902 100644 --- a/src/analytics/influx.rs +++ b/src/analytics/influx.rs @@ -182,12 +182,12 @@ impl Measurement for BlockActivityMeasurement { .add_field("block_accepted_count", self.block_accepted_count as u64) .add_field("block_confirmed_count", self.block_confirmed_count as u64) .add_field("block_finalized_count", self.block_finalized_count as u64) - .add_field("block_rejected_count", self.block_rejected_count as u64) - .add_field("block_failed_count", self.block_failed_count as u64) + .add_field("block_dropped_count", self.block_dropped_count as u64) + .add_field("block_orphaned_count", self.block_orphaned_count as u64) .add_field("block_unknown_count", self.block_unknown_count as u64) .add_field("txn_pending_count", self.txn_pending_count as u64) .add_field("txn_accepted_count", self.txn_accepted_count as u64) - .add_field("txn_confirmed_count", self.txn_confirmed_count as u64) + .add_field("txn_committed_count", self.txn_committed_count as u64) .add_field("txn_finalized_count", self.txn_finalized_count as u64) .add_field("txn_failed_count", self.txn_failed_count as u64) } diff --git a/src/analytics/ledger/active_addresses.rs b/src/analytics/ledger/active_addresses.rs index 81ca9828e..508009ccd 100644 --- a/src/analytics/ledger/active_addresses.rs +++ b/src/analytics/ledger/active_addresses.rs @@ -11,7 +11,10 @@ use iota_sdk::types::block::{ use crate::{ analytics::{Analytics, AnalyticsContext, AnalyticsInterval, IntervalAnalytics}, db::{mongodb::collections::OutputCollection, MongoDb}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; #[derive(Debug, Default)] @@ -65,6 +68,7 @@ impl Analytics for AddressActivityAnalytics { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/address_balance.rs b/src/analytics/ledger/address_balance.rs index c62d27106..6c7861bfe 100644 --- a/src/analytics/ledger/address_balance.rs +++ b/src/analytics/ledger/address_balance.rs @@ -15,6 +15,7 @@ use crate::{ }, model::{ address::AddressDto, + block_metadata::TransactionMetadata, ledger::{LedgerOutput, LedgerSpent}, }, }; @@ -81,6 +82,7 @@ impl Analytics for AddressBalancesAnalytics { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/base_token.rs b/src/analytics/ledger/base_token.rs index 211af92ca..7edb90b01 100644 --- a/src/analytics/ledger/base_token.rs +++ b/src/analytics/ledger/base_token.rs @@ -7,7 +7,10 @@ use iota_sdk::types::block::{address::Address, payload::SignedTransactionPayload use crate::{ analytics::{Analytics, AnalyticsContext}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; /// Measures activity of the base token, such as Shimmer or IOTA. @@ -27,6 +30,7 @@ impl Analytics for BaseTokenActivityMeasurement { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/features.rs b/src/analytics/ledger/features.rs index 5d933ddd4..9e852445e 100644 --- a/src/analytics/ledger/features.rs +++ b/src/analytics/ledger/features.rs @@ -21,7 +21,7 @@ use crate::{ analytics::{Analytics, AnalyticsContext}, db::{mongodb::collections::AccountCandidacyCollection, MongoDb}, model::{ - block_metadata::BlockMetadata, + block_metadata::{BlockMetadata, TransactionMetadata}, ledger::{LedgerOutput, LedgerSpent}, }, }; @@ -85,6 +85,7 @@ impl Analytics for FeaturesMeasurement { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/ledger_outputs.rs b/src/analytics/ledger/ledger_outputs.rs index 00ae1a242..85ea15330 100644 --- a/src/analytics/ledger/ledger_outputs.rs +++ b/src/analytics/ledger/ledger_outputs.rs @@ -17,7 +17,10 @@ use serde::{Deserialize, Serialize}; use super::CountAndAmount; use crate::{ analytics::{Analytics, AnalyticsContext}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] @@ -73,6 +76,7 @@ impl Analytics for LedgerOutputMeasurement { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], _ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/ledger_size.rs b/src/analytics/ledger/ledger_size.rs index 63700f927..19222aec0 100644 --- a/src/analytics/ledger/ledger_size.rs +++ b/src/analytics/ledger/ledger_size.rs @@ -10,7 +10,10 @@ use serde::{Deserialize, Serialize}; use crate::{ analytics::{Analytics, AnalyticsContext}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; trait LedgerSize { @@ -72,6 +75,7 @@ impl Analytics for LedgerSizeAnalytics { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/output_activity.rs b/src/analytics/ledger/output_activity.rs index ed2d427a6..7bb529f32 100644 --- a/src/analytics/ledger/output_activity.rs +++ b/src/analytics/ledger/output_activity.rs @@ -12,7 +12,10 @@ use serde::{Deserialize, Serialize}; use crate::{ analytics::{Analytics, AnalyticsContext}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; /// Nft activity statistics. @@ -33,6 +36,7 @@ impl Analytics for OutputActivityMeasurement { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], _ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/transaction_size.rs b/src/analytics/ledger/transaction_size.rs index 7e8440655..f3d3a42af 100644 --- a/src/analytics/ledger/transaction_size.rs +++ b/src/analytics/ledger/transaction_size.rs @@ -6,7 +6,10 @@ use serde::{Deserialize, Serialize}; use crate::{ analytics::{Analytics, AnalyticsContext}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] @@ -63,6 +66,7 @@ impl Analytics for TransactionSizeMeasurement { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], _ctx: &dyn AnalyticsContext, diff --git a/src/analytics/ledger/unlock_conditions.rs b/src/analytics/ledger/unlock_conditions.rs index a87ab5018..b97023c55 100644 --- a/src/analytics/ledger/unlock_conditions.rs +++ b/src/analytics/ledger/unlock_conditions.rs @@ -7,7 +7,10 @@ use serde::{Deserialize, Serialize}; use super::CountAndAmount; use crate::{ analytics::{Analytics, AnalyticsContext}, - model::ledger::{LedgerOutput, LedgerSpent}, + model::{ + block_metadata::TransactionMetadata, + ledger::{LedgerOutput, LedgerSpent}, + }, }; #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] @@ -81,6 +84,7 @@ impl Analytics for UnlockConditionMeasurement { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], _ctx: &dyn AnalyticsContext, diff --git a/src/analytics/mod.rs b/src/analytics/mod.rs index 877fe62f8..465bd7ddd 100644 --- a/src/analytics/mod.rs +++ b/src/analytics/mod.rs @@ -3,7 +3,7 @@ //! Various analytics that give insight into the usage of the tangle. -use futures::TryStreamExt; +use futures::{prelude::stream::StreamExt, TryStreamExt}; use iota_sdk::types::block::{ output::OutputId, payload::SignedTransactionPayload, @@ -31,7 +31,7 @@ use crate::{ MongoDb, }, model::{ - block_metadata::{BlockMetadata, BlockState, BlockWithMetadata}, + block_metadata::{BlockMetadata, BlockWithMetadata, TransactionMetadata}, ledger::{LedgerOutput, LedgerSpent}, }, tangle::{InputSource, Slot}, @@ -68,6 +68,7 @@ pub trait Analytics { async fn handle_transaction( &mut self, _payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, _consumed: &[LedgerSpent], _created: &[LedgerOutput], _ctx: &dyn AnalyticsContext, @@ -93,6 +94,7 @@ trait DynAnalytics: Send { async fn handle_transaction( &mut self, payload: &SignedTransactionPayload, + metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, @@ -114,11 +116,12 @@ where async fn handle_transaction( &mut self, payload: &SignedTransactionPayload, + metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, ) -> eyre::Result<()> { - Analytics::handle_transaction(self, payload, consumed, created, ctx).await + Analytics::handle_transaction(self, payload, metadata, consumed, created, ctx).await } async fn handle_block( @@ -245,6 +248,7 @@ impl + Send> Analytics for T { async fn handle_transaction( &mut self, payload: &SignedTransactionPayload, + metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, @@ -252,7 +256,7 @@ impl + Send> Analytics for T { futures::future::join_all( self.as_mut() .iter_mut() - .map(|analytic| analytic.0.handle_transaction(payload, consumed, created, ctx)), + .map(|analytic| analytic.0.handle_transaction(payload, metadata, consumed, created, ctx)), ) .await; Ok(()) @@ -307,10 +311,22 @@ impl<'a, I: InputSource> Slot<'a, I> { db, }; - let mut block_stream = self.accepted_block_stream().await?; + let mut block_stream = self.accepted_block_stream().await?.boxed(); - while let Some(block_data) = block_stream.try_next().await? { - self.handle_block(analytics, &block_data, &ctx).await?; + while let Some(data) = block_stream.try_next().await? { + if let Some((payload, metadata)) = data + .block + .block + .inner() + .body() + .as_basic_opt() + .and_then(|body| body.payload()) + .and_then(|p| p.as_signed_transaction_opt()) + .zip(data.transaction) + { + self.handle_transaction(analytics, payload, &metadata, &ctx).await?; + } + self.handle_block(analytics, &data.block, &ctx).await?; } influxdb @@ -320,6 +336,52 @@ impl<'a, I: InputSource> Slot<'a, I> { Ok(()) } + async fn handle_transaction( + &self, + analytics: &mut A, + payload: &SignedTransactionPayload, + metadata: &TransactionMetadata, + ctx: &BasicContext<'_>, + ) -> eyre::Result<()> { + let consumed = payload + .transaction() + .inputs() + .iter() + .map(|input| input.as_utxo().output_id()) + .map(|output_id| { + Ok(self + .ledger_updates() + .get_consumed(output_id) + .ok_or(AnalyticsError::MissingLedgerSpent { + output_id: *output_id, + slot_index: metadata.transaction_id.slot_index(), + })? + .clone()) + }) + .collect::>>()?; + let created = payload + .transaction() + .outputs() + .iter() + .enumerate() + .map(|(index, _)| { + let output_id = metadata.transaction_id.into_output_id(index as _); + Ok(self + .ledger_updates() + .get_created(&output_id) + .ok_or(AnalyticsError::MissingLedgerOutput { + output_id, + slot_index: metadata.transaction_id.slot_index(), + })? + .clone()) + }) + .collect::>>()?; + analytics + .handle_transaction(payload, metadata, &consumed, &created, ctx) + .await?; + Ok(()) + } + async fn handle_block( &self, analytics: &mut A, @@ -327,50 +389,6 @@ impl<'a, I: InputSource> Slot<'a, I> { ctx: &BasicContext<'_>, ) -> eyre::Result<()> { let block = block_data.block.inner(); - // TODO: Is this right? - if block_data.metadata.block_state == BlockState::Confirmed { - if let Some(payload) = block - .body() - .as_basic_opt() - .and_then(|b| b.payload()) - .and_then(|p| p.as_signed_transaction_opt()) - { - let consumed = payload - .transaction() - .inputs() - .iter() - .map(|input| input.as_utxo().output_id()) - .map(|output_id| { - Ok(self - .ledger_updates() - .get_consumed(output_id) - .ok_or(AnalyticsError::MissingLedgerSpent { - output_id: *output_id, - slot_index: block.slot_commitment_id().slot_index(), - })? - .clone()) - }) - .collect::>>()?; - let created = payload - .transaction() - .outputs() - .iter() - .enumerate() - .map(|(index, _)| { - let output_id = payload.transaction().id().into_output_id(index as _); - Ok(self - .ledger_updates() - .get_created(&output_id) - .ok_or(AnalyticsError::MissingLedgerOutput { - output_id, - slot_index: block.slot_commitment_id().slot_index(), - })? - .clone()) - }) - .collect::>>()?; - analytics.handle_transaction(payload, &consumed, &created, ctx).await?; - } - } analytics.handle_block(block, &block_data.metadata, ctx).await?; Ok(()) } diff --git a/src/analytics/tangle/block_activity.rs b/src/analytics/tangle/block_activity.rs index 509f9ef4f..a7d3695b1 100644 --- a/src/analytics/tangle/block_activity.rs +++ b/src/analytics/tangle/block_activity.rs @@ -1,11 +1,20 @@ // Copyright 2023 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -use iota_sdk::types::block::{payload::Payload, Block, BlockBody}; +use iota_sdk::types::{ + api::core::{BlockState, TransactionState}, + block::{ + payload::{Payload, SignedTransactionPayload}, + Block, BlockBody, + }, +}; use crate::{ analytics::{Analytics, AnalyticsContext}, - model::block_metadata::{BlockMetadata, BlockState, TransactionState}, + model::{ + block_metadata::{BlockMetadata, TransactionMetadata}, + ledger::{LedgerOutput, LedgerSpent}, + }, }; /// The type of payloads that occured within a single slot. @@ -21,12 +30,12 @@ pub(crate) struct BlockActivityMeasurement { pub(crate) block_accepted_count: usize, pub(crate) block_confirmed_count: usize, pub(crate) block_finalized_count: usize, - pub(crate) block_rejected_count: usize, - pub(crate) block_failed_count: usize, + pub(crate) block_dropped_count: usize, + pub(crate) block_orphaned_count: usize, pub(crate) block_unknown_count: usize, pub(crate) txn_pending_count: usize, pub(crate) txn_accepted_count: usize, - pub(crate) txn_confirmed_count: usize, + pub(crate) txn_committed_count: usize, pub(crate) txn_finalized_count: usize, pub(crate) txn_failed_count: usize, } @@ -38,7 +47,7 @@ impl Analytics for BlockActivityMeasurement { async fn handle_block( &mut self, block: &Block, - metadata: &BlockMetadata, + block_metadata: &BlockMetadata, _ctx: &dyn AnalyticsContext, ) -> eyre::Result<()> { match block.body() { @@ -53,23 +62,38 @@ impl Analytics for BlockActivityMeasurement { } BlockBody::Validation(_) => self.validation_count += 1, } - match &metadata.block_state { - BlockState::Pending => self.block_pending_count += 1, - BlockState::Accepted => self.block_accepted_count += 1, - BlockState::Confirmed => self.block_confirmed_count += 1, - BlockState::Finalized => self.block_finalized_count += 1, - BlockState::Rejected => self.block_rejected_count += 1, - BlockState::Failed => self.block_failed_count += 1, - BlockState::Unknown => self.block_unknown_count += 1, + match &block_metadata.block_state { + Some(state) => match state { + BlockState::Pending => self.block_pending_count += 1, + BlockState::Accepted => self.block_accepted_count += 1, + BlockState::Confirmed => self.block_confirmed_count += 1, + BlockState::Finalized => self.block_finalized_count += 1, + BlockState::Dropped => self.block_dropped_count += 1, + BlockState::Orphaned => self.block_orphaned_count += 1, + }, + None => self.block_unknown_count += 1, } - if let Some(txn_state) = metadata.transaction_metadata.as_ref().map(|m| &m.transaction_state) { - match txn_state { + + Ok(()) + } + + async fn handle_transaction( + &mut self, + _payload: &SignedTransactionPayload, + metadata: &TransactionMetadata, + _consumed: &[LedgerSpent], + _created: &[LedgerOutput], + _ctx: &dyn AnalyticsContext, + ) -> eyre::Result<()> { + match &metadata.transaction_state { + Some(state) => match state { TransactionState::Pending => self.txn_pending_count += 1, TransactionState::Accepted => self.txn_accepted_count += 1, - TransactionState::Confirmed => self.txn_confirmed_count += 1, + TransactionState::Committed => self.txn_committed_count += 1, TransactionState::Finalized => self.txn_finalized_count += 1, TransactionState::Failed => self.txn_failed_count += 1, - } + }, + None => (), } Ok(()) diff --git a/src/analytics/tangle/mana_activity.rs b/src/analytics/tangle/mana_activity.rs index fe1b3c9af..fb50ae09e 100644 --- a/src/analytics/tangle/mana_activity.rs +++ b/src/analytics/tangle/mana_activity.rs @@ -10,7 +10,7 @@ use iota_sdk::types::block::{ use crate::{ analytics::{Analytics, AnalyticsContext}, model::{ - block_metadata::BlockMetadata, + block_metadata::{BlockMetadata, TransactionMetadata}, ledger::{LedgerOutput, LedgerSpent}, }, }; @@ -30,6 +30,7 @@ impl Analytics for ManaActivityMeasurement { async fn handle_transaction( &mut self, payload: &SignedTransactionPayload, + _metadata: &TransactionMetadata, consumed: &[LedgerSpent], created: &[LedgerOutput], ctx: &dyn AnalyticsContext, diff --git a/src/bin/inx-chronicle/api/core/routes.rs b/src/bin/inx-chronicle/api/core/routes.rs index c9eae59a8..3efb1ecd0 100644 --- a/src/bin/inx-chronicle/api/core/routes.rs +++ b/src/bin/inx-chronicle/api/core/routes.rs @@ -21,7 +21,7 @@ use chronicle::{ use iota_sdk::types::{ api::core::{ BaseTokenResponse, BlockMetadataResponse, OutputResponse, OutputWithMetadataResponse, - ProtocolParametersResponse, TransactionMetadataResponse, UtxoChangesResponse, + ProtocolParametersResponse, UtxoChangesResponse, }, block::{ output::{ @@ -155,19 +155,11 @@ async fn block( Ok(IotaRawResponse::Json((&block).into())) } -fn create_block_metadata_response(block_id: BlockId, metadata: BlockMetadata) -> BlockMetadataResponse { - BlockMetadataResponse { - block_id, - block_state: metadata.block_state.into(), - block_failure_reason: metadata.block_failure_reason.map(Into::into), - transaction_metadata: metadata - .transaction_metadata - .map(|metadata| TransactionMetadataResponse { - transaction_id: metadata.transaction_id, - transaction_state: metadata.transaction_state.into(), - transaction_failure_reason: metadata.transaction_failure_reason.map(Into::into), - }), - } +fn create_block_metadata_response(metadata: BlockMetadata) -> ApiResult { + Ok(BlockMetadataResponse { + block_id: metadata.block_id, + block_state: metadata.block_state.ok_or(MissingError::NoResults)?.into(), + }) } async fn block_metadata( @@ -181,15 +173,15 @@ async fn block_metadata( .await? .ok_or(MissingError::NoResults)?; - Ok(create_block_metadata_response(block_id, metadata).into()) + Ok(create_block_metadata_response(metadata)?.into()) } fn create_output_metadata_response( output_id: OutputId, metadata: OutputMetadata, latest_commitment_id: SlotCommitmentId, -) -> ApiResult { - Ok(OutputMetadataResponse::new( +) -> OutputMetadataResponse { + OutputMetadataResponse::new( output_id, metadata.block_id, OutputInclusionMetadata::new( @@ -205,7 +197,7 @@ fn create_output_metadata_response( ) }), latest_commitment_id, - )) + ) } async fn output( @@ -257,7 +249,7 @@ async fn output_metadata( .await? .ok_or(MissingError::NoResults)?; - Ok(create_output_metadata_response(metadata.output_id, metadata.metadata, latest_slot.commitment_id)?.into()) + Ok(create_output_metadata_response(metadata.output_id, metadata.metadata, latest_slot.commitment_id).into()) } async fn output_full( @@ -290,7 +282,7 @@ async fn output_full( .as_signed_transaction() .transaction() .output_id_proof(output_id.index())?, - metadata: create_output_metadata_response(output_id, output_with_metadata.metadata, latest_slot.commitment_id)?, + metadata: create_output_metadata_response(output_id, output_with_metadata.metadata, latest_slot.commitment_id), } .into()) } @@ -327,15 +319,13 @@ async fn included_block_metadata( ) -> ApiResult> { let transaction_id = TransactionId::from_str(&transaction_id).map_err(RequestError::from)?; - let res = database + let metadata = database .collection::() .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()) + Ok(create_block_metadata_response(metadata)?.into()) } async fn commitment( diff --git a/src/bin/inx-chronicle/inx/mod.rs b/src/bin/inx-chronicle/inx/mod.rs index 1365b85b4..2aeccfa7c 100644 --- a/src/bin/inx-chronicle/inx/mod.rs +++ b/src/bin/inx-chronicle/inx/mod.rs @@ -335,7 +335,9 @@ impl InxWorker { .try_fold(JoinSet::new(), |mut tasks, batch| async { let db = self.db.clone(); tasks.spawn(async move { - db.collection::().insert_blocks(&batch).await?; + db.collection::() + .insert_blocks(batch.iter().map(|data| &data.block)) + .await?; db.collection::() .insert_blocks_with_metadata(batch) .await?; diff --git a/src/db/mongodb/collections/block.rs b/src/db/mongodb/collections/block.rs index f051ddc95..2923b52c1 100644 --- a/src/db/mongodb/collections/block.rs +++ b/src/db/mongodb/collections/block.rs @@ -2,8 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use futures::{Stream, StreamExt, TryStreamExt}; -use iota_sdk::types::block::{ - output::OutputId, payload::signed_transaction::TransactionId, slot::SlotIndex, Block, BlockId, +use iota_sdk::types::{ + api::core::BlockState, + block::{payload::signed_transaction::TransactionId, slot::SlotIndex, Block, BlockId}, }; use mongodb::{ bson::doc, @@ -20,7 +21,7 @@ use crate::{ MongoDb, }, model::{ - block_metadata::{BlockMetadata, BlockState, BlockWithMetadata}, + block_metadata::{BlockMetadata, BlockWithMetadata, BlockWithTransactionMetadata, TransactionMetadata}, raw::Raw, SerializeToBson, }, @@ -33,8 +34,8 @@ pub struct BlockDocument { block_id: BlockId, /// The block. block: Raw, - /// The block's metadata. - metadata: BlockMetadata, + /// The block's state. + block_state: Option, /// The index of the slot to which this block commits. slot_index: SlotIndex, /// The block's payload type. @@ -43,23 +44,13 @@ pub struct BlockDocument { transaction: Option, } -impl From for BlockDocument { - fn from(BlockWithMetadata { block, metadata }: BlockWithMetadata) -> Self { - let transaction = block - .inner() - .body() - .as_basic_opt() - .and_then(|b| b.payload()) - .and_then(|p| p.as_signed_transaction_opt()) - .map(|txn| TransactionMetadata { - transaction_id: txn.transaction().id(), - inputs: txn - .transaction() - .inputs() - .iter() - .map(|i| *i.as_utxo().output_id()) - .collect(), - }); +impl From for BlockDocument { + fn from( + BlockWithTransactionMetadata { + block: BlockWithMetadata { metadata, block }, + transaction, + }: BlockWithTransactionMetadata, + ) -> Self { Self { block_id: metadata.block_id, slot_index: block.inner().slot_commitment_id().slot_index(), @@ -70,18 +61,12 @@ impl From for BlockDocument { .and_then(|b| b.payload()) .map(|p| p.kind()), block, - metadata, + block_state: metadata.block_state, transaction, } } } -#[derive(Clone, Debug, Serialize, Deserialize)] -struct TransactionMetadata { - transaction_id: TransactionId, - inputs: Vec, -} - /// The iota blocks collection. pub struct BlockCollection { collection: mongodb::Collection, @@ -109,8 +94,7 @@ impl MongoDbCollection for BlockCollection { .unique(true) .name("transaction_id_index".to_string()) .partial_filter_expression(doc! { - "transaction.transaction_id": { "$exists": true }, - "metadata.block_state": { "$eq": BlockState::Finalized.to_bson() }, + "transaction": { "$exists": true }, }) .build(), ) @@ -121,7 +105,7 @@ impl MongoDbCollection for BlockCollection { self.create_index( IndexModel::builder() - .keys(doc! { "slot_index": -1, "metadata.block_state": 1 }) + .keys(doc! { "slot_index": -1 }) .options( IndexOptions::builder() .name("block_slot_index_comp".to_string()) @@ -142,13 +126,6 @@ pub struct IncludedBlockResult { pub block: Block, } -#[derive(Deserialize, Debug, Clone)] -pub struct IncludedBlockMetadataResult { - #[serde(rename = "_id")] - pub block_id: BlockId, - pub metadata: BlockMetadata, -} - #[derive(Deserialize)] struct RawResult { block: Raw, @@ -183,7 +160,10 @@ impl BlockCollection { .aggregate( [ doc! { "$match": { "_id": block_id.to_bson() } }, - doc! { "$replaceWith": "$metadata" }, + doc! { "$project": { + "block_id": "$_id", + "block_state": 1, + } }, ], None, ) @@ -192,22 +172,21 @@ impl BlockCollection { .await?) } - /// Get the accepted blocks from a slot. - pub async fn get_accepted_blocks( + /// Get the blocks from a slot. + pub async fn get_blocks_by_slot( &self, SlotIndex(index): SlotIndex, ) -> Result>, DbError> { Ok(self .aggregate( [ - doc! { "$match": { - "slot_index": index, - "metadata.block_state": BlockState::Confirmed.to_bson() - } }, - doc! { "$sort": { "_id": 1 } }, + doc! { "$match": { "slot_index": index } }, doc! { "$project": { "block": 1, - "metadata": 1 + "metadata": { + "block_id": "$_id", + "block_state": 1, + } } }, ], None, @@ -220,7 +199,7 @@ impl BlockCollection { #[instrument(skip_all, err, level = "trace")] pub async fn insert_blocks_with_metadata(&self, blocks_with_metadata: I) -> Result<(), DbError> where - I: IntoIterator, + I: IntoIterator, I::IntoIter: Send + Sync, { let docs = blocks_with_metadata.into_iter().map(BlockDocument::from); @@ -247,10 +226,13 @@ impl BlockCollection { .aggregate( [ doc! { "$match": { - "metadata.block_state": BlockState::Finalized.to_bson(), + "transaction": { "$exists": true }, "transaction.transaction_id": transaction_id.to_bson(), } }, - doc! { "$project": { "block_id": "$_id", "block": 1 } }, + doc! { "$project": { + "_id": 1, + "block": 1, + } }, ], None, ) @@ -272,7 +254,7 @@ impl BlockCollection { .aggregate( [ doc! { "$match": { - "metadata.block_state": BlockState::Finalized.to_bson(), + "transaction": { "$exists": true }, "transaction.transaction_id": transaction_id.to_bson(), } }, doc! { "$project": { "block": 1 } }, @@ -289,17 +271,17 @@ impl BlockCollection { pub async fn get_block_metadata_for_transaction( &self, transaction_id: &TransactionId, - ) -> Result, DbError> { + ) -> Result, DbError> { Ok(self .aggregate( [ doc! { "$match": { - "metadata.block_state": BlockState::Finalized.to_bson(), + "transaction": { "$exists": true }, "transaction.transaction_id": transaction_id.to_bson(), } }, doc! { "$project": { - "_id": 1, - "metadata": 1, + "block_id": "$_id", + "block_state": 1, } }, ], None, @@ -309,21 +291,23 @@ impl BlockCollection { .await?) } - /// Gets the block containing the spending transaction of an output by [`OutputId`]. - pub async fn get_spending_transaction(&self, output_id: &OutputId) -> Result, DbError> { + /// Finds the [`TransactionMetadata`] by [`TransactionId`]. + pub async fn get_transaction_metadata( + &self, + transaction_id: &TransactionId, + ) -> Result, DbError> { Ok(self .aggregate( [ doc! { "$match": { - "metadata.block_state": BlockState::Finalized.to_bson(), - "inputs.output_id": output_id.to_bson(), + "transaction": { "$exists": true }, + "transaction.transaction_id": transaction_id.to_bson(), } }, - doc! { "$project": { "block": 1 } }, + doc! { "$replaceWith": "$transaction" }, ], None, ) .await? - .map_ok(|RawResult { block }| block.into_inner()) .try_next() .await?) } diff --git a/src/inx/client.rs b/src/inx/client.rs index cd85d67e9..e64d41c76 100644 --- a/src/inx/client.rs +++ b/src/inx/client.rs @@ -3,7 +3,8 @@ use futures::stream::{Stream, StreamExt}; use inx::{client::InxClient, proto}; -use iota_sdk::types::block::slot::SlotIndex; +use iota_sdk::types::block::{payload::signed_transaction::TransactionId, slot::SlotIndex}; +use packable::PackableExt; use super::{ convert::TryConvertTo, @@ -12,7 +13,7 @@ use super::{ InxError, }; use crate::model::{ - block_metadata::BlockWithMetadata, + block_metadata::{BlockWithMetadata, TransactionMetadata}, node::{NodeConfiguration, NodeStatus}, slot::Commitment, }; @@ -54,20 +55,34 @@ impl Inx { .listen_to_commitments(proto::SlotRangeRequest::from(request)) .await? .into_inner() - .map(|msg| TryConvertTo::try_convert(msg?))) + .map(|msg| msg?.try_convert())) } /// Get accepted blocks for a given slot. pub async fn get_accepted_blocks_for_slot( &mut self, - slot_index: SlotIndex, + SlotIndex(slot): SlotIndex, ) -> Result>, InxError> { Ok(self .inx - .read_accepted_blocks(proto::SlotIndex { index: slot_index.0 }) + .read_accepted_blocks(proto::SlotRequest { slot }) .await? .into_inner() - .map(|msg| TryConvertTo::try_convert(msg?))) + .map(|msg| msg?.try_convert())) + } + + /// Get the associated metadata by transaction id. + pub async fn get_transaction_metadata( + &mut self, + transaction_id: TransactionId, + ) -> Result { + self.inx + .read_transaction_metadata(proto::TransactionId { + id: transaction_id.pack_to_vec(), + }) + .await? + .into_inner() + .try_convert() } /// Read the current unspent outputs. @@ -79,7 +94,7 @@ impl Inx { .read_unspent_outputs(proto::NoParams {}) .await? .into_inner() - .map(|msg| TryConvertTo::try_convert(msg?))) + .map(|msg| msg?.try_convert())) } /// Listen to ledger updates. @@ -92,6 +107,6 @@ impl Inx { .listen_to_ledger_updates(proto::SlotRangeRequest::from(request)) .await? .into_inner() - .map(|msg| TryConvertTo::try_convert(msg?))) + .map(|msg| msg?.try_convert())) } } diff --git a/src/inx/ledger.rs b/src/inx/ledger.rs index b1c88eae4..60733de64 100644 --- a/src/inx/ledger.rs +++ b/src/inx/ledger.rs @@ -3,7 +3,7 @@ use inx::proto; use iota_sdk::types::{ - api::core::BlockFailureReason, + api::core::{BlockState, TransactionState}, block::{ payload::signed_transaction::TransactionId, semantic::TransactionFailureReason, @@ -17,10 +17,7 @@ use super::{ }; use crate::{ maybe_missing, - model::{ - block_metadata::{BlockState, TransactionState}, - ledger::{LedgerOutput, LedgerSpent}, - }, + model::ledger::{LedgerOutput, LedgerSpent}, }; impl TryConvertFrom for LedgerOutput { @@ -186,18 +183,18 @@ impl TryConvertFrom for AcceptedTransaction { } } -impl ConvertFrom for BlockState { +impl ConvertFrom for Option { fn convert_from(proto: proto::block_metadata::BlockState) -> Self { use proto::block_metadata::BlockState as ProtoState; - match proto { + Some(match proto { ProtoState::Pending => BlockState::Pending, ProtoState::Confirmed => BlockState::Confirmed, ProtoState::Finalized => BlockState::Finalized, - ProtoState::Rejected => BlockState::Rejected, - ProtoState::Failed => BlockState::Failed, + ProtoState::Dropped => BlockState::Dropped, + ProtoState::Orphaned => BlockState::Orphaned, ProtoState::Accepted => BlockState::Accepted, - ProtoState::Unknown => BlockState::Unknown, - } + ProtoState::Unknown => return None, + }) } } @@ -206,32 +203,11 @@ impl ConvertFrom for Option TransactionState::Pending, - ProtoState::Confirmed => TransactionState::Confirmed, + ProtoState::Committed => TransactionState::Committed, ProtoState::Finalized => TransactionState::Finalized, ProtoState::Failed => TransactionState::Failed, ProtoState::Accepted => TransactionState::Accepted, - ProtoState::NoTransaction => return None, - }) - } -} - -impl ConvertFrom for Option { - fn convert_from(proto: proto::block_metadata::BlockFailureReason) -> Self { - use proto::block_metadata::BlockFailureReason as ProtoState; - Some(match proto { - ProtoState::None => return None, - ProtoState::IsTooOld => BlockFailureReason::TooOldToIssue, - ProtoState::ParentIsTooOld => BlockFailureReason::ParentTooOld, - ProtoState::ParentNotFound => BlockFailureReason::ParentDoesNotExist, - ProtoState::IssuerAccountNotFound => BlockFailureReason::IssuerAccountNotFound, - ProtoState::ManaCostCalculationFailed => BlockFailureReason::ManaCostCalculationFailed, - ProtoState::BurnedInsufficientMana => BlockFailureReason::BurnedInsufficientMana, - ProtoState::AccountLocked => BlockFailureReason::AccountLocked, - ProtoState::AccountExpired => BlockFailureReason::AccountLocked, - ProtoState::SignatureInvalid => BlockFailureReason::SignatureInvalid, - ProtoState::DroppedDueToCongestion => BlockFailureReason::DroppedDueToCongestion, - ProtoState::PayloadInvalid => BlockFailureReason::PayloadInvalid, - ProtoState::Invalid => BlockFailureReason::Invalid, + ProtoState::Unknown => return None, }) } } @@ -242,6 +218,7 @@ impl ConvertFrom for Opti Some(match proto { ProtoState::None => return None, ProtoState::ConflictRejected => TransactionFailureReason::ConflictRejected, + ProtoState::Orphaned => TransactionFailureReason::Orphaned, ProtoState::InputAlreadySpent => TransactionFailureReason::InputAlreadySpent, ProtoState::InputCreationAfterTxCreation => TransactionFailureReason::InputCreationAfterTxCreation, ProtoState::UnlockSignatureInvalid => TransactionFailureReason::UnlockSignatureInvalid, @@ -282,7 +259,6 @@ impl ConvertFrom for Opti ProtoState::SenderFeatureNotUnlocked => TransactionFailureReason::SenderFeatureNotUnlocked, ProtoState::IssuerFeatureNotUnlocked => TransactionFailureReason::IssuerFeatureNotUnlocked, ProtoState::StakingRewardInputMissing => TransactionFailureReason::StakingRewardInputMissing, - ProtoState::StakingBlockIssuerFeatureMissing => TransactionFailureReason::StakingBlockIssuerFeatureMissing, ProtoState::StakingCommitmentInputMissing => TransactionFailureReason::StakingCommitmentInputMissing, ProtoState::StakingRewardClaimingInvalid => TransactionFailureReason::StakingRewardClaimingInvalid, ProtoState::StakingFeatureRemovedBeforeUnbonding => { diff --git a/src/inx/responses.rs b/src/inx/responses.rs index 6d50ce516..faee59107 100644 --- a/src/inx/responses.rs +++ b/src/inx/responses.rs @@ -192,31 +192,23 @@ impl TryConvertFrom for BlockMetadata { { Ok(Self { block_state: proto.block_state().convert(), - block_failure_reason: proto.block_failure_reason().convert(), - transaction_metadata: proto.transaction_metadata.try_convert()?, block_id: maybe_missing!(proto.block_id).try_convert()?, }) } } -impl TryConvertFrom> for Option { +impl TryConvertFrom for TransactionMetadata { type Error = InxError; - fn try_convert_from(proto: Option) -> Result + fn try_convert_from(proto: proto::TransactionMetadata) -> Result where Self: Sized, { - if let Some(proto) = proto { - // We can receive a metadata with null values so we can't assume this is actually a transaction - if let Some(transaction_state) = proto.transaction_state().convert() { - return Ok(Some(TransactionMetadata { - transaction_state, - transaction_failure_reason: proto.transaction_failure_reason().convert(), - transaction_id: maybe_missing!(proto.transaction_id).try_convert()?, - })); - } - } - Ok(None) + Ok(Self { + transaction_state: proto.transaction_state().convert(), + transaction_failure_reason: proto.transaction_failure_reason().convert(), + transaction_id: maybe_missing!(proto.transaction_id).try_convert()?, + }) } } diff --git a/src/model/block_metadata.rs b/src/model/block_metadata.rs index 9aad05e55..f03231658 100644 --- a/src/model/block_metadata.rs +++ b/src/model/block_metadata.rs @@ -5,7 +5,7 @@ use iota_sdk::{ types::{ - api::core::BlockFailureReason, + api::core::{BlockState, TransactionState}, block::{ self as iota, payload::signed_transaction::TransactionId, semantic::TransactionFailureReason, BlockId, }, @@ -20,10 +20,8 @@ use super::raw::Raw; #[allow(missing_docs)] pub struct BlockMetadata { pub block_id: BlockId, - pub block_state: BlockState, - #[serde(with = "option_string")] - pub block_failure_reason: Option, - pub transaction_metadata: Option, + #[serde(default, with = "option_strum_string")] + pub block_state: Option, } #[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -31,8 +29,9 @@ pub struct BlockMetadata { pub struct TransactionMetadata { pub transaction_id: TransactionId, - pub transaction_state: TransactionState, - #[serde(with = "option_string")] + #[serde(with = "option_strum_string")] + pub transaction_state: Option, + #[serde(default, with = "option_string")] pub transaction_failure_reason: Option, } @@ -43,64 +42,39 @@ pub struct BlockWithMetadata { pub block: Raw, } -/// Describes the state of a block. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -pub enum BlockState { - /// Stored but not confirmed. - Pending, - /// Acccepted. - Accepted, - /// Confirmed with the first level of knowledge. - Confirmed, - /// Included and can no longer be reverted. - Finalized, - /// Rejected by the node, and user should reissue payload if it contains one. - Rejected, - /// Not successfully issued due to failure reason. - Failed, - /// Unknown state. - Unknown, +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[allow(missing_docs)] +pub struct BlockWithTransactionMetadata { + pub block: BlockWithMetadata, + pub transaction: Option, } -impl From for iota_sdk::types::api::core::BlockState { - fn from(value: BlockState) -> Self { - match value { - BlockState::Pending => Self::Pending, - BlockState::Accepted => Self::Pending, - BlockState::Confirmed => Self::Confirmed, - BlockState::Finalized => Self::Finalized, - BlockState::Rejected => Self::Rejected, - BlockState::Failed => Self::Failed, - BlockState::Unknown => panic!("invalid block state"), - } - } -} +/// Serializes types that `impl AsRef` +#[allow(missing_docs)] +pub mod option_strum_string { + use core::{fmt::Display, str::FromStr}; -/// Describes the state of a transaction. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "snake_case")] -pub enum TransactionState { - /// Stored but not confirmed. - Pending, - /// Accepted. - Accepted, - /// Confirmed with the first level of knowledge. - Confirmed, - /// Included and can no longer be reverted. - Finalized, - /// The block is not successfully issued due to failure reason. - Failed, -} + use serde::{de, Deserialize, Deserializer, Serializer}; -impl From for iota_sdk::types::api::core::TransactionState { - fn from(value: TransactionState) -> Self { + pub fn serialize(value: &Option, serializer: S) -> Result + where + T: AsRef, + S: Serializer, + { match value { - TransactionState::Pending => Self::Pending, - TransactionState::Accepted => Self::Pending, - TransactionState::Confirmed => Self::Confirmed, - TransactionState::Finalized => Self::Finalized, - TransactionState::Failed => Self::Failed, + Some(value) => serializer.collect_str(value.as_ref()), + None => serializer.serialize_none(), } } + + pub fn deserialize<'de, T, D>(deserializer: D) -> Result, D::Error> + where + T: FromStr, + T::Err: Display, + D: Deserializer<'de>, + { + Option::::deserialize(deserializer)? + .map(|string| string.parse().map_err(de::Error::custom)) + .transpose() + } } diff --git a/src/tangle/slot_stream.rs b/src/tangle/slot_stream.rs index 566a8b2cc..70c6b236c 100644 --- a/src/tangle/slot_stream.rs +++ b/src/tangle/slot_stream.rs @@ -6,11 +6,13 @@ use std::{ task::{Context, Poll}, }; -use futures::{stream::BoxStream, Stream}; +use futures::{stream::BoxStream, Stream, TryStreamExt}; use iota_sdk::types::block::slot::{SlotCommitment, SlotCommitmentId, SlotIndex}; use super::InputSource; -use crate::model::{block_metadata::BlockWithMetadata, ledger::LedgerUpdateStore, raw::Raw, slot::Commitment}; +use crate::model::{ + block_metadata::BlockWithTransactionMetadata, ledger::LedgerUpdateStore, raw::Raw, slot::Commitment, +}; #[allow(missing_docs)] pub struct Slot<'a, I: InputSource> { @@ -38,8 +40,28 @@ impl<'a, I: InputSource> Slot<'a, I> { impl<'a, I: InputSource> Slot<'a, I> { /// Returns the accepted blocks of a slot. - pub async fn accepted_block_stream(&self) -> Result>, I::Error> { - self.source.accepted_blocks(self.index()).await + pub async fn accepted_block_stream( + &self, + ) -> Result> + '_, I::Error> { + Ok(self.source.accepted_blocks(self.index()).await?.and_then(|res| async { + let transaction = if let Some(transaction_id) = res + .block + .inner() + .body() + .as_basic_opt() + .and_then(|body| body.payload()) + .and_then(|p| p.as_signed_transaction_opt()) + .map(|txn| txn.transaction().id()) + { + Some(self.source.transaction_metadata(transaction_id).await?) + } else { + None + }; + Ok(BlockWithTransactionMetadata { + transaction, + block: res, + }) + })) } /// Returns the ledger update store. diff --git a/src/tangle/sources/inx.rs b/src/tangle/sources/inx.rs index 0d89368c1..98db1add0 100644 --- a/src/tangle/sources/inx.rs +++ b/src/tangle/sources/inx.rs @@ -5,13 +5,17 @@ use core::ops::RangeBounds; use async_trait::async_trait; use futures::{stream::BoxStream, StreamExt, TryStreamExt}; -use iota_sdk::types::block::slot::SlotIndex; +use iota_sdk::types::block::{payload::signed_transaction::TransactionId, slot::SlotIndex}; use thiserror::Error; use super::InputSource; use crate::{ inx::{ledger::MarkerMessage, Inx, InxError, SlotRangeRequest}, - model::{block_metadata::BlockWithMetadata, ledger::LedgerUpdateStore, slot::Commitment}, + model::{ + block_metadata::{BlockWithMetadata, TransactionMetadata}, + ledger::LedgerUpdateStore, + slot::Commitment, + }, }; #[derive(Debug, Error)] @@ -52,6 +56,11 @@ impl InputSource for Inx { )) } + async fn transaction_metadata(&self, transaction_id: TransactionId) -> Result { + let mut inx = self.clone(); + Ok(inx.get_transaction_metadata(transaction_id).await?) + } + async fn ledger_updates(&self, index: SlotIndex) -> Result { let mut inx = self.clone(); let mut stream = inx.get_ledger_updates((index.0..=index.0).into()).await?; diff --git a/src/tangle/sources/memory.rs b/src/tangle/sources/memory.rs index 15aeb5a19..6b6d4ad03 100644 --- a/src/tangle/sources/memory.rs +++ b/src/tangle/sources/memory.rs @@ -6,17 +6,22 @@ use std::collections::BTreeMap; use async_trait::async_trait; use futures::stream::BoxStream; -use iota_sdk::types::block::{slot::SlotIndex, BlockId}; +use iota_sdk::types::block::{payload::signed_transaction::TransactionId, slot::SlotIndex, BlockId}; use serde::{Deserialize, Serialize}; use thiserror::Error; use super::InputSource; -use crate::model::{block_metadata::BlockWithMetadata, ledger::LedgerUpdateStore, slot::Commitment}; +use crate::model::{ + block_metadata::{BlockWithMetadata, TransactionMetadata}, + ledger::LedgerUpdateStore, + slot::Commitment, +}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct InMemoryData { pub commitment: Commitment, - pub confirmed_blocks: BTreeMap, + pub committed_blocks: BTreeMap, + pub transaction_metadata: BTreeMap, pub ledger_updates: LedgerUpdateStore, } @@ -24,6 +29,8 @@ pub struct InMemoryData { pub enum InMemoryInputSourceError { #[error("missing block data for slot {0}")] MissingBlockData(SlotIndex), + #[error("missing metadata for transaction {0}")] + MissingTransactionMetadata(TransactionId), } #[async_trait] @@ -46,10 +53,21 @@ impl InputSource for BTreeMap { let blocks = &self .get(&index) .ok_or(InMemoryInputSourceError::MissingBlockData(index))? - .confirmed_blocks; + .committed_blocks; Ok(Box::pin(futures::stream::iter(blocks.values().map(|v| Ok(v.clone()))))) } + async fn transaction_metadata(&self, transaction_id: TransactionId) -> Result { + let index = transaction_id.slot_index(); + Ok(self + .get(&index) + .ok_or(InMemoryInputSourceError::MissingBlockData(index))? + .transaction_metadata + .get(&transaction_id) + .ok_or(InMemoryInputSourceError::MissingTransactionMetadata(transaction_id))? + .clone()) + } + async fn ledger_updates(&self, index: SlotIndex) -> Result { Ok(self .get(&index) diff --git a/src/tangle/sources/mod.rs b/src/tangle/sources/mod.rs index 4ea6f79bd..c656d99eb 100644 --- a/src/tangle/sources/mod.rs +++ b/src/tangle/sources/mod.rs @@ -10,9 +10,13 @@ use core::ops::RangeBounds; use async_trait::async_trait; use futures::stream::BoxStream; -use iota_sdk::types::block::slot::SlotIndex; +use iota_sdk::types::block::{payload::signed_transaction::TransactionId, slot::SlotIndex}; -use crate::model::{block_metadata::BlockWithMetadata, ledger::LedgerUpdateStore, slot::Commitment}; +use crate::model::{ + block_metadata::{BlockWithMetadata, TransactionMetadata}, + ledger::LedgerUpdateStore, + slot::Commitment, +}; /// Defines a type as a source for block and ledger update data. #[async_trait] @@ -32,6 +36,9 @@ pub trait InputSource: Send + Sync { index: SlotIndex, ) -> Result>, Self::Error>; + /// Retrieves metadata for a given transaction id. + async fn transaction_metadata(&self, transaction_id: TransactionId) -> Result; + /// Retrieves the updates to the ledger for a given range of slots. async fn ledger_updates(&self, index: SlotIndex) -> Result; } diff --git a/src/tangle/sources/mongodb.rs b/src/tangle/sources/mongodb.rs index 5361fe59f..e63187f16 100644 --- a/src/tangle/sources/mongodb.rs +++ b/src/tangle/sources/mongodb.rs @@ -5,7 +5,7 @@ use core::ops::RangeBounds; use async_trait::async_trait; use futures::{stream::BoxStream, StreamExt, TryStreamExt}; -use iota_sdk::types::block::slot::SlotIndex; +use iota_sdk::types::block::{payload::signed_transaction::TransactionId, slot::SlotIndex}; use thiserror::Error; use super::InputSource; @@ -17,13 +17,19 @@ use crate::{ }, MongoDb, }, - model::{block_metadata::BlockWithMetadata, ledger::LedgerUpdateStore, slot::Commitment}, + model::{ + block_metadata::{BlockWithMetadata, TransactionMetadata}, + ledger::LedgerUpdateStore, + slot::Commitment, + }, }; #[derive(Debug, Error)] pub enum MongoDbInputSourceError { #[error("missing commitment for slot index {0}")] MissingCommitment(SlotIndex), + #[error("missing metadata for transaction {0}")] + MissingTransactionMetadata(TransactionId), #[error(transparent)] MongoDb(#[from] DbError), } @@ -68,12 +74,19 @@ impl InputSource for MongoDb { ) -> Result>, Self::Error> { Ok(Box::pin( self.collection::() - .get_accepted_blocks(index) + .get_blocks_by_slot(index) .await? .map_err(Into::into), )) } + async fn transaction_metadata(&self, transaction_id: TransactionId) -> Result { + self.collection::() + .get_transaction_metadata(&transaction_id) + .await? + .ok_or(MongoDbInputSourceError::MissingTransactionMetadata(transaction_id)) + } + async fn ledger_updates(&self, index: SlotIndex) -> Result { let consumed = self .collection::()