de_mls/core/conversation/
config.rs1use std::time::Duration;
4
5use crate::core::ProposalKind;
6use crate::protos::de_mls::messages::v1::TimingConfig;
7
8pub const DEFAULT_COMMIT_INACTIVITY_DURATION: Duration = Duration::from_secs(60);
11
12pub const DEFAULT_PROPOSAL_EXPIRATION: Duration = Duration::from_secs(600);
15
16pub const DEFAULT_CONSENSUS_TIMEOUT: Duration = Duration::from_secs(30);
19
20pub const DEFAULT_RECOVERY_INACTIVITY_DURATION: Duration = Duration::from_secs(5);
24
25pub const DEFAULT_VOTING_DELAY: Duration = Duration::from_secs(10);
28
29pub const DEFAULT_ELECTION_VOTING_DELAY: Duration = Duration::from_secs(5);
32
33pub const DEFAULT_LIVENESS_CRITERIA_YES: bool = true;
34
35pub const DEFAULT_PENDING_UPDATE_MAX_EPOCHS: u32 = 3;
36
37pub use crate::core::DEFAULT_MAX_RETRIES;
39
40#[derive(Debug, Clone)]
44pub struct ConversationConfig {
45 pub commit_inactivity_duration: Duration,
48 pub freeze_duration: Duration,
51 pub recovery_inactivity_duration: Duration,
54 pub proposal_expiration: Duration,
56 pub consensus_timeout: Duration,
57 pub pending_update_max_epochs: u32,
61 pub max_reelection_attempts: u32,
64 pub voting_delay: Duration,
69 pub election_voting_delay: Duration,
72 pub liveness_criteria_yes: bool,
76}
77
78impl Default for ConversationConfig {
79 fn default() -> Self {
80 Self {
81 commit_inactivity_duration: DEFAULT_COMMIT_INACTIVITY_DURATION,
82 freeze_duration: DEFAULT_COMMIT_INACTIVITY_DURATION / 2,
83 recovery_inactivity_duration: DEFAULT_RECOVERY_INACTIVITY_DURATION,
84 proposal_expiration: DEFAULT_PROPOSAL_EXPIRATION,
85 consensus_timeout: DEFAULT_CONSENSUS_TIMEOUT,
86 pending_update_max_epochs: DEFAULT_PENDING_UPDATE_MAX_EPOCHS,
87 max_reelection_attempts: DEFAULT_MAX_RETRIES,
88 voting_delay: DEFAULT_VOTING_DELAY,
89 election_voting_delay: DEFAULT_ELECTION_VOTING_DELAY,
90 liveness_criteria_yes: DEFAULT_LIVENESS_CRITERIA_YES,
91 }
92 }
93}
94
95impl ConversationConfig {
96 pub fn voting_delay_for(&self, kind: ProposalKind) -> Duration {
98 if kind.is_steward_election() {
99 self.election_voting_delay
100 } else {
101 self.voting_delay
102 }
103 }
104
105 pub fn apply_timing(&mut self, timing: &TimingConfig) {
110 self.commit_inactivity_duration =
111 Duration::from_millis(timing.commit_inactivity_duration_ms);
112 self.freeze_duration = Duration::from_millis(timing.freeze_duration_ms);
113 self.recovery_inactivity_duration =
114 Duration::from_millis(timing.recovery_inactivity_duration_ms);
115 self.proposal_expiration = Duration::from_millis(timing.proposal_expiration_ms);
116 self.consensus_timeout = Duration::from_millis(timing.consensus_timeout_ms);
117 }
118}
119
120impl From<&ConversationConfig> for TimingConfig {
123 fn from(config: &ConversationConfig) -> Self {
124 Self {
125 commit_inactivity_duration_ms: config.commit_inactivity_duration.as_millis() as u64,
126 freeze_duration_ms: config.freeze_duration.as_millis() as u64,
127 recovery_inactivity_duration_ms: config.recovery_inactivity_duration.as_millis() as u64,
128 proposal_expiration_ms: config.proposal_expiration.as_millis() as u64,
129 consensus_timeout_ms: config.consensus_timeout.as_millis() as u64,
130 }
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::*;
137
138 #[test]
142 fn timing_config_round_trip() {
143 let original = ConversationConfig {
144 commit_inactivity_duration: Duration::from_millis(100),
145 freeze_duration: Duration::from_millis(200),
146 recovery_inactivity_duration: Duration::from_millis(300),
147 proposal_expiration: Duration::from_millis(400),
148 consensus_timeout: Duration::from_millis(500),
149 ..ConversationConfig::default()
150 };
151 let timing = TimingConfig::from(&original);
152 let mut applied = ConversationConfig::default();
153 applied.apply_timing(&timing);
154 assert_eq!(
155 applied.commit_inactivity_duration,
156 Duration::from_millis(100)
157 );
158 assert_eq!(applied.freeze_duration, Duration::from_millis(200));
159 assert_eq!(
160 applied.recovery_inactivity_duration,
161 Duration::from_millis(300)
162 );
163 assert_eq!(applied.proposal_expiration, Duration::from_millis(400));
164 assert_eq!(applied.consensus_timeout, Duration::from_millis(500));
165 }
166
167 #[test]
170 fn voting_delay_dispatch_on_proposal_kind() {
171 let config = ConversationConfig {
172 voting_delay: Duration::from_secs(7),
173 election_voting_delay: Duration::from_secs(3),
174 ..ConversationConfig::default()
175 };
176 assert_eq!(
177 config.voting_delay_for(ProposalKind::Commit),
178 Duration::from_secs(7)
179 );
180 assert_eq!(
181 config.voting_delay_for(ProposalKind::StewardElection),
182 Duration::from_secs(3)
183 );
184 }
185}