sc_consensus_beefy/communication/
peers.rs1use sc_network::ReputationChange;
22use sc_network_types::PeerId;
23use sp_runtime::traits::{Block, NumberFor, Zero};
24use std::collections::{HashMap, VecDeque};
25
26#[derive(Debug, PartialEq)]
28pub struct PeerReport {
29 pub who: PeerId,
30 pub cost_benefit: ReputationChange,
31}
32
33struct PeerData<B: Block> {
34 last_voted_on: NumberFor<B>,
35}
36
37impl<B: Block> Default for PeerData<B> {
38 fn default() -> Self {
39 PeerData { last_voted_on: Zero::zero() }
40 }
41}
42
43pub struct KnownPeers<B: Block> {
46 live: HashMap<PeerId, PeerData<B>>,
47}
48
49impl<B: Block> KnownPeers<B> {
50 pub fn new() -> Self {
51 Self { live: HashMap::new() }
52 }
53
54 pub fn note_vote_for(&mut self, peer: PeerId, round: NumberFor<B>) {
56 let data = self.live.entry(peer).or_default();
57 data.last_voted_on = round.max(data.last_voted_on);
58 }
59
60 pub fn remove(&mut self, peer: &PeerId) {
62 self.live.remove(peer);
63 }
64
65 pub fn further_than(&self, block: NumberFor<B>) -> VecDeque<PeerId> {
67 self.live
68 .iter()
69 .filter_map(|(k, v)| (v.last_voted_on > block).then_some(k))
70 .cloned()
71 .collect()
72 }
73
74 pub fn contains(&self, peer: &PeerId) -> bool {
76 self.live.contains_key(peer)
77 }
78
79 pub fn len(&self) -> usize {
81 self.live.len()
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn should_track_known_peers_progress() {
91 let (alice, bob, charlie) = (PeerId::random(), PeerId::random(), PeerId::random());
92 let mut peers = KnownPeers::<sc_network_test::Block>::new();
93 assert!(peers.live.is_empty());
94
95 peers.note_vote_for(bob, 5);
97 peers.note_vote_for(charlie, 10);
99
100 assert_eq!(peers.live.len(), 2);
101 assert!(!peers.contains(&alice));
102 assert!(peers.contains(&bob));
103 assert!(peers.contains(&charlie));
104
105 let further_than_4 = peers.further_than(4);
107 assert_eq!(further_than_4.len(), 2);
109 assert!(further_than_4.contains(&bob));
110 assert!(further_than_4.contains(&charlie));
111
112 peers.note_vote_for(alice, 10);
114
115 let further_than_9 = peers.further_than(9);
117 assert_eq!(further_than_9.len(), 2);
119 assert!(further_than_9.contains(&charlie));
120 assert!(further_than_9.contains(&alice));
121
122 peers.remove(&alice);
124 assert_eq!(peers.live.len(), 2);
125 assert!(!peers.contains(&alice));
126
127 let further_than_9 = peers.further_than(9);
129 assert_eq!(further_than_9.len(), 1);
131 assert!(further_than_9.contains(&charlie));
132 }
133}