From c10f9144b1436d4918855a657715b453a6228a44 Mon Sep 17 00:00:00 2001 From: tv Date: Thu, 5 Nov 2026 02:27:03 +0100 Subject: dashboard: map remake votes --- src/remake/mod.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/remake/mod.rs') diff --git a/src/remake/mod.rs b/src/remake/mod.rs index 9351cc5..2273456 100644 --- a/src/remake/mod.rs +++ b/src/remake/mod.rs @@ -76,6 +76,43 @@ pub(crate) struct Summary { pub(crate) archived_epochs: usize, } +/// A remake of the local epoch as a dashboard shows it (`current`). +#[cfg_attr(not(feature = "dashboard"), allow(dead_code))] +#[derive(Debug, Clone, serde::Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) struct Current { + pub(crate) id: String, + pub(crate) coordinator: String, + pub(crate) phase: records::Phase, + /// Who voted for it (node IDs). + pub(crate) voters: Vec, + /// The epoch's generation it remakes: a member past it switched. + pub(crate) from_generation: u64, +} + +/// The remakes of `epoch` in `doc`, with their phase at `now` (expiry by `grace`, this +/// node's for records without their own: `Record::phase`). +#[cfg_attr(not(feature = "dashboard"), allow(dead_code))] +pub(crate) fn current( + doc: &Document, + epoch: Epoch, + now: crate::clock::UnixMillis, + grace: u64, +) -> Vec { + let local = records::EpochRecord::from(epoch); + records::load_all(doc) + .into_iter() + .filter(|(_, record)| record.proposal.from_epoch == local) + .map(|(id, record)| Current { + phase: record.phase(now, grace), + coordinator: record.proposal.coordinator.clone(), + voters: record.votes.keys().cloned().collect(), + from_generation: local.generation, + id, + }) + .collect() +} + /// The `Summary` of `remake` with the records of `doc`, whose epoch is `epoch`. pub(crate) fn summary(remake: &RemakeState, doc: &Document, epoch: Epoch) -> Summary { let local = records::EpochRecord::from(epoch); -- cgit v1.3.1