Skip to content

Commit ab65869

Browse files
committed
Implement actual voting rules
1 parent 13ffd97 commit ab65869

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

sim-rs/sim-core/src/model.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ pub enum NoVoteReason {
263263
ExtraTX,
264264
MissingTX,
265265
UncertifiedEBReference,
266+
LateEB,
267+
WrongEB,
266268
}
267269

268270
#[derive(Debug, Clone, Serialize)]

sim-rs/sim-core/src/sim/linear_leios.rs

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
model::{
1818
BlockId, Endorsement, EndorserBlockId, LinearEndorserBlock as EndorserBlock,
1919
LinearRankingBlock as RankingBlock, LinearRankingBlockHeader as RankingBlockHeader,
20-
Transaction, TransactionId, VoteBundle, VoteBundleId,
20+
NoVoteReason, Transaction, TransactionId, VoteBundle, VoteBundleId,
2121
},
2222
sim::{MiniProtocol, NodeImpl, SimCpuTask, SimMessage, lottery},
2323
};
@@ -116,7 +116,7 @@ pub enum CpuTask {
116116
/// An endorser block has been received, and its header has been validated. It is ready to propagate.
117117
EBHeaderValidated(NodeId, Arc<EndorserBlock>),
118118
/// An endorser block has been received and validated, and is ready to propagate
119-
EBBlockValidated(Arc<EndorserBlock>),
119+
EBBlockValidated(Arc<EndorserBlock>, Timestamp),
120120
/// A bundle of votes has been generated and is ready to propagate
121121
VTBundleGenerated(VoteBundle, Arc<EndorserBlock>),
122122
/// A bundle of votes has been received and validated, and is ready to propagate
@@ -131,7 +131,7 @@ impl SimCpuTask for CpuTask {
131131
Self::RBHeaderValidated(_, _, _, _) => "ValRH",
132132
Self::RBBlockValidated(_) => "ValRB",
133133
Self::EBHeaderValidated(_, _) => "ValEH",
134-
Self::EBBlockValidated(_) => "ValEB",
134+
Self::EBBlockValidated(_, _) => "ValEB",
135135
Self::VTBundleGenerated(_, _) => "GenVote",
136136
Self::VTBundleValidated(_, _) => "ValVote",
137137
}
@@ -145,7 +145,7 @@ impl SimCpuTask for CpuTask {
145145
Self::RBHeaderValidated(_, _, _, _) => "".to_string(),
146146
Self::RBBlockValidated(_) => "".to_string(),
147147
Self::EBHeaderValidated(_, _) => "".to_string(),
148-
Self::EBBlockValidated(_) => "".to_string(),
148+
Self::EBBlockValidated(_, _) => "".to_string(),
149149
Self::VTBundleGenerated(_, _) => "".to_string(),
150150
Self::VTBundleValidated(_, _) => "".to_string(),
151151
}
@@ -165,7 +165,7 @@ impl SimCpuTask for CpuTask {
165165
vec![time]
166166
}
167167
Self::EBHeaderValidated(_, _) => vec![config.eb_header_validation],
168-
Self::EBBlockValidated(eb) => {
168+
Self::EBBlockValidated(eb, _) => {
169169
let mut time = config.eb_body_validation_constant;
170170
let bytes: u64 = eb.txs.iter().map(|tx| tx.bytes).sum();
171171
time += config.eb_body_validation_per_byte * (bytes as u32);
@@ -351,7 +351,7 @@ impl NodeImpl for LinearLeiosNode {
351351
}
352352
CpuTask::RBBlockValidated(rb) => self.finish_validating_rb(rb),
353353
CpuTask::EBHeaderValidated(from, eb) => self.finish_validating_eb_header(from, eb),
354-
CpuTask::EBBlockValidated(eb) => self.finish_validating_eb(eb),
354+
CpuTask::EBBlockValidated(eb, seen) => self.finish_validating_eb(eb, seen),
355355
CpuTask::VTBundleGenerated(votes, _) => self.finish_generating_vote_bundle(votes),
356356
CpuTask::VTBundleValidated(from, votes) => {
357357
self.finish_validating_vote_bundle(from, votes)
@@ -748,7 +748,7 @@ impl LinearLeiosNode {
748748
for peer in &self.consumers {
749749
self.queued.send_to(*peer, Message::AnnounceEB(eb_id));
750750
}
751-
self.vote_for_endorser_block(&eb);
751+
self.vote_for_endorser_block(&eb, self.clock.now());
752752
}
753753
fn receive_announce_eb(&mut self, from: NodeId, id: EndorserBlockId) {
754754
self.leios
@@ -801,11 +801,12 @@ impl LinearLeiosNode {
801801
self.queued.send_to(*peer, Message::AnnounceEB(eb.id()));
802802
}
803803

804-
self.queued.schedule_cpu_task(CpuTask::EBBlockValidated(eb));
804+
self.queued
805+
.schedule_cpu_task(CpuTask::EBBlockValidated(eb, self.clock.now()));
805806
}
806807

807-
fn finish_validating_eb(&mut self, eb: Arc<EndorserBlock>) {
808-
self.vote_for_endorser_block(&eb);
808+
fn finish_validating_eb(&mut self, eb: Arc<EndorserBlock>, seen: Timestamp) {
809+
self.vote_for_endorser_block(&eb, seen);
809810
}
810811

811812
fn process_certified_ebs(&mut self, slot: u64) {
@@ -837,14 +838,14 @@ impl LinearLeiosNode {
837838

838839
// Voting
839840
impl LinearLeiosNode {
840-
fn vote_for_endorser_block(&mut self, eb: &Arc<EndorserBlock>) {
841-
if !self.try_vote_for_endorser_block(eb) && self.sim_config.emit_conformance_events {
841+
fn vote_for_endorser_block(&mut self, eb: &Arc<EndorserBlock>, seen: Timestamp) {
842+
if !self.try_vote_for_endorser_block(eb, seen) && self.sim_config.emit_conformance_events {
842843
self.tracker
843844
.track_linear_no_vote_generated(self.id, eb.id());
844845
}
845846
}
846847

847-
fn try_vote_for_endorser_block(&mut self, eb: &Arc<EndorserBlock>) -> bool {
848+
fn try_vote_for_endorser_block(&mut self, eb: &Arc<EndorserBlock>, seen: Timestamp) -> bool {
848849
let vrf_wins = lottery::vrf_probabilities(self.sim_config.vote_probability)
849850
.filter_map(|f| self.run_vrf(f))
850851
.count();
@@ -859,7 +860,11 @@ impl LinearLeiosNode {
859860
};
860861
self.tracker.track_vote_lottery_won(id);
861862

862-
// TODO: sometimes, don't vote
863+
if let Err(reason) = self.should_vote_for(eb, seen) {
864+
self.tracker
865+
.track_no_vote(eb.slot, 0, self.id, eb.id(), reason);
866+
return false;
867+
}
863868

864869
let mut ebs = BTreeMap::new();
865870
ebs.insert(eb.id(), vrf_wins);
@@ -873,6 +878,23 @@ impl LinearLeiosNode {
873878
true
874879
}
875880

881+
fn should_vote_for(&self, eb: &EndorserBlock, seen: Timestamp) -> Result<(), NoVoteReason> {
882+
let must_be_received_by =
883+
Timestamp::from_secs(eb.slot + self.sim_config.linear_vote_stage_length);
884+
if seen > must_be_received_by {
885+
// An EB must be received within L_vote slots of its creation.
886+
return Err(NoVoteReason::LateEB);
887+
}
888+
if self
889+
.latest_rb()
890+
.is_none_or(|rb| rb.header.eb_announcement != eb.id())
891+
{
892+
// We only vote for whichever EB we was referenced by the head of the current chain.
893+
return Err(NoVoteReason::WrongEB);
894+
}
895+
Ok(())
896+
}
897+
876898
fn finish_generating_vote_bundle(&mut self, votes: VoteBundle) {
877899
self.tracker.track_votes_generated(&votes);
878900
self.count_votes(&votes);

0 commit comments

Comments
 (0)