sui_analytics_indexer/handlers/tables/
checkpoint.rs1use std::sync::Arc;
5
6use anyhow::Result;
7use async_trait::async_trait;
8use fastcrypto::traits::EncodeDecodeBase64;
9use sui_indexer_alt_framework::pipeline::Processor;
10use sui_types::base_types::EpochId;
11use sui_types::effects::TransactionEffectsAPI;
12use sui_types::full_checkpoint_content::Checkpoint;
13use sui_types::transaction::TransactionDataAPI;
14
15use crate::Row;
16use crate::pipeline::Pipeline;
17use crate::tables::CheckpointRow;
18
19pub struct CheckpointProcessor;
20
21impl Row for CheckpointRow {
22 fn get_epoch(&self) -> EpochId {
23 self.epoch
24 }
25
26 fn get_checkpoint(&self) -> u64 {
27 self.sequence_number
28 }
29}
30
31#[async_trait]
32impl Processor for CheckpointProcessor {
33 const NAME: &'static str = Pipeline::Checkpoint.name();
34 type Value = CheckpointRow;
35
36 async fn process(&self, checkpoint: &Arc<Checkpoint>) -> Result<Vec<Self::Value>> {
37 let epoch = checkpoint.summary.data().epoch;
38 let sequence_number = checkpoint.summary.data().sequence_number;
39 let network_total_transactions = checkpoint.summary.data().network_total_transactions;
40 let previous_digest = checkpoint.summary.data().previous_digest;
41 let epoch_rolling_gas_cost_summary =
42 &checkpoint.summary.data().epoch_rolling_gas_cost_summary;
43 let timestamp_ms = checkpoint.summary.data().timestamp_ms;
44 let end_of_epoch_data = &checkpoint.summary.data().end_of_epoch_data;
45
46 let total_gas_cost = epoch_rolling_gas_cost_summary.computation_cost as i64
47 + epoch_rolling_gas_cost_summary.storage_cost as i64
48 - epoch_rolling_gas_cost_summary.storage_rebate as i64;
49 let total_transaction_blocks = checkpoint.transactions.len() as u64;
50 let mut total_transactions: u64 = 0;
51 let mut total_successful_transaction_blocks: u64 = 0;
52 let mut total_successful_transactions: u64 = 0;
53
54 for checkpoint_transaction in &checkpoint.transactions {
55 let cmds = checkpoint_transaction.transaction.kind().num_commands() as u64;
56 total_transactions += cmds;
57 if checkpoint_transaction.effects.status().is_ok() {
58 total_successful_transaction_blocks += 1;
59 total_successful_transactions += cmds;
60 }
61 }
62
63 let checkpoint_row = CheckpointRow {
64 sequence_number,
65 checkpoint_digest: checkpoint.summary.digest().base58_encode(),
66 previous_checkpoint_digest: previous_digest.map(|d| d.base58_encode()),
67 epoch,
68 end_of_epoch: end_of_epoch_data.is_some(),
69 total_gas_cost,
70 computation_cost: epoch_rolling_gas_cost_summary.computation_cost,
71 storage_cost: epoch_rolling_gas_cost_summary.storage_cost,
72 storage_rebate: epoch_rolling_gas_cost_summary.storage_rebate,
73 non_refundable_storage_fee: epoch_rolling_gas_cost_summary.non_refundable_storage_fee,
74 total_transaction_blocks,
75 total_transactions,
76 total_successful_transaction_blocks,
77 total_successful_transactions,
78 network_total_transaction: network_total_transactions,
79 timestamp_ms,
80 validator_signature: checkpoint.summary.auth_sig().signature.encode_base64(),
81 };
82
83 Ok(vec![checkpoint_row])
84 }
85}