tycho_collator/mempool/
state_update_context.rs1use std::sync::Arc;
2
3use anyhow::Result;
4use tycho_network::PeerId;
5use tycho_types::cell::HashBytes;
6use tycho_types::models::{
7 BlockId, ConsensusConfig, ConsensusInfo, ValidatorDescription, ValidatorSet,
8};
9
10use super::MempoolAnchorId;
11
12#[derive(Debug)]
13pub struct StateUpdateContext {
14 pub mc_block_id: BlockId,
15 pub mc_block_chain_time: u64,
16 pub top_processed_to_anchor_id: MempoolAnchorId,
17 pub consensus_info: ConsensusInfo,
18 pub consensus_config: ConsensusConfig,
19 pub shuffle_validators: bool,
20 pub prev_validator_set: Option<(HashBytes, Arc<ValidatorSet>)>,
21 pub current_validator_set: (HashBytes, Arc<ValidatorSet>),
22 pub next_validator_set: Option<(HashBytes, Arc<ValidatorSet>)>,
23}
24
25#[derive(PartialEq, Eq)]
27pub struct VSetsId<'a> {
28 prev_vset_switch_round: u32,
29 prev_shuffle_mc_validators: bool,
30 prev_validator_set: Option<&'a HashBytes>,
31
32 vset_switch_round: u32,
33 shuffle_validators: bool,
34 current_validator_set: &'a HashBytes,
35
36 next_validator_set: Option<&'a HashBytes>,
37}
38
39impl StateUpdateContext {
40 pub fn vid(&self) -> VSetsId<'_> {
42 VSetsId {
43 prev_vset_switch_round: self.consensus_info.prev_vset_switch_round,
44 prev_shuffle_mc_validators: self.consensus_info.prev_shuffle_mc_validators,
45 prev_validator_set: self.prev_validator_set.as_ref().map(|(hash, _)| hash),
46
47 vset_switch_round: self.consensus_info.vset_switch_round,
48 shuffle_validators: self.shuffle_validators,
49 current_validator_set: &self.current_validator_set.0,
50
51 next_validator_set: self.next_validator_set.as_ref().map(|(hash, _)| hash),
52 }
53 }
54
55 pub fn prev_v_set(&self) -> Vec<PeerId> {
57 Self::peer_ids((self.prev_validator_set.iter()).flat_map(|(_, v_set)| v_set.list.iter()))
58 }
59
60 pub fn curr_v_set(&self) -> Vec<PeerId> {
62 Self::peer_ids(self.current_validator_set.1.list.iter())
63 }
64
65 pub fn next_v_set(&self) -> Vec<PeerId> {
67 Self::peer_ids((self.next_validator_set.iter()).flat_map(|(_, v_set)| v_set.list.iter()))
68 }
69
70 pub fn prev_v_subset(&self) -> Result<Vec<(PeerId, u16)>> {
73 let Some((_, prev_validator_set)) = self.prev_validator_set.as_ref() else {
74 return Ok(Vec::new());
75 };
76 Self::compute_subset(
77 prev_validator_set,
78 self.consensus_info.prev_vset_switch_round,
79 self.consensus_info.prev_shuffle_mc_validators,
80 )
81 .ok_or_else(|| anyhow::anyhow!("failed to compute previous validator subset"))
82 }
83
84 pub fn curr_v_subset(&self) -> Result<Vec<(PeerId, u16)>> {
87 Self::compute_subset(
88 &self.current_validator_set.1,
89 self.consensus_info.vset_switch_round,
90 self.shuffle_validators,
91 )
92 .ok_or_else(|| anyhow::anyhow!("failed to compute current validator subset"))
93 }
94
95 fn compute_subset(
99 validator_set: &ValidatorSet,
100 switch_round: u32,
101 shuffle_validators: bool,
102 ) -> Option<Vec<(PeerId, u16)>> {
103 let (v_subset, _) =
104 validator_set.compute_mc_subset_indexed(switch_round, shuffle_validators)?;
105 let peer_idxs = v_subset
106 .into_iter()
107 .map(|desc| (PeerId(desc.public_key.0), desc.validator_idx))
108 .collect();
109 Some(peer_idxs)
110 }
111
112 fn peer_ids<'a>(iter: impl Iterator<Item = &'a ValidatorDescription>) -> Vec<PeerId> {
113 iter.map(|descr| PeerId(descr.public_key.0)).collect()
114 }
115}
116
117pub struct DebugStateUpdateContext<'a>(pub &'a StateUpdateContext);
118impl std::fmt::Debug for DebugStateUpdateContext<'_> {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 f.debug_struct("StateUpdateContext")
121 .field("mc_block_id", &self.0.mc_block_id.as_short_id())
122 .field("mc_block_chain_time", &self.0.mc_block_chain_time)
123 .field(
124 "top_processed_to_anchor_id",
125 &self.0.top_processed_to_anchor_id,
126 )
127 .field("consensus_info", &self.0.consensus_info)
128 .field("consensus_config", &self.0.consensus_config)
129 .field("shuffle_validators", &self.0.shuffle_validators)
130 .field(
131 "prev_validator_set.hash",
132 &self.0.prev_validator_set.as_ref().map(|s| s.0),
133 )
134 .field(
135 "current_validator_set.hash",
136 &self.0.current_validator_set.0,
137 )
138 .field(
139 "next_validator_set.hash",
140 &self.0.next_validator_set.as_ref().map(|s| s.0),
141 )
142 .finish()
143 }
144}