sui_analytics_indexer/handlers/
checkpoint_handler.rs1use anyhow::Result;
5use fastcrypto::traits::EncodeDecodeBase64;
6use std::sync::Arc;
7
8use sui_types::effects::TransactionEffectsAPI;
9use sui_types::full_checkpoint_content::CheckpointData;
10use sui_types::messages_checkpoint::CheckpointSummary;
11use sui_types::transaction::TransactionDataAPI;
12
13use crate::FileType;
14use crate::handlers::AnalyticsHandler;
15use crate::tables::CheckpointEntry;
16
17pub struct CheckpointHandler {}
18
19impl CheckpointHandler {
20 pub fn new() -> Self {
21 CheckpointHandler {}
22 }
23}
24
25#[async_trait::async_trait]
26impl AnalyticsHandler<CheckpointEntry> for CheckpointHandler {
27 async fn process_checkpoint(
28 &self,
29 checkpoint_data: &Arc<CheckpointData>,
30 ) -> Result<Box<dyn Iterator<Item = CheckpointEntry> + Send + Sync>> {
31 let checkpoint_entry = process_checkpoint_data(checkpoint_data);
32 Ok(Box::new(std::iter::once(checkpoint_entry)))
33 }
34
35 fn file_type(&self) -> Result<FileType> {
36 Ok(FileType::Checkpoint)
37 }
38
39 fn name(&self) -> &'static str {
40 "checkpoint"
41 }
42}
43
44fn process_checkpoint_data(checkpoint_data: &CheckpointData) -> CheckpointEntry {
45 let CheckpointSummary {
46 epoch,
47 sequence_number,
48 network_total_transactions,
49 previous_digest,
50 epoch_rolling_gas_cost_summary,
51 timestamp_ms,
52 end_of_epoch_data,
53 ..
54 } = checkpoint_data.checkpoint_summary.data();
55
56 let total_gas_cost = epoch_rolling_gas_cost_summary.computation_cost as i64
57 + epoch_rolling_gas_cost_summary.storage_cost as i64
58 - epoch_rolling_gas_cost_summary.storage_rebate as i64;
59 let total_transaction_blocks = checkpoint_data.transactions.len() as u64;
60 let mut total_transactions: u64 = 0;
61 let mut total_successful_transaction_blocks: u64 = 0;
62 let mut total_successful_transactions: u64 = 0;
63 for checkpoint_transaction in &checkpoint_data.transactions {
64 let txn_data = checkpoint_transaction.transaction.transaction_data();
65 let cmds = txn_data.kind().num_commands() as u64;
66 total_transactions += cmds;
67 if checkpoint_transaction.effects.status().is_ok() {
68 total_successful_transaction_blocks += 1;
69 total_successful_transactions += cmds;
70 }
71 }
72
73 CheckpointEntry {
74 sequence_number: *sequence_number,
75 checkpoint_digest: checkpoint_data.checkpoint_summary.digest().base58_encode(),
76 previous_checkpoint_digest: previous_digest.map(|d| d.base58_encode()),
77 epoch: *epoch,
78 end_of_epoch: end_of_epoch_data.is_some(),
79 total_gas_cost,
80 computation_cost: epoch_rolling_gas_cost_summary.computation_cost,
81 storage_cost: epoch_rolling_gas_cost_summary.storage_cost,
82 storage_rebate: epoch_rolling_gas_cost_summary.storage_rebate,
83 non_refundable_storage_fee: epoch_rolling_gas_cost_summary.non_refundable_storage_fee,
84 total_transaction_blocks,
85 total_transactions,
86 total_successful_transaction_blocks,
87 total_successful_transactions,
88 network_total_transaction: *network_total_transactions,
89 timestamp_ms: *timestamp_ms,
90 validator_signature: checkpoint_data
91 .checkpoint_summary
92 .auth_sig()
93 .signature
94 .encode_base64(),
95 }
96}