sui_analytics_indexer/handlers/tables/
checkpoint.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use 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}