cat_gateway/db/index/block/cip36/
mod.rs1pub(crate) mod insert_cip36;
4pub(crate) mod insert_cip36_for_vote_key;
5pub(crate) mod insert_cip36_invalid;
6
7use std::sync::Arc;
8
9use cardano_blockchain_types::{Cip36, MultiEraBlock, Slot, TxnIndex};
10use scylla::Session;
11
12use crate::{
13 db::index::{
14 queries::{FallibleQueryTasks, PreparedQuery, SizedBatch},
15 session::CassandraSession,
16 },
17 settings::cassandra_db,
18};
19
20pub(crate) struct Cip36InsertQuery {
22 registrations: Vec<insert_cip36::Params>,
24 invalid: Vec<insert_cip36_invalid::Params>,
26 for_vote_key: Vec<insert_cip36_for_vote_key::Params>,
28}
29
30impl Cip36InsertQuery {
31 pub(crate) fn new() -> Self {
33 Cip36InsertQuery {
34 registrations: Vec::new(),
35 invalid: Vec::new(),
36 for_vote_key: Vec::new(),
37 }
38 }
39
40 pub(crate) async fn prepare_batch(
42 session: &Arc<Session>, cfg: &cassandra_db::EnvVars,
43 ) -> anyhow::Result<(SizedBatch, SizedBatch, SizedBatch)> {
44 let insert_cip36_batch = insert_cip36::Params::prepare_batch(session, cfg).await;
45 let insert_cip36_invalid_batch =
46 insert_cip36_invalid::Params::prepare_batch(session, cfg).await;
47 let insert_cip36_for_vote_key_addr_batch =
48 insert_cip36_for_vote_key::Params::prepare_batch(session, cfg).await;
49
50 Ok((
51 insert_cip36_batch?,
52 insert_cip36_invalid_batch?,
53 insert_cip36_for_vote_key_addr_batch?,
54 ))
55 }
56
57 pub(crate) fn index(&mut self, index: TxnIndex, slot_no: Slot, block: &MultiEraBlock) {
59 match Cip36::new(block, index, true) {
61 Ok(Some(cip36)) if cip36.is_valid() && cip36.is_cip36().unwrap_or_default() => {
64 if let Some(voting_key) = cip36.voting_pks().first() {
66 self.registrations.push(insert_cip36::Params::new(
67 voting_key, slot_no, index, &cip36,
68 ));
69
70 self.for_vote_key
71 .push(insert_cip36_for_vote_key::Params::new(
72 voting_key, slot_no, index, &cip36, true,
73 ));
74 }
75 },
76 Ok(Some(cip36)) if cip36.is_cip36().unwrap_or_default() => {
78 if cip36.stake_pk().is_some() {
80 if cip36.voting_pks().is_empty() {
81 self.invalid.push(insert_cip36_invalid::Params::new(
82 None, slot_no, index, &cip36,
83 ));
84 } else {
85 for voting_key in cip36.voting_pks() {
86 self.invalid.push(insert_cip36_invalid::Params::new(
87 Some(voting_key),
88 slot_no,
89 index,
90 &cip36,
91 ));
92 self.for_vote_key
93 .push(insert_cip36_for_vote_key::Params::new(
94 voting_key, slot_no, index, &cip36, false,
95 ));
96 }
97 }
98 }
99 },
100 _ => {},
101 }
102 }
103
104 pub(crate) fn execute(self, session: &Arc<CassandraSession>) -> FallibleQueryTasks {
108 let mut query_handles: FallibleQueryTasks = Vec::new();
109
110 if !self.registrations.is_empty() {
111 let inner_session = session.clone();
112 query_handles.push(tokio::spawn(async move {
113 inner_session
114 .execute_batch(
115 PreparedQuery::Cip36RegistrationInsertQuery,
116 self.registrations,
117 )
118 .await
119 }));
120 }
121
122 if !self.invalid.is_empty() {
123 let inner_session = session.clone();
124 query_handles.push(tokio::spawn(async move {
125 inner_session
126 .execute_batch(
127 PreparedQuery::Cip36RegistrationInsertErrorQuery,
128 self.invalid,
129 )
130 .await
131 }));
132 }
133
134 if !self.for_vote_key.is_empty() {
135 let inner_session = session.clone();
136 query_handles.push(tokio::spawn(async move {
137 inner_session
138 .execute_batch(
139 PreparedQuery::Cip36RegistrationForStakeAddrInsertQuery,
140 self.for_vote_key,
141 )
142 .await
143 }));
144 }
145
146 query_handles
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153 use crate::db::index::tests::test_utils;
154
155 #[test]
156 fn index() {
157 let block = test_utils::block_2();
158 let mut query = Cip36InsertQuery::new();
159 query.index(0.into(), 0.into(), &block);
160 assert_eq!(1, query.registrations.len());
161 assert!(query.invalid.is_empty());
162 assert_eq!(1, query.for_vote_key.len());
163 }
164}