cat_gateway/db/index/block/cip36/
insert_cip36.rs

1//! Insert CIP36 Registration Query
2
3use std::{fmt::Debug, sync::Arc};
4
5use cardano_blockchain_types::{Cip36, Slot, TxnIndex, VotingPubKey};
6use scylla::{frame::value::MaybeUnset, SerializeRow, Session};
7use tracing::error;
8
9use crate::{
10    db::{
11        index::queries::{PreparedQueries, SizedBatch},
12        types::{DbSlot, DbTxnIndex},
13    },
14    settings::cassandra_db,
15};
16
17/// Index Registration by Stake Address
18const INSERT_CIP36_REGISTRATION_QUERY: &str = include_str!("./cql/insert_cip36.cql");
19
20/// Insert CIP-36 Registration Query Parameters
21#[derive(SerializeRow, Clone)]
22pub(crate) struct Params {
23    /// Full Stake Address (not hashed, 32 byte ED25519 Public key).
24    stake_public_key: Vec<u8>,
25    /// Nonce value after normalization.
26    nonce: num_bigint::BigInt,
27    /// Slot Number the cert is in.
28    slot_no: DbSlot,
29    /// Transaction Index.
30    txn_index: DbTxnIndex,
31    /// Voting Public Key
32    vote_key: Vec<u8>,
33    /// Full Payment Address (not hashed, 32 byte ED25519 Public key).
34    payment_address: MaybeUnset<Vec<u8>>,
35    /// Is the stake address a script or not.
36    is_payable: bool,
37    /// Raw nonce value.
38    raw_nonce: num_bigint::BigInt,
39    /// Is the Registration CIP36 format, or CIP15
40    cip36: bool,
41}
42
43impl Debug for Params {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        let payment_address = match self.payment_address {
46            MaybeUnset::Unset => "UNSET",
47            MaybeUnset::Set(ref v) => &hex::encode(v),
48        };
49        f.debug_struct("Params")
50            .field("stake_public_key", &self.stake_public_key)
51            .field("nonce", &self.nonce)
52            .field("slot_no", &self.slot_no)
53            .field("txn_index", &self.txn_index)
54            .field("vote_key", &self.vote_key)
55            .field("payment_address", &payment_address)
56            .field("is_payable", &self.is_payable)
57            .field("raw_nonce", &self.raw_nonce)
58            .field("cip36", &self.cip36)
59            .finish()
60    }
61}
62
63impl Params {
64    /// Create a new Insert Query.
65    pub fn new(vote_key: &VotingPubKey, slot_no: Slot, txn_index: TxnIndex, cip36: &Cip36) -> Self {
66        let stake_public_key = cip36
67            .stake_pk()
68            .map_or_else(Vec::new, |s| s.to_bytes().to_vec());
69        let vote_key = vote_key
70            .voting_pk()
71            .map_or_else(Vec::new, |v| v.to_bytes().to_vec());
72        let payment_address = cip36
73            .payment_address()
74            .map_or(MaybeUnset::Unset, |a| MaybeUnset::Set(a.to_vec()));
75        let is_cip36 = cip36.is_cip36().unwrap_or_default();
76        Params {
77            stake_public_key,
78            nonce: cip36.nonce().unwrap_or_default().into(),
79            slot_no: slot_no.into(),
80            txn_index: txn_index.into(),
81            vote_key,
82            payment_address,
83            is_payable: cip36.is_payable().unwrap_or_default(),
84            raw_nonce: cip36.raw_nonce().unwrap_or_default().into(),
85            cip36: is_cip36,
86        }
87    }
88
89    /// Prepare Batch of Insert CIP-36 Registration Index Data Queries
90    pub(crate) async fn prepare_batch(
91        session: &Arc<Session>, cfg: &cassandra_db::EnvVars,
92    ) -> anyhow::Result<SizedBatch> {
93        PreparedQueries::prepare_batch(
94            session.clone(),
95            INSERT_CIP36_REGISTRATION_QUERY,
96            cfg,
97            scylla::statement::Consistency::Any,
98            true,
99            false,
100        )
101        .await
102        .inspect_err(
103            |error| error!(error=%error,"Failed to prepare Insert CIP-36 Registration Query."),
104        )
105        .map_err(|error| anyhow::anyhow!("{error}\n--\n{INSERT_CIP36_REGISTRATION_QUERY}"))
106    }
107}