zebra_network/peer/
minimum_peer_version.rs1use std::fmt;
4
5use zebra_chain::{chain_tip::ChainTip, parameters::Network};
6
7use crate::protocol::external::types::Version;
8
9#[cfg(any(test, feature = "proptest-impl"))]
10mod tests;
11
12pub struct MinimumPeerVersion<C> {
15 network: Network,
16 chain_tip: C,
17 current_minimum: Version,
18 has_changed: bool,
19}
20
21impl<C> fmt::Debug for MinimumPeerVersion<C> {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 f.debug_struct(std::any::type_name::<MinimumPeerVersion<C>>())
25 .field("network", &self.network)
26 .field("current_minimum", &self.current_minimum)
27 .field("has_changed", &self.has_changed)
28 .finish()
29 }
30}
31
32impl<C> MinimumPeerVersion<C>
33where
34 C: ChainTip,
35{
36 pub fn new(chain_tip: C, network: &Network) -> Self {
39 MinimumPeerVersion {
40 network: network.clone(),
41 chain_tip,
42 current_minimum: Version::min_remote_for_height(network, None),
43 has_changed: true,
44 }
45 }
46
47 pub fn changed(&mut self) -> Option<Version> {
55 self.update();
56
57 if self.has_changed {
58 self.has_changed = false;
59 Some(self.current_minimum)
60 } else {
61 None
62 }
63 }
64
65 pub fn current(&mut self) -> Version {
67 self.update();
68 self.current_minimum
69 }
70
71 fn update(&mut self) {
74 let height = self.chain_tip.best_tip_height();
75 let new_minimum = Version::min_remote_for_height(&self.network, height);
76
77 if self.current_minimum != new_minimum {
78 self.current_minimum = new_minimum;
79 self.has_changed = true;
80 }
81 }
82
83 pub fn chain_tip(&self) -> &C {
85 &self.chain_tip
86 }
87}
88
89impl<C> Clone for MinimumPeerVersion<C>
92where
93 C: Clone,
94{
95 fn clone(&self) -> Self {
96 MinimumPeerVersion {
97 network: self.network.clone(),
98 chain_tip: self.chain_tip.clone(),
99 current_minimum: self.current_minimum,
100 has_changed: true,
101 }
102 }
103}