sui_core/
consensus_commit_summary.rs1use consensus_core::{
8 BlockAPI, CommitAPI, CommitIndex, CommitRange, CommitRef, TrustedCommit,
9 storage::{Store as ConsensusStore, rocksdb_store::RocksDBStore},
10};
11use itertools::Itertools;
12use sui_types::messages_consensus::ConsensusTransaction;
13
14pub struct ConsensusCommitSummary {
17 pub commit: TrustedCommit,
18 pub tx_keys: Vec<String>,
19 pub missing_blocks: Vec<String>,
21}
22
23pub fn build_consensus_commit_summary(
25 cs: &RocksDBStore,
26 index: CommitIndex,
27) -> anyhow::Result<Option<ConsensusCommitSummary>> {
28 let commits = cs
29 .scan_commits(CommitRange::new(index..=index))
30 .map_err(|e| anyhow::anyhow!("{e}"))?;
31 let Some(commit) = commits.into_iter().next() else {
32 return Ok(None);
33 };
34
35 let commit_ref: CommitRef = commit.reference();
36 let block_refs: Vec<_> = commit.blocks().to_vec();
37 let blocks = cs
38 .read_blocks(&block_refs)
39 .map_err(|e| anyhow::anyhow!("{e}"))?;
40 let rejected = cs
41 .read_rejected_transactions(commit_ref)
42 .map_err(|e| anyhow::anyhow!("{e}"))?
43 .unwrap_or_default();
44
45 let mut tx_keys: Vec<String> = Vec::new();
46 let mut missing_blocks: Vec<String> = Vec::new();
47 for (block_ref, block_opt) in block_refs.iter().zip_eq(blocks) {
48 let Some(block) = block_opt else {
49 missing_blocks.push(format!("{block_ref:?}"));
50 continue;
51 };
52 let rejected_indices: std::collections::HashSet<u16> = rejected
53 .get(block_ref)
54 .map(|v| v.iter().copied().collect())
55 .unwrap_or_default();
56 for (i, tx_bytes) in block.transactions_data().iter().enumerate() {
57 if let Ok(tx) = bcs::from_bytes::<ConsensusTransaction>(tx_bytes) {
58 let key = format!("{:?}", tx.key());
59 if rejected_indices.contains(&(i as u16)) {
60 tx_keys.push(format!("{key} [rejected]"));
61 } else {
62 tx_keys.push(key);
63 }
64 }
65 }
66 }
67
68 Ok(Some(ConsensusCommitSummary {
69 commit,
70 tx_keys,
71 missing_blocks,
72 }))
73}