1use std::{
2 collections::{BTreeMap, HashMap, HashSet},
3 iter::once,
4 sync::Arc,
5};
6
7use anyhow::Context;
8use async_lock::RwLock;
9use async_trait::async_trait;
10use hotshot::{
11 tasks::EventTransformerState,
12 types::{SignatureKey, SystemContextHandle},
13};
14use hotshot_task_impls::{
15 events::HotShotEvent,
16 network::{
17 test::{ModifierClosure, NetworkEventTaskStateModifier},
18 NetworkEventTaskState,
19 },
20};
21use hotshot_types::{
22 consensus::OuterConsensus,
23 data::QuorumProposalWrapper,
24 epoch_membership::EpochMembershipCoordinator,
25 message::{
26 convert_proposal, GeneralConsensusMessage, Message, MessageKind, Proposal,
27 SequencingMessage, UpgradeLock,
28 },
29 simple_vote::{
30 HasEpoch, QuorumVote2, ViewSyncPreCommitData, ViewSyncPreCommitData2,
31 ViewSyncPreCommitVote, ViewSyncPreCommitVote2,
32 },
33 traits::{
34 election::Membership,
35 network::ConnectedNetwork,
36 node_implementation::{ConsensusTime, NodeImplementation, NodeType, Versions},
37 },
38 vote::HasViewNumber,
39};
40
41#[derive(Debug)]
42pub struct BadProposalViewDos {
44 pub multiplier: u64,
46 pub increment: u64,
48}
49
50#[async_trait]
51impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> EventTransformerState<TYPES, I, V>
52 for BadProposalViewDos
53{
54 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
55 vec![event.clone()]
56 }
57
58 async fn send_handler(
59 &mut self,
60 event: &HotShotEvent<TYPES>,
61 _public_key: &TYPES::SignatureKey,
62 _private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
63 _upgrade_lock: &UpgradeLock<TYPES, V>,
64 consensus: OuterConsensus<TYPES>,
65 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
66 _network: Arc<I::Network>,
67 ) -> Vec<HotShotEvent<TYPES>> {
68 match event {
69 HotShotEvent::QuorumProposalSend(proposal, signature) => {
70 let mut result = Vec::new();
71
72 for n in 1..self.multiplier {
73 let mut modified_proposal = proposal.clone();
74
75 modified_proposal.data.proposal.view_number += n * self.increment;
76
77 result.push(HotShotEvent::QuorumProposalSend(
78 modified_proposal,
79 signature.clone(),
80 ));
81 }
82
83 consensus.write().await.reset_actions();
84 result
85 },
86 _ => vec![event.clone()],
87 }
88 }
89}
90
91#[derive(Debug)]
92pub struct DoubleProposeVote;
94
95#[async_trait]
96impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> EventTransformerState<TYPES, I, V>
97 for DoubleProposeVote
98{
99 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
100 vec![event.clone()]
101 }
102
103 async fn send_handler(
104 &mut self,
105 event: &HotShotEvent<TYPES>,
106 _public_key: &TYPES::SignatureKey,
107 _private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
108 _upgrade_lock: &UpgradeLock<TYPES, V>,
109 _consensus: OuterConsensus<TYPES>,
110 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
111 _network: Arc<I::Network>,
112 ) -> Vec<HotShotEvent<TYPES>> {
113 match event {
114 HotShotEvent::QuorumProposalSend(..) | HotShotEvent::QuorumVoteSend(_) => {
115 vec![event.clone(), event.clone()]
116 },
117 _ => vec![event.clone()],
118 }
119 }
120}
121
122#[derive(Debug)]
123pub struct DishonestLeader<TYPES: NodeType> {
125 pub validated_proposals: Vec<QuorumProposalWrapper<TYPES>>,
127 pub total_proposals_from_node: u64,
129 pub dishonest_at_proposal_numbers: HashSet<u64>,
131 pub view_look_back: usize,
133 pub dishonest_proposal_view_numbers: Arc<RwLock<HashSet<TYPES::View>>>,
135}
136
137impl<TYPES: NodeType> DishonestLeader<TYPES> {
141 async fn handle_proposal_send_event(
144 &self,
145 event: &HotShotEvent<TYPES>,
146 proposal: &Proposal<TYPES, QuorumProposalWrapper<TYPES>>,
147 sender: &TYPES::SignatureKey,
148 ) -> HotShotEvent<TYPES> {
149 let length = self.validated_proposals.len();
150 if !self
151 .dishonest_at_proposal_numbers
152 .contains(&self.total_proposals_from_node)
153 || length == 0
154 {
155 return event.clone();
156 }
157
158 let proposal_from_look_back = if length - 1 < self.view_look_back {
160 self.validated_proposals[0].clone()
162 } else {
163 let index = (self.validated_proposals.len() - 1) - self.view_look_back;
164 self.validated_proposals[index].clone()
165 };
166
167 let mut dishonest_proposal = proposal.clone();
169 dishonest_proposal.data.proposal.justify_qc = proposal_from_look_back.proposal.justify_qc;
170
171 let mut dishonest_proposal_sent = self.dishonest_proposal_view_numbers.write().await;
173 dishonest_proposal_sent.insert(proposal.data.view_number());
174
175 HotShotEvent::QuorumProposalSend(dishonest_proposal, sender.clone())
176 }
177}
178
179#[async_trait]
180impl<TYPES: NodeType, I: NodeImplementation<TYPES> + std::fmt::Debug, V: Versions>
181 EventTransformerState<TYPES, I, V> for DishonestLeader<TYPES>
182{
183 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
184 vec![event.clone()]
185 }
186
187 async fn send_handler(
188 &mut self,
189 event: &HotShotEvent<TYPES>,
190 _public_key: &TYPES::SignatureKey,
191 _private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
192 _upgrade_lock: &UpgradeLock<TYPES, V>,
193 _consensus: OuterConsensus<TYPES>,
194 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
195 _network: Arc<I::Network>,
196 ) -> Vec<HotShotEvent<TYPES>> {
197 match event {
198 HotShotEvent::QuorumProposalSend(proposal, sender) => {
199 self.total_proposals_from_node += 1;
200 return vec![
201 self.handle_proposal_send_event(event, proposal, sender)
202 .await,
203 ];
204 },
205 HotShotEvent::QuorumProposalValidated(proposal, _) => {
206 self.validated_proposals.push(proposal.data.clone());
207 },
208 _ => {},
209 }
210 vec![event.clone()]
211 }
212}
213
214#[derive(Debug)]
215pub struct DishonestDa {
217 pub total_da_certs_sent_from_node: u64,
219 pub dishonest_at_da_cert_sent_numbers: HashSet<u64>,
221 pub total_views_add_to_cert: u64,
223}
224
225#[async_trait]
226impl<TYPES: NodeType, I: NodeImplementation<TYPES> + std::fmt::Debug, V: Versions>
227 EventTransformerState<TYPES, I, V> for DishonestDa
228{
229 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
230 vec![event.clone()]
231 }
232
233 async fn send_handler(
234 &mut self,
235 event: &HotShotEvent<TYPES>,
236 _public_key: &TYPES::SignatureKey,
237 _private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
238 _upgrade_lock: &UpgradeLock<TYPES, V>,
239 _consensus: OuterConsensus<TYPES>,
240 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
241 _network: Arc<I::Network>,
242 ) -> Vec<HotShotEvent<TYPES>> {
243 if let HotShotEvent::DacSend(cert, sender) = event {
244 self.total_da_certs_sent_from_node += 1;
245 if self
246 .dishonest_at_da_cert_sent_numbers
247 .contains(&self.total_da_certs_sent_from_node)
248 {
249 let mut result = vec![HotShotEvent::DacSend(cert.clone(), sender.clone())];
250 for i in 1..=self.total_views_add_to_cert {
251 let mut bad_cert = cert.clone();
252 bad_cert.view_number = cert.view_number + i;
253 result.push(HotShotEvent::DacSend(bad_cert, sender.clone()));
254 }
255 return result;
256 }
257 }
258 vec![event.clone()]
259 }
260}
261
262#[derive(Debug)]
264pub struct ViewDelay<TYPES: NodeType> {
265 pub number_of_views_to_delay: u64,
267 pub events_for_view: HashMap<TYPES::View, Vec<HotShotEvent<TYPES>>>,
269 pub stop_view_delay_at_view_number: u64,
271}
272
273#[async_trait]
274impl<TYPES: NodeType, I: NodeImplementation<TYPES> + std::fmt::Debug, V: Versions>
275 EventTransformerState<TYPES, I, V> for ViewDelay<TYPES>
276{
277 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
278 let correct_event = vec![event.clone()];
279 if let Some(view_number) = event.view_number() {
280 if *view_number >= self.stop_view_delay_at_view_number {
281 return correct_event;
282 }
283
284 let events_for_current_view = self.events_for_view.entry(view_number).or_default();
286 events_for_current_view.push(event.clone());
287
288 let view_diff = (*view_number).saturating_sub(self.number_of_views_to_delay);
290 if view_diff > 0 {
291 return match self
292 .events_for_view
293 .remove(&<TYPES as NodeType>::View::new(view_diff))
294 {
295 Some(lookback_events) => lookback_events.clone(),
296 None => vec![],
298 };
299 }
300 }
301
302 correct_event
303 }
304
305 async fn send_handler(
306 &mut self,
307 event: &HotShotEvent<TYPES>,
308 _public_key: &TYPES::SignatureKey,
309 _private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
310 _upgrade_lock: &UpgradeLock<TYPES, V>,
311 _consensus: OuterConsensus<TYPES>,
312 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
313 _network: Arc<I::Network>,
314 ) -> Vec<HotShotEvent<TYPES>> {
315 vec![event.clone()]
316 }
317}
318
319pub struct DishonestVoting<TYPES: NodeType> {
321 pub view_increment: u64,
323 pub modifier: Arc<ModifierClosure<TYPES>>,
325}
326
327#[async_trait]
328impl<TYPES: NodeType, I: NodeImplementation<TYPES> + std::fmt::Debug, V: Versions>
329 EventTransformerState<TYPES, I, V> for DishonestVoting<TYPES>
330{
331 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
332 vec![event.clone()]
333 }
334
335 async fn send_handler(
336 &mut self,
337 event: &HotShotEvent<TYPES>,
338 public_key: &TYPES::SignatureKey,
339 private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
340 upgrade_lock: &UpgradeLock<TYPES, V>,
341 _consensus: OuterConsensus<TYPES>,
342 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
343 _network: Arc<I::Network>,
344 ) -> Vec<HotShotEvent<TYPES>> {
345 if let HotShotEvent::QuorumVoteSend(vote) = event {
346 let new_view = vote.view_number + self.view_increment;
347 let spoofed_vote = QuorumVote2::<TYPES>::create_signed_vote(
348 vote.data.clone(),
349 new_view,
350 public_key,
351 private_key,
352 upgrade_lock,
353 )
354 .await
355 .context("Failed to sign vote")
356 .unwrap();
357 tracing::debug!("Sending Quorum Vote for view: {new_view:?}");
358 return vec![HotShotEvent::QuorumVoteSend(spoofed_vote)];
359 }
360 vec![event.clone()]
361 }
362
363 fn add_network_event_task(
364 &self,
365 handle: &mut SystemContextHandle<TYPES, I, V>,
366 network: Arc<<I as NodeImplementation<TYPES>>::Network>,
367 ) {
368 let network_state: NetworkEventTaskState<_, V, _, _> = NetworkEventTaskState {
369 network,
370 view: TYPES::View::genesis(),
371 epoch: None,
372 membership_coordinator: handle.membership_coordinator.clone(),
373 storage: handle.storage(),
374 storage_metrics: handle.storage_metrics(),
375 consensus: OuterConsensus::new(handle.consensus()),
376 upgrade_lock: handle.hotshot.upgrade_lock.clone(),
377 transmit_tasks: BTreeMap::new(),
378 epoch_height: handle.epoch_height,
379 id: handle.hotshot.id,
380 };
381 let modified_network_state = NetworkEventTaskStateModifier {
382 network_event_task_state: network_state,
383 modifier: Arc::clone(&self.modifier),
384 };
385 handle.add_task(modified_network_state);
386 }
387}
388
389impl<TYPES: NodeType> std::fmt::Debug for DishonestVoting<TYPES> {
390 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
391 f.debug_struct("DishonestVoting")
392 .field("view_increment", &self.view_increment)
393 .finish_non_exhaustive()
394 }
395}
396
397#[derive(Debug)]
398pub struct DishonestVoter<TYPES: NodeType> {
400 pub votes_sent: Vec<QuorumVote2<TYPES>>,
402 pub dishonest_proposal_view_numbers: Arc<RwLock<HashSet<TYPES::View>>>,
404}
405
406#[async_trait]
407impl<TYPES: NodeType, I: NodeImplementation<TYPES> + std::fmt::Debug, V: Versions>
408 EventTransformerState<TYPES, I, V> for DishonestVoter<TYPES>
409{
410 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
411 vec![event.clone()]
412 }
413
414 async fn send_handler(
415 &mut self,
416 event: &HotShotEvent<TYPES>,
417 public_key: &TYPES::SignatureKey,
418 private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
419 upgrade_lock: &UpgradeLock<TYPES, V>,
420 _consensus: OuterConsensus<TYPES>,
421 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
422 _network: Arc<I::Network>,
423 ) -> Vec<HotShotEvent<TYPES>> {
424 match event {
425 HotShotEvent::QuorumProposalRecv(proposal, _sender) => {
426 let dishonest_proposals = self.dishonest_proposal_view_numbers.read().await;
428 if dishonest_proposals.contains(&proposal.data.view_number()) {
429 let vote = QuorumVote2::<TYPES>::create_signed_vote(
433 self.votes_sent.last().unwrap().data.clone(),
434 event.view_number().unwrap(),
435 public_key,
436 private_key,
437 upgrade_lock,
438 )
439 .await
440 .context("Failed to sign vote")
441 .unwrap();
442 return vec![HotShotEvent::QuorumVoteSend(vote)];
443 }
444 },
445 HotShotEvent::TimeoutVoteSend(vote) => {
446 let dishonest_proposals = self.dishonest_proposal_view_numbers.read().await;
448 if dishonest_proposals.contains(&vote.view_number) {
449 return vec![];
452 }
453 },
454 HotShotEvent::QuorumVoteSend(vote) => {
455 self.votes_sent.push(vote.clone());
456 },
457 _ => {},
458 }
459 vec![event.clone()]
460 }
461}
462
463#[derive(Debug)]
478pub struct DishonestViewSyncRelay {
479 pub dishonest_proposal_view_numbers: Vec<u64>,
480 pub dishonest_vote_view_numbers: Vec<u64>,
481 pub first_f_honest_nodes: Vec<u64>,
482 pub second_f_honest_nodes: Vec<u64>,
483 pub one_honest_node: u64,
484 pub f_dishonest_nodes: Vec<u64>,
485}
486
487#[async_trait]
488impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> EventTransformerState<TYPES, I, V>
489 for DishonestViewSyncRelay
490{
491 async fn send_handler(
492 &mut self,
493 event: &HotShotEvent<TYPES>,
494 _public_key: &TYPES::SignatureKey,
495 _private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
496 upgrade_lock: &UpgradeLock<TYPES, V>,
497 _consensus: OuterConsensus<TYPES>,
498 membership_coordinator: EpochMembershipCoordinator<TYPES>,
499 network: Arc<I::Network>,
500 ) -> Vec<HotShotEvent<TYPES>> {
501 match event {
502 HotShotEvent::QuorumProposalSend(proposal, sender) => {
503 let view_number = proposal.data.view_number();
504 if !self.dishonest_proposal_view_numbers.contains(&view_number) {
505 return vec![event.clone()];
506 }
507 let message_kind = if upgrade_lock.epochs_enabled(view_number).await {
508 MessageKind::<TYPES>::from_consensus_message(SequencingMessage::General(
509 GeneralConsensusMessage::Proposal2(convert_proposal(proposal.clone())),
510 ))
511 } else {
512 MessageKind::<TYPES>::from_consensus_message(SequencingMessage::General(
513 GeneralConsensusMessage::Proposal(convert_proposal(proposal.clone())),
514 ))
515 };
516 let message = Message {
517 sender: sender.clone(),
518 kind: message_kind,
519 };
520 let serialized_message = match upgrade_lock.serialize(&message).await {
521 Ok(serialized) => serialized,
522 Err(e) => {
523 panic!("Failed to serialize message: {e}");
524 },
525 };
526 let second_f_honest_it = self.second_f_honest_nodes.iter();
527 let f_dishonest_it = self.f_dishonest_nodes.iter();
528 let one_honest_it = once(&self.one_honest_node);
529 let chained_it: Box<dyn Iterator<Item = &u64> + Send> =
530 if &*view_number == self.dishonest_proposal_view_numbers.first().unwrap() {
531 Box::new(second_f_honest_it.chain(one_honest_it.chain(f_dishonest_it)))
533 } else {
534 Box::new(second_f_honest_it.chain(one_honest_it))
536 };
537 for node_id in chained_it {
538 let dummy_view = TYPES::View::new(*node_id);
539 let Ok(node) = membership_coordinator
540 .membership()
541 .read()
542 .await
543 .leader(dummy_view, proposal.data.epoch())
544 else {
545 panic!(
546 "Failed to find leader for view {} and epoch {:?}",
547 dummy_view,
548 proposal.data.epoch()
549 );
550 };
551 let transmit_result = network
552 .direct_message(serialized_message.clone(), node.clone())
553 .await;
554 match transmit_result {
555 Ok(()) => tracing::info!(
556 "Sent proposal for view {} to node {}",
557 proposal.data.view_number(),
558 node_id
559 ),
560 Err(e) => panic!("Failed to send message task: {e:?}"),
561 }
562 }
563 vec![]
564 },
565 HotShotEvent::QuorumVoteSend(vote) => {
566 if !self.dishonest_vote_view_numbers.contains(&vote.view_number) {
567 return vec![event.clone()];
568 }
569 vec![]
570 },
571 HotShotEvent::TimeoutVoteSend(vote) => {
572 if !self.dishonest_vote_view_numbers.contains(&vote.view_number) {
573 return vec![event.clone()];
574 }
575 vec![]
576 },
577 HotShotEvent::ViewSyncPreCommitVoteSend(vote) => {
578 if !self.dishonest_vote_view_numbers.contains(&vote.view_number) {
579 return vec![event.clone()];
580 }
581 vec![]
582 },
583 HotShotEvent::ViewSyncPreCommitCertificateSend(certificate, sender) => {
584 let view_number = certificate.data.round;
585 if !self.dishonest_proposal_view_numbers.contains(&view_number) {
586 return vec![event.clone()];
587 }
588 let message_kind = if upgrade_lock.epochs_enabled(view_number).await {
589 MessageKind::<TYPES>::from_consensus_message(SequencingMessage::General(
590 GeneralConsensusMessage::ViewSyncPreCommitCertificate2(certificate.clone()),
591 ))
592 } else {
593 MessageKind::<TYPES>::from_consensus_message(SequencingMessage::General(
594 GeneralConsensusMessage::ViewSyncPreCommitCertificate(
595 certificate.clone().to_vsc(),
596 ),
597 ))
598 };
599 let message = Message {
600 sender: sender.clone(),
601 kind: message_kind,
602 };
603 let serialized_message = match upgrade_lock.serialize(&message).await {
604 Ok(serialized) => serialized,
605 Err(e) => {
606 panic!("Failed to serialize message: {e}");
607 },
608 };
609 let second_f_honest_it = self.second_f_honest_nodes.iter();
610 let f_dishonest_it = self.f_dishonest_nodes.iter();
611 let one_honest_it = once(&self.one_honest_node);
612 let chained_it: Box<dyn Iterator<Item = &u64> + Send> =
614 Box::new(second_f_honest_it.chain(one_honest_it.chain(f_dishonest_it)));
615 for node_id in chained_it {
616 let dummy_view = TYPES::View::new(*node_id);
617 let Ok(node) = membership_coordinator
618 .membership()
619 .read()
620 .await
621 .leader(dummy_view, certificate.epoch())
622 else {
623 panic!(
624 "Failed to find leader for view {} and epoch {:?}",
625 dummy_view,
626 certificate.epoch()
627 );
628 };
629 let transmit_result = network
630 .direct_message(serialized_message.clone(), node.clone())
631 .await;
632 match transmit_result {
633 Ok(()) => tracing::info!(
634 "Sent ViewSyncPreCommitCertificate for view {} to node {}",
635 view_number,
636 node_id
637 ),
638 Err(e) => panic!("Failed to send message task: {e:?}"),
639 }
640 }
641 vec![]
642 },
643 HotShotEvent::ViewSyncCommitCertificateSend(certificate, sender) => {
644 let view_number = certificate.data.round;
645 if !self.dishonest_proposal_view_numbers.contains(&view_number) {
646 return vec![event.clone()];
647 }
648 let message_kind = if upgrade_lock.epochs_enabled(view_number).await {
649 MessageKind::<TYPES>::from_consensus_message(SequencingMessage::General(
650 GeneralConsensusMessage::ViewSyncCommitCertificate2(certificate.clone()),
651 ))
652 } else {
653 MessageKind::<TYPES>::from_consensus_message(SequencingMessage::General(
654 GeneralConsensusMessage::ViewSyncCommitCertificate(
655 certificate.clone().to_vsc(),
656 ),
657 ))
658 };
659 let message = Message {
660 sender: sender.clone(),
661 kind: message_kind,
662 };
663 let serialized_message = match upgrade_lock.serialize(&message).await {
664 Ok(serialized) => serialized,
665 Err(e) => {
666 panic!("Failed to serialize message: {e}");
667 },
668 };
669 let one_honest_it = once(&self.one_honest_node);
670 let chained_it: Box<dyn Iterator<Item = &u64> + Send> = Box::new(one_honest_it);
672 for node_id in chained_it {
673 let dummy_view = TYPES::View::new(*node_id);
674 let Ok(node) = membership_coordinator
675 .membership()
676 .read()
677 .await
678 .leader(dummy_view, certificate.epoch())
679 else {
680 panic!(
681 "Failed to find leader for view {} and epoch {:?}",
682 dummy_view,
683 certificate.epoch()
684 );
685 };
686 let transmit_result = network
687 .direct_message(serialized_message.clone(), node.clone())
688 .await;
689 match transmit_result {
690 Ok(()) => tracing::info!(
691 "Sent ViewSyncCommitCertificate for view {} to node {}",
692 view_number,
693 node_id
694 ),
695 Err(e) => panic!("Failed to send message task: {e:?}"),
696 }
697 }
698 vec![]
699 },
700 _ => vec![event.clone()],
701 }
702 }
703
704 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
705 vec![event.clone()]
706 }
707}
708
709#[derive(Debug)]
710pub struct DishonestViewSyncWrongEpoch<TYPES: NodeType> {
711 pub first_dishonest_view_number: u64,
712 pub epoch_modifier: fn(TYPES::Epoch) -> TYPES::Epoch,
713}
714
715#[async_trait]
716impl<TYPES: NodeType, I: NodeImplementation<TYPES>, V: Versions> EventTransformerState<TYPES, I, V>
717 for DishonestViewSyncWrongEpoch<TYPES>
718{
719 async fn send_handler(
720 &mut self,
721 event: &HotShotEvent<TYPES>,
722 public_key: &TYPES::SignatureKey,
723 private_key: &<TYPES::SignatureKey as SignatureKey>::PrivateKey,
724 upgrade_lock: &UpgradeLock<TYPES, V>,
725 _consensus: OuterConsensus<TYPES>,
726 _membership_coordinator: EpochMembershipCoordinator<TYPES>,
727 _network: Arc<I::Network>,
728 ) -> Vec<HotShotEvent<TYPES>> {
729 match event {
730 HotShotEvent::QuorumProposalSend(proposal, _) => {
731 if self.first_dishonest_view_number > proposal.data.view_number().u64() {
732 return vec![event.clone()];
733 }
734 vec![]
735 },
736 HotShotEvent::QuorumVoteSend(vote) => {
737 if self.first_dishonest_view_number > vote.view_number().u64() {
738 return vec![event.clone()];
739 }
740 vec![]
741 },
742 HotShotEvent::TimeoutVoteSend(vote) => {
743 if self.first_dishonest_view_number > vote.view_number().u64() {
744 return vec![event.clone()];
745 }
746 vec![]
747 },
748 HotShotEvent::ViewSyncPreCommitVoteSend(vote) => {
749 if self.first_dishonest_view_number > vote.view_number().u64() {
750 return vec![event.clone()];
751 }
752 let view_number = vote.data.round;
753 let vote = if upgrade_lock.epochs_enabled(view_number).await {
754 ViewSyncPreCommitVote2::<TYPES>::create_signed_vote(
755 ViewSyncPreCommitData2 {
756 relay: 0,
757 round: view_number,
758 epoch: vote.data.epoch.map(self.epoch_modifier),
759 },
760 view_number,
761 public_key,
762 private_key,
763 upgrade_lock,
764 )
765 .await
766 .context("Failed to sign pre commit vote!")
767 .unwrap()
768 } else {
769 let vote = ViewSyncPreCommitVote::<TYPES>::create_signed_vote(
770 ViewSyncPreCommitData {
771 relay: 0,
772 round: view_number,
773 },
774 view_number,
775 public_key,
776 private_key,
777 upgrade_lock,
778 )
779 .await
780 .context("Failed to sign pre commit vote!")
781 .unwrap();
782 vote.to_vote2()
783 };
784 vec![HotShotEvent::ViewSyncPreCommitVoteSend(vote)]
785 },
786 _ => vec![event.clone()],
787 }
788 }
789
790 async fn recv_handler(&mut self, event: &HotShotEvent<TYPES>) -> Vec<HotShotEvent<TYPES>> {
791 vec![event.clone()]
792 }
793}