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

1//! Insert CIP36 Registration Query
2
3use std::{fmt::Debug, sync::Arc};
4
5use cardano_chain_follower::{Cip36, Slot, TxnIndex, VotingPubKey};
6use scylla::{client::session::Session, value::MaybeUnset, SerializeRow};
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(
45        &self,
46        f: &mut std::fmt::Formatter<'_>,
47    ) -> std::fmt::Result {
48        let payment_address = match self.payment_address {
49            MaybeUnset::Unset => "UNSET",
50            MaybeUnset::Set(ref v) => &hex::encode(v),
51        };
52        f.debug_struct("Params")
53            .field("stake_public_key", &self.stake_public_key)
54            .field("nonce", &self.nonce)
55            .field("slot_no", &self.slot_no)
56            .field("txn_index", &self.txn_index)
57            .field("vote_key", &self.vote_key)
58            .field("payment_address", &payment_address)
59            .field("is_payable", &self.is_payable)
60            .field("raw_nonce", &self.raw_nonce)
61            .field("cip36", &self.cip36)
62            .finish()
63    }
64}
65
66impl Params {
67    /// Create a new Insert Query.
68    pub fn new(
69        vote_key: &VotingPubKey,
70        slot_no: Slot,
71        txn_index: TxnIndex,
72        cip36: &Cip36,
73    ) -> Self {
74        let stake_public_key = cip36
75            .stake_pk()
76            .map_or_else(Vec::new, |s| s.to_bytes().to_vec());
77        let vote_key = vote_key
78            .voting_pk()
79            .map_or_else(Vec::new, |v| v.to_bytes().to_vec());
80        let payment_address = cip36
81            .payment_address()
82            .map_or(MaybeUnset::Unset, |a| MaybeUnset::Set(a.to_vec()));
83        let is_cip36 = cip36.is_cip36().unwrap_or_default();
84        Params {
85            stake_public_key,
86            nonce: cip36.nonce().unwrap_or_default().into(),
87            slot_no: slot_no.into(),
88            txn_index: txn_index.into(),
89            vote_key,
90            payment_address,
91            is_payable: cip36.is_payable().unwrap_or_default(),
92            raw_nonce: cip36.raw_nonce().unwrap_or_default().into(),
93            cip36: is_cip36,
94        }
95    }
96
97    /// Prepare Batch of Insert CIP-36 Registration Index Data Queries
98    pub(crate) async fn prepare_batch(
99        session: &Arc<Session>,
100        cfg: &cassandra_db::EnvVars,
101    ) -> anyhow::Result<SizedBatch> {
102        PreparedQueries::prepare_batch(
103            session.clone(),
104            INSERT_CIP36_REGISTRATION_QUERY,
105            cfg,
106            scylla::statement::Consistency::Any,
107            true,
108            false,
109        )
110        .await
111        .inspect_err(
112            |error| error!(error=%error,"Failed to prepare Insert CIP-36 Registration Query."),
113        )
114        .map_err(|error| anyhow::anyhow!("{error}\n--\n{INSERT_CIP36_REGISTRATION_QUERY}"))
115    }
116}