use std::time::Duration;
use crate::core::ProposalKind;
use crate::protos::de_mls::messages::v1::TimingConfig;
pub const DEFAULT_COMMIT_INACTIVITY_DURATION: Duration = Duration::from_secs(60);
pub const DEFAULT_PROPOSAL_EXPIRATION: Duration = Duration::from_secs(600);
pub const DEFAULT_CONSENSUS_TIMEOUT: Duration = Duration::from_secs(30);
pub const DEFAULT_RECOVERY_INACTIVITY_DURATION: Duration = Duration::from_secs(5);
pub const DEFAULT_VOTING_DELAY: Duration = Duration::from_secs(10);
pub const DEFAULT_ELECTION_VOTING_DELAY: Duration = Duration::from_secs(5);
pub const DEFAULT_LIVENESS_CRITERIA_YES: bool = true;
pub const DEFAULT_PENDING_UPDATE_MAX_EPOCHS: u32 = 3;
pub use crate::core::DEFAULT_MAX_RETRIES;
#[derive(Debug, Clone)]
pub struct ConversationConfig {
pub commit_inactivity_duration: Duration,
pub freeze_duration: Duration,
pub recovery_inactivity_duration: Duration,
pub proposal_expiration: Duration,
pub consensus_timeout: Duration,
pub pending_update_max_epochs: u32,
pub max_reelection_attempts: u32,
pub voting_delay: Duration,
pub election_voting_delay: Duration,
pub liveness_criteria_yes: bool,
}
impl Default for ConversationConfig {
fn default() -> Self {
Self {
commit_inactivity_duration: DEFAULT_COMMIT_INACTIVITY_DURATION,
freeze_duration: DEFAULT_COMMIT_INACTIVITY_DURATION / 2,
recovery_inactivity_duration: DEFAULT_RECOVERY_INACTIVITY_DURATION,
proposal_expiration: DEFAULT_PROPOSAL_EXPIRATION,
consensus_timeout: DEFAULT_CONSENSUS_TIMEOUT,
pending_update_max_epochs: DEFAULT_PENDING_UPDATE_MAX_EPOCHS,
max_reelection_attempts: DEFAULT_MAX_RETRIES,
voting_delay: DEFAULT_VOTING_DELAY,
election_voting_delay: DEFAULT_ELECTION_VOTING_DELAY,
liveness_criteria_yes: DEFAULT_LIVENESS_CRITERIA_YES,
}
}
}
impl ConversationConfig {
pub fn voting_delay_for(&self, kind: ProposalKind) -> Duration {
if kind.is_steward_election() {
self.election_voting_delay
} else {
self.voting_delay
}
}
pub fn apply_timing(&mut self, timing: &TimingConfig) {
self.commit_inactivity_duration =
Duration::from_millis(timing.commit_inactivity_duration_ms);
self.freeze_duration = Duration::from_millis(timing.freeze_duration_ms);
self.recovery_inactivity_duration =
Duration::from_millis(timing.recovery_inactivity_duration_ms);
self.proposal_expiration = Duration::from_millis(timing.proposal_expiration_ms);
self.consensus_timeout = Duration::from_millis(timing.consensus_timeout_ms);
}
}
impl From<&ConversationConfig> for TimingConfig {
fn from(config: &ConversationConfig) -> Self {
Self {
commit_inactivity_duration_ms: config.commit_inactivity_duration.as_millis() as u64,
freeze_duration_ms: config.freeze_duration.as_millis() as u64,
recovery_inactivity_duration_ms: config.recovery_inactivity_duration.as_millis() as u64,
proposal_expiration_ms: config.proposal_expiration.as_millis() as u64,
consensus_timeout_ms: config.consensus_timeout.as_millis() as u64,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn timing_config_round_trip() {
let original = ConversationConfig {
commit_inactivity_duration: Duration::from_millis(100),
freeze_duration: Duration::from_millis(200),
recovery_inactivity_duration: Duration::from_millis(300),
proposal_expiration: Duration::from_millis(400),
consensus_timeout: Duration::from_millis(500),
..ConversationConfig::default()
};
let timing = TimingConfig::from(&original);
let mut applied = ConversationConfig::default();
applied.apply_timing(&timing);
assert_eq!(
applied.commit_inactivity_duration,
Duration::from_millis(100)
);
assert_eq!(applied.freeze_duration, Duration::from_millis(200));
assert_eq!(
applied.recovery_inactivity_duration,
Duration::from_millis(300)
);
assert_eq!(applied.proposal_expiration, Duration::from_millis(400));
assert_eq!(applied.consensus_timeout, Duration::from_millis(500));
}
#[test]
fn voting_delay_dispatch_on_proposal_kind() {
let config = ConversationConfig {
voting_delay: Duration::from_secs(7),
election_voting_delay: Duration::from_secs(3),
..ConversationConfig::default()
};
assert_eq!(
config.voting_delay_for(ProposalKind::Commit),
Duration::from_secs(7)
);
assert_eq!(
config.voting_delay_for(ProposalKind::StewardElection),
Duration::from_secs(3)
);
}
}