From f1a5d96831ea045851cfb2ee58c1f15463d1e415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 21:49:15 -0600 Subject: [PATCH 01/26] feat(cat-gateway): add Query trait, use DashMap --- .../bin/src/db/index/queries/mod.rs | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index a3f6f6791081..6313333c5a26 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -11,7 +11,7 @@ pub(crate) mod sync_status; use std::{fmt::Debug, sync::Arc}; use anyhow::bail; -use crossbeam_skiplist::SkipMap; +use dashmap::DashMap; use registrations::{ get_all_invalids::GetAllInvalidRegistrationsQuery, get_all_registrations::GetAllRegistrationsQuery, get_from_stake_addr::GetRegistrationQuery, @@ -50,7 +50,26 @@ use crate::{ }; /// Batches of different sizes, prepared and ready for use. -pub(crate) type SizedBatch = SkipMap>; +pub(crate) type SizedBatch = DashMap>; + +/// Kind of result +#[derive(Clone)] +#[allow(dead_code)] +pub(crate) enum QueryKind { + /// Sized-batch + Batch(SizedBatch), + /// Prepared statement + Statement(PreparedStatement), +} + +/// A trait to prepare Index DB queries. +#[allow(dead_code)] +pub(crate) trait Query { + /// Prepare the query + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result; +} /// All Prepared insert Queries that we know about. #[derive(strum_macros::Display)] @@ -296,7 +315,7 @@ impl PreparedQueries { session: Arc, query: &str, cfg: &cassandra_db::EnvVars, consistency: scylla::statement::Consistency, idempotent: bool, logged: bool, ) -> anyhow::Result { - let sized_batches: SizedBatch = SkipMap::new(); + let sized_batches: SizedBatch = DashMap::new(); // First prepare the query. Only needs to be done once, all queries on a batch are the // same. From 61f5cce2f3c10c24468c8025d9a819863b74bde8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 21:50:23 -0600 Subject: [PATCH 02/26] feat(cat-gateway): add prepared_queries field to CassandraSession --- catalyst-gateway/bin/src/db/index/session.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/catalyst-gateway/bin/src/db/index/session.rs b/catalyst-gateway/bin/src/db/index/session.rs index 6abeb86210d1..f26472e14b24 100644 --- a/catalyst-gateway/bin/src/db/index/session.rs +++ b/catalyst-gateway/bin/src/db/index/session.rs @@ -1,6 +1,7 @@ //! Session creation and storage use std::{ + any::TypeId, fmt::Debug, path::PathBuf, sync::{Arc, OnceLock}, @@ -8,6 +9,7 @@ use std::{ }; use cardano_blockchain_types::Network; +use dashmap::DashMap; use openssl::ssl::{SslContextBuilder, SslFiletype, SslMethod, SslVerifyMode}; use scylla::{ frame::Compression, serialize::row::SerializeRow, transport::iterator::QueryPager, @@ -21,7 +23,7 @@ use super::{ queries::{ purge::{self, PreparedDeleteQuery}, FallibleQueryResults, PreparedQueries, PreparedQuery, PreparedSelectQuery, - PreparedUpsertQuery, + PreparedUpsertQuery, QueryKind, }, schema::create_schema, }; @@ -115,6 +117,9 @@ pub(crate) struct CassandraSession { queries: Arc, /// All prepared purge queries we can use on this session. purge_queries: Arc, + /// All prepared queries we can use on this session. + #[allow(dead_code)] + prepared_queries: DashMap, } /// Session error while initialization. @@ -433,6 +438,7 @@ async fn retry_init(cfg: cassandra_db::EnvVars, network: Network, persistent: bo session, queries, purge_queries, + prepared_queries: DashMap::default(), }; // Save the session so we can execute queries on the DB From 57b67a35265f16a462b011e5655bab5ee540fdcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 21:51:22 -0600 Subject: [PATCH 03/26] feat(cat-gateway): impl Query for TxiInsertQuery --- .../bin/src/db/index/block/txi.rs | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/txi.rs b/catalyst-gateway/bin/src/db/index/block/txi.rs index 397a42bb26c0..cd8f148ca8b5 100644 --- a/catalyst-gateway/bin/src/db/index/block/txi.rs +++ b/catalyst-gateway/bin/src/db/index/block/txi.rs @@ -1,6 +1,6 @@ //! Insert TXI Index Data Queries. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, TransactionId, TxnOutputOffset}; use catalyst_types::hashes::Blake2b256Hash; @@ -10,7 +10,9 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{FallibleQueryTasks, PreparedQueries, PreparedQuery, SizedBatch}, + queries::{ + FallibleQueryTasks, PreparedQueries, PreparedQuery, Query, QueryKind, SizedBatch, + }, session::CassandraSession, }, types::{DbSlot, DbTransactionId, DbTxnOutputOffset}, @@ -46,9 +48,26 @@ pub(crate) struct TxiInsertQuery { txi_data: Vec, } +impl Query for TxiInsertQuery { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + TxiInsertQuery::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + /// TXI by Txn hash Index const INSERT_TXI_QUERY: &str = include_str!("./cql/insert_txi.cql"); +impl fmt::Display for TxiInsertQuery { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_TXI_QUERY}") + } +} + impl TxiInsertQuery { /// Create a new record for this transaction. pub(crate) fn new() -> Self { From 59129b9e881d9adbbae21b23a1b5d6d7c3bb4969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 21:52:03 -0600 Subject: [PATCH 04/26] feat(cat-gateway): impl Query for TxoInsert --- .../bin/src/db/index/block/txo/insert_txo.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs index 46b1bdceb965..490d67998a70 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs @@ -2,7 +2,7 @@ //! //! Note, there are multiple ways TXO Data is indexed and they all happen in here. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, StakeAddress, TransactionId, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -10,7 +10,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbStakeAddress, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, settings::cassandra_db, @@ -39,6 +39,22 @@ pub(crate) struct Params { txn_hash: DbTransactionId, } +impl fmt::Display for Params { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_TXO_QUERY}") + } +} + +impl Query for Params { + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Params::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + impl Params { /// Create a new record for this transaction. pub(crate) fn new( From fd4c746797953f628b6bf63883781472413895fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 22:07:43 -0600 Subject: [PATCH 05/26] feat(cat-gateway): impl Query for InsertTxoAsset --- .../db/index/block/txo/insert_txo_asset.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs index 2eb83cc934f1..f0ab4be13947 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs @@ -1,6 +1,6 @@ //! Insert TXO Native Assets into the DB. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, StakeAddress, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -8,7 +8,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, }, settings::cassandra_db, @@ -37,6 +37,22 @@ pub(crate) struct Params { value: num_bigint::BigInt, } +impl fmt::Display for Params { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_TXO_ASSET_QUERY}") + } +} + +impl Query for Params { + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Params::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + impl Params { /// Create a new record for this transaction. /// From 500e86b3e8d3aa69f75b2dcdf988994ce2a64c92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 22:08:15 -0600 Subject: [PATCH 06/26] feat(cat-gateway): impl Query for InsertUnstakedTxo --- .../db/index/block/txo/insert_unstaked_txo.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs index 346460579a15..511cf3735981 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs @@ -1,5 +1,5 @@ //! Insert Unstaked TXOs into the DB. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, TransactionId, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -7,7 +7,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, settings::cassandra_db, @@ -34,6 +34,22 @@ pub(crate) struct Params { value: num_bigint::BigInt, } +impl fmt::Display for Params { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_UNSTAKED_TXO_QUERY}") + } +} + +impl Query for Params { + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Params::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + impl Params { /// Create a new record for this transaction. pub(crate) fn new( From bc3e8700ce077b8402149a1a193fb7a12e32fc00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 2 Jun 2025 22:08:36 -0600 Subject: [PATCH 07/26] feat(cat-gateway): impl Query for InsertUnstakedTxoAsset --- .../block/txo/insert_unstaked_txo_asset.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs index f9b5f26a5dc3..14d72161a414 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs @@ -1,6 +1,6 @@ //! Insert Unstaked TXO Native Assets into the DB. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, TransactionId, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -8,7 +8,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, settings::cassandra_db, @@ -37,6 +37,22 @@ pub(crate) struct Params { value: num_bigint::BigInt, } +impl fmt::Display for Params { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_UNSTAKED_TXO_ASSET_QUERY}") + } +} + +impl Query for Params { + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Params::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + impl Params { /// Create a new record for this transaction. /// From ca2468eb224ebaabf37a760a328fe5c17e6b2016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 11:40:06 -0600 Subject: [PATCH 08/26] wip(cat-gateway): cleanup queries for refactoring --- .../bin/src/db/index/block/txo/insert_txo.rs | 10 ++-- .../bin/src/db/index/block/txo/mod.rs | 6 +-- .../bin/src/db/index/queries/mod.rs | 51 ++++++++++--------- .../bin/src/db/index/tests/scylla_purge.rs | 4 +- 4 files changed, 36 insertions(+), 35 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs index 490d67998a70..ab8c88758d12 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs @@ -22,7 +22,7 @@ const INSERT_TXO_QUERY: &str = include_str!("./cql/insert_txo.cql"); /// Insert TXO Query Parameters /// (Superset of data to support both Staked and Unstaked TXO records.) #[derive(SerializeRow, Debug)] -pub(crate) struct Params { +pub(crate) struct TxoInsertQuery { /// Stake Address - Binary 29 bytes. stake_address: DbStakeAddress, /// Block Slot Number @@ -39,23 +39,23 @@ pub(crate) struct Params { txn_hash: DbTransactionId, } -impl fmt::Display for Params { +impl fmt::Display for TxoInsertQuery { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{INSERT_TXO_QUERY}") } } -impl Query for Params { +impl Query for TxoInsertQuery { async fn prepare_query( session: &Arc, cfg: &cassandra_db::EnvVars, ) -> anyhow::Result { - Params::prepare_batch(session, cfg) + TxoInsertQuery::prepare_batch(session, cfg) .await .map(QueryKind::Batch) } } -impl Params { +impl TxoInsertQuery { /// Create a new record for this transaction. pub(crate) fn new( stake_address: StakeAddress, slot_no: Slot, txn_index: TxnIndex, txo: TxnOutputOffset, diff --git a/catalyst-gateway/bin/src/db/index/block/txo/mod.rs b/catalyst-gateway/bin/src/db/index/block/txo/mod.rs index dd7a520447ac..5d5c682526d6 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/mod.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/mod.rs @@ -28,7 +28,7 @@ use crate::{ /// There are multiple possible parameters to a query, which are represented separately. pub(crate) struct TxoInsertQuery { /// Staked TXO Data Parameters - staked_txo: Vec, + staked_txo: Vec, /// Unstaked TXO Data Parameters unstaked_txo: Vec, /// Staked TXO Asset Data Parameters @@ -52,7 +52,7 @@ impl TxoInsertQuery { pub(crate) async fn prepare_batch( session: &Arc, cfg: &cassandra_db::EnvVars, ) -> anyhow::Result<(SizedBatch, SizedBatch, SizedBatch, SizedBatch)> { - let txo_staked_insert_batch = insert_txo::Params::prepare_batch(session, cfg).await; + let txo_staked_insert_batch = insert_txo::TxoInsertQuery::prepare_batch(session, cfg).await; let txo_unstaked_insert_batch = insert_unstaked_txo::Params::prepare_batch(session, cfg).await; let txo_staked_asset_insert_batch = @@ -152,7 +152,7 @@ impl TxoInsertQuery { let txo_index = TxnOutputOffset::from(txo_index); if let Some(stake_address) = stake_address.clone() { - let params = insert_txo::Params::new( + let params = insert_txo::TxoInsertQuery::new( stake_address, slot_no, index, diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 6313333c5a26..f67577fd92af 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -34,8 +34,15 @@ use sync_status::update::SyncStatusInsertQuery; use tracing::error; use super::block::{ - certs::CertInsertQuery, cip36::Cip36InsertQuery, rbac509::Rbac509InsertQuery, - txi::TxiInsertQuery, txo::TxoInsertQuery, + certs::CertInsertQuery, + cip36::Cip36InsertQuery, + rbac509::Rbac509InsertQuery, + txi::TxiInsertQuery, + txo::{ + insert_txo::TxoInsertQuery, insert_txo_asset::Params as TxoAssetInsert, + insert_unstaked_txo::Params as TxoUnstaked, + insert_unstaked_txo_asset::Params as TxoUnstakedAsset, TxoInsertQuery as TxoInsertQueries, + }, }; use crate::{ db::index::{ @@ -215,15 +222,29 @@ impl PreparedQueries { ) -> anyhow::Result { // We initialize like this, so that all errors preparing querys get shown before aborting. let txi_insert_queries = TxiInsertQuery::prepare_batch(&session, cfg).await?; - let all_txo_queries = TxoInsertQuery::prepare_batch(&session, cfg).await; + let ( + txo_insert_queries, + unstaked_txo_insert_queries, + txo_asset_insert_queries, + unstaked_txo_asset_insert_queries, + ) = TxoInsertQueries::prepare_batch(&session, cfg).await?; let stake_registration_insert_queries = CertInsertQuery::prepare_batch(&session, cfg).await?; - let all_cip36_queries = Cip36InsertQuery::prepare_batch(&session, cfg).await; + let ( + cip36_registration_insert_queries, + cip36_registration_error_insert_queries, + cip36_registration_for_vote_key_insert_queries, + ) = Cip36InsertQuery::prepare_batch(&session, cfg).await?; let txo_spent_update_queries = UpdateTxoSpentQuery::prepare_batch(session.clone(), cfg).await?; let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(session.clone()).await; let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(session.clone()).await; - let all_rbac_queries = Rbac509InsertQuery::prepare_batch(&session, cfg).await; + let ( + rbac509_registration_insert_queries, + rbac509_invalid_registration_insert_queries, + catalyst_id_for_txn_id_insert_queries, + catalyst_id_for_stake_address_insert_queries, + ) = Rbac509InsertQuery::prepare_batch(&session, cfg).await?; let native_assets_by_stake_address_query = GetAssetsByStakeAddressQuery::prepare(session.clone()).await; let registration_from_stake_addr_query = @@ -244,26 +265,6 @@ impl PreparedQueries { let rbac_invalid_registrations_by_catalyst_id_query = get_rbac_invalid_registrations::Query::prepare(session.clone()).await?; - let ( - txo_insert_queries, - unstaked_txo_insert_queries, - txo_asset_insert_queries, - unstaked_txo_asset_insert_queries, - ) = all_txo_queries?; - - let ( - cip36_registration_insert_queries, - cip36_registration_error_insert_queries, - cip36_registration_for_vote_key_insert_queries, - ) = all_cip36_queries?; - - let ( - rbac509_registration_insert_queries, - rbac509_invalid_registration_insert_queries, - catalyst_id_for_txn_id_insert_queries, - catalyst_id_for_stake_address_insert_queries, - ) = all_rbac_queries?; - Ok(Self { txo_insert_queries, txo_asset_insert_queries, diff --git a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs index df41225bc348..8631d90e5d4d 100644 --- a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs +++ b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs @@ -674,7 +674,7 @@ async fn test_txo_ada() { // data let data = vec![ - txo::insert_txo::Params::new( + txo::insert_txo::TxoInsertQuery::new( stake_address_1(), 0.into(), 0.into(), @@ -683,7 +683,7 @@ async fn test_txo_ada() { 0, TransactionId::new(&[0]), ), - txo::insert_txo::Params::new( + txo::insert_txo::TxoInsertQuery::new( stake_address_2(), 1.into(), 1.into(), From 877035fb63f693292ef8cd40b4029d92208e8523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 11:40:57 -0600 Subject: [PATCH 09/26] feat(cat-gateway): impl Query for StakeRegistrationInsertQuery --- .../bin/src/db/index/block/certs.rs | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/certs.rs b/catalyst-gateway/bin/src/db/index/block/certs.rs index d29614e8eeef..856c99bc9d89 100644 --- a/catalyst-gateway/bin/src/db/index/block/certs.rs +++ b/catalyst-gateway/bin/src/db/index/block/certs.rs @@ -1,6 +1,6 @@ //! Index certs found in a transaction. -use std::{fmt::Debug, sync::Arc}; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{MultiEraBlock, Slot, StakeAddress, TxnIndex, VKeyHash}; use ed25519_dalek::VerifyingKey; @@ -11,7 +11,9 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{FallibleQueryTasks, PreparedQueries, PreparedQuery, SizedBatch}, + queries::{ + FallibleQueryTasks, PreparedQueries, PreparedQuery, Query, QueryKind, SizedBatch, + }, session::CassandraSession, }, types::{DbPublicKey, DbSlot, DbStakeAddress, DbTxnIndex}, @@ -42,8 +44,19 @@ pub(crate) struct StakeRegistrationInsertQuery { pool_delegation: MaybeUnset>, } -impl Debug for StakeRegistrationInsertQuery { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { +impl Query for StakeRegistrationInsertQuery { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + StakeRegistrationInsertQuery::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + +impl fmt::Debug for StakeRegistrationInsertQuery { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let stake_public_key = hex::encode(self.stake_public_key.as_ref()); let register = match self.register { MaybeUnset::Unset => "UNSET", @@ -79,6 +92,12 @@ impl Debug for StakeRegistrationInsertQuery { /// Insert stake registration const INSERT_STAKE_REGISTRATION_QUERY: &str = include_str!("./cql/insert_stake_registration.cql"); +impl fmt::Display for StakeRegistrationInsertQuery { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_STAKE_REGISTRATION_QUERY}") + } +} + impl StakeRegistrationInsertQuery { /// Create a new Insert Query. #[allow(clippy::too_many_arguments, clippy::fn_params_excessive_bools)] From 64882a47ca77c904552de2f40891c2bb4ce89712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 11:43:49 -0600 Subject: [PATCH 10/26] wip(cat-gateway): draft generic query preparation --- .../bin/src/db/index/queries/mod.rs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index f67577fd92af..e40b6826a260 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -8,7 +8,7 @@ pub(crate) mod registrations; pub(crate) mod staked_ada; pub(crate) mod sync_status; -use std::{fmt::Debug, sync::Arc}; +use std::{any::TypeId, fmt::Debug, sync::Arc}; use anyhow::bail; use dashmap::DashMap; @@ -46,6 +46,7 @@ use super::block::{ }; use crate::{ db::index::{ + block::certs::StakeRegistrationInsertQuery, queries::rbac::{ get_catalyst_id_from_stake_address, get_catalyst_id_from_transaction_id, get_rbac_invalid_registrations, get_rbac_registrations, @@ -214,6 +215,36 @@ pub(crate) type FallibleQueryResults = anyhow::Result>; /// A set of query responses from tasks that can fail. pub(crate) type FallibleQueryTasks = Vec>; +/// Prepare Queries +#[allow(dead_code)] +async fn prepare_queries( + session: &Arc, cfg: &cassandra_db::EnvVars, +) -> anyhow::Result> { + // Prepare a query dashmap + macro_rules! prepare_q { + ( $( $i:ty),* ) => { + { + let queries = vec![ + $( + (TypeId::of::<$i>(), <$i>::prepare_query(session, cfg).await?), + )* + ]; + DashMap::from_iter(queries) + } + } + } + // WIP: Adding queries as they implement trait + let queries = prepare_q!( + TxiInsertQuery, + TxoInsertQuery, + TxoAssetInsert, + TxoUnstaked, + TxoUnstakedAsset, + StakeRegistrationInsertQuery + ); + Ok(queries) +} + impl PreparedQueries { /// Create new prepared queries for a given session. #[allow(clippy::too_many_lines)] From d1f9c2ebeef18043305ea5fbde2b505861f12690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 12:07:12 -0600 Subject: [PATCH 11/26] fix(cat-gateway): remove unused dependency --- catalyst-gateway/bin/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/catalyst-gateway/bin/Cargo.toml b/catalyst-gateway/bin/Cargo.toml index af323c89548b..305e7fc5aada 100644 --- a/catalyst-gateway/bin/Cargo.toml +++ b/catalyst-gateway/bin/Cargo.toml @@ -64,7 +64,6 @@ num-bigint = "0.4.6" futures = "0.3.31" rand = "0.8.5" moka = { version = "0.12.8", features = ["future"] } -crossbeam-skiplist = "0.1.3" poem = { version = "=3.1.6", features = ["embed", "prometheus", "compression"] } poem-openapi = { version = "=5.1.5", features = [ "openapi-explorer", From 2bd7c987e9a00b05a7620186a28902b362507fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 18:04:38 -0600 Subject: [PATCH 12/26] feat(cat-gateway): impl Query for Cip36Insert --- .../src/db/index/block/cip36/insert_cip36.rs | 33 ++++++++++++++----- .../bin/src/db/index/block/cip36/mod.rs | 6 ++-- .../bin/src/db/index/queries/mod.rs | 14 ++++---- .../bin/src/db/index/tests/scylla_purge.rs | 4 +-- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs index 86ab060955b7..882b969d0f3a 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs @@ -1,6 +1,6 @@ //! Insert CIP36 Registration Query -use std::{fmt::Debug, sync::Arc}; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Cip36, Slot, TxnIndex, VotingPubKey}; use scylla::{frame::value::MaybeUnset, SerializeRow, Session}; @@ -8,7 +8,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbTxnIndex}, }, settings::cassandra_db, @@ -19,7 +19,7 @@ const INSERT_CIP36_REGISTRATION_QUERY: &str = include_str!("./cql/insert_cip36.c /// Insert CIP-36 Registration Query Parameters #[derive(SerializeRow, Clone)] -pub(crate) struct Params { +pub(crate) struct Cip36Insert { /// Full Stake Address (not hashed, 32 byte ED25519 Public key). stake_public_key: Vec, /// Nonce value after normalization. @@ -40,13 +40,24 @@ pub(crate) struct Params { cip36: bool, } -impl Debug for Params { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl Query for Cip36Insert { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Self::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + +impl fmt::Debug for Cip36Insert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let payment_address = match self.payment_address { MaybeUnset::Unset => "UNSET", MaybeUnset::Set(ref v) => &hex::encode(v), }; - f.debug_struct("Params") + f.debug_struct("Cip36Insert") .field("stake_public_key", &self.stake_public_key) .field("nonce", &self.nonce) .field("slot_no", &self.slot_no) @@ -60,7 +71,13 @@ impl Debug for Params { } } -impl Params { +impl fmt::Display for Cip36Insert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_CIP36_REGISTRATION_QUERY}") + } +} + +impl Cip36Insert { /// Create a new Insert Query. pub fn new(vote_key: &VotingPubKey, slot_no: Slot, txn_index: TxnIndex, cip36: &Cip36) -> Self { let stake_public_key = cip36 @@ -73,7 +90,7 @@ impl Params { .payment_address() .map_or(MaybeUnset::Unset, |a| MaybeUnset::Set(a.to_vec())); let is_cip36 = cip36.is_cip36().unwrap_or_default(); - Params { + Cip36Insert { stake_public_key, nonce: cip36.nonce().unwrap_or_default().into(), slot_no: slot_no.into(), diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs b/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs index eaed97ab8fb0..9f741114f897 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs @@ -22,7 +22,7 @@ use crate::{ /// Insert CIP-36 Registration Queries pub(crate) struct Cip36InsertQuery { /// Stake Registration Data captured during indexing. - registrations: Vec, + registrations: Vec, /// Stake Registration Data captured during indexing. invalid: Vec, /// Stake Registration Data captured during indexing. @@ -46,7 +46,7 @@ impl Cip36InsertQuery { pub(crate) async fn prepare_batch( session: &Arc, cfg: &cassandra_db::EnvVars, ) -> anyhow::Result<(SizedBatch, SizedBatch, SizedBatch)> { - let insert_cip36_batch = insert_cip36::Params::prepare_batch(session, cfg).await; + let insert_cip36_batch = insert_cip36::Cip36Insert::prepare_batch(session, cfg).await; let insert_cip36_invalid_batch = insert_cip36_invalid::Params::prepare_batch(session, cfg).await; let insert_cip36_for_vote_key_addr_batch = @@ -82,7 +82,7 @@ impl Cip36InsertQuery { let stake_pk_hash = Blake2b224Hash::new(&stake_pk.to_bytes()); let stake_address = StakeAddress::new(block.network(), false, stake_pk_hash); - self.registrations.push(insert_cip36::Params::new( + self.registrations.push(insert_cip36::Cip36Insert::new( voting_key, slot_no, index, &cip36, )); self.for_vote_key diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index e40b6826a260..dbf1bc7998ea 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -40,13 +40,14 @@ use super::block::{ txi::TxiInsertQuery, txo::{ insert_txo::TxoInsertQuery, insert_txo_asset::Params as TxoAssetInsert, - insert_unstaked_txo::Params as TxoUnstaked, - insert_unstaked_txo_asset::Params as TxoUnstakedAsset, TxoInsertQuery as TxoInsertQueries, + insert_unstaked_txo::Params as TxoUnstakedInsert, + insert_unstaked_txo_asset::Params as TxoUnstakedAssetInsert, + TxoInsertQuery as TxoInsertQueries, }, }; use crate::{ db::index::{ - block::certs::StakeRegistrationInsertQuery, + block::{certs::StakeRegistrationInsertQuery, cip36::insert_cip36::Cip36Insert}, queries::rbac::{ get_catalyst_id_from_stake_address, get_catalyst_id_from_transaction_id, get_rbac_invalid_registrations, get_rbac_registrations, @@ -238,9 +239,10 @@ async fn prepare_queries( TxiInsertQuery, TxoInsertQuery, TxoAssetInsert, - TxoUnstaked, - TxoUnstakedAsset, - StakeRegistrationInsertQuery + TxoUnstakedInsert, + TxoUnstakedAssetInsert, + StakeRegistrationInsertQuery, + Cip36Insert ); Ok(queries) } diff --git a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs index 8631d90e5d4d..93511aa99a3f 100644 --- a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs +++ b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs @@ -460,13 +460,13 @@ async fn test_cip36_registration() { // data let data = vec![ - cip36::insert_cip36::Params::new( + cip36::insert_cip36::Cip36Insert::new( &voting_pub_key(0), 0.into(), 0.into(), &test_utils::cip_36_1(), ), - cip36::insert_cip36::Params::new( + cip36::insert_cip36::Cip36Insert::new( &voting_pub_key(1), 1.into(), 1.into(), From 5d6aa3de23ee7f60945b0eb054f430fe79d35ee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 18:37:42 -0600 Subject: [PATCH 13/26] feat(cat-gateway): impl Query for Cip36InvalidInsert --- .../index/block/cip36/insert_cip36_invalid.rs | 33 ++++++++++++++----- .../bin/src/db/index/block/cip36/mod.rs | 24 +++++++------- .../bin/src/db/index/queries/mod.rs | 8 +++-- .../bin/src/db/index/tests/scylla_purge.rs | 4 +-- 4 files changed, 46 insertions(+), 23 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs index c14dc31d100b..cbfde3204ba4 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs @@ -1,6 +1,6 @@ //! Insert CIP36 Registration Query (Invalid Records) -use std::{fmt::Debug, sync::Arc}; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Cip36, Slot, TxnIndex, VotingPubKey}; use pallas::ledger::addresses::Address; @@ -9,7 +9,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbTxnIndex}, }, settings::cassandra_db, @@ -21,7 +21,7 @@ const INSERT_CIP36_REGISTRATION_INVALID_QUERY: &str = /// Insert CIP-36 Registration Invalid Query Parameters #[derive(SerializeRow, Clone)] -pub(crate) struct Params { +pub(crate) struct Cip36InvalidInsert { /// Full Stake Address (not hashed, 32 byte ED25519 Public key). stake_public_key: Vec, /// Slot Number the cert is in. @@ -46,13 +46,24 @@ pub(crate) struct Params { problem_report: String, } -impl Debug for Params { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl Query for Cip36InvalidInsert { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Self::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + +impl fmt::Debug for Cip36InvalidInsert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let cip36 = match self.cip36 { MaybeUnset::Unset => "UNSET", MaybeUnset::Set(v) => &format!("{v:?}"), }; - f.debug_struct("Params") + f.debug_struct("Cip36InvalidInsert") .field("stake_public_key", &self.stake_public_key) .field("slot_no", &self.slot_no) .field("txn_index", &self.txn_index) @@ -68,7 +79,13 @@ impl Debug for Params { } } -impl Params { +impl fmt::Display for Cip36InvalidInsert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_CIP36_REGISTRATION_INVALID_QUERY}") + } +} + +impl Cip36InvalidInsert { /// Create a new Insert Query. pub fn new( vote_key: Option<&VotingPubKey>, slot_no: Slot, txn_index: TxnIndex, cip36: &Cip36, @@ -89,7 +106,7 @@ impl Params { String::new() }); - Params { + Cip36InvalidInsert { stake_public_key, slot_no: slot_no.into(), txn_index: txn_index.into(), diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs b/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs index 9f741114f897..8867c1438381 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs @@ -24,7 +24,7 @@ pub(crate) struct Cip36InsertQuery { /// Stake Registration Data captured during indexing. registrations: Vec, /// Stake Registration Data captured during indexing. - invalid: Vec, + invalid: Vec, /// Stake Registration Data captured during indexing. for_vote_key: Vec, /// Stake Registration Data captured during indexing. @@ -48,7 +48,7 @@ impl Cip36InsertQuery { ) -> anyhow::Result<(SizedBatch, SizedBatch, SizedBatch)> { let insert_cip36_batch = insert_cip36::Cip36Insert::prepare_batch(session, cfg).await; let insert_cip36_invalid_batch = - insert_cip36_invalid::Params::prepare_batch(session, cfg).await; + insert_cip36_invalid::Cip36InvalidInsert::prepare_batch(session, cfg).await; let insert_cip36_for_vote_key_addr_batch = insert_cip36_for_vote_key::Params::prepare_batch(session, cfg).await; // Its a hack of inserting `stake_regs` during the indexing CIP 36 registrations. @@ -107,17 +107,19 @@ impl Cip36InsertQuery { // Cannot index an invalid CIP36, if there is no stake public key. if let Some(stake_pk) = cip36.stake_pk() { if cip36.voting_pks().is_empty() { - self.invalid.push(insert_cip36_invalid::Params::new( - None, slot_no, index, &cip36, - )); + self.invalid + .push(insert_cip36_invalid::Cip36InvalidInsert::new( + None, slot_no, index, &cip36, + )); } else { for voting_key in cip36.voting_pks() { - self.invalid.push(insert_cip36_invalid::Params::new( - Some(voting_key), - slot_no, - index, - &cip36, - )); + self.invalid + .push(insert_cip36_invalid::Cip36InvalidInsert::new( + Some(voting_key), + slot_no, + index, + &cip36, + )); self.for_vote_key .push(insert_cip36_for_vote_key::Params::new( voting_key, slot_no, index, &cip36, false, diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index dbf1bc7998ea..fb9edb7be123 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -47,7 +47,10 @@ use super::block::{ }; use crate::{ db::index::{ - block::{certs::StakeRegistrationInsertQuery, cip36::insert_cip36::Cip36Insert}, + block::{ + certs::StakeRegistrationInsertQuery, + cip36::{insert_cip36::Cip36Insert, insert_cip36_invalid::Cip36InvalidInsert}, + }, queries::rbac::{ get_catalyst_id_from_stake_address, get_catalyst_id_from_transaction_id, get_rbac_invalid_registrations, get_rbac_registrations, @@ -242,7 +245,8 @@ async fn prepare_queries( TxoUnstakedInsert, TxoUnstakedAssetInsert, StakeRegistrationInsertQuery, - Cip36Insert + Cip36Insert, + Cip36InvalidInsert ); Ok(queries) } diff --git a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs index 93511aa99a3f..0d50f7753515 100644 --- a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs +++ b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs @@ -392,13 +392,13 @@ async fn test_cip36_registration_invalid() { // data let data = vec![ - cip36::insert_cip36_invalid::Params::new( + cip36::insert_cip36_invalid::Cip36InvalidInsert::new( Some(&voting_pub_key(0)), 0.into(), 0.into(), &test_utils::cip_36_1(), ), - cip36::insert_cip36_invalid::Params::new( + cip36::insert_cip36_invalid::Cip36InvalidInsert::new( Some(&voting_pub_key(1)), 1.into(), 1.into(), From b7122eb72e982a238d99e007138b2535ec483c08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 18:43:00 -0600 Subject: [PATCH 14/26] feat(cat-gateway): impl Query for Cip36ForVoteKeyInsert --- .../block/cip36/insert_cip36_for_vote_key.rs | 27 +++++++++++++++---- .../bin/src/db/index/block/cip36/mod.rs | 13 ++++----- .../bin/src/db/index/queries/mod.rs | 8 ++++-- .../bin/src/db/index/tests/scylla_purge.rs | 4 +-- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs index 2c80e8e3c2ba..718d142d1bf5 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs @@ -1,6 +1,6 @@ //! Insert CIP36 Registration Query -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Cip36, Slot, TxnIndex, VotingPubKey}; use scylla::{SerializeRow, Session}; @@ -8,7 +8,7 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, SizedBatch}, + index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, types::{DbSlot, DbTxnIndex}, }, settings::cassandra_db, @@ -20,7 +20,7 @@ const INSERT_CIP36_REGISTRATION_FOR_VOTE_KEY_QUERY: &str = /// Insert CIP-36 Registration Invalid Query Parameters #[derive(SerializeRow, Debug)] -pub(crate) struct Params { +pub(crate) struct Cip36ForVoteKeyInsert { /// Voting Public Key vote_key: Vec, /// Full Stake Address (not hashed, 32 byte ED25519 Public key). @@ -33,12 +33,29 @@ pub(crate) struct Params { valid: bool, } -impl Params { +impl Query for Cip36ForVoteKeyInsert { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Self::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + +impl fmt::Display for Cip36ForVoteKeyInsert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{INSERT_CIP36_REGISTRATION_FOR_VOTE_KEY_QUERY}") + } +} + +impl Cip36ForVoteKeyInsert { /// Create a new Insert Query. pub fn new( vote_key: &VotingPubKey, slot_no: Slot, txn_index: TxnIndex, cip36: &Cip36, valid: bool, ) -> Self { - Params { + Cip36ForVoteKeyInsert { vote_key: vote_key .voting_pk() .map(|k| k.to_bytes().to_vec()) diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs b/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs index 8867c1438381..dadb14a0e1b2 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/mod.rs @@ -26,7 +26,7 @@ pub(crate) struct Cip36InsertQuery { /// Stake Registration Data captured during indexing. invalid: Vec, /// Stake Registration Data captured during indexing. - for_vote_key: Vec, + for_vote_key: Vec, /// Stake Registration Data captured during indexing. stake_regs: Vec, } @@ -50,7 +50,7 @@ impl Cip36InsertQuery { let insert_cip36_invalid_batch = insert_cip36_invalid::Cip36InvalidInsert::prepare_batch(session, cfg).await; let insert_cip36_for_vote_key_addr_batch = - insert_cip36_for_vote_key::Params::prepare_batch(session, cfg).await; + insert_cip36_for_vote_key::Cip36ForVoteKeyInsert::prepare_batch(session, cfg).await; // Its a hack of inserting `stake_regs` during the indexing CIP 36 registrations. // Its done because some of the CIP 36 registrations contains some stake addresses which // are not actually some how registered using cardano certs. @@ -86,7 +86,7 @@ impl Cip36InsertQuery { voting_key, slot_no, index, &cip36, )); self.for_vote_key - .push(insert_cip36_for_vote_key::Params::new( + .push(insert_cip36_for_vote_key::Cip36ForVoteKeyInsert::new( voting_key, slot_no, index, &cip36, true, )); self.stake_regs @@ -120,10 +120,11 @@ impl Cip36InsertQuery { index, &cip36, )); - self.for_vote_key - .push(insert_cip36_for_vote_key::Params::new( + self.for_vote_key.push( + insert_cip36_for_vote_key::Cip36ForVoteKeyInsert::new( voting_key, slot_no, index, &cip36, false, - )); + ), + ); } } diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index fb9edb7be123..4f15efd33cd9 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -49,7 +49,10 @@ use crate::{ db::index::{ block::{ certs::StakeRegistrationInsertQuery, - cip36::{insert_cip36::Cip36Insert, insert_cip36_invalid::Cip36InvalidInsert}, + cip36::{ + insert_cip36::Cip36Insert, insert_cip36_for_vote_key::Cip36ForVoteKeyInsert, + insert_cip36_invalid::Cip36InvalidInsert, + }, }, queries::rbac::{ get_catalyst_id_from_stake_address, get_catalyst_id_from_transaction_id, @@ -246,7 +249,8 @@ async fn prepare_queries( TxoUnstakedAssetInsert, StakeRegistrationInsertQuery, Cip36Insert, - Cip36InvalidInsert + Cip36InvalidInsert, + Cip36ForVoteKeyInsert ); Ok(queries) } diff --git a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs index 0d50f7753515..f02ddbc7ca90 100644 --- a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs +++ b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs @@ -321,14 +321,14 @@ async fn test_cip36_registration_for_vote_key() { // data let data = vec![ - cip36::insert_cip36_for_vote_key::Params::new( + cip36::insert_cip36_for_vote_key::Cip36ForVoteKeyInsert::new( &voting_pub_key(0), 0.into(), 0.into(), &test_utils::cip_36_1(), false, ), - cip36::insert_cip36_for_vote_key::Params::new( + cip36::insert_cip36_for_vote_key::Cip36ForVoteKeyInsert::new( &voting_pub_key(1), 1.into(), 1.into(), From 1408c2d775710a2126bdd743b9f3b7b506671a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 18:48:39 -0600 Subject: [PATCH 15/26] feat(cat-gateway): impl Query for UpdateTxoSpentQuery --- .../bin/src/db/index/queries/mod.rs | 6 ++--- .../queries/staked_ada/update_txo_spent.rs | 25 ++++++++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 4f15efd33cd9..30d0b85826a3 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -250,7 +250,8 @@ async fn prepare_queries( StakeRegistrationInsertQuery, Cip36Insert, Cip36InvalidInsert, - Cip36ForVoteKeyInsert + Cip36ForVoteKeyInsert, + UpdateTxoSpentQuery ); Ok(queries) } @@ -276,8 +277,7 @@ impl PreparedQueries { cip36_registration_error_insert_queries, cip36_registration_for_vote_key_insert_queries, ) = Cip36InsertQuery::prepare_batch(&session, cfg).await?; - let txo_spent_update_queries = - UpdateTxoSpentQuery::prepare_batch(session.clone(), cfg).await?; + let txo_spent_update_queries = UpdateTxoSpentQuery::prepare_batch(&session, cfg).await?; let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(session.clone()).await; let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(session.clone()).await; let ( diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs index d069d758a496..856963cfe954 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs @@ -1,6 +1,6 @@ //! Update the TXO Spent column to optimize future queries. -use std::sync::Arc; +use std::{fmt, sync::Arc}; use scylla::{SerializeRow, Session}; use tracing::error; @@ -8,7 +8,9 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{FallibleQueryResults, PreparedQueries, PreparedQuery, SizedBatch}, + queries::{ + FallibleQueryResults, PreparedQueries, PreparedQuery, Query, QueryKind, SizedBatch, + }, session::CassandraSession, }, types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, @@ -37,10 +39,27 @@ pub(crate) struct UpdateTxoSpentQueryParams { /// Update TXO spent query. pub(crate) struct UpdateTxoSpentQuery; +impl Query for UpdateTxoSpentQuery { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Self::prepare_batch(session, cfg) + .await + .map(QueryKind::Batch) + } +} + +impl fmt::Display for UpdateTxoSpentQuery { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{UPDATE_TXO_SPENT_QUERY}") + } +} + impl UpdateTxoSpentQuery { /// Prepare a batch of update TXO spent queries. pub(crate) async fn prepare_batch( - session: Arc, cfg: &cassandra_db::EnvVars, + session: &Arc, cfg: &cassandra_db::EnvVars, ) -> anyhow::Result { PreparedQueries::prepare_batch( session.clone(), From bdf3bb32e5752c6cda49c22222ef10cb7bd5c3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 20:28:45 -0600 Subject: [PATCH 16/26] feat(cat-gateway): impl Query for GetTxiByTxnHashesQuery --- .../bin/src/db/index/queries/mod.rs | 14 ++++++-- .../queries/staked_ada/get_txi_by_txn_hash.rs | 34 ++++++++++++++----- .../staked_ada/get_txo_by_stake_address.rs | 34 ++++++++++++++----- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 30d0b85826a3..e12731c265df 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -242,6 +242,7 @@ async fn prepare_queries( } // WIP: Adding queries as they implement trait let queries = prepare_q!( + // prepared batch queries TxiInsertQuery, TxoInsertQuery, TxoAssetInsert, @@ -251,7 +252,10 @@ async fn prepare_queries( Cip36Insert, Cip36InvalidInsert, Cip36ForVoteKeyInsert, - UpdateTxoSpentQuery + // prepared statement queries + UpdateTxoSpentQuery, + GetTxoByStakeAddressQuery, + GetTxiByTxnHashesQuery ); Ok(queries) } @@ -263,6 +267,8 @@ impl PreparedQueries { session: Arc, cfg: &cassandra_db::EnvVars, ) -> anyhow::Result { // We initialize like this, so that all errors preparing querys get shown before aborting. + + // Prepared batched queries let txi_insert_queries = TxiInsertQuery::prepare_batch(&session, cfg).await?; let ( txo_insert_queries, @@ -278,14 +284,16 @@ impl PreparedQueries { cip36_registration_for_vote_key_insert_queries, ) = Cip36InsertQuery::prepare_batch(&session, cfg).await?; let txo_spent_update_queries = UpdateTxoSpentQuery::prepare_batch(&session, cfg).await?; - let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(session.clone()).await; - let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(session.clone()).await; let ( rbac509_registration_insert_queries, rbac509_invalid_registration_insert_queries, catalyst_id_for_txn_id_insert_queries, catalyst_id_for_stake_address_insert_queries, ) = Rbac509InsertQuery::prepare_batch(&session, cfg).await?; + + // Prepared Statement queries + let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(&session).await; + let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(&session).await; let native_assets_by_stake_address_query = GetAssetsByStakeAddressQuery::prepare(session.clone()).await; let registration_from_stake_addr_query = diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs index bc7fc86b18f7..8eb739538971 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs @@ -1,6 +1,6 @@ //! Get TXI by Transaction hash query -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::TransactionId; use scylla::{ @@ -9,12 +9,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery, Query, QueryKind}, + session::CassandraSession, + }, + types::{DbSlot, DbTransactionId, DbTxnOutputOffset}, }, - types::{DbSlot, DbTransactionId, DbTxnOutputOffset}, + settings::cassandra_db, }; /// Get TXI query string. @@ -46,11 +49,26 @@ pub(crate) struct GetTxiByTxnHashesQuery { pub slot_no: DbSlot, } +impl Query for GetTxiByTxnHashesQuery { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, _cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Self::prepare(session).await.map(QueryKind::Statement) + } +} + +impl fmt::Display for GetTxiByTxnHashesQuery { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{GET_TXI_BY_TXN_HASHES_QUERY}") + } +} + impl GetTxiByTxnHashesQuery { /// Prepares a get txi query. - pub(crate) async fn prepare(session: Arc) -> anyhow::Result { + pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { PreparedQueries::prepare( - session, + session.clone(), GET_TXI_BY_TXN_HASHES_QUERY, scylla::statement::Consistency::All, true, diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs index dd2cfbe21096..d5d142d4255c 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs @@ -1,5 +1,5 @@ //! Get the TXO by Stake Address -use std::sync::Arc; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, StakeAddress}; use scylla::{ @@ -8,12 +8,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery, Query, QueryKind}, + session::CassandraSession, + }, + types::{DbSlot, DbStakeAddress, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, - types::{DbSlot, DbStakeAddress, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, + settings::cassandra_db, }; /// Get txo by stake address query string. @@ -55,11 +58,26 @@ pub(crate) struct GetTxoByStakeAddressQuery { pub spent_slot: Option, } +impl Query for GetTxoByStakeAddressQuery { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &Arc, _cfg: &cassandra_db::EnvVars, + ) -> anyhow::Result { + Self::prepare(session).await.map(QueryKind::Statement) + } +} + +impl fmt::Display for GetTxoByStakeAddressQuery { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{GET_TXO_BY_STAKE_ADDRESS_QUERY}") + } +} + impl GetTxoByStakeAddressQuery { /// Prepares a get txo by stake address query. - pub(crate) async fn prepare(session: Arc) -> anyhow::Result { + pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { PreparedQueries::prepare( - session, + session.clone(), GET_TXO_BY_STAKE_ADDRESS_QUERY, scylla::statement::Consistency::All, true, From 029071dee6af0cd1c62ee7c81b73f45a34bc44a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 21:31:39 -0600 Subject: [PATCH 17/26] feat(cat-gateway): add macros to implement Query trait --- .../bin/src/db/index/queries/mod.rs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index e12731c265df..2465af20468a 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -86,6 +86,54 @@ pub(crate) trait Query { ) -> anyhow::Result; } +/// Implement Query trait for batched types +#[macro_export] +macro_rules! impl_query_batch { + ($i:ty, $c:ident) => { + impl $crate::db::index::queries::Query for $i { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &std::sync::Arc, + cfg: &$crate::settings::cassandra_db::EnvVars, + ) -> anyhow::Result<$crate::db::index::queries::QueryKind> { + Self::prepare_batch(session, cfg) + .await + .map($crate::db::index::queries::QueryKind::Batch) + } + } + + impl std::fmt::Display for $i { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{{$c}}") + } + } + }; +} + +/// Implement Query trait for statement types +#[macro_export] +macro_rules! impl_query_statement { + ($i:ty, $c:ident) => { + impl $crate::db::index::queries::Query for $i { + /// Prepare Batch of Insert TXI Index Data Queries + async fn prepare_query( + session: &std::sync::Arc, + _: &$crate::settings::cassandra_db::EnvVars, + ) -> anyhow::Result<$crate::db::index::queries::QueryKind> { + Self::prepare(session) + .await + .map($crate::db::index::queries::QueryKind::Statement) + } + } + + impl std::fmt::Display for $i { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{{$c}}") + } + } + }; +} + /// All Prepared insert Queries that we know about. #[derive(strum_macros::Display)] #[allow(clippy::enum_variant_names)] From 4f151a0bf56b39c8e42fb0870e3508f0cdddee4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 22:16:26 -0600 Subject: [PATCH 18/26] wip(cat-gateway): implement query trait for batched queries --- .../bin/src/db/index/block/certs.rs | 25 +++------ .../src/db/index/block/cip36/insert_cip36.rs | 20 ++------ .../block/cip36/insert_cip36_for_vote_key.rs | 25 +++------ .../index/block/cip36/insert_cip36_invalid.rs | 20 ++------ .../insert_catalyst_id_for_stake_address.rs | 13 +++-- .../rbac509/insert_catalyst_id_for_txn_id.rs | 13 +++-- .../db/index/block/rbac509/insert_rbac509.rs | 15 +++--- .../block/rbac509/insert_rbac509_invalid.rs | 15 +++--- .../bin/src/db/index/block/rbac509/mod.rs | 51 +++++++++++-------- .../bin/src/db/index/block/txi.rs | 24 ++------- .../bin/src/db/index/block/txo/insert_txo.rs | 21 ++------ .../db/index/block/txo/insert_txo_asset.rs | 21 ++------ .../db/index/block/txo/insert_unstaked_txo.rs | 21 ++------ .../block/txo/insert_unstaked_txo_asset.rs | 21 ++------ .../bin/src/db/index/queries/mod.rs | 11 +++- .../staked_ada/get_txo_by_stake_address.rs | 21 ++------ .../bin/src/db/index/tests/scylla_purge.rs | 16 +++--- 17 files changed, 124 insertions(+), 229 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/certs.rs b/catalyst-gateway/bin/src/db/index/block/certs.rs index 856c99bc9d89..57a5852ee42a 100644 --- a/catalyst-gateway/bin/src/db/index/block/certs.rs +++ b/catalyst-gateway/bin/src/db/index/block/certs.rs @@ -11,13 +11,12 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{ - FallibleQueryTasks, PreparedQueries, PreparedQuery, Query, QueryKind, SizedBatch, - }, + queries::{FallibleQueryTasks, PreparedQueries, PreparedQuery, SizedBatch}, session::CassandraSession, }, types::{DbPublicKey, DbSlot, DbStakeAddress, DbTxnIndex}, }, + impl_query_batch, settings::cassandra_db, }; @@ -44,17 +43,6 @@ pub(crate) struct StakeRegistrationInsertQuery { pool_delegation: MaybeUnset>, } -impl Query for StakeRegistrationInsertQuery { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - StakeRegistrationInsertQuery::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} - impl fmt::Debug for StakeRegistrationInsertQuery { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let stake_public_key = hex::encode(self.stake_public_key.as_ref()); @@ -92,11 +80,10 @@ impl fmt::Debug for StakeRegistrationInsertQuery { /// Insert stake registration const INSERT_STAKE_REGISTRATION_QUERY: &str = include_str!("./cql/insert_stake_registration.cql"); -impl fmt::Display for StakeRegistrationInsertQuery { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_STAKE_REGISTRATION_QUERY}") - } -} +impl_query_batch!( + StakeRegistrationInsertQuery, + INSERT_STAKE_REGISTRATION_QUERY +); impl StakeRegistrationInsertQuery { /// Create a new Insert Query. diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs index 882b969d0f3a..7d94df57c162 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36.rs @@ -8,9 +8,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbTxnIndex}, }, + impl_query_batch, settings::cassandra_db, }; @@ -40,16 +41,7 @@ pub(crate) struct Cip36Insert { cip36: bool, } -impl Query for Cip36Insert { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Self::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} +impl_query_batch!(Cip36Insert, INSERT_CIP36_REGISTRATION_QUERY); impl fmt::Debug for Cip36Insert { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -71,12 +63,6 @@ impl fmt::Debug for Cip36Insert { } } -impl fmt::Display for Cip36Insert { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_CIP36_REGISTRATION_QUERY}") - } -} - impl Cip36Insert { /// Create a new Insert Query. pub fn new(vote_key: &VotingPubKey, slot_no: Slot, txn_index: TxnIndex, cip36: &Cip36) -> Self { diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs index 718d142d1bf5..a706f5270a7a 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_for_vote_key.rs @@ -1,6 +1,6 @@ //! Insert CIP36 Registration Query -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Cip36, Slot, TxnIndex, VotingPubKey}; use scylla::{SerializeRow, Session}; @@ -8,9 +8,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbTxnIndex}, }, + impl_query_batch, settings::cassandra_db, }; @@ -33,22 +34,10 @@ pub(crate) struct Cip36ForVoteKeyInsert { valid: bool, } -impl Query for Cip36ForVoteKeyInsert { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Self::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} - -impl fmt::Display for Cip36ForVoteKeyInsert { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_CIP36_REGISTRATION_FOR_VOTE_KEY_QUERY}") - } -} +impl_query_batch!( + Cip36ForVoteKeyInsert, + INSERT_CIP36_REGISTRATION_FOR_VOTE_KEY_QUERY +); impl Cip36ForVoteKeyInsert { /// Create a new Insert Query. diff --git a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs index cbfde3204ba4..ed949029d4b1 100644 --- a/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs +++ b/catalyst-gateway/bin/src/db/index/block/cip36/insert_cip36_invalid.rs @@ -9,9 +9,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbTxnIndex}, }, + impl_query_batch, settings::cassandra_db, }; @@ -46,16 +47,7 @@ pub(crate) struct Cip36InvalidInsert { problem_report: String, } -impl Query for Cip36InvalidInsert { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Self::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} +impl_query_batch!(Cip36InvalidInsert, INSERT_CIP36_REGISTRATION_INVALID_QUERY); impl fmt::Debug for Cip36InvalidInsert { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -79,12 +71,6 @@ impl fmt::Debug for Cip36InvalidInsert { } } -impl fmt::Display for Cip36InvalidInsert { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_CIP36_REGISTRATION_INVALID_QUERY}") - } -} - impl Cip36InvalidInsert { /// Create a new Insert Query. pub fn new( diff --git a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_stake_address.rs b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_stake_address.rs index c98e6bd091d6..f48d730625f4 100644 --- a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_stake_address.rs @@ -12,6 +12,7 @@ use crate::{ index::queries::{PreparedQueries, SizedBatch}, types::{DbCatalystId, DbSlot, DbStakeAddress}, }, + impl_query_batch, settings::cassandra_db::EnvVars, }; @@ -20,7 +21,7 @@ const QUERY: &str = include_str!("cql/insert_catalyst_id_for_stake_address.cql") /// Insert Catalyst ID For Stake Address Query Parameters #[derive(SerializeRow)] -pub(crate) struct Params { +pub(crate) struct CatalystIdForStakeAddressInsert { /// A stake address. stake_address: DbStakeAddress, /// A Catalyst short identifier. @@ -29,9 +30,11 @@ pub(crate) struct Params { slot_no: DbSlot, } -impl Debug for Params { +impl_query_batch!(CatalystIdForStakeAddressInsert, QUERY); + +impl Debug for CatalystIdForStakeAddressInsert { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Params") + f.debug_struct("CatalystIdForStakeAddressInsert") .field("stake_address", &self.stake_address) .field("catalyst_id", &self.catalyst_id) .field("slot_no", &self.slot_no) @@ -39,10 +42,10 @@ impl Debug for Params { } } -impl Params { +impl CatalystIdForStakeAddressInsert { /// Create a new record for this transaction. pub(crate) fn new(stake_address: StakeAddress, slot_no: Slot, catalyst_id: CatalystId) -> Self { - Params { + CatalystIdForStakeAddressInsert { stake_address: stake_address.into(), catalyst_id: catalyst_id.into(), slot_no: slot_no.into(), diff --git a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_txn_id.rs b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_txn_id.rs index 2e72fa1c069d..fd2f024d3563 100644 --- a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_txn_id.rs +++ b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_catalyst_id_for_txn_id.rs @@ -12,6 +12,7 @@ use crate::{ index::queries::{PreparedQueries, SizedBatch}, types::{DbCatalystId, DbTransactionId}, }, + impl_query_batch, settings::cassandra_db::EnvVars, }; @@ -20,26 +21,28 @@ const QUERY: &str = include_str!("cql/insert_catalyst_id_for_txn_id.cql"); /// Insert Catalyst ID For Transaction ID Query Parameters #[derive(SerializeRow)] -pub(crate) struct Params { +pub(crate) struct CatalystIdForTxnIdInsert { /// A transaction hash. txn_id: DbTransactionId, /// A Catalyst short identifier. catalyst_id: DbCatalystId, } -impl Debug for Params { +impl_query_batch!(CatalystIdForTxnIdInsert, QUERY); + +impl Debug for CatalystIdForTxnIdInsert { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Params") + f.debug_struct("CatalystIdForTxnIdInsert") .field("txn_id", &self.txn_id) .field("catalyst_id", &self.catalyst_id) .finish() } } -impl Params { +impl CatalystIdForTxnIdInsert { /// Creates a new record for this transaction. pub(crate) fn new(catalyst_id: CatalystId, txn_id: TransactionId) -> Self { - Params { + CatalystIdForTxnIdInsert { txn_id: txn_id.into(), catalyst_id: catalyst_id.into(), } diff --git a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509.rs b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509.rs index cbeb184d5a0e..dfe88d90effa 100644 --- a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509.rs +++ b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509.rs @@ -1,6 +1,6 @@ //! Insert RBAC 509 Registration Query. -use std::{fmt::Debug, sync::Arc}; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, TransactionId, TxnIndex}; use catalyst_types::{catalyst_id::CatalystId, uuid::UuidV4}; @@ -12,6 +12,7 @@ use crate::{ index::queries::{PreparedQueries, SizedBatch}, types::{DbCatalystId, DbSlot, DbTransactionId, DbTxnIndex, DbUuidV4}, }, + impl_query_batch, settings::cassandra_db::EnvVars, }; @@ -20,7 +21,7 @@ const QUERY: &str = include_str!("cql/insert_rbac509.cql"); /// Insert RBAC Registration Query Parameters #[derive(SerializeRow)] -pub(crate) struct Params { +pub(crate) struct Rbac509Insert { /// A Catalyst short identifier. catalyst_id: DbCatalystId, /// A transaction hash @@ -35,13 +36,15 @@ pub(crate) struct Params { purpose: DbUuidV4, } -impl Debug for Params { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl_query_batch!(Rbac509Insert, QUERY); + +impl fmt::Debug for Rbac509Insert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let prv_txn_id = match self.prv_txn_id { MaybeUnset::Unset => "UNSET".to_owned(), MaybeUnset::Set(ref v) => format!("{v:?}"), }; - f.debug_struct("Params") + f.debug_struct("Rbac509Insert") .field("catalyst_id", &self.catalyst_id) .field("txn_id", &self.txn_id) .field("slot_no", &self.slot_no) @@ -52,7 +55,7 @@ impl Debug for Params { } } -impl Params { +impl Rbac509Insert { /// Create a new record for this transaction. pub(crate) fn new( catalyst_id: CatalystId, txn_id: TransactionId, slot_no: Slot, txn_index: TxnIndex, diff --git a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509_invalid.rs b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509_invalid.rs index 98d354968f49..fcac1d034be6 100644 --- a/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509_invalid.rs +++ b/catalyst-gateway/bin/src/db/index/block/rbac509/insert_rbac509_invalid.rs @@ -1,6 +1,6 @@ //! Insert invalid RBAC 509 Registration Query. -use std::{fmt::Debug, sync::Arc}; +use std::{fmt, sync::Arc}; use cardano_blockchain_types::{Slot, TransactionId, TxnIndex}; use catalyst_types::{catalyst_id::CatalystId, problem_report::ProblemReport, uuid::UuidV4}; @@ -12,6 +12,7 @@ use crate::{ index::queries::{PreparedQueries, SizedBatch}, types::{DbCatalystId, DbSlot, DbTransactionId, DbTxnIndex, DbUuidV4}, }, + impl_query_batch, settings::cassandra_db::EnvVars, }; @@ -20,7 +21,7 @@ const QUERY: &str = include_str!("cql/insert_rbac509_invalid.cql"); /// Insert an invalid RBAC registration query parameters. #[derive(SerializeRow)] -pub(crate) struct Params { +pub(crate) struct Rbac509InvalidInsert { /// A Catalyst short identifier. catalyst_id: DbCatalystId, /// A transaction hash of this registration. @@ -37,7 +38,9 @@ pub(crate) struct Params { problem_report: String, } -impl Params { +impl_query_batch!(Rbac509InvalidInsert, QUERY); + +impl Rbac509InvalidInsert { /// Create a new record for this transaction. pub(crate) fn new( catalyst_id: CatalystId, txn_id: TransactionId, slot_no: Slot, txn_index: TxnIndex, @@ -81,8 +84,8 @@ impl Params { } } -impl Debug for Params { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl fmt::Debug for Rbac509InvalidInsert { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let prv_txn_id = match self.prv_txn_id { MaybeUnset::Unset => "UNSET".to_owned(), MaybeUnset::Set(v) => format!("{v}"), @@ -91,7 +94,7 @@ impl Debug for Params { MaybeUnset::Unset => "UNSET".to_owned(), MaybeUnset::Set(v) => format!("{}", UuidV4::from(v)), }; - f.debug_struct("Params") + f.debug_struct("Rbac509InvalidInsert") .field("catalyst_id", &self.catalyst_id) .field("txn_id", &self.txn_id) .field("slot_no", &self.slot_no) diff --git a/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs b/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs index e75fd16309d3..83720e12a41a 100644 --- a/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs +++ b/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs @@ -29,13 +29,14 @@ use crate::{ #[derive(Debug)] pub(crate) struct Rbac509InsertQuery { /// RBAC Registration Data captured during indexing. - pub(crate) registrations: Vec, + pub(crate) registrations: Vec, /// An invalid RBAC registration data. - pub(crate) invalid: Vec, + pub(crate) invalid: Vec, /// A Catalyst ID for transaction ID Data captured during indexing. - pub(crate) catalyst_id_for_txn_id: Vec, + pub(crate) catalyst_id_for_txn_id: Vec, /// A Catalyst ID for stake address data captured during indexing. - pub(crate) catalyst_id_for_stake_address: Vec, + pub(crate) catalyst_id_for_stake_address: + Vec, } impl Rbac509InsertQuery { @@ -54,10 +55,14 @@ impl Rbac509InsertQuery { session: &Arc, cfg: &EnvVars, ) -> anyhow::Result<(SizedBatch, SizedBatch, SizedBatch, SizedBatch)> { Ok(( - insert_rbac509::Params::prepare_batch(session, cfg).await?, - insert_rbac509_invalid::Params::prepare_batch(session, cfg).await?, - insert_catalyst_id_for_txn_id::Params::prepare_batch(session, cfg).await?, - insert_catalyst_id_for_stake_address::Params::prepare_batch(session, cfg).await?, + insert_rbac509::Rbac509Insert::prepare_batch(session, cfg).await?, + insert_rbac509_invalid::Rbac509InvalidInsert::prepare_batch(session, cfg).await?, + insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert::prepare_batch(session, cfg) + .await?, + insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert::prepare_batch( + session, cfg, + ) + .await?, )) } @@ -121,7 +126,7 @@ impl Rbac509InsertQuery { let purpose = cip509.purpose(); match cip509.consume() { Ok((purpose, metadata, _)) => { - self.registrations.push(insert_rbac509::Params::new( + self.registrations.push(insert_rbac509::Rbac509Insert::new( catalyst_id.clone(), txn_hash, slot, @@ -129,14 +134,15 @@ impl Rbac509InsertQuery { purpose, previous_transaction, )); - self.catalyst_id_for_txn_id - .push(insert_catalyst_id_for_txn_id::Params::new( + self.catalyst_id_for_txn_id.push( + insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert::new( catalyst_id.clone(), txn_hash, - )); + ), + ); for address in stake_addresses(&metadata) { self.catalyst_id_for_stake_address.push( - insert_catalyst_id_for_stake_address::Params::new( + insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert::new( address, slot, catalyst_id.clone(), @@ -145,15 +151,16 @@ impl Rbac509InsertQuery { } }, Err(report) => { - self.invalid.push(insert_rbac509_invalid::Params::new( - catalyst_id, - txn_hash, - slot, - index, - purpose, - previous_transaction, - &report, - )); + self.invalid + .push(insert_rbac509_invalid::Rbac509InvalidInsert::new( + catalyst_id, + txn_hash, + slot, + index, + purpose, + previous_transaction, + &report, + )); }, } } diff --git a/catalyst-gateway/bin/src/db/index/block/txi.rs b/catalyst-gateway/bin/src/db/index/block/txi.rs index cd8f148ca8b5..47683aac7547 100644 --- a/catalyst-gateway/bin/src/db/index/block/txi.rs +++ b/catalyst-gateway/bin/src/db/index/block/txi.rs @@ -1,6 +1,6 @@ //! Insert TXI Index Data Queries. -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Slot, TransactionId, TxnOutputOffset}; use catalyst_types::hashes::Blake2b256Hash; @@ -10,13 +10,12 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{ - FallibleQueryTasks, PreparedQueries, PreparedQuery, Query, QueryKind, SizedBatch, - }, + queries::{FallibleQueryTasks, PreparedQueries, PreparedQuery, SizedBatch}, session::CassandraSession, }, types::{DbSlot, DbTransactionId, DbTxnOutputOffset}, }, + impl_query_batch, settings::cassandra_db, }; @@ -48,25 +47,10 @@ pub(crate) struct TxiInsertQuery { txi_data: Vec, } -impl Query for TxiInsertQuery { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - TxiInsertQuery::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} - /// TXI by Txn hash Index const INSERT_TXI_QUERY: &str = include_str!("./cql/insert_txi.cql"); -impl fmt::Display for TxiInsertQuery { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_TXI_QUERY}") - } -} +impl_query_batch!(TxiInsertQuery, INSERT_TXI_QUERY); impl TxiInsertQuery { /// Create a new record for this transaction. diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs index ab8c88758d12..12aca8a3bc76 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo.rs @@ -2,7 +2,7 @@ //! //! Note, there are multiple ways TXO Data is indexed and they all happen in here. -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Slot, StakeAddress, TransactionId, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -10,9 +10,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbStakeAddress, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, settings::cassandra_db, }; @@ -39,21 +40,7 @@ pub(crate) struct TxoInsertQuery { txn_hash: DbTransactionId, } -impl fmt::Display for TxoInsertQuery { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_TXO_QUERY}") - } -} - -impl Query for TxoInsertQuery { - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - TxoInsertQuery::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} +impl_query_batch!(TxoInsertQuery, INSERT_TXO_QUERY); impl TxoInsertQuery { /// Create a new record for this transaction. diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs index f0ab4be13947..05cb8565eb8a 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs @@ -1,6 +1,6 @@ //! Insert TXO Native Assets into the DB. -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Slot, StakeAddress, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -8,9 +8,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, settings::cassandra_db, }; @@ -37,21 +38,7 @@ pub(crate) struct Params { value: num_bigint::BigInt, } -impl fmt::Display for Params { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_TXO_ASSET_QUERY}") - } -} - -impl Query for Params { - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Params::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} +impl_query_batch!(Params, INSERT_TXO_ASSET_QUERY); impl Params { /// Create a new record for this transaction. diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs index 511cf3735981..c68c89e46fb8 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo.rs @@ -1,5 +1,5 @@ //! Insert Unstaked TXOs into the DB. -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Slot, TransactionId, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -7,9 +7,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, settings::cassandra_db, }; @@ -34,21 +35,7 @@ pub(crate) struct Params { value: num_bigint::BigInt, } -impl fmt::Display for Params { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_UNSTAKED_TXO_QUERY}") - } -} - -impl Query for Params { - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Params::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} +impl_query_batch!(Params, INSERT_UNSTAKED_TXO_QUERY); impl Params { /// Create a new record for this transaction. diff --git a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs index 14d72161a414..8c41e671c8f0 100644 --- a/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs +++ b/catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs @@ -1,6 +1,6 @@ //! Insert Unstaked TXO Native Assets into the DB. -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Slot, TransactionId, TxnIndex, TxnOutputOffset}; use scylla::{SerializeRow, Session}; @@ -8,9 +8,10 @@ use tracing::error; use crate::{ db::{ - index::queries::{PreparedQueries, Query, QueryKind, SizedBatch}, + index::queries::{PreparedQueries, SizedBatch}, types::{DbSlot, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, settings::cassandra_db, }; @@ -37,21 +38,7 @@ pub(crate) struct Params { value: num_bigint::BigInt, } -impl fmt::Display for Params { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{INSERT_UNSTAKED_TXO_ASSET_QUERY}") - } -} - -impl Query for Params { - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Params::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} +impl_query_batch!(Params, INSERT_UNSTAKED_TXO_ASSET_QUERY); impl Params { /// Create a new record for this transaction. diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 2465af20468a..4fedcb63c4f8 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -53,6 +53,11 @@ use crate::{ insert_cip36::Cip36Insert, insert_cip36_for_vote_key::Cip36ForVoteKeyInsert, insert_cip36_invalid::Cip36InvalidInsert, }, + rbac509::{ + insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert, + insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert, + insert_rbac509::Rbac509Insert, insert_rbac509_invalid::Rbac509InvalidInsert, + }, }, queries::rbac::{ get_catalyst_id_from_stake_address, get_catalyst_id_from_transaction_id, @@ -300,8 +305,12 @@ async fn prepare_queries( Cip36Insert, Cip36InvalidInsert, Cip36ForVoteKeyInsert, - // prepared statement queries UpdateTxoSpentQuery, + Rbac509Insert, + Rbac509InvalidInsert, + CatalystIdForTxnIdInsert, + CatalystIdForStakeAddressInsert, + // prepared statement queries GetTxoByStakeAddressQuery, GetTxiByTxnHashesQuery ); diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs index d5d142d4255c..94681a102b5c 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs @@ -1,5 +1,5 @@ //! Get the TXO by Stake Address -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::{Slot, StakeAddress}; use scylla::{ @@ -11,12 +11,12 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{PreparedQueries, PreparedSelectQuery, Query, QueryKind}, + queries::{PreparedQueries, PreparedSelectQuery}, session::CassandraSession, }, types::{DbSlot, DbStakeAddress, DbTransactionId, DbTxnIndex, DbTxnOutputOffset}, }, - settings::cassandra_db, + impl_query_statement, }; /// Get txo by stake address query string. @@ -58,20 +58,7 @@ pub(crate) struct GetTxoByStakeAddressQuery { pub spent_slot: Option, } -impl Query for GetTxoByStakeAddressQuery { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, _cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Self::prepare(session).await.map(QueryKind::Statement) - } -} - -impl fmt::Display for GetTxoByStakeAddressQuery { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{GET_TXO_BY_STAKE_ADDRESS_QUERY}") - } -} +impl_query_statement!(GetTxoByStakeAddressQuery, GET_TXO_BY_STAKE_ADDRESS_QUERY); impl GetTxoByStakeAddressQuery { /// Prepares a get txo by stake address query. diff --git a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs index f02ddbc7ca90..7483a6217549 100644 --- a/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs +++ b/catalyst-gateway/bin/src/db/index/tests/scylla_purge.rs @@ -28,14 +28,14 @@ async fn catalyst_id_for_stake_address() { // data let data = vec![ - rbac509::insert_catalyst_id_for_stake_address::Params::new( + rbac509::insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert::new( stake_address_1(), 0.into(), "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), ), - rbac509::insert_catalyst_id_for_stake_address::Params::new( + rbac509::insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert::new( stake_address_2(), 1.into(), "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" @@ -98,13 +98,13 @@ async fn catalyst_id_for_txn_id() { // data let data = vec![ - rbac509::insert_catalyst_id_for_txn_id::Params::new( + rbac509::insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert::new( "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), TransactionId::new(&[0]), ), - rbac509::insert_catalyst_id_for_txn_id::Params::new( + rbac509::insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert::new( "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), @@ -166,7 +166,7 @@ async fn rbac509_registration() { // data let data = vec![ - rbac509::insert_rbac509::Params::new( + rbac509::insert_rbac509::Rbac509Insert::new( "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), @@ -176,7 +176,7 @@ async fn rbac509_registration() { UuidV4::new(), None, ), - rbac509::insert_rbac509::Params::new( + rbac509::insert_rbac509::Rbac509Insert::new( "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), @@ -243,7 +243,7 @@ async fn rbac509_invalid_registration() { // data let report = ProblemReport::new("test context"); let data = vec![ - rbac509::insert_rbac509_invalid::Params::new( + rbac509::insert_rbac509_invalid::Rbac509InvalidInsert::new( "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), @@ -254,7 +254,7 @@ async fn rbac509_invalid_registration() { None, &report, ), - rbac509::insert_rbac509_invalid::Params::new( + rbac509::insert_rbac509_invalid::Rbac509InvalidInsert::new( "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(), From 464d781fb580b2bd0f99cdc92562c1c9ec7115b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Wed, 11 Jun 2025 22:53:27 -0600 Subject: [PATCH 19/26] wip(cat-gateway): implement query trait for statement queries --- .../bin/src/db/index/queries/mod.rs | 20 ++++++++++------ .../queries/registrations/get_all_invalids.rs | 11 ++++++--- .../registrations/get_all_registrations.rs | 15 ++++++++---- .../registrations/get_from_stake_addr.rs | 18 +++++++++++---- .../registrations/get_from_stake_address.rs | 15 ++++++++---- .../registrations/get_from_vote_key.rs | 11 ++++++--- .../queries/registrations/get_invalid.rs | 6 +++++ .../staked_ada/get_assets_by_stake_address.rs | 18 +++++++++++---- .../queries/staked_ada/get_txi_by_txn_hash.rs | 23 ++++--------------- .../staked_ada/get_txo_by_stake_address.rs | 4 ++-- .../db/index/queries/sync_status/update.rs | 3 +++ 11 files changed, 91 insertions(+), 53 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 4fedcb63c4f8..5b002ed9215a 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -125,7 +125,7 @@ macro_rules! impl_query_statement { session: &std::sync::Arc, _: &$crate::settings::cassandra_db::EnvVars, ) -> anyhow::Result<$crate::db::index::queries::QueryKind> { - Self::prepare(session) + Self::prepare(session.clone()) .await .map($crate::db::index::queries::QueryKind::Statement) } @@ -285,9 +285,7 @@ async fn prepare_queries( ( $( $i:ty),* ) => { { let queries = vec![ - $( - (TypeId::of::<$i>(), <$i>::prepare_query(session, cfg).await?), - )* + $( (TypeId::of::<$i>(), <$i>::prepare_query(session, cfg).await?), )* ]; DashMap::from_iter(queries) } @@ -312,7 +310,15 @@ async fn prepare_queries( CatalystIdForStakeAddressInsert, // prepared statement queries GetTxoByStakeAddressQuery, - GetTxiByTxnHashesQuery + GetTxiByTxnHashesQuery, + GetAssetsByStakeAddressQuery, + GetRegistrationQuery, + GetStakeAddrQuery, + GetStakeAddrFromVoteKeyQuery, + GetInvalidRegistrationQuery, + GetAllRegistrationsQuery, + GetAllInvalidRegistrationsQuery, + SyncStatusInsertQuery ); Ok(queries) } @@ -349,8 +355,8 @@ impl PreparedQueries { ) = Rbac509InsertQuery::prepare_batch(&session, cfg).await?; // Prepared Statement queries - let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(&session).await; - let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(&session).await; + let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(session.clone()).await; + let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(session.clone()).await; let native_assets_by_stake_address_query = GetAssetsByStakeAddressQuery::prepare(session.clone()).await; let registration_from_stake_addr_query = diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_invalids.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_invalids.rs index 8b475e5b968a..6269cf0c943d 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_invalids.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_invalids.rs @@ -8,9 +8,12 @@ use scylla::{ }; use tracing::error; -use crate::db::index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + impl_query_statement, }; /// Get all invalid registrations @@ -39,6 +42,8 @@ pub(crate) struct GetAllInvalidRegistrationsQuery { pub cip36: bool, } +impl_query_statement!(GetAllInvalidRegistrationsQuery, GET_ALL_INVALIDS); + impl GetAllInvalidRegistrationsQuery { /// Prepares get all registrations pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs index 1f0cbed63bf0..25629fa651fa 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs @@ -8,12 +8,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::DbTxnIndex, }, - types::DbTxnIndex, + impl_query_statement, }; /// Get all registrations @@ -44,6 +47,8 @@ pub(crate) struct GetAllRegistrationsQuery { pub cip36: bool, } +impl_query_statement!(GetAllRegistrationsQuery, GET_ALL_REGISTRATIONS); + impl GetAllRegistrationsQuery { /// Prepares get all registrations pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_addr.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_addr.rs index f1cdf090c4af..081edfbae385 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_addr.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_addr.rs @@ -8,12 +8,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::{DbSlot, DbTxnIndex}, }, - types::{DbSlot, DbTxnIndex}, + impl_query_statement, }; /// Get registrations from stake addr query. @@ -54,6 +57,11 @@ pub(crate) struct GetRegistrationQuery { pub cip36: bool, } +impl_query_statement!( + GetRegistrationQuery, + GET_REGISTRATIONS_FROM_STAKE_ADDR_QUERY +); + impl GetRegistrationQuery { /// Prepares a get registration query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_address.rs index 5f79629f457c..b5cd0131dac4 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_stake_address.rs @@ -9,12 +9,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::DbStakeAddress, }, - types::DbStakeAddress, + impl_query_statement, }; /// Get stake addr from stake hash query string. @@ -43,6 +46,8 @@ pub(crate) struct GetStakeAddrQuery { pub stake_public_key: Vec, } +impl_query_statement!(GetStakeAddrQuery, GET_QUERY); + impl GetStakeAddrQuery { /// Prepares a get get stake addr from stake hash query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_vote_key.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_vote_key.rs index b67a2ed20fa7..300cb5519c44 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_vote_key.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_from_vote_key.rs @@ -7,9 +7,12 @@ use scylla::{ }; use tracing::error; -use crate::db::index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + impl_query_statement, }; /// Get stake addr from vote key query. @@ -36,6 +39,8 @@ pub(crate) struct GetStakeAddrFromVoteKeyQuery { pub stake_public_key: Vec, } +impl_query_statement!(GetStakeAddrFromVoteKeyQuery, GET_STAKE_ADDR_FROM_VOTE_KEY); + impl GetStakeAddrFromVoteKeyQuery { /// Prepares a get stake addr from vote key query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_invalid.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_invalid.rs index bfca481f7a4c..51354f84ba4e 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_invalid.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_invalid.rs @@ -16,6 +16,7 @@ use crate::{ }, types::DbSlot, }, + impl_query_statement, service::common::types::cardano::slot_no::SlotNo, }; @@ -59,6 +60,11 @@ pub(crate) struct GetInvalidRegistrationQuery { pub cip36: bool, } +impl_query_statement!( + GetInvalidRegistrationQuery, + GET_INVALID_REGISTRATIONS_FROM_STAKE_ADDR_QUERY +); + impl GetInvalidRegistrationQuery { /// Prepares a get invalid registration query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_assets_by_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_assets_by_stake_address.rs index 765a66914ad1..02f513290aa6 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_assets_by_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_assets_by_stake_address.rs @@ -8,12 +8,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, }, - types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, + impl_query_statement, }; /// Get assets by stake address query string. @@ -56,6 +59,11 @@ pub(crate) struct GetAssetsByStakeAddressQuery { pub value: num_bigint::BigInt, } +impl_query_statement!( + GetAssetsByStakeAddressQuery, + GET_ASSETS_BY_STAKE_ADDRESS_QUERY +); + impl GetAssetsByStakeAddressQuery { /// Prepares a get assets by stake address query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs index 8eb739538971..83d916d0e381 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txi_by_txn_hash.rs @@ -1,6 +1,6 @@ //! Get TXI by Transaction hash query -use std::{fmt, sync::Arc}; +use std::sync::Arc; use cardano_blockchain_types::TransactionId; use scylla::{ @@ -12,12 +12,12 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{PreparedQueries, PreparedSelectQuery, Query, QueryKind}, + queries::{PreparedQueries, PreparedSelectQuery}, session::CassandraSession, }, types::{DbSlot, DbTransactionId, DbTxnOutputOffset}, }, - settings::cassandra_db, + impl_query_statement, }; /// Get TXI query string. @@ -49,24 +49,11 @@ pub(crate) struct GetTxiByTxnHashesQuery { pub slot_no: DbSlot, } -impl Query for GetTxiByTxnHashesQuery { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, _cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Self::prepare(session).await.map(QueryKind::Statement) - } -} - -impl fmt::Display for GetTxiByTxnHashesQuery { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{GET_TXI_BY_TXN_HASHES_QUERY}") - } -} +impl_query_statement!(GetTxiByTxnHashesQuery, GET_TXI_BY_TXN_HASHES_QUERY); impl GetTxiByTxnHashesQuery { /// Prepares a get txi query. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { + pub(crate) async fn prepare(session: Arc) -> anyhow::Result { PreparedQueries::prepare( session.clone(), GET_TXI_BY_TXN_HASHES_QUERY, diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs index 94681a102b5c..760d2b6842e3 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/get_txo_by_stake_address.rs @@ -62,9 +62,9 @@ impl_query_statement!(GetTxoByStakeAddressQuery, GET_TXO_BY_STAKE_ADDRESS_QUERY) impl GetTxoByStakeAddressQuery { /// Prepares a get txo by stake address query. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { + pub(crate) async fn prepare(session: Arc) -> anyhow::Result { PreparedQueries::prepare( - session.clone(), + session, GET_TXO_BY_STAKE_ADDRESS_QUERY, scylla::statement::Consistency::All, true, diff --git a/catalyst-gateway/bin/src/db/index/queries/sync_status/update.rs b/catalyst-gateway/bin/src/db/index/queries/sync_status/update.rs index c02e98343900..ddfe99840c5b 100644 --- a/catalyst-gateway/bin/src/db/index/queries/sync_status/update.rs +++ b/catalyst-gateway/bin/src/db/index/queries/sync_status/update.rs @@ -13,6 +13,7 @@ use crate::{ queries::{PreparedQueries, PreparedUpsertQuery}, session::CassandraSession, }, + impl_query_statement, service::utilities::convert::from_saturating, settings::Settings, }; @@ -60,6 +61,8 @@ impl SyncStatusQueryParams { /// Sync Status Insert query. pub(crate) struct SyncStatusInsertQuery; +impl_query_statement!(SyncStatusInsertQuery, INSERT_SYNC_STATUS_QUERY); + impl SyncStatusInsertQuery { /// Prepares a Sync Status Insert query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { From 674ef1a49d33af0f782a870e11eec59f59f25375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Thu, 12 Jun 2025 10:22:13 -0600 Subject: [PATCH 20/26] wip(cat-gateway): update implementation query trait for UpdateTxoSpent --- .../queries/staked_ada/update_txo_spent.rs | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs b/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs index 856963cfe954..88ca8bc91c61 100644 --- a/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs +++ b/catalyst-gateway/bin/src/db/index/queries/staked_ada/update_txo_spent.rs @@ -1,6 +1,6 @@ //! Update the TXO Spent column to optimize future queries. -use std::{fmt, sync::Arc}; +use std::sync::Arc; use scylla::{SerializeRow, Session}; use tracing::error; @@ -8,13 +8,12 @@ use tracing::error; use crate::{ db::{ index::{ - queries::{ - FallibleQueryResults, PreparedQueries, PreparedQuery, Query, QueryKind, SizedBatch, - }, + queries::{FallibleQueryResults, PreparedQueries, PreparedQuery, SizedBatch}, session::CassandraSession, }, types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, settings::cassandra_db, }; @@ -39,22 +38,7 @@ pub(crate) struct UpdateTxoSpentQueryParams { /// Update TXO spent query. pub(crate) struct UpdateTxoSpentQuery; -impl Query for UpdateTxoSpentQuery { - /// Prepare Batch of Insert TXI Index Data Queries - async fn prepare_query( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - Self::prepare_batch(session, cfg) - .await - .map(QueryKind::Batch) - } -} - -impl fmt::Display for UpdateTxoSpentQuery { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{UPDATE_TXO_SPENT_QUERY}") - } -} +impl_query_batch!(UpdateTxoSpentQuery, UPDATE_TXO_SPENT_QUERY); impl UpdateTxoSpentQuery { /// Prepare a batch of update TXO spent queries. From e252d43f337927bc81b7aa5f1c7646329811158d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Thu, 12 Jun 2025 11:12:57 -0600 Subject: [PATCH 21/26] feat(cat-gateway): impl Query for prepared statement types --- .../bin/src/db/index/block/rbac509/mod.rs | 6 ++-- .../bin/src/db/index/queries/mod.rs | 20 ++++++++----- .../get_catalyst_id_from_stake_address.rs | 23 +++++++++------ .../get_catalyst_id_from_transaction_id.rs | 29 +++++++++++-------- .../rbac/get_rbac_invalid_registrations.rs | 23 +++++++++------ .../queries/rbac/get_rbac_registrations.rs | 29 +++++++++++-------- .../bin/src/db/index/tests/scylla_queries.rs | 16 +++++----- .../rbac/registrations_get/chain_info.rs | 6 ++-- .../api/cardano/rbac/registrations_get/mod.rs | 6 ++-- 9 files changed, 94 insertions(+), 64 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs b/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs index 83720e12a41a..3cc11384be7c 100644 --- a/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs +++ b/catalyst-gateway/bin/src/db/index/block/rbac509/mod.rs @@ -243,9 +243,9 @@ async fn catalyst_id( async fn query_catalyst_id( session: &Arc, txn_id: TransactionId, is_immutable: bool, ) -> anyhow::Result { - use crate::db::index::queries::rbac::get_catalyst_id_from_transaction_id::Query; + use crate::db::index::queries::rbac::get_catalyst_id_from_transaction_id::GetCatalystIdForTxnId; - if let Some(q) = Query::get_latest(session, txn_id.into()) + if let Some(q) = GetCatalystIdForTxnId::get_latest(session, txn_id.into()) .await .context("Failed to query Catalyst ID from transaction ID")? { @@ -259,7 +259,7 @@ async fn query_catalyst_id( // persistent database. let persistent_session = CassandraSession::get(true).context("Failed to get persistent DB session")?; - Query::get_latest(&persistent_session, txn_id.into()) + GetCatalystIdForTxnId::get_latest(&persistent_session, txn_id.into()) .await .transpose() .context("Unable to find Catalyst ID in the persistent DB")? diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 5b002ed9215a..9346a945dda7 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -60,8 +60,10 @@ use crate::{ }, }, queries::rbac::{ - get_catalyst_id_from_stake_address, get_catalyst_id_from_transaction_id, - get_rbac_invalid_registrations, get_rbac_registrations, + get_catalyst_id_from_stake_address::GetCatalystIdForStakeAddress, + get_catalyst_id_from_transaction_id::GetCatalystIdForTxnId, + get_rbac_invalid_registrations::GetRbac509InvalidRegistrations, + get_rbac_registrations::GetRbac509Registrations, }, session::CassandraSessionError, }, @@ -318,7 +320,11 @@ async fn prepare_queries( GetInvalidRegistrationQuery, GetAllRegistrationsQuery, GetAllInvalidRegistrationsQuery, - SyncStatusInsertQuery + SyncStatusInsertQuery, + GetCatalystIdForStakeAddress, + GetCatalystIdForTxnId, + GetRbac509Registrations, + GetRbac509InvalidRegistrations ); Ok(queries) } @@ -369,13 +375,13 @@ impl PreparedQueries { GetAllInvalidRegistrationsQuery::prepare(session.clone()).await; let sync_status_insert = SyncStatusInsertQuery::prepare(session.clone()).await?; let catalyst_id_by_stake_address_query = - get_catalyst_id_from_stake_address::Query::prepare(session.clone()).await?; + GetCatalystIdForStakeAddress::prepare(session.clone()).await?; let catalyst_id_by_transaction_id_query = - get_catalyst_id_from_transaction_id::Query::prepare(session.clone()).await?; + GetCatalystIdForTxnId::prepare(session.clone()).await?; let rbac_registrations_by_catalyst_id_query = - get_rbac_registrations::Query::prepare(session.clone()).await?; + GetRbac509Registrations::prepare(session.clone()).await?; let rbac_invalid_registrations_by_catalyst_id_query = - get_rbac_invalid_registrations::Query::prepare(session.clone()).await?; + GetRbac509InvalidRegistrations::prepare(session.clone()).await?; Ok(Self { txo_insert_queries, diff --git a/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_stake_address.rs index 4e6dd70cb612..c4f532aeeec5 100644 --- a/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_stake_address.rs @@ -8,12 +8,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::{DbCatalystId, DbSlot, DbStakeAddress}, }, - types::{DbCatalystId, DbSlot, DbStakeAddress}, + impl_query_statement, }; /// Get Catalyst ID by stake address query string. @@ -28,14 +31,16 @@ pub(crate) struct QueryParams { /// Get Catalyst ID by stake address query. #[derive(Debug, Clone, DeserializeRow)] -pub(crate) struct Query { +pub(crate) struct GetCatalystIdForStakeAddress { /// Catalyst ID for the queries stake address. pub catalyst_id: DbCatalystId, /// A slot number. pub slot_no: DbSlot, } -impl Query { +impl_query_statement!(GetCatalystIdForStakeAddress, QUERY); + +impl GetCatalystIdForStakeAddress { /// Prepares a get Catalyst ID by stake address query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { PreparedQueries::prepare(session, QUERY, Consistency::All, true) @@ -48,11 +53,11 @@ impl Query { /// Executes a get Catalyst ID by stake address query. pub(crate) async fn execute( session: &CassandraSession, params: QueryParams, - ) -> anyhow::Result> { + ) -> anyhow::Result> { session .execute_iter(PreparedSelectQuery::CatalystIdByStakeAddress, params) .await? - .rows_stream::() + .rows_stream::() .map_err(Into::into) } } diff --git a/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_transaction_id.rs b/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_transaction_id.rs index 8a63507b1295..2470a1a8267b 100644 --- a/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_transaction_id.rs +++ b/catalyst-gateway/bin/src/db/index/queries/rbac/get_catalyst_id_from_transaction_id.rs @@ -13,17 +13,20 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::{DbCatalystId, DbTransactionId}, }, - types::{DbCatalystId, DbTransactionId}, + impl_query_statement, }; /// Cached data. #[allow(dead_code)] -static CACHE: LazyLock> = LazyLock::new(|| { +static CACHE: LazyLock> = LazyLock::new(|| { Cache::builder() .eviction_policy(EvictionPolicy::lru()) .build() @@ -41,12 +44,14 @@ pub(crate) struct QueryParams { /// Get Catalyst ID by stake address query. #[derive(Debug, Clone, DeserializeRow)] -pub(crate) struct Query { +pub(crate) struct GetCatalystIdForTxnId { /// A Catalyst ID. pub catalyst_id: DbCatalystId, } -impl Query { +impl_query_statement!(GetCatalystIdForTxnId, QUERY); + +impl GetCatalystIdForTxnId { /// Prepares a get catalyst ID by transaction ID query. pub(crate) async fn prepare(session: Arc) -> Result { PreparedQueries::prepare(session, QUERY, Consistency::All, true) @@ -61,11 +66,11 @@ impl Query { /// Don't call directly, use one of the methods instead. pub(crate) async fn execute( session: &CassandraSession, params: QueryParams, - ) -> Result> { + ) -> Result> { session .execute_iter(PreparedSelectQuery::CatalystIdByTransactionId, params) .await? - .rows_stream::() + .rows_stream::() .map_err(Into::into) } @@ -74,7 +79,7 @@ impl Query { /// Unless you really know you need an uncached result, use the cached version. pub(crate) async fn get_latest_uncached( session: &CassandraSession, txn_id: DbTransactionId, - ) -> Result> { + ) -> Result> { Self::execute(session, QueryParams { txn_id }) .await? .next() @@ -86,7 +91,7 @@ impl Query { /// Gets the latest Catalyst ID for the given transaction ID. pub(crate) async fn get_latest( session: &CassandraSession, transaction_id: DbTransactionId, - ) -> Result> { + ) -> Result> { // TODO: Caching is disabled because we want to measure the performance without it and be // sure that the logic is sound. Also caches needs to be tunable. Self::get_latest_uncached(session, transaction_id).await diff --git a/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_invalid_registrations.rs b/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_invalid_registrations.rs index d1187e0ad48d..412aff5efa4e 100644 --- a/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_invalid_registrations.rs +++ b/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_invalid_registrations.rs @@ -8,12 +8,15 @@ use scylla::{ }; use tracing::error; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::{DbCatalystId, DbSlot, DbTransactionId, DbTxnIndex, DbUuidV4}, }, - types::{DbCatalystId, DbSlot, DbTransactionId, DbTxnIndex, DbUuidV4}, + impl_query_statement, }; /// Get invalid registrations by Catalyst ID query. @@ -29,7 +32,7 @@ pub(crate) struct QueryParams { /// Get invalid registrations by Catalyst ID query. #[allow(dead_code)] #[derive(DeserializeRow)] -pub(crate) struct Query { +pub(crate) struct GetRbac509InvalidRegistrations { /// Registration transaction id. pub txn_id: DbTransactionId, /// A block slot number. @@ -44,7 +47,9 @@ pub(crate) struct Query { pub problem_report: String, } -impl Query { +impl_query_statement!(GetRbac509InvalidRegistrations, QUERY); + +impl GetRbac509InvalidRegistrations { /// Prepares a query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { PreparedQueries::prepare(session, QUERY, Consistency::All, true) @@ -59,14 +64,14 @@ impl Query { #[allow(dead_code)] pub(crate) async fn execute( session: &CassandraSession, params: QueryParams, - ) -> anyhow::Result> { + ) -> anyhow::Result> { session .execute_iter( PreparedSelectQuery::RbacInvalidRegistrationsByCatalystId, params, ) .await? - .rows_stream::() + .rows_stream::() .map_err(Into::into) } } diff --git a/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_registrations.rs b/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_registrations.rs index 4eeb3e64fe1f..246c356fb3ae 100644 --- a/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_registrations.rs +++ b/catalyst-gateway/bin/src/db/index/queries/rbac/get_rbac_registrations.rs @@ -14,12 +14,15 @@ use scylla::{ }; use tracing::{debug, error}; -use crate::db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, +use crate::{ + db::{ + index::{ + queries::{PreparedQueries, PreparedSelectQuery}, + session::CassandraSession, + }, + types::{DbCatalystId, DbSlot, DbTransactionId, DbTxnIndex, DbUuidV4}, }, - types::{DbCatalystId, DbSlot, DbTransactionId, DbTxnIndex, DbUuidV4}, + impl_query_statement, }; /// Get registrations by Catalyst ID query. @@ -34,7 +37,7 @@ pub(crate) struct QueryParams { /// Get registrations by Catalyst ID query. #[derive(DeserializeRow, Clone)] -pub(crate) struct Query { +pub(crate) struct GetRbac509Registrations { /// Registration transaction id. #[allow(dead_code)] pub txn_id: DbTransactionId, @@ -49,7 +52,9 @@ pub(crate) struct Query { pub purpose: DbUuidV4, } -impl Query { +impl_query_statement!(GetRbac509Registrations, QUERY); + +impl GetRbac509Registrations { /// Prepares a query. pub(crate) async fn prepare(session: Arc) -> anyhow::Result { PreparedQueries::prepare(session, QUERY, Consistency::All, true) @@ -62,11 +67,11 @@ impl Query { /// Executes a get registrations by Catalyst ID query. pub(crate) async fn execute( session: &CassandraSession, params: QueryParams, - ) -> anyhow::Result> { + ) -> anyhow::Result> { session .execute_iter(PreparedSelectQuery::RbacRegistrationsByCatalystId, params) .await? - .rows_stream::() + .rows_stream::() .map_err(Into::into) } } @@ -75,8 +80,8 @@ impl Query { /// database. pub(crate) async fn indexed_registrations( session: &CassandraSession, catalyst_id: &CatalystId, -) -> anyhow::Result> { - let mut result: Vec<_> = Query::execute(session, QueryParams { +) -> anyhow::Result> { + let mut result: Vec<_> = GetRbac509Registrations::execute(session, QueryParams { catalyst_id: catalyst_id.clone().into(), }) .and_then(|r| r.try_collect().map_err(Into::into)) @@ -90,7 +95,7 @@ pub(crate) async fn indexed_registrations( /// /// # NOTE: provided `reg_queries` must be sorted by `slot_no`, look into `indexed_registrations` function. pub(crate) async fn build_reg_chain( - mut reg_queries_iter: impl Iterator, network: Network, + mut reg_queries_iter: impl Iterator, network: Network, mut on_success: OnSuccessFn, ) -> anyhow::Result> { let Some((is_persistent, root)) = reg_queries_iter.next() else { diff --git a/catalyst-gateway/bin/src/db/index/tests/scylla_queries.rs b/catalyst-gateway/bin/src/db/index/tests/scylla_queries.rs index 4951821a2c81..b736a1f19fa6 100644 --- a/catalyst-gateway/bin/src/db/index/tests/scylla_queries.rs +++ b/catalyst-gateway/bin/src/db/index/tests/scylla_queries.rs @@ -49,13 +49,13 @@ async fn test_get_assets_by_stake_addr() { #[ignore = "An integration test which requires a running Scylla node instance, disabled from `testunit` CI run"] #[tokio::test] async fn get_catalyst_id_by_stake_address() { - use rbac::get_catalyst_id_from_stake_address::{Query, QueryParams}; + use rbac::get_catalyst_id_from_stake_address::{GetCatalystIdForStakeAddress, QueryParams}; let Ok((session, _)) = get_shared_session().await else { panic!("{SESSION_ERR_MSG}"); }; - let mut row_stream = Query::execute(&session, QueryParams { + let mut row_stream = GetCatalystIdForStakeAddress::execute(&session, QueryParams { stake_address: stake_address_1().into(), }) .await @@ -69,14 +69,14 @@ async fn get_catalyst_id_by_stake_address() { #[ignore = "An integration test which requires a running Scylla node instance, disabled from `testunit` CI run"] #[tokio::test] async fn get_catalyst_id_by_transaction_id() { - use rbac::get_catalyst_id_from_transaction_id::{Query, QueryParams}; + use rbac::get_catalyst_id_from_transaction_id::{GetCatalystIdForTxnId, QueryParams}; let Ok((session, _)) = get_shared_session().await else { panic!("{SESSION_ERR_MSG}"); }; let txn_id = TransactionId::new(&[1, 2, 3]).into(); - let mut row_stream = Query::execute(&session, QueryParams { txn_id }) + let mut row_stream = GetCatalystIdForTxnId::execute(&session, QueryParams { txn_id }) .await .unwrap(); @@ -107,7 +107,7 @@ async fn test_get_invalid_registration_w_stake_addr() { #[ignore = "An integration test which requires a running Scylla node instance, disabled from `testunit` CI run"] #[tokio::test] async fn get_rbac_registrations_by_catalyst_id() { - use rbac::get_rbac_registrations::{Query, QueryParams}; + use rbac::get_rbac_registrations::{GetRbac509Registrations, QueryParams}; let Ok((session, _)) = get_shared_session().await else { panic!("{SESSION_ERR_MSG}"); @@ -116,7 +116,7 @@ async fn get_rbac_registrations_by_catalyst_id() { let id: CatalystId = "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(); - let mut row_stream = Query::execute(&session, QueryParams { + let mut row_stream = GetRbac509Registrations::execute(&session, QueryParams { catalyst_id: id.into(), }) .await @@ -130,7 +130,7 @@ async fn get_rbac_registrations_by_catalyst_id() { #[ignore = "An integration test which requires a running Scylla node instance, disabled from `testunit` CI run"] #[tokio::test] async fn get_rbac_invalid_registrations_by_catalyst_id() { - use rbac::get_rbac_invalid_registrations::{Query, QueryParams}; + use rbac::get_rbac_invalid_registrations::{GetRbac509InvalidRegistrations, QueryParams}; let Ok((session, _)) = get_shared_session().await else { panic!("{SESSION_ERR_MSG}"); @@ -139,7 +139,7 @@ async fn get_rbac_invalid_registrations_by_catalyst_id() { let id: CatalystId = "cardano/FftxFnOrj2qmTuB2oZG2v0YEWJfKvQ9Gg8AgNAhDsKE" .parse() .unwrap(); - let mut row_stream = Query::execute(&session, QueryParams { + let mut row_stream = GetRbac509InvalidRegistrations::execute(&session, QueryParams { catalyst_id: id.into(), }) .await diff --git a/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/chain_info.rs b/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/chain_info.rs index 411be500960b..4a93b61efa3d 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/chain_info.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/chain_info.rs @@ -10,7 +10,9 @@ use rbac_registration::registration::cardano::RegistrationChain; use crate::{ db::index::{ - queries::rbac::get_rbac_registrations::{build_reg_chain, indexed_registrations, Query}, + queries::rbac::get_rbac_registrations::{ + build_reg_chain, indexed_registrations, GetRbac509Registrations, + }, session::CassandraSession, }, settings::Settings, @@ -72,7 +74,7 @@ impl ChainInfo { async fn last_registration_chain( persistent_session: &CassandraSession, volatile_session: &CassandraSession, catalyst_id: &CatalystId, -) -> anyhow::Result> { +) -> anyhow::Result> { let (persistent_registrations, volatile_registrations) = try_join( indexed_registrations(persistent_session, catalyst_id), indexed_registrations(volatile_session, catalyst_id), diff --git a/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/mod.rs b/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/mod.rs index b5571f8d63c7..929c4466fba5 100644 --- a/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/mod.rs +++ b/catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/mod.rs @@ -26,7 +26,9 @@ use tracing::error; use crate::{ db::index::{ - queries::rbac::get_catalyst_id_from_stake_address::{Query, QueryParams}, + queries::rbac::get_catalyst_id_from_stake_address::{ + GetCatalystIdForStakeAddress, QueryParams, + }, session::CassandraSession, }, service::{ @@ -110,7 +112,7 @@ pub(crate) async fn endpoint( async fn catalyst_id_from_stake( session: &CassandraSession, address: StakeAddress, ) -> anyhow::Result> { - let mut result: Vec<_> = Query::execute(session, QueryParams { + let mut result: Vec<_> = GetCatalystIdForStakeAddress::execute(session, QueryParams { stake_address: address.into(), }) .and_then(|r| r.try_collect().map_err(Into::into)) From 7b7f5df1d872fd068727831528f30cee4dddb861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Thu, 12 Jun 2025 11:42:20 -0600 Subject: [PATCH 22/26] wip(cat-gateway): impl Query for purge TxoAda --- .../bin/src/db/index/queries/mod.rs | 20 +++++++++++++------ .../bin/src/db/index/queries/purge/mod.rs | 13 +++++++----- .../bin/src/db/index/queries/purge/txo_ada.rs | 7 ++++++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 9346a945dda7..04fbe53a4b33 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -59,11 +59,16 @@ use crate::{ insert_rbac509::Rbac509Insert, insert_rbac509_invalid::Rbac509InvalidInsert, }, }, - queries::rbac::{ - get_catalyst_id_from_stake_address::GetCatalystIdForStakeAddress, - get_catalyst_id_from_transaction_id::GetCatalystIdForTxnId, - get_rbac_invalid_registrations::GetRbac509InvalidRegistrations, - get_rbac_registrations::GetRbac509Registrations, + queries::{ + purge::txo_ada::{ + DeleteQuery as PurgeTxoAdaDelete, PrimaryKeyQuery as PurgeTxoAdaSelect, + }, + rbac::{ + get_catalyst_id_from_stake_address::GetCatalystIdForStakeAddress, + get_catalyst_id_from_transaction_id::GetCatalystIdForTxnId, + get_rbac_invalid_registrations::GetRbac509InvalidRegistrations, + get_rbac_registrations::GetRbac509Registrations, + }, }, session::CassandraSessionError, }, @@ -324,7 +329,10 @@ async fn prepare_queries( GetCatalystIdForStakeAddress, GetCatalystIdForTxnId, GetRbac509Registrations, - GetRbac509InvalidRegistrations + GetRbac509InvalidRegistrations, + // purge queries + PurgeTxoAdaSelect, + PurgeTxoAdaDelete ); Ok(queries) } diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs b/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs index bb0b1aa5153d..60f22474e147 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs @@ -152,15 +152,18 @@ impl PreparedQueries { ) -> anyhow::Result { // We initialize like this, so that all errors preparing querys get shown before aborting. Ok(Self { - select_txo_ada: txo_ada::PrimaryKeyQuery::prepare(&session).await?, + select_txo_ada: txo_ada::PrimaryKeyQuery::prepare(session.clone()).await?, delete_txo_ada: txo_ada::DeleteQuery::prepare_batch(&session, cfg).await?, - select_txo_assets: txo_assets::PrimaryKeyQuery::prepare(&session).await?, + select_txo_assets: txo_assets::PrimaryKeyQuery::prepare(&session.clone()).await?, delete_txo_assets: txo_assets::DeleteQuery::prepare_batch(&session, cfg).await?, - select_unstaked_txo_ada: unstaked_txo_ada::PrimaryKeyQuery::prepare(&session).await?, - delete_unstaked_txo_ada: unstaked_txo_ada::DeleteQuery::prepare_batch(&session, cfg) + select_unstaked_txo_ada: unstaked_txo_ada::PrimaryKeyQuery::prepare(&session.clone()) .await?, - select_unstaked_txo_assets: unstaked_txo_assets::PrimaryKeyQuery::prepare(&session) + delete_unstaked_txo_ada: unstaked_txo_ada::DeleteQuery::prepare_batch(&session, cfg) .await?, + select_unstaked_txo_assets: unstaked_txo_assets::PrimaryKeyQuery::prepare( + &session.clone(), + ) + .await?, delete_unstaked_txo_assets: unstaked_txo_assets::DeleteQuery::prepare_batch( &session, cfg, ) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/txo_ada.rs b/catalyst-gateway/bin/src/db/index/queries/purge/txo_ada.rs index 7d0be42ed96d..cb1f811d6253 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/txo_ada.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/txo_ada.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -70,9 +71,11 @@ impl From for Params { /// Get primary key for TXO by Stake Address query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all TXO by stake address primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { + pub(crate) async fn prepare(session: Arc) -> anyhow::Result { PreparedQueries::prepare( session.clone(), SELECT_QUERY, @@ -105,6 +108,8 @@ const DELETE_QUERY: &str = include_str!("cql/delete_txo_by_stake_address.cql"); /// Delete TXO by Stake Address Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( From 8225be295503608368e024ef0734cac4f9c99208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Fri, 13 Jun 2025 12:23:26 -0600 Subject: [PATCH 23/26] feat(cat-gateway): add type_id associated function to Query trait --- .../bin/src/db/index/queries/mod.rs | 122 ++++++++++++------ 1 file changed, 84 insertions(+), 38 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 04fbe53a4b33..b892fccdec5a 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -91,7 +91,10 @@ pub(crate) enum QueryKind { /// A trait to prepare Index DB queries. #[allow(dead_code)] -pub(crate) trait Query { +pub(crate) trait Query: std::fmt::Display + std::any::Any { + /// Returns the type id for the query. + fn type_id() -> TypeId; + /// Prepare the query async fn prepare_query( session: &Arc, cfg: &cassandra_db::EnvVars, @@ -103,14 +106,27 @@ pub(crate) trait Query { macro_rules! impl_query_batch { ($i:ty, $c:ident) => { impl $crate::db::index::queries::Query for $i { - /// Prepare Batch of Insert TXI Index Data Queries + + fn type_id() -> std::any::TypeId { + std::any::TypeId::of::<$i>() + } + async fn prepare_query( session: &std::sync::Arc, cfg: &$crate::settings::cassandra_db::EnvVars, ) -> anyhow::Result<$crate::db::index::queries::QueryKind> { - Self::prepare_batch(session, cfg) - .await - .map($crate::db::index::queries::QueryKind::Batch) + $crate::db::index::queries::prepare_batch( + session.clone(), + $c, + cfg, + scylla::statement::Consistency::Any, + true, + false, + ) + .await + .map($crate::db::index::queries::QueryKind::Batch) + .inspect_err(|error| error!(error=%error,"Failed to prepare $c Query.")) + .map_err(|error| anyhow::anyhow!("{error}\n--\n{{$c}}")) } } @@ -127,14 +143,27 @@ macro_rules! impl_query_batch { macro_rules! impl_query_statement { ($i:ty, $c:ident) => { impl $crate::db::index::queries::Query for $i { - /// Prepare Batch of Insert TXI Index Data Queries + + fn type_id() -> std::any::TypeId { + std::any::TypeId::of::<$i>() + } + async fn prepare_query( session: &std::sync::Arc, _: &$crate::settings::cassandra_db::EnvVars, ) -> anyhow::Result<$crate::db::index::queries::QueryKind> { - Self::prepare(session.clone()) + + $crate::db::index::queries::prepare_statement( + session, + $c, + scylla::statement::Consistency::All, + true, + ) .await .map($crate::db::index::queries::QueryKind::Statement) + .inspect_err(|error| error!(error=%error, "Failed to prepare $c query.")) + .map_err(|error| anyhow::anyhow!("{error}\n--\n{{$c}}")) + } } @@ -146,6 +175,48 @@ macro_rules! impl_query_statement { }; } +/// Prepares a statement. +pub(crate) async fn prepare_statement( + session: &Arc, query: Q, consistency: scylla::statement::Consistency, idempotent: bool, +) -> anyhow::Result { + let mut prepared = session.prepare(format!("{query}")).await?; + prepared.set_consistency(consistency); + prepared.set_is_idempotent(idempotent); + + Ok(prepared) +} + +/// Prepares all permutations of the batch from 1 to max. +/// It is necessary to do this because batches are pre-sized, they can not be dynamic. +/// Preparing the batches in advance is a very larger performance increase. +pub(crate) async fn prepare_batch( + session: Arc, query: Q, cfg: &cassandra_db::EnvVars, + consistency: scylla::statement::Consistency, idempotent: bool, logged: bool, +) -> anyhow::Result { + let sized_batches: SizedBatch = DashMap::new(); + + // First prepare the query. Only needs to be done once, all queries on a batch are the + // same. + let prepared = prepare_statement(&session, query, consistency, idempotent).await?; + + for batch_size in cassandra_db::MIN_BATCH_SIZE..=cfg.max_batch_size { + let mut batch: Batch = Batch::new(if logged { + scylla::batch::BatchType::Logged + } else { + scylla::batch::BatchType::Unlogged + }); + batch.set_consistency(consistency); + batch.set_is_idempotent(idempotent); + for _ in cassandra_db::MIN_BATCH_SIZE..=batch_size { + batch.append_statement(prepared.clone()); + } + + sized_batches.insert(batch_size.try_into()?, Arc::new(batch)); + } + + Ok(sized_batches) +} + /// All Prepared insert Queries that we know about. #[derive(strum_macros::Display)] #[allow(clippy::enum_variant_names)] @@ -424,46 +495,21 @@ impl PreparedQueries { } /// Prepares a statement. - pub(crate) async fn prepare( - session: Arc, query: &str, consistency: scylla::statement::Consistency, + pub(crate) async fn prepare( + session: Arc, query: Q, consistency: scylla::statement::Consistency, idempotent: bool, ) -> anyhow::Result { - let mut prepared = session.prepare(query).await?; - prepared.set_consistency(consistency); - prepared.set_is_idempotent(idempotent); - - Ok(prepared) + prepare_statement(&session, query, consistency, idempotent).await } /// Prepares all permutations of the batch from 1 to max. /// It is necessary to do this because batches are pre-sized, they can not be dynamic. /// Preparing the batches in advance is a very larger performance increase. - pub(crate) async fn prepare_batch( - session: Arc, query: &str, cfg: &cassandra_db::EnvVars, + pub(crate) async fn prepare_batch( + session: Arc, query: Q, cfg: &cassandra_db::EnvVars, consistency: scylla::statement::Consistency, idempotent: bool, logged: bool, ) -> anyhow::Result { - let sized_batches: SizedBatch = DashMap::new(); - - // First prepare the query. Only needs to be done once, all queries on a batch are the - // same. - let prepared = Self::prepare(session, query, consistency, idempotent).await?; - - for batch_size in cassandra_db::MIN_BATCH_SIZE..=cfg.max_batch_size { - let mut batch: Batch = Batch::new(if logged { - scylla::batch::BatchType::Logged - } else { - scylla::batch::BatchType::Unlogged - }); - batch.set_consistency(consistency); - batch.set_is_idempotent(idempotent); - for _ in cassandra_db::MIN_BATCH_SIZE..=batch_size { - batch.append_statement(prepared.clone()); - } - - sized_batches.insert(batch_size.try_into()?, Arc::new(batch)); - } - - Ok(sized_batches) + prepare_batch(session, query, cfg, consistency, idempotent, logged).await } /// Executes a single query with the given parameters. From 0ea4da272954682e4dc805cd7ad49aa10864dd00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Fri, 13 Jun 2025 12:24:49 -0600 Subject: [PATCH 24/26] feat(cat-gateway): all queries implement Query trait --- .../bin/src/db/index/queries/mod.rs | 239 +++++++++++------- .../purge/catalyst_id_for_stake_address.rs | 5 + .../queries/purge/catalyst_id_for_txn_id.rs | 5 + .../index/queries/purge/cip36_registration.rs | 5 + .../purge/cip36_registration_for_vote_key.rs | 5 + .../purge/cip36_registration_invalid.rs | 5 + .../purge/rbac509_invalid_registration.rs | 5 + .../queries/purge/rbac509_registration.rs | 5 + .../index/queries/purge/stake_registration.rs | 5 + .../src/db/index/queries/purge/txi_by_hash.rs | 5 + .../src/db/index/queries/purge/txo_assets.rs | 5 + .../index/queries/purge/unstaked_txo_ada.rs | 5 + .../queries/purge/unstaked_txo_assets.rs | 5 + 13 files changed, 206 insertions(+), 93 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index b892fccdec5a..0574df31ed13 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -12,6 +12,54 @@ use std::{any::TypeId, fmt::Debug, sync::Arc}; use anyhow::bail; use dashmap::DashMap; +use purge::{ + catalyst_id_for_stake_address::{ + DeleteQuery as PurgeCatalystIdForStakeAddressDelete, + PrimaryKeyQuery as PurgeCatalystIdForStakeAddressSelect, + }, + catalyst_id_for_txn_id::{ + DeleteQuery as PurgeCatalystIdForTxnIdDelete, + PrimaryKeyQuery as PurgeCatalystIdForTxnIdSelect, + }, + cip36_registration::{ + DeleteQuery as PurgeCip36RegistrationDelete, + PrimaryKeyQuery as PurgeCip36RegistrationSelect, + }, + cip36_registration_for_vote_key::{ + DeleteQuery as PurgeCip36RegistrationForVoteKeyDelete, + PrimaryKeyQuery as PurgeCip36RegistrationForVoteKeySelect, + }, + cip36_registration_invalid::{ + DeleteQuery as PurgeCip36RegistrationInvalidDelete, + PrimaryKeyQuery as PurgeCip36RegistrationInvalidSelect, + }, + rbac509_invalid_registration::{ + DeleteQuery as PurgeRbacRegistrationInvalidDelete, + PrimaryKeyQuery as PurgeRbacRegistrationInvalidSelect, + }, + rbac509_registration::{ + DeleteQuery as PurgeRbacRegistrationDelete, PrimaryKeyQuery as PurgeRbacRegistrationSelect, + }, + stake_registration::{ + DeleteQuery as PurgeStakeRegistrationDelete, + PrimaryKeyQuery as PurgeStakeRegistrationSelect, + }, + txi_by_hash::{DeleteQuery as PurgeTxiByHashDelete, PrimaryKeyQuery as PurgeTxiByHashSelect}, + txo_ada::{DeleteQuery as PurgeTxoAdaDelete, PrimaryKeyQuery as PurgeTxoAdaSelect}, + txo_assets::{DeleteQuery as PurgeTxoAssetsDelete, PrimaryKeyQuery as PurgeTxoAssetsSelect}, + unstaked_txo_ada::{ + DeleteQuery as PurgeTxoUnstakedAdaDelete, PrimaryKeyQuery as PurgeTxoUnstakedAdaSelect, + }, + unstaked_txo_assets::{ + DeleteQuery as PurgeTxoUnstakedAssetDelete, PrimaryKeyQuery as PurgeTxoUnstakedAssetSelect, + }, +}; +use rbac::{ + get_catalyst_id_from_stake_address::GetCatalystIdForStakeAddress, + get_catalyst_id_from_transaction_id::GetCatalystIdForTxnId, + get_rbac_invalid_registrations::GetRbac509InvalidRegistrations, + get_rbac_registrations::GetRbac509Registrations, +}; use registrations::{ get_all_invalids::GetAllInvalidRegistrationsQuery, get_all_registrations::GetAllRegistrationsQuery, get_from_stake_addr::GetRegistrationQuery, @@ -33,48 +81,29 @@ use staked_ada::{ use sync_status::update::SyncStatusInsertQuery; use tracing::error; -use super::block::{ - certs::CertInsertQuery, - cip36::Cip36InsertQuery, - rbac509::Rbac509InsertQuery, - txi::TxiInsertQuery, - txo::{ - insert_txo::TxoInsertQuery, insert_txo_asset::Params as TxoAssetInsert, - insert_unstaked_txo::Params as TxoUnstakedInsert, - insert_unstaked_txo_asset::Params as TxoUnstakedAssetInsert, - TxoInsertQuery as TxoInsertQueries, - }, -}; -use crate::{ - db::index::{ - block::{ - certs::StakeRegistrationInsertQuery, - cip36::{ - insert_cip36::Cip36Insert, insert_cip36_for_vote_key::Cip36ForVoteKeyInsert, - insert_cip36_invalid::Cip36InvalidInsert, - }, - rbac509::{ - insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert, - insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert, - insert_rbac509::Rbac509Insert, insert_rbac509_invalid::Rbac509InvalidInsert, - }, +use super::{ + block::{ + certs::{CertInsertQuery, StakeRegistrationInsertQuery}, + cip36::{ + insert_cip36::Cip36Insert, insert_cip36_for_vote_key::Cip36ForVoteKeyInsert, + insert_cip36_invalid::Cip36InvalidInsert, Cip36InsertQuery, }, - queries::{ - purge::txo_ada::{ - DeleteQuery as PurgeTxoAdaDelete, PrimaryKeyQuery as PurgeTxoAdaSelect, - }, - rbac::{ - get_catalyst_id_from_stake_address::GetCatalystIdForStakeAddress, - get_catalyst_id_from_transaction_id::GetCatalystIdForTxnId, - get_rbac_invalid_registrations::GetRbac509InvalidRegistrations, - get_rbac_registrations::GetRbac509Registrations, - }, + rbac509::{ + insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert, + insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert, insert_rbac509::Rbac509Insert, + insert_rbac509_invalid::Rbac509InvalidInsert, Rbac509InsertQuery, + }, + txi::TxiInsertQuery, + txo::{ + insert_txo::TxoInsertQuery, insert_txo_asset::Params as TxoAssetInsert, + insert_unstaked_txo::Params as TxoUnstakedInsert, + insert_unstaked_txo_asset::Params as TxoUnstakedAssetInsert, + TxoInsertQuery as TxoInsertQueries, }, - session::CassandraSessionError, }, - service::utilities::health::set_index_db_liveness, - settings::cassandra_db, + session::CassandraSessionError, }; +use crate::{service::utilities::health::set_index_db_liveness, settings::cassandra_db}; /// Batches of different sizes, prepared and ready for use. pub(crate) type SizedBatch = DashMap>; @@ -175,6 +204,85 @@ macro_rules! impl_query_statement { }; } +/// Prepare Queries +#[allow(dead_code)] +async fn prepare_queries( + session: &Arc, cfg: &cassandra_db::EnvVars, +) -> anyhow::Result> { + // Prepare a query dashmap + macro_rules! prepare_q { + ( $( $i:ty),* ) => { + { + let queries = vec![ + $( (<$i as Query>::type_id(), <$i as Query>::prepare_query(session, cfg).await?), )* + ]; + DashMap::from_iter(queries) + } + } + } + // WIP: Adding queries as they implement trait + let queries = prepare_q!( + // prepared batch queries + TxiInsertQuery, + TxoInsertQuery, + TxoAssetInsert, + TxoUnstakedInsert, + TxoUnstakedAssetInsert, + StakeRegistrationInsertQuery, + Cip36Insert, + Cip36InvalidInsert, + Cip36ForVoteKeyInsert, + UpdateTxoSpentQuery, + Rbac509Insert, + Rbac509InvalidInsert, + CatalystIdForTxnIdInsert, + CatalystIdForStakeAddressInsert, + // prepared statement queries + GetTxoByStakeAddressQuery, + GetTxiByTxnHashesQuery, + GetAssetsByStakeAddressQuery, + GetRegistrationQuery, + GetStakeAddrQuery, + GetStakeAddrFromVoteKeyQuery, + GetInvalidRegistrationQuery, + GetAllRegistrationsQuery, + GetAllInvalidRegistrationsQuery, + SyncStatusInsertQuery, + GetCatalystIdForStakeAddress, + GetCatalystIdForTxnId, + GetRbac509Registrations, + GetRbac509InvalidRegistrations, + // purge queries + PurgeTxoAdaSelect, + PurgeTxoAdaDelete, + PurgeTxoAssetsSelect, + PurgeTxoAssetsDelete, + PurgeTxoUnstakedAdaSelect, + PurgeTxoUnstakedAdaDelete, + PurgeTxoUnstakedAssetSelect, + PurgeTxoUnstakedAssetDelete, + PurgeTxiByHashSelect, + PurgeTxiByHashDelete, + PurgeStakeRegistrationSelect, + PurgeStakeRegistrationDelete, + PurgeCip36RegistrationSelect, + PurgeCip36RegistrationDelete, + PurgeCip36RegistrationInvalidSelect, + PurgeCip36RegistrationInvalidDelete, + PurgeCip36RegistrationForVoteKeySelect, + PurgeCip36RegistrationForVoteKeyDelete, + PurgeRbacRegistrationSelect, + PurgeRbacRegistrationDelete, + PurgeRbacRegistrationInvalidSelect, + PurgeRbacRegistrationInvalidDelete, + PurgeCatalystIdForTxnIdSelect, + PurgeCatalystIdForTxnIdDelete, + PurgeCatalystIdForStakeAddressSelect, + PurgeCatalystIdForStakeAddressDelete + ); + Ok(queries) +} + /// Prepares a statement. pub(crate) async fn prepare_statement( session: &Arc, query: Q, consistency: scylla::statement::Consistency, idempotent: bool, @@ -353,61 +461,6 @@ pub(crate) type FallibleQueryResults = anyhow::Result>; /// A set of query responses from tasks that can fail. pub(crate) type FallibleQueryTasks = Vec>; -/// Prepare Queries -#[allow(dead_code)] -async fn prepare_queries( - session: &Arc, cfg: &cassandra_db::EnvVars, -) -> anyhow::Result> { - // Prepare a query dashmap - macro_rules! prepare_q { - ( $( $i:ty),* ) => { - { - let queries = vec![ - $( (TypeId::of::<$i>(), <$i>::prepare_query(session, cfg).await?), )* - ]; - DashMap::from_iter(queries) - } - } - } - // WIP: Adding queries as they implement trait - let queries = prepare_q!( - // prepared batch queries - TxiInsertQuery, - TxoInsertQuery, - TxoAssetInsert, - TxoUnstakedInsert, - TxoUnstakedAssetInsert, - StakeRegistrationInsertQuery, - Cip36Insert, - Cip36InvalidInsert, - Cip36ForVoteKeyInsert, - UpdateTxoSpentQuery, - Rbac509Insert, - Rbac509InvalidInsert, - CatalystIdForTxnIdInsert, - CatalystIdForStakeAddressInsert, - // prepared statement queries - GetTxoByStakeAddressQuery, - GetTxiByTxnHashesQuery, - GetAssetsByStakeAddressQuery, - GetRegistrationQuery, - GetStakeAddrQuery, - GetStakeAddrFromVoteKeyQuery, - GetInvalidRegistrationQuery, - GetAllRegistrationsQuery, - GetAllInvalidRegistrationsQuery, - SyncStatusInsertQuery, - GetCatalystIdForStakeAddress, - GetCatalystIdForTxnId, - GetRbac509Registrations, - GetRbac509InvalidRegistrations, - // purge queries - PurgeTxoAdaSelect, - PurgeTxoAdaDelete - ); - Ok(queries) -} - impl PreparedQueries { /// Create new prepared queries for a given session. #[allow(clippy::too_many_lines)] diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs index e3a2a5211613..3bcc6113d34c 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs @@ -19,6 +19,7 @@ use crate::{ }, types::DbStakeAddress, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -59,6 +60,8 @@ impl From for Params { /// Get primary key for Catalyst ID For Stake Address registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all Catalyst ID For Stake Address registration primary /// keys. @@ -96,6 +99,8 @@ const DELETE_QUERY: &str = include_str!("cql/delete_catalyst_id_for_stake_addres /// Delete Catalyst ID For Stake Address registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs index cb3046d09ec1..6caa25430c82 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs @@ -19,6 +19,7 @@ use crate::{ }, types::DbTransactionId, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -65,6 +66,8 @@ impl From for Params { /// Get primary key for Catalyst ID For TX ID registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all Catalyst ID For TX ID registration primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -100,6 +103,8 @@ const DELETE_QUERY: &str = include_str!("cql/delete_catalyst_id_for_txn_id.cql") /// Delete Catalyst ID For TX ID registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs index 208d597828bf..4e651cfd7ea7 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbSlot, DbTxnIndex}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -70,6 +71,8 @@ impl From for Params { /// Get primary key for CIP-36 registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all CIP-36 registration primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -105,6 +108,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_cip36_registration.cql"); /// Delete CIP-36 registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs index 24a3ca157e69..4d7ae8d9b492 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbSlot, DbTxnIndex}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -74,6 +75,8 @@ impl From for Params { /// Get primary key for CIP-36 registration by Vote key query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all CIP-36 registration by Vote key primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -109,6 +112,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_cip36_registration_for_vot /// Delete CIP-36 registration by Vote key Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs index acd56bdb0e95..da57c7e02413 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbSlot, DbTxnIndex}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -66,6 +67,8 @@ impl From for Params { /// Get primary key for CIP-36 invalid registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all CIP-36 invalid registration primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -101,6 +104,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_cip36_registration_invalid /// Delete CIP-36 invalid registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs index b5e9a5c004dd..2d715de86495 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbCatalystId, DbTransactionId}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -62,6 +63,8 @@ impl From for Params { /// Get primary key for RBAC 509 invalid registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, DELETE_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all RBAC 509 invalid registration primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -97,6 +100,8 @@ const DELETE_QUERY: &str = include_str!("cql/delete_rbac_invalid_registration.cq /// Delete RBAC 509 invalid registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs index 6a6a04f4907e..054e94e35ba6 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbCatalystId, DbTransactionId}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -62,6 +63,8 @@ impl From for Params { /// Get primary key for RBAC 509 registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all RBAC 509 registration primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -97,6 +100,8 @@ const DELETE_QUERY: &str = include_str!("cql/delete_rbac_registration.cql"); /// Delete RBAC 509 registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs index 406c216bb0a7..29daa2cbe47f 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbSlot, DbStakeAddress, DbTxnIndex}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -70,6 +71,8 @@ impl From for Params { /// Get primary key for Stake Registration query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all Stake Registration primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -105,6 +108,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_stake_registration.cql"); /// Delete Stake Registration Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/txi_by_hash.rs b/catalyst-gateway/bin/src/db/index/queries/purge/txi_by_hash.rs index 20e59d301a52..40fdfdaed859 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/txi_by_hash.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/txi_by_hash.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbTransactionId, DbTxnOutputOffset}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -62,6 +63,8 @@ impl From for Params { /// Get primary key for TXI by hash query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all TXI by hash primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -97,6 +100,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_txi_by_txn_hashes.cql"); /// Delete TXI by hash Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/txo_assets.rs b/catalyst-gateway/bin/src/db/index/queries/purge/txo_assets.rs index a4597c4f1de0..b6a79b53df0d 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/txo_assets.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/txo_assets.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbSlot, DbStakeAddress, DbTxnIndex, DbTxnOutputOffset}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -85,6 +86,8 @@ impl From for Params { /// Get primary key for TXO Assets by Stake Address query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all TXO Assets by stake address primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -120,6 +123,8 @@ const DELETE_QUERY: &str = include_str!("cql/delete_txo_assets_by_stake_address. /// Delete TXO Assets by Stake Address Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_ada.rs b/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_ada.rs index 2b8f0ef424ae..28305863042b 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_ada.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_ada.rs @@ -19,6 +19,7 @@ use crate::{ }, types::{DbTransactionId, DbTxnOutputOffset}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -63,6 +64,8 @@ impl From for Params { /// Get primary key for Unstaked TXO ADA query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all Unstaked TXO ADA primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -98,6 +101,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_unstaked_txo_by_txn_hash.c /// Delete TXO by Stake Address Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_assets.rs b/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_assets.rs index 4d67842d5354..73568585391d 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_assets.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_assets.rs @@ -18,6 +18,7 @@ use crate::{ }, types::{DbTransactionId, DbTxnOutputOffset}, }, + impl_query_batch, impl_query_statement, settings::cassandra_db, }; @@ -76,6 +77,8 @@ impl From for Params { /// Get primary key for TXO Assets by TXN Hash query. pub(crate) struct PrimaryKeyQuery; +impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); + impl PrimaryKeyQuery { /// Prepares a query to get all TXO Assets by TXN Hash primary keys. pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { @@ -111,6 +114,8 @@ const DELETE_QUERY: &str = include_str!("./cql/delete_unstaked_txo_assets_by_txn /// Delete TXO Assets by TXN Hash Query pub(crate) struct DeleteQuery; +impl_query_batch!(DeleteQuery, DELETE_QUERY); + impl DeleteQuery { /// Prepare Batch of Delete Queries pub(crate) async fn prepare_batch( From b7c68e303c419dee1b534fae6b66135137ae1ffb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 23 Jun 2025 10:13:21 -0600 Subject: [PATCH 25/26] wip(cat-gateway): associated QUERY_STR const in Query trait * Begin replacing prepared queries * Update execute methods in CassandraSession --- .../bin/src/db/index/queries/mod.rs | 432 +++--------------- catalyst-gateway/bin/src/db/index/session.rs | 101 ++-- 2 files changed, 113 insertions(+), 420 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/mod.rs b/catalyst-gateway/bin/src/db/index/queries/mod.rs index 0574df31ed13..b408ed128eb7 100644 --- a/catalyst-gateway/bin/src/db/index/queries/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/mod.rs @@ -83,25 +83,24 @@ use tracing::error; use super::{ block::{ - certs::{CertInsertQuery, StakeRegistrationInsertQuery}, + certs::StakeRegistrationInsertQuery, cip36::{ insert_cip36::Cip36Insert, insert_cip36_for_vote_key::Cip36ForVoteKeyInsert, - insert_cip36_invalid::Cip36InvalidInsert, Cip36InsertQuery, + insert_cip36_invalid::Cip36InvalidInsert, }, rbac509::{ insert_catalyst_id_for_stake_address::CatalystIdForStakeAddressInsert, insert_catalyst_id_for_txn_id::CatalystIdForTxnIdInsert, insert_rbac509::Rbac509Insert, - insert_rbac509_invalid::Rbac509InvalidInsert, Rbac509InsertQuery, + insert_rbac509_invalid::Rbac509InvalidInsert, }, txi::TxiInsertQuery, txo::{ insert_txo::TxoInsertQuery, insert_txo_asset::Params as TxoAssetInsert, insert_unstaked_txo::Params as TxoUnstakedInsert, insert_unstaked_txo_asset::Params as TxoUnstakedAssetInsert, - TxoInsertQuery as TxoInsertQueries, }, }, - session::CassandraSessionError, + session::{CassandraSession, CassandraSessionError}, }; use crate::{service::utilities::health::set_index_db_liveness, settings::cassandra_db}; @@ -121,8 +120,18 @@ pub(crate) enum QueryKind { /// A trait to prepare Index DB queries. #[allow(dead_code)] pub(crate) trait Query: std::fmt::Display + std::any::Any { + /// CQL for query preparation. + const QUERY_STR: &'static str; + /// Returns the type id for the query. - fn type_id() -> TypeId; + fn type_id() -> std::any::TypeId { + std::any::TypeId::of::() + } + + /// Returns the CQL statement for the query in plain text. + fn query_str() -> &'static str { + Self::QUERY_STR + } /// Prepare the query async fn prepare_query( @@ -130,15 +139,29 @@ pub(crate) trait Query: std::fmt::Display + std::any::Any { ) -> anyhow::Result; } +/// Implement Display trait for types that implement Query +#[macro_export] +macro_rules! impl_display_for_query_type { + ($i:ty) => { + impl std::fmt::Display for $i { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + ::query_str() + ) + } + } + }; +} + /// Implement Query trait for batched types #[macro_export] macro_rules! impl_query_batch { ($i:ty, $c:ident) => { impl $crate::db::index::queries::Query for $i { - fn type_id() -> std::any::TypeId { - std::any::TypeId::of::<$i>() - } + const QUERY_STR: &'static str = $c; async fn prepare_query( session: &std::sync::Arc, @@ -159,11 +182,7 @@ macro_rules! impl_query_batch { } } - impl std::fmt::Display for $i { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{{$c}}") - } - } + $crate::impl_display_for_query_type!($i); }; } @@ -173,9 +192,7 @@ macro_rules! impl_query_statement { ($i:ty, $c:ident) => { impl $crate::db::index::queries::Query for $i { - fn type_id() -> std::any::TypeId { - std::any::TypeId::of::<$i>() - } + const QUERY_STR: &'static str = $c; async fn prepare_query( session: &std::sync::Arc, @@ -196,17 +213,12 @@ macro_rules! impl_query_statement { } } - impl std::fmt::Display for $i { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{{$c}}") - } - } + $crate::impl_display_for_query_type!($i); }; } /// Prepare Queries -#[allow(dead_code)] -async fn prepare_queries( +pub(crate) async fn prepare_queries( session: &Arc, cfg: &cassandra_db::EnvVars, ) -> anyhow::Result> { // Prepare a query dashmap @@ -325,357 +337,11 @@ pub(crate) async fn prepare_batch( Ok(sized_batches) } -/// All Prepared insert Queries that we know about. -#[derive(strum_macros::Display)] -#[allow(clippy::enum_variant_names)] -pub(crate) enum PreparedQuery { - /// TXO Insert query. - TxoAdaInsertQuery, - /// TXO Asset Insert query. - TxoAssetInsertQuery, - /// Unstaked TXO Insert query. - UnstakedTxoAdaInsertQuery, - /// Unstaked TXO Asset Insert query. - UnstakedTxoAssetInsertQuery, - /// TXI Insert query. - TxiInsertQuery, - /// Stake Registration Insert query. - StakeRegistrationInsertQuery, - /// CIP 36 Registration Insert Query. - Cip36RegistrationInsertQuery, - /// CIP 36 Registration Error Insert query. - Cip36RegistrationInsertErrorQuery, - /// CIP 36 Registration for voting key Insert query. - Cip36RegistrationForVoteKeyInsertQuery, - /// TXO spent Update query. - TxoSpentUpdateQuery, - /// RBAC 509 Registration Insert query. - Rbac509InsertQuery, - /// An invalid RBAC 509 registration Insert query. - Rbac509InvalidInsertQuery, - /// A Catalyst ID for transaction ID insert query. - CatalystIdForTxnIdInsertQuery, - /// A Catalyst ID for stake address insert query. - CatalystIdForStakeAddressInsertQuery, -} - -/// All prepared SELECT query statements (return data). -pub(crate) enum PreparedSelectQuery { - /// Get TXO by stake address query. - TxoByStakeAddress, - /// Get TXI by transaction hash query. - TxiByTransactionHash, - /// Get native assets by stake address query. - AssetsByStakeAddress, - /// Get Registrations - RegistrationFromStakeAddr, - /// Get invalid Registration - InvalidRegistrationsFromStakeAddr, - /// Get stake addr from stake hash - StakeAddrFromStakeHash, - /// Get stake addr from vote key - StakeAddrFromVoteKey, - /// Get Catalyst ID by transaction ID. - CatalystIdByTransactionId, - /// Get Catalyst ID by stake address. - CatalystIdByStakeAddress, - /// Get RBAC registrations by Catalyst ID. - RbacRegistrationsByCatalystId, - /// Get invalid RBAC registrations by Catalyst ID. - RbacInvalidRegistrationsByCatalystId, - /// Get all registrations for snapshot - GetAllRegistrations, - /// Get all invalid registrations for snapshot - GetAllInvalidRegistrations, -} - -/// All prepared UPSERT query statements (inserts/updates a single value of data). -pub(crate) enum PreparedUpsertQuery { - /// Sync Status Insert - SyncStatusInsert, -} - -/// All prepared queries for a session. -#[allow(clippy::struct_field_names)] -pub(crate) struct PreparedQueries { - /// TXO Insert query. - txo_insert_queries: SizedBatch, - /// TXO Asset Insert query. - txo_asset_insert_queries: SizedBatch, - /// Unstaked TXO Insert query. - unstaked_txo_insert_queries: SizedBatch, - /// Unstaked TXO Asset Insert query. - unstaked_txo_asset_insert_queries: SizedBatch, - /// TXI Insert query. - txi_insert_queries: SizedBatch, - /// TXI Insert query. - stake_registration_insert_queries: SizedBatch, - /// CIP36 Registrations. - cip36_registration_insert_queries: SizedBatch, - /// CIP36 Registration errors. - cip36_registration_error_insert_queries: SizedBatch, - /// CIP36 Registration for Stake Address Insert query. - cip36_registration_for_vote_key_insert_queries: SizedBatch, - /// Update TXO spent query. - txo_spent_update_queries: SizedBatch, - /// Get TXO by stake address query. - txo_by_stake_address_query: PreparedStatement, - /// Get TXI by transaction hash. - txi_by_txn_hash_query: PreparedStatement, - /// RBAC 509 Registrations. - rbac509_registration_insert_queries: SizedBatch, - /// Invalid RBAC 509 registrations. - rbac509_invalid_registration_insert_queries: SizedBatch, - /// Catalyst ID for transaction ID insert query. - catalyst_id_for_txn_id_insert_queries: SizedBatch, - /// Catalyst ID for stake address insert query. - catalyst_id_for_stake_address_insert_queries: SizedBatch, - /// Get native assets by stake address query. - native_assets_by_stake_address_query: PreparedStatement, - /// Get registrations - registration_from_stake_addr_query: PreparedStatement, - /// stake addr from stake hash - stake_addr_from_stake_address_query: PreparedStatement, - /// stake addr from vote key - stake_addr_from_vote_key_query: PreparedStatement, - /// Get invalid registrations - invalid_registrations_from_stake_addr_query: PreparedStatement, - /// Insert Sync Status update. - sync_status_insert: PreparedStatement, - /// Get Catalyst ID by stake address. - catalyst_id_by_stake_address_query: PreparedStatement, - /// Get Catalyst ID by transaction ID. - catalyst_id_by_transaction_id_query: PreparedStatement, - /// Get RBAC registrations by Catalyst ID. - rbac_registrations_by_catalyst_id_query: PreparedStatement, - /// Get invalid RBAC registrations by Catalyst ID. - rbac_invalid_registrations_by_catalyst_id_query: PreparedStatement, - /// Get all registrations for snapshot - get_all_registrations_query: PreparedStatement, - /// Get all invalid registrations for snapshot - get_all_invalid_registrations_query: PreparedStatement, -} - /// A set of query responses that can fail. pub(crate) type FallibleQueryResults = anyhow::Result>; /// A set of query responses from tasks that can fail. pub(crate) type FallibleQueryTasks = Vec>; -impl PreparedQueries { - /// Create new prepared queries for a given session. - #[allow(clippy::too_many_lines)] - pub(crate) async fn new( - session: Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - // We initialize like this, so that all errors preparing querys get shown before aborting. - - // Prepared batched queries - let txi_insert_queries = TxiInsertQuery::prepare_batch(&session, cfg).await?; - let ( - txo_insert_queries, - unstaked_txo_insert_queries, - txo_asset_insert_queries, - unstaked_txo_asset_insert_queries, - ) = TxoInsertQueries::prepare_batch(&session, cfg).await?; - let stake_registration_insert_queries = - CertInsertQuery::prepare_batch(&session, cfg).await?; - let ( - cip36_registration_insert_queries, - cip36_registration_error_insert_queries, - cip36_registration_for_vote_key_insert_queries, - ) = Cip36InsertQuery::prepare_batch(&session, cfg).await?; - let txo_spent_update_queries = UpdateTxoSpentQuery::prepare_batch(&session, cfg).await?; - let ( - rbac509_registration_insert_queries, - rbac509_invalid_registration_insert_queries, - catalyst_id_for_txn_id_insert_queries, - catalyst_id_for_stake_address_insert_queries, - ) = Rbac509InsertQuery::prepare_batch(&session, cfg).await?; - - // Prepared Statement queries - let txo_by_stake_address_query = GetTxoByStakeAddressQuery::prepare(session.clone()).await; - let txi_by_txn_hash_query = GetTxiByTxnHashesQuery::prepare(session.clone()).await; - let native_assets_by_stake_address_query = - GetAssetsByStakeAddressQuery::prepare(session.clone()).await; - let registration_from_stake_addr_query = - GetRegistrationQuery::prepare(session.clone()).await; - let stake_addr_from_stake_address = GetStakeAddrQuery::prepare(session.clone()).await; - let stake_addr_from_vote_key = GetStakeAddrFromVoteKeyQuery::prepare(session.clone()).await; - let invalid_registrations = GetInvalidRegistrationQuery::prepare(session.clone()).await; - let get_all_registrations_query = GetAllRegistrationsQuery::prepare(session.clone()).await; - let get_all_invalid_registrations_query = - GetAllInvalidRegistrationsQuery::prepare(session.clone()).await; - let sync_status_insert = SyncStatusInsertQuery::prepare(session.clone()).await?; - let catalyst_id_by_stake_address_query = - GetCatalystIdForStakeAddress::prepare(session.clone()).await?; - let catalyst_id_by_transaction_id_query = - GetCatalystIdForTxnId::prepare(session.clone()).await?; - let rbac_registrations_by_catalyst_id_query = - GetRbac509Registrations::prepare(session.clone()).await?; - let rbac_invalid_registrations_by_catalyst_id_query = - GetRbac509InvalidRegistrations::prepare(session.clone()).await?; - - Ok(Self { - txo_insert_queries, - txo_asset_insert_queries, - unstaked_txo_insert_queries, - unstaked_txo_asset_insert_queries, - txi_insert_queries, - stake_registration_insert_queries, - cip36_registration_insert_queries, - cip36_registration_error_insert_queries, - cip36_registration_for_vote_key_insert_queries, - txo_spent_update_queries, - txo_by_stake_address_query: txo_by_stake_address_query?, - txi_by_txn_hash_query: txi_by_txn_hash_query?, - rbac509_registration_insert_queries, - rbac509_invalid_registration_insert_queries, - catalyst_id_for_txn_id_insert_queries, - catalyst_id_for_stake_address_insert_queries, - native_assets_by_stake_address_query: native_assets_by_stake_address_query?, - registration_from_stake_addr_query: registration_from_stake_addr_query?, - stake_addr_from_stake_address_query: stake_addr_from_stake_address?, - stake_addr_from_vote_key_query: stake_addr_from_vote_key?, - invalid_registrations_from_stake_addr_query: invalid_registrations?, - sync_status_insert, - rbac_registrations_by_catalyst_id_query, - rbac_invalid_registrations_by_catalyst_id_query, - catalyst_id_by_stake_address_query, - catalyst_id_by_transaction_id_query, - get_all_registrations_query: get_all_registrations_query?, - get_all_invalid_registrations_query: get_all_invalid_registrations_query?, - }) - } - - /// Prepares a statement. - pub(crate) async fn prepare( - session: Arc, query: Q, consistency: scylla::statement::Consistency, - idempotent: bool, - ) -> anyhow::Result { - prepare_statement(&session, query, consistency, idempotent).await - } - - /// Prepares all permutations of the batch from 1 to max. - /// It is necessary to do this because batches are pre-sized, they can not be dynamic. - /// Preparing the batches in advance is a very larger performance increase. - pub(crate) async fn prepare_batch( - session: Arc, query: Q, cfg: &cassandra_db::EnvVars, - consistency: scylla::statement::Consistency, idempotent: bool, logged: bool, - ) -> anyhow::Result { - prepare_batch(session, query, cfg, consistency, idempotent, logged).await - } - - /// Executes a single query with the given parameters. - /// - /// Returns no data, and an error if the query fails. - pub(crate) async fn execute_upsert

( - &self, session: Arc, upsert_query: PreparedUpsertQuery, params: P, - ) -> anyhow::Result<()> - where P: SerializeRow { - let prepared_stmt = match upsert_query { - PreparedUpsertQuery::SyncStatusInsert => &self.sync_status_insert, - }; - - session - .execute_unpaged(prepared_stmt, params) - .await - .map_err(|e| { - match e { - QueryError::ConnectionPoolError(err) => { - set_index_db_liveness(false); - error!(error = %err, "Index DB connection failed. Liveness set to false."); - CassandraSessionError::ConnectionUnavailable { source: err.into() }.into() - }, - _ => anyhow::anyhow!(e), - } - })?; - - Ok(()) - } - - /// Executes a select query with the given parameters. - /// - /// Returns an iterator that iterates over all the result pages that the query - /// returns. - pub(crate) async fn execute_iter

( - &self, session: Arc, select_query: PreparedSelectQuery, params: P, - ) -> anyhow::Result - where P: SerializeRow { - let prepared_stmt = match select_query { - PreparedSelectQuery::TxoByStakeAddress => &self.txo_by_stake_address_query, - PreparedSelectQuery::TxiByTransactionHash => &self.txi_by_txn_hash_query, - PreparedSelectQuery::AssetsByStakeAddress => &self.native_assets_by_stake_address_query, - PreparedSelectQuery::RegistrationFromStakeAddr => { - &self.registration_from_stake_addr_query - }, - PreparedSelectQuery::StakeAddrFromStakeHash => { - &self.stake_addr_from_stake_address_query - }, - PreparedSelectQuery::StakeAddrFromVoteKey => &self.stake_addr_from_vote_key_query, - PreparedSelectQuery::InvalidRegistrationsFromStakeAddr => { - &self.invalid_registrations_from_stake_addr_query - }, - PreparedSelectQuery::RbacRegistrationsByCatalystId => { - &self.rbac_registrations_by_catalyst_id_query - }, - PreparedSelectQuery::RbacInvalidRegistrationsByCatalystId => { - &self.rbac_invalid_registrations_by_catalyst_id_query - }, - PreparedSelectQuery::CatalystIdByTransactionId => { - &self.catalyst_id_by_transaction_id_query - }, - PreparedSelectQuery::CatalystIdByStakeAddress => { - &self.catalyst_id_by_stake_address_query - }, - PreparedSelectQuery::GetAllRegistrations => &self.get_all_registrations_query, - PreparedSelectQuery::GetAllInvalidRegistrations => { - &self.get_all_invalid_registrations_query - }, - }; - session_execute_iter(session, prepared_stmt, params).await - } - - /// Execute a Batch query with the given parameters. - /// - /// Values should be a Vec of values which implement `SerializeRow` and they MUST be - /// the same, and must match the query being executed. - /// - /// This will divide the batch into optimal sized chunks and execute them until all - /// values have been executed or the first error is encountered. - pub(crate) async fn execute_batch( - &self, session: Arc, cfg: Arc, query: PreparedQuery, - values: Vec, - ) -> FallibleQueryResults { - let query_map = match query { - PreparedQuery::TxoAdaInsertQuery => &self.txo_insert_queries, - PreparedQuery::TxoAssetInsertQuery => &self.txo_asset_insert_queries, - PreparedQuery::UnstakedTxoAdaInsertQuery => &self.unstaked_txo_insert_queries, - PreparedQuery::UnstakedTxoAssetInsertQuery => &self.unstaked_txo_asset_insert_queries, - PreparedQuery::TxiInsertQuery => &self.txi_insert_queries, - PreparedQuery::StakeRegistrationInsertQuery => &self.stake_registration_insert_queries, - PreparedQuery::Cip36RegistrationInsertQuery => &self.cip36_registration_insert_queries, - PreparedQuery::Cip36RegistrationInsertErrorQuery => { - &self.cip36_registration_error_insert_queries - }, - PreparedQuery::Cip36RegistrationForVoteKeyInsertQuery => { - &self.cip36_registration_for_vote_key_insert_queries - }, - PreparedQuery::TxoSpentUpdateQuery => &self.txo_spent_update_queries, - PreparedQuery::Rbac509InsertQuery => &self.rbac509_registration_insert_queries, - PreparedQuery::Rbac509InvalidInsertQuery => { - &self.rbac509_invalid_registration_insert_queries - }, - PreparedQuery::CatalystIdForTxnIdInsertQuery => { - &self.catalyst_id_for_txn_id_insert_queries - }, - PreparedQuery::CatalystIdForStakeAddressInsertQuery => { - &self.catalyst_id_for_stake_address_insert_queries - }, - }; - session_execute_batch(session, query_map, cfg, query, values).await - } -} - /// Execute a Batch query with the given parameters. /// /// Values should be a Vec of values which implement `SerializeRow` and they MUST be @@ -683,7 +349,7 @@ impl PreparedQueries { /// /// This will divide the batch into optimal sized chunks and execute them until all /// values have been executed or the first error is encountered. -async fn session_execute_batch( +pub(crate) async fn session_execute_batch( session: Arc, query_map: &SizedBatch, cfg: Arc, query: Q, values: Vec, ) -> FallibleQueryResults { @@ -744,3 +410,27 @@ where P: SerializeRow { } }) } + +/// Executes a single query with the given parameters. +/// +/// Returns no data, and an error if the query fails. +pub(crate) async fn session_execute_upsert

( + session: Arc, prepared_stmt: &PreparedStatement, params: P, +) -> anyhow::Result<()> +where P: SerializeRow { + session + .execute_unpaged(prepared_stmt, params) + .await + .map_err(|e| { + match e { + QueryError::ConnectionPoolError(err) => { + set_index_db_liveness(false); + error!(error = %err, "Index DB connection failed. Liveness set to false."); + CassandraSessionError::ConnectionUnavailable { source: err.into() }.into() + }, + _ => anyhow::anyhow!(e), + } + })?; + + Ok(()) +} diff --git a/catalyst-gateway/bin/src/db/index/session.rs b/catalyst-gateway/bin/src/db/index/session.rs index f26472e14b24..c8c68fc8b66c 100644 --- a/catalyst-gateway/bin/src/db/index/session.rs +++ b/catalyst-gateway/bin/src/db/index/session.rs @@ -21,9 +21,8 @@ use tracing::{error, info}; use super::{ queries::{ - purge::{self, PreparedDeleteQuery}, - FallibleQueryResults, PreparedQueries, PreparedQuery, PreparedSelectQuery, - PreparedUpsertQuery, QueryKind, + prepare_queries, session_execute_batch, session_execute_iter, session_execute_upsert, + FallibleQueryResults, QueryKind, }, schema::create_schema, }; @@ -114,11 +113,6 @@ pub(crate) struct CassandraSession { /// The actual session. session: Arc, /// All prepared queries we can use on this session. - queries: Arc, - /// All prepared purge queries we can use on this session. - purge_queries: Arc, - /// All prepared queries we can use on this session. - #[allow(dead_code)] prepared_queries: DashMap, } @@ -185,13 +179,18 @@ impl CassandraSession { /// Returns an iterator that iterates over all the result pages that the query /// returns. pub(crate) async fn execute_iter

( - &self, select_query: PreparedSelectQuery, params: P, + &self, select_query: TypeId, params: P, ) -> anyhow::Result where P: SerializeRow { let session = self.session.clone(); - let queries = self.queries.clone(); + let Some(key_value) = self.prepared_queries.get(&select_query) else { + anyhow::bail!("Unregistered Query"); + }; + let QueryKind::Statement(ref stmt) = key_value.value() else { + anyhow::bail!("Invalid query kind"); + }; - queries.execute_iter(session, select_query, params).await + session_execute_iter(session, stmt, params).await } /// Execute a Batch query with the given parameters. @@ -202,24 +201,36 @@ impl CassandraSession { /// This will divide the batch into optimal sized chunks and execute them until all /// values have been executed or the first error is encountered. pub(crate) async fn execute_batch( - &self, query: PreparedQuery, values: Vec, + &self, query: TypeId, query_str: &str, values: Vec, ) -> FallibleQueryResults { let session = self.session.clone(); let cfg = self.cfg.clone(); - let queries = self.queries.clone(); - queries.execute_batch(session, cfg, query, values).await + let Some(key_value) = self.prepared_queries.get(&query) else { + anyhow::bail!("Unregistered Query"); + }; + let QueryKind::Batch(ref batch) = key_value.value() else { + anyhow::bail!("Invalid query kind"); + }; + + session_execute_batch(session, batch, cfg, query_str, values).await } /// Execute a query which returns no results, except an error if it fails. /// Can not be batched, takes a single set of parameters. pub(crate) async fn execute_upsert( - &self, query: PreparedUpsertQuery, value: T, + &self, query: TypeId, params: T, ) -> anyhow::Result<()> { let session = self.session.clone(); - let queries = self.queries.clone(); - queries.execute_upsert(session, query, value).await + let Some(key_value) = self.prepared_queries.get(&query) else { + anyhow::bail!("Unregistered Query"); + }; + let QueryKind::Statement(ref query) = key_value.value() else { + anyhow::bail!("Invalid query kind"); + }; + + session_execute_upsert(session, query, params).await } /// Execute a purge query with the given parameters. @@ -232,7 +243,7 @@ impl CassandraSession { /// /// NOTE: This is currently only used to purge volatile data. pub(crate) async fn purge_execute_batch( - &self, query: PreparedDeleteQuery, values: Vec, + &self, query: TypeId, query_str: &str, values: Vec, ) -> FallibleQueryResults { // Only execute purge queries on the volatile session let persistent = false; @@ -241,15 +252,20 @@ impl CassandraSession { anyhow::bail!("Volatile DB Session not found"); }; let cfg = self.cfg.clone(); - let queries = self.purge_queries.clone(); let session = volatile_db.session.clone(); + let Some(key_value) = self.prepared_queries.get(&query) else { + anyhow::bail!("Unregistered Query"); + }; + let QueryKind::Batch(ref batch) = key_value.value() else { + anyhow::bail!("Invalid query kind"); + }; - queries.execute_batch(session, cfg, query, values).await + session_execute_batch(session, batch, cfg, query_str, values).await } /// Execute a select query to gather primary keys for purging. pub(crate) async fn purge_execute_iter( - &self, query: purge::PreparedSelectQuery, + &self, query_type: TypeId, ) -> anyhow::Result { // Only execute purge queries on the volatile session let persistent = false; @@ -257,11 +273,15 @@ impl CassandraSession { // This should never happen anyhow::bail!("Volatile DB Session not found"); }; - let queries = self.purge_queries.clone(); - queries - .execute_iter(volatile_db.session.clone(), query) - .await + let Some(key_value) = self.prepared_queries.get(&query_type) else { + anyhow::bail!("Unregistered Query"); + }; + let QueryKind::Statement(ref query) = key_value.value() else { + anyhow::bail!("Invalid query kind"); + }; + + session_execute_iter(volatile_db.session.clone(), query, ()).await } /// Get underlying Raw Cassandra Session. @@ -399,14 +419,14 @@ async fn retry_init(cfg: cassandra_db::EnvVars, network: Network, persistent: bo continue; } - let queries = match PreparedQueries::new(session.clone(), &cfg).await { - Ok(queries) => Arc::new(queries), + let prepared_queries = match prepare_queries(&session, &cfg).await { + Ok(queries) => queries, Err(error) => { error!( db_type = db_type, network = %network, - error = %error, - "Failed to Create Cassandra Prepared Queries" + error = format!("{error:?}"), + "Failed to Prepare Queries for Cassandra DB Session" ); drop(INIT_SESSION_ERROR.set(Arc::new( CassandraSessionError::PreparingQueriesFailed { source: error }, @@ -415,30 +435,13 @@ async fn retry_init(cfg: cassandra_db::EnvVars, network: Network, persistent: bo }, }; - let purge_queries = match Box::pin(purge::PreparedQueries::new(session.clone(), &cfg)).await - { - Ok(queries) => Arc::new(queries), - Err(error) => { - error!( - db_type = db_type, - network = %network, - error = %error, - "Failed to Create Cassandra Prepared Purge Queries" - ); - drop(INIT_SESSION_ERROR.set(Arc::new( - CassandraSessionError::PreparingPurgeQueriesFailed { source: error }, - ))); - continue; - }, - }; + let cfg = Arc::new(cfg); let cassandra_session = CassandraSession { persistent, - cfg: Arc::new(cfg), + cfg, session, - queries, - purge_queries, - prepared_queries: DashMap::default(), + prepared_queries, }; // Save the session so we can execute queries on the DB From 5dfc47165ecb7b11e0a06a3d0b9d708ff4b52171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20Rosales?= Date: Mon, 23 Jun 2025 10:15:45 -0600 Subject: [PATCH 26/26] wip(cat-gateway): remove duplicated query preparation code --- .../purge/catalyst_id_for_stake_address.rs | 55 +--- .../queries/purge/catalyst_id_for_txn_id.rs | 52 +--- .../index/queries/purge/cip36_registration.rs | 55 +--- .../purge/cip36_registration_for_vote_key.rs | 55 +--- .../purge/cip36_registration_invalid.rs | 55 +--- .../bin/src/db/index/queries/purge/mod.rs | 283 ------------------ .../purge/rbac509_invalid_registration.rs | 55 +--- .../queries/purge/rbac509_registration.rs | 55 +--- .../index/queries/purge/stake_registration.rs | 55 +--- .../registrations/get_all_registrations.rs | 27 +- 10 files changed, 71 insertions(+), 676 deletions(-) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs index 3bcc6113d34c..81a002f36842 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_stake_address.rs @@ -1,26 +1,19 @@ //! Catalyst ID For Stake Address (RBAC 509 registrations) Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::DbStakeAddress, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -63,29 +56,13 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all Catalyst ID For Stake Address registration primary - /// keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get Catalyst ID For Stake Address registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all Catalyst ID For Stake Address registration primary /// keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::CatalystIdForStakeAddress) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -103,30 +80,16 @@ impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete Catalyst ID For Stake Address registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::CatalystIdForStakeAddress, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs index 6caa25430c82..1fce9f3e414d 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/catalyst_id_for_txn_id.rs @@ -1,26 +1,19 @@ //! Catalyst ID For TX ID (RBAC 509 registrations) Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::DbTransactionId, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -69,27 +62,11 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all Catalyst ID For TX ID registration primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get Catalyst ID For TX ID registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - - /// Executes a query to get all Catalyst ID For TX ID registration primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::CatalystIdForTxnId) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -106,31 +83,12 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete Catalyst ID For TX ID registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::CatalystIdForTxnId, params) + .purge_execute_batch(Self::type_id(), Self::query_str(), params) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs index 4e651cfd7ea7..1c50b0fb73b7 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration.rs @@ -1,25 +1,18 @@ //! CIP-36 registration Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::{DbSlot, DbTxnIndex}, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -74,27 +67,12 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all CIP-36 registration primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get CIP-36 registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all CIP-36 registration primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::Cip36Registration) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -111,31 +89,16 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete CIP-36 registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::Cip36Registration, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs index 4d7ae8d9b492..983d2ad5d40d 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_for_vote_key.rs @@ -1,25 +1,18 @@ //! CIP-36 registration by Vote Key Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow, Session}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::{DbSlot, DbTxnIndex}, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -78,27 +71,12 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all CIP-36 registration by Vote key primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get CIP-36 registration by Vote key primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all CIP-36 registration by Vote key primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::Cip36RegistrationForVoteKey) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -115,31 +93,16 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete CIP-36 registration by Vote key primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::Cip36RegistrationForVoteKey, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs index da57c7e02413..295e6e2b6da4 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/cip36_registration_invalid.rs @@ -1,25 +1,18 @@ //! CIP-36 Registration (Invalid) Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::{DbSlot, DbTxnIndex}, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -70,27 +63,12 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all CIP-36 invalid registration primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get CIP-36 invalid registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all CIP-36 invalid registration primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::Cip36RegistrationInvalid) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -107,31 +85,16 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete CIP-36 invalid registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::Cip36RegistrationInvalid, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs b/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs index 60f22474e147..505b7456a307 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/mod.rs @@ -13,286 +13,3 @@ pub(crate) mod txo_ada; pub(crate) mod txo_assets; pub(crate) mod unstaked_txo_ada; pub(crate) mod unstaked_txo_assets; - -use std::{fmt::Debug, sync::Arc}; - -use scylla::{ - prepared_statement::PreparedStatement, serialize::row::SerializeRow, - transport::iterator::QueryPager, Session, -}; - -use super::{FallibleQueryResults, SizedBatch}; -use crate::settings::cassandra_db; - -/// No parameters -const NO_PARAMS: () = (); - -/// All prepared DELETE query statements (purge DB table rows). -#[derive(strum_macros::Display)] -pub(crate) enum PreparedDeleteQuery { - /// TXO Delete query. - TxoAda, - /// TXO Assets Delete query. - TxoAssets, - /// Unstaked TXO Delete query. - UnstakedTxoAda, - /// Unstaked TXO Asset Delete query. - UnstakedTxoAsset, - /// TXI by TXN Hash Delete query. - Txi, - /// Stake Registration Delete query. - StakeRegistration, - /// CIP 36 Registration Delete Query. - Cip36Registration, - /// CIP 36 Registration Invalid Delete query. - Cip36RegistrationInvalid, - /// CIP 36 Registration for vote key Delete query. - Cip36RegistrationForVoteKey, - /// RBAC 509 Registration Delete query. - Rbac509, - /// Invalid RBAC 509 Registration Delete query. - Rbac509Invalid, - /// Catalyst ID For Transaction ID Delete query. - CatalystIdForTxnId, - /// Catalyst ID For Stake Address Delete query. - CatalystIdForStakeAddress, -} - -/// All prepared SELECT query statements (primary keys from table). -#[derive(strum_macros::Display)] -pub(crate) enum PreparedSelectQuery { - /// TXO Select query. - TxoAda, - /// TXO Asset Select query. - TxoAssets, - /// Unstaked TXO Select query. - UnstakedTxoAda, - /// Unstaked TXO Asset Select query. - UnstakedTxoAsset, - /// TXI by TXN Hash Select query. - Txi, - /// Stake Registration Select query. - StakeRegistration, - /// CIP 36 Registration Select Query. - Cip36Registration, - /// CIP 36 Registration Invalid Select query. - Cip36RegistrationInvalid, - /// CIP 36 Registration for vote key Select query. - Cip36RegistrationForVoteKey, - /// RBAC 509 Registration Select query. - Rbac509, - /// Invalid RBAC 509 Registration Select query. - Rbac509Invalid, - /// Catalyst ID For Transaction ID Select query. - CatalystIdForTxnId, - /// Catalyst ID For Stake Address Select query. - CatalystIdForStakeAddress, -} - -/// All prepared purge queries for a session. -pub(crate) struct PreparedQueries { - /// TXO ADA Primary Key Query. - select_txo_ada: PreparedStatement, - /// TXO Delete Query. - delete_txo_ada: SizedBatch, - /// TXO Asset Primary Key Query. - select_txo_assets: PreparedStatement, - /// TXO Assets Delete Query. - delete_txo_assets: SizedBatch, - /// Unstaked TXO ADA Primary Key Query. - select_unstaked_txo_ada: PreparedStatement, - /// Unstaked TXO ADA Delete Query. - delete_unstaked_txo_ada: SizedBatch, - /// Unstaked TXO Assets Primary Key Query. - select_unstaked_txo_assets: PreparedStatement, - /// Unstaked TXO Asset Delete Query. - delete_unstaked_txo_assets: SizedBatch, - /// TXI by TXN Hash by TXN Hash Primary Key Query. - select_txi_by_hash: PreparedStatement, - /// TXI by TXN Hash Delete Query. - delete_txi_by_hash: SizedBatch, - /// Stake Registration Primary Key Query. - select_stake_registration: PreparedStatement, - /// Stake Registration Delete Query. - delete_stake_registration: SizedBatch, - /// CIP36 Registrations Primary Key Query. - select_cip36_registration: PreparedStatement, - /// CIP36 Registrations Delete Query. - delete_cip36_registration: SizedBatch, - /// CIP36 Registration Invalid Primary Key Query. - select_cip36_registration_invalid: PreparedStatement, - /// CIP36 Registration Invalid Delete Query. - delete_cip36_registration_invalid: SizedBatch, - /// CIP36 Registration for Vote Key Primary Key Query. - select_cip36_registration_for_vote_key: PreparedStatement, - /// CIP36 Registration for Vote Key Delete Query. - delete_cip36_registration_for_vote_key: SizedBatch, - /// RBAC 509 Registrations Primary Key Query. - select_rbac509_registration: PreparedStatement, - /// RBAC 509 Registrations Delete Query. - delete_rbac509_registration: SizedBatch, - /// RBAC 509 invalid registrations Primary Key Query. - select_rbac509_invalid_registration: PreparedStatement, - /// RBAC 509 invalid registrations Delete Query. - delete_rbac509_invalid_registration: SizedBatch, - /// Catalyst ID for TX ID Primary Key Query.. - select_catalyst_id_for_txn_id: PreparedStatement, - /// Catalyst ID for TX ID Delete Query.. - delete_catalyst_id_for_txn_id: SizedBatch, - /// Catalyst ID for Stake Address Primary Key Query.. - select_catalyst_id_for_stake_address: PreparedStatement, - /// Catalyst ID for Stake Address Delete Query.. - delete_catalyst_id_for_stake_address: SizedBatch, -} - -impl PreparedQueries { - /// Create new prepared queries for a given session. - pub(crate) async fn new( - session: Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - // We initialize like this, so that all errors preparing querys get shown before aborting. - Ok(Self { - select_txo_ada: txo_ada::PrimaryKeyQuery::prepare(session.clone()).await?, - delete_txo_ada: txo_ada::DeleteQuery::prepare_batch(&session, cfg).await?, - select_txo_assets: txo_assets::PrimaryKeyQuery::prepare(&session.clone()).await?, - delete_txo_assets: txo_assets::DeleteQuery::prepare_batch(&session, cfg).await?, - select_unstaked_txo_ada: unstaked_txo_ada::PrimaryKeyQuery::prepare(&session.clone()) - .await?, - delete_unstaked_txo_ada: unstaked_txo_ada::DeleteQuery::prepare_batch(&session, cfg) - .await?, - select_unstaked_txo_assets: unstaked_txo_assets::PrimaryKeyQuery::prepare( - &session.clone(), - ) - .await?, - delete_unstaked_txo_assets: unstaked_txo_assets::DeleteQuery::prepare_batch( - &session, cfg, - ) - .await?, - select_txi_by_hash: txi_by_hash::PrimaryKeyQuery::prepare(&session).await?, - delete_txi_by_hash: txi_by_hash::DeleteQuery::prepare_batch(&session, cfg).await?, - select_stake_registration: stake_registration::PrimaryKeyQuery::prepare(&session) - .await?, - delete_stake_registration: stake_registration::DeleteQuery::prepare_batch( - &session, cfg, - ) - .await?, - select_cip36_registration: cip36_registration::PrimaryKeyQuery::prepare(&session) - .await?, - delete_cip36_registration: cip36_registration::DeleteQuery::prepare_batch( - &session, cfg, - ) - .await?, - select_cip36_registration_invalid: - cip36_registration_invalid::PrimaryKeyQuery::prepare(&session).await?, - delete_cip36_registration_invalid: - cip36_registration_invalid::DeleteQuery::prepare_batch(&session, cfg).await?, - select_cip36_registration_for_vote_key: - cip36_registration_for_vote_key::PrimaryKeyQuery::prepare(&session).await?, - delete_cip36_registration_for_vote_key: - cip36_registration_for_vote_key::DeleteQuery::prepare_batch(&session, cfg).await?, - select_rbac509_registration: rbac509_registration::PrimaryKeyQuery::prepare(&session) - .await?, - delete_rbac509_registration: rbac509_registration::DeleteQuery::prepare_batch( - &session, cfg, - ) - .await?, - select_rbac509_invalid_registration: - rbac509_invalid_registration::PrimaryKeyQuery::prepare(&session).await?, - delete_rbac509_invalid_registration: - rbac509_invalid_registration::DeleteQuery::prepare_batch(&session, cfg).await?, - select_catalyst_id_for_txn_id: catalyst_id_for_txn_id::PrimaryKeyQuery::prepare( - &session, - ) - .await?, - delete_catalyst_id_for_txn_id: catalyst_id_for_txn_id::DeleteQuery::prepare_batch( - &session, cfg, - ) - .await?, - select_catalyst_id_for_stake_address: - catalyst_id_for_stake_address::PrimaryKeyQuery::prepare(&session).await?, - delete_catalyst_id_for_stake_address: - catalyst_id_for_stake_address::DeleteQuery::prepare_batch(&session, cfg).await?, - }) - } - - /// Prepares a statement. - pub(crate) async fn prepare( - session: Arc, query: &str, consistency: scylla::statement::Consistency, - idempotent: bool, - ) -> anyhow::Result { - super::PreparedQueries::prepare(session, query, consistency, idempotent).await - } - - /// Prepares all permutations of the batch from 1 to max. - /// It is necessary to do this because batches are pre-sized, they can not be dynamic. - /// Preparing the batches in advance is a very larger performance increase. - pub(crate) async fn prepare_batch( - session: Arc, query: &str, cfg: &cassandra_db::EnvVars, - consistency: scylla::statement::Consistency, idempotent: bool, logged: bool, - ) -> anyhow::Result { - super::PreparedQueries::prepare_batch(session, query, cfg, consistency, idempotent, logged) - .await - } - - /// Executes a select query with the given parameters. - /// - /// Returns an iterator that iterates over all the result pages that the query - /// returns. - pub(crate) async fn execute_iter( - &self, session: Arc, select_query: PreparedSelectQuery, - ) -> anyhow::Result { - let prepared_stmt = match select_query { - PreparedSelectQuery::TxoAda => &self.select_txo_ada, - PreparedSelectQuery::TxoAssets => &self.select_txo_assets, - PreparedSelectQuery::UnstakedTxoAda => &self.select_unstaked_txo_ada, - PreparedSelectQuery::UnstakedTxoAsset => &self.select_unstaked_txo_assets, - PreparedSelectQuery::Txi => &self.select_txi_by_hash, - PreparedSelectQuery::StakeRegistration => &self.select_stake_registration, - PreparedSelectQuery::Cip36Registration => &self.select_cip36_registration, - PreparedSelectQuery::Cip36RegistrationInvalid => { - &self.select_cip36_registration_invalid - }, - PreparedSelectQuery::Cip36RegistrationForVoteKey => { - &self.select_cip36_registration_for_vote_key - }, - PreparedSelectQuery::Rbac509 => &self.select_rbac509_registration, - PreparedSelectQuery::Rbac509Invalid => &self.select_rbac509_invalid_registration, - PreparedSelectQuery::CatalystIdForTxnId => &self.select_catalyst_id_for_txn_id, - PreparedSelectQuery::CatalystIdForStakeAddress => { - &self.select_catalyst_id_for_stake_address - }, - }; - - super::session_execute_iter(session, prepared_stmt, NO_PARAMS).await - } - - /// Execute a purge query with the given parameters. - pub(crate) async fn execute_batch( - &self, session: Arc, cfg: Arc, query: PreparedDeleteQuery, - values: Vec, - ) -> FallibleQueryResults { - let query_map = match query { - PreparedDeleteQuery::TxoAda => &self.delete_txo_ada, - PreparedDeleteQuery::TxoAssets => &self.delete_txo_assets, - PreparedDeleteQuery::UnstakedTxoAda => &self.delete_unstaked_txo_ada, - PreparedDeleteQuery::UnstakedTxoAsset => &self.delete_unstaked_txo_assets, - PreparedDeleteQuery::Txi => &self.delete_txi_by_hash, - PreparedDeleteQuery::StakeRegistration => &self.delete_stake_registration, - PreparedDeleteQuery::Cip36Registration => &self.delete_cip36_registration, - PreparedDeleteQuery::Cip36RegistrationInvalid => { - &self.delete_cip36_registration_invalid - }, - PreparedDeleteQuery::Cip36RegistrationForVoteKey => { - &self.delete_cip36_registration_for_vote_key - }, - PreparedDeleteQuery::Rbac509 => &self.delete_rbac509_registration, - PreparedDeleteQuery::Rbac509Invalid => &self.delete_rbac509_invalid_registration, - PreparedDeleteQuery::CatalystIdForTxnId => &self.delete_catalyst_id_for_txn_id, - PreparedDeleteQuery::CatalystIdForStakeAddress => { - &self.delete_catalyst_id_for_stake_address - }, - }; - - super::session_execute_batch(session, query_map, cfg, query, values).await - } -} diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs index 2d715de86495..d198aac27b33 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_invalid_registration.rs @@ -1,25 +1,18 @@ //! RBAC 509 Registration Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::{DbCatalystId, DbTransactionId}, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -66,27 +59,12 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, DELETE_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all RBAC 509 invalid registration primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get RBAC 509 invalid registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all RBAC 509 invalid registration primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::Rbac509Invalid) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -103,31 +81,16 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete RBAC 509 invalid registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::Rbac509Invalid, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) } diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs index 054e94e35ba6..47252dbec6b1 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/rbac509_registration.rs @@ -1,25 +1,18 @@ //! RBAC 509 Registration Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::{DbCatalystId, DbTransactionId}, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -66,27 +59,12 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all RBAC 509 registration primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get RBAC 509 registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all RBAC 509 registration primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::Rbac509) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -103,31 +81,16 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete RBAC 509 registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::Rbac509, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs b/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs index 29daa2cbe47f..50b5a6aba040 100644 --- a/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs +++ b/catalyst-gateway/bin/src/db/index/queries/purge/stake_registration.rs @@ -1,25 +1,18 @@ //! Stake Registration Queries used in purging data. -use std::{fmt::Debug, sync::Arc}; +use std::fmt::Debug; -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, SerializeRow, - Session, -}; +use scylla::{transport::iterator::TypedRowStream, SerializeRow}; use tracing::error; use crate::{ db::{ index::{ - queries::{ - purge::{PreparedDeleteQuery, PreparedQueries, PreparedSelectQuery}, - FallibleQueryResults, SizedBatch, - }, + queries::{FallibleQueryResults, Query}, session::CassandraSession, }, types::{DbSlot, DbStakeAddress, DbTxnIndex}, }, impl_query_batch, impl_query_statement, - settings::cassandra_db, }; pub(crate) mod result { @@ -74,27 +67,12 @@ pub(crate) struct PrimaryKeyQuery; impl_query_statement!(PrimaryKeyQuery, SELECT_QUERY); impl PrimaryKeyQuery { - /// Prepares a query to get all Stake Registration primary keys. - pub(crate) async fn prepare(session: &Arc) -> anyhow::Result { - PreparedQueries::prepare( - session.clone(), - SELECT_QUERY, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare get Stake Registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{SELECT_QUERY}")) - } - /// Executes a query to get all Stake Registration primary keys. pub(crate) async fn execute( session: &CassandraSession, ) -> anyhow::Result> { let iter = session - .purge_execute_iter(PreparedSelectQuery::StakeRegistration) + .purge_execute_iter(::type_id()) .await? .rows_stream::()?; @@ -111,31 +89,16 @@ pub(crate) struct DeleteQuery; impl_query_batch!(DeleteQuery, DELETE_QUERY); impl DeleteQuery { - /// Prepare Batch of Delete Queries - pub(crate) async fn prepare_batch( - session: &Arc, cfg: &cassandra_db::EnvVars, - ) -> anyhow::Result { - PreparedQueries::prepare_batch( - session.clone(), - DELETE_QUERY, - cfg, - scylla::statement::Consistency::Any, - true, - false, - ) - .await - .inspect_err( - |error| error!(error=%error, "Failed to prepare delete Stake Registration primary key query."), - ) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{DELETE_QUERY}")) - } - /// Executes a DELETE Query pub(crate) async fn execute( session: &CassandraSession, params: Vec, ) -> FallibleQueryResults { let results = session - .purge_execute_batch(PreparedDeleteQuery::StakeRegistration, params) + .purge_execute_batch( + ::type_id(), + ::query_str(), + params, + ) .await?; Ok(results) diff --git a/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs b/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs index 25629fa651fa..a30a719522ba 100644 --- a/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs +++ b/catalyst-gateway/bin/src/db/index/queries/registrations/get_all_registrations.rs @@ -1,19 +1,11 @@ //! Get all registrations for snapshot -use std::sync::Arc; - -use scylla::{ - prepared_statement::PreparedStatement, transport::iterator::TypedRowStream, DeserializeRow, - SerializeRow, Session, -}; +use scylla::{transport::iterator::TypedRowStream, DeserializeRow, SerializeRow, Session}; use tracing::error; use crate::{ db::{ - index::{ - queries::{PreparedQueries, PreparedSelectQuery}, - session::CassandraSession, - }, + index::{queries::Query, session::CassandraSession}, types::DbTxnIndex, }, impl_query_statement, @@ -50,25 +42,12 @@ pub(crate) struct GetAllRegistrationsQuery { impl_query_statement!(GetAllRegistrationsQuery, GET_ALL_REGISTRATIONS); impl GetAllRegistrationsQuery { - /// Prepares get all registrations - pub(crate) async fn prepare(session: Arc) -> anyhow::Result { - PreparedQueries::prepare( - session, - GET_ALL_REGISTRATIONS, - scylla::statement::Consistency::All, - true, - ) - .await - .inspect_err(|error| error!(error=%error, "Failed to prepare get all registrations")) - .map_err(|error| anyhow::anyhow!("{error}\n--\n{GET_ALL_REGISTRATIONS}")) - } - /// Executes get all registrations for snapshot pub(crate) async fn execute( session: &CassandraSession, params: GetAllRegistrationsParams, ) -> anyhow::Result> { let iter = session - .execute_iter(PreparedSelectQuery::GetAllRegistrations, params) + .execute_iter(::type_id(), params) .await? .rows_stream::()?;