WIP lot V : le tampon câblé dans le serveur (migration 0010, simulation, discard-simulation), tests en cours de reprise — repris tel quel après la coupure du 02/11

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-11-03 05:22:24 +01:00
co-authored by Claude Opus 5.5
parent ee37c3b4d5
commit 4b81a2e909
16 changed files with 1503 additions and 213 deletions
+29 -26
View File
@@ -25,10 +25,12 @@ use crate::objection;
use crate::threshold::Tally;
use serde::Serialize;
/// Whether a simulated vote counts for adoption, while the chain is closed.
/// The default of lot V, until Yvv answers: like a proven vote (with C = 50 and
/// five people, nothing enters into force in Monnaie libre). `false` turns it to
/// « shown, never counted for adoption »; the totals shown do not change.
/// Whether a simulated vote counts for adoption. Yvv, 2026-11-02: « Il compte,
/// puis s'efface » — like a proven vote, marked as simulated, until an act
/// « supprime » sets every simulated vote aside and examines again, with the
/// proven votes only, what they brought into force (`ld_server::simulation`).
/// `false` would turn it to « shown, never counted for adoption »; the totals
/// shown would not change.
pub const SIMULATED_ADOPTS: bool = true;
/// Where a vote stands.
@@ -39,7 +41,8 @@ pub enum Stage {
Recorded,
/// An intention still waiting for its proof, within its window.
Pending,
/// A vote of the simulation, while the chain is closed.
/// A vote of the simulation (cast while the chain was closed), until the act
/// that sets them aside.
Simulated,
}
@@ -59,21 +62,26 @@ impl Stage {
}
}
/// What the stages weigh, given whether the chain is open.
/// What the stages weigh. Opening the chain changes nothing by itself: the
/// simulated votes weigh until the act that sets them aside (Yvv, 2026-11-02).
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Rules {
/// The vote account is set: votes go through the chain, the simulation is over.
pub chain_open: bool,
/// See `SIMULATED_ADOPTS`.
pub simulated_adopts: bool,
}
impl Default for Rules {
fn default() -> Self {
Self { simulated_adopts: SIMULATED_ADOPTS }
}
}
impl Rules {
/// Does a vote at this stage weigh in the totals shown?
/// Does a vote at this stage weigh in the totals shown? Every stage: the
/// intention at once, the simulated vote with its mark.
pub fn shown(&self, stage: Stage) -> bool {
match stage {
Stage::Recorded | Stage::Pending => true,
Stage::Simulated => !self.chain_open,
Stage::Recorded | Stage::Pending | Stage::Simulated => true,
}
}
@@ -83,7 +91,7 @@ impl Rules {
match stage {
Stage::Recorded => true,
Stage::Pending => false,
Stage::Simulated => !self.chain_open && self.simulated_adopts,
Stage::Simulated => self.simulated_adopts,
}
}
}
@@ -316,24 +324,19 @@ mod tests {
#[test]
fn what_each_stage_weighs() {
let closed = Rules { chain_open: false, simulated_adopts: SIMULATED_ADOPTS };
let rules = Rules::default();
assert_eq!(rules.simulated_adopts, SIMULATED_ADOPTS);
for stage in [Stage::Recorded, Stage::Pending, Stage::Simulated] {
assert!(closed.shown(stage), "{stage:?}: everything is seen while the chain is closed");
assert!(rules.shown(stage), "{stage:?}: everything is seen, at once");
}
assert!(closed.adopts(Stage::Recorded));
assert!(!closed.adopts(Stage::Pending), "never an intention without proof");
assert!(closed.adopts(Stage::Simulated), "the default: a simulated vote counts like a proven one");
// The switch: shown, never counted for adoption.
let shown_only = Rules { simulated_adopts: false, ..closed };
assert!(rules.adopts(Stage::Recorded));
assert!(!rules.adopts(Stage::Pending), "never an intention without proof");
// Yvv, 2026-11-02: « Il compte, puis s'efface » — like a proven vote, until the act.
assert!(SIMULATED_ADOPTS && rules.adopts(Stage::Simulated));
// The other way, kept at hand: shown, never counted for adoption.
let shown_only = Rules { simulated_adopts: false };
assert!(shown_only.shown(Stage::Simulated) && !shown_only.adopts(Stage::Simulated));
assert!(shown_only.adopts(Stage::Recorded) && !shown_only.adopts(Stage::Pending));
// The chain opens: the simulated votes weigh nothing any more, anywhere.
for adopts in [true, false] {
let open = Rules { chain_open: true, simulated_adopts: adopts };
assert!(!open.shown(Stage::Simulated) && !open.adopts(Stage::Simulated));
assert!(open.shown(Stage::Pending) && !open.adopts(Stage::Pending));
assert!(open.shown(Stage::Recorded) && open.adopts(Stage::Recorded));
}
assert_eq!(Stage::of_source("simulated"), Stage::Simulated);
assert_eq!(Stage::of_source("chain"), Stage::Recorded);
assert_eq!(Stage::of_source("server"), Stage::Recorded);