cat_gateway/db/index/block/rbac509/
insert_rbac509.rs

1//! Insert RBAC 509 Registration Query.
2
3use std::{collections::HashSet, fmt::Debug, sync::Arc};
4
5use cardano_chain_follower::{hashes::TransactionId, Slot, StakeAddress, TxnIndex};
6use catalyst_types::{catalyst_id::CatalystId, uuid::UuidV4};
7use scylla::{client::session::Session, value::MaybeUnset, SerializeRow};
8use tracing::error;
9
10use crate::{
11    db::{
12        index::queries::{PreparedQueries, SizedBatch},
13        types::{DbCatalystId, DbSlot, DbStakeAddress, DbTransactionId, DbTxnIndex, DbUuidV4},
14    },
15    settings::cassandra_db::EnvVars,
16};
17
18/// RBAC Registration Indexing query
19const QUERY: &str = include_str!("cql/insert_rbac509.cql");
20
21/// Insert RBAC Registration Query Parameters
22#[derive(SerializeRow)]
23pub(crate) struct Params {
24    /// A Catalyst short identifier.
25    catalyst_id: DbCatalystId,
26    /// A block slot number.
27    slot_no: DbSlot,
28    /// A transaction offset inside the block.
29    txn_index: DbTxnIndex,
30    /// A transaction hash
31    txn_id: DbTransactionId,
32    /// Hash of Previous Transaction. Is `None` for the first registration. 32 Bytes.
33    prv_txn_id: MaybeUnset<DbTransactionId>,
34    /// A set of removed stake addresses.
35    removed_stake_addresses: HashSet<DbStakeAddress>,
36    /// A registration purpose.
37    ///
38    /// The value of purpose is `None` if the chain is modified by the registration
39    /// belonging to another chain (a stake address has been removed).
40    purpose: MaybeUnset<DbUuidV4>,
41}
42
43impl Debug for Params {
44    fn fmt(
45        &self,
46        f: &mut std::fmt::Formatter<'_>,
47    ) -> std::fmt::Result {
48        let prv_txn_id = match self.prv_txn_id {
49            MaybeUnset::Unset => "UNSET".to_owned(),
50            MaybeUnset::Set(ref v) => format!("{v:?}"),
51        };
52        f.debug_struct("Params")
53            .field("catalyst_id", &self.catalyst_id)
54            .field("txn_id", &self.txn_id)
55            .field("slot_no", &self.slot_no)
56            .field("txn_index", &self.txn_index)
57            .field("prv_txn_id", &prv_txn_id)
58            .field("removed_stake_addresses", &self.removed_stake_addresses)
59            .field("purpose", &self.purpose)
60            .finish()
61    }
62}
63
64impl Params {
65    /// Create a new record for this transaction.
66    pub(crate) fn new(
67        catalyst_id: CatalystId,
68        txn_id: TransactionId,
69        slot_no: Slot,
70        txn_index: TxnIndex,
71        prv_txn_id: Option<TransactionId>,
72        removed_stake_addresses: HashSet<StakeAddress>,
73        purpose: Option<UuidV4>,
74    ) -> Self {
75        let prv_txn_id = prv_txn_id.map_or(MaybeUnset::Unset, |v| MaybeUnset::Set(v.into()));
76        let removed_stake_addresses = removed_stake_addresses
77            .into_iter()
78            .map(Into::into)
79            .collect();
80        let purpose = purpose.map_or(MaybeUnset::Unset, |v| MaybeUnset::Set(v.into()));
81
82        Self {
83            catalyst_id: catalyst_id.into(),
84            txn_id: txn_id.into(),
85            slot_no: slot_no.into(),
86            txn_index: txn_index.into(),
87            prv_txn_id,
88            removed_stake_addresses,
89            purpose,
90        }
91    }
92
93    /// Prepare Batch of RBAC Registration Index Data Queries
94    pub(crate) async fn prepare_batch(
95        session: &Arc<Session>,
96        cfg: &EnvVars,
97    ) -> anyhow::Result<SizedBatch> {
98        PreparedQueries::prepare_batch(
99            session.clone(),
100            QUERY,
101            cfg,
102            scylla::statement::Consistency::Any,
103            true,
104            false,
105        )
106        .await
107        .inspect_err(
108            |error| error!(error=%error,"Failed to prepare Insert RBAC 509 Registration Query."),
109        )
110        .map_err(|error| anyhow::anyhow!("{error}\n--\n{QUERY}"))
111    }
112}