• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tari-project / tari / 20773089691

07 Jan 2026 06:45AM UTC coverage: 60.457% (-0.3%) from 60.745%
20773089691

push

github

web-flow
chore(deps): bump rsa from 0.9.7 to 0.9.10 (#7649)

Bumps [rsa](https://github.com/RustCrypto/RSA) from 0.9.7 to 0.9.10.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/RustCrypto/RSA/blob/v0.9.10/CHANGELOG.md">rsa's
changelog</a>.</em></p>
<blockquote>
<h2>0.9.10 (2026-01-06)</h2>
<h3>Fixed</h3>
<ul>
<li>do not panic on a prime being 1 when loading a secret key (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/624">#624</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/RustCrypto/RSA/issues/624">#624</a>:
<a
href="https://redirect.github.com/RustCrypto/RSA/pull/624">RustCrypto/RSA#624</a></p>
<h2>0.9.9 (2025-11-13)</h2>
<h3>Fixed</h3>
<ul>
<li>Support for cryptographic operations with larger keys (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/594">#594</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/RustCrypto/RSA/issues/594">#594</a>:
<a
href="https://redirect.github.com/RustCrypto/RSA/pull/594">RustCrypto/RSA#594</a></p>
<h2>0.9.8 (2025-03-12)</h2>
<h3>Added</h3>
<ul>
<li>Doc comments to specify the <code>rand</code> version (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/473">#473</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/RustCrypto/RSA/issues/473">#473</a>:
<a
href="https://redirect.github.com/RustCrypto/RSA/pull/473">RustCrypto/RSA#473</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/RustCrypto/RSA/commit/da2af9a0f"><code>da2af9a</code></a>
chore: release v0.9.10</li>
<li><a
href="https://github.com/RustCrypto/RSA/commit/2926c91be"><code>2926c91</code></a>
fix: do not panic on a prime being 1 when loading a secret key (<a
href="https://redirect.github.com/RustCrypto/RSA/issues/624">#624</a>)</li>
<li><a
href="https://github.com/RustCrypto/RSA/commit/488d2ad60"><code>488d2ad</code></a>
chore: relea... (continued)

70166 of 116059 relevant lines covered (60.46%)

299924.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.25
/base_layer/core/src/base_node/sync/sync_peer.rs
1
//  Copyright 2020, The Tari Project
2
//
3
//  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
4
//  following conditions are met:
5
//
6
//  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
7
//  disclaimer.
8
//
9
//  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
10
//  following disclaimer in the documentation and/or other materials provided with the distribution.
11
//
12
//  3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
13
//  products derived from this software without specific prior written permission.
14
//
15
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
16
//  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
//  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19
//  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
20
//  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
21
//  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22

23
use std::{
24
    cmp::Ordering,
25
    fmt::{Display, Formatter},
26
    time::Duration,
27
};
28

29
use primitive_types::U512;
30
use tari_common_types::chain_metadata::ChainMetadata;
31
use tari_comms::peer_manager::NodeId;
32

33
use crate::{base_node::chain_metadata_service::PeerChainMetadata, common::rolling_avg::RollingAverageTime};
34

35
#[derive(Debug, Clone)]
36
pub struct SyncPeer {
37
    peer_metadata: PeerChainMetadata,
38
    avg_latency: RollingAverageTime,
39
}
40

41
impl SyncPeer {
42
    pub fn node_id(&self) -> &NodeId {
42✔
43
        self.peer_metadata.node_id()
42✔
44
    }
42✔
45

46
    pub fn claimed_chain_metadata(&self) -> &ChainMetadata {
16✔
47
        self.peer_metadata.claimed_chain_metadata()
16✔
48
    }
16✔
49

50
    pub fn claimed_difficulty(&self) -> U512 {
28✔
51
        self.peer_metadata.claimed_chain_metadata().accumulated_difficulty()
28✔
52
    }
28✔
53

54
    pub fn latency(&self) -> Option<Duration> {
111✔
55
        self.peer_metadata.latency()
111✔
56
    }
111✔
57

58
    pub(super) fn set_latency(&mut self, latency: Duration) -> &mut Self {
3✔
59
        self.peer_metadata.set_latency(latency);
3✔
60
        self
3✔
61
    }
3✔
62

63
    pub fn items_per_second(&self) -> Option<f64> {
×
64
        self.avg_latency.calc_samples_per_second()
×
65
    }
×
66

67
    pub(super) fn add_sample(&mut self, time: Duration) -> &mut Self {
×
68
        self.avg_latency.add_sample(time);
×
69
        self
×
70
    }
×
71

72
    pub fn calc_avg_latency(&self) -> Option<Duration> {
×
73
        self.avg_latency.calculate_average()
×
74
    }
×
75
}
76

77
impl From<PeerChainMetadata> for SyncPeer {
78
    fn from(peer_metadata: PeerChainMetadata) -> Self {
41✔
79
        Self {
41✔
80
            peer_metadata,
41✔
81
            avg_latency: RollingAverageTime::new(20),
41✔
82
        }
41✔
83
    }
41✔
84
}
85

86
impl Display for SyncPeer {
87
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
×
88
        write!(
×
89
            f,
×
90
            "Node ID: {}, Chain metadata: {}, Latency: {}",
×
91
            self.node_id(),
×
92
            self.claimed_chain_metadata(),
×
93
            self.latency()
×
94
                .map(|d| format!("{d:.2?}"))
×
95
                .unwrap_or_else(|| "--".to_string())
×
96
        )
97
    }
×
98
}
99

100
impl PartialEq for SyncPeer {
101
    fn eq(&self, other: &Self) -> bool {
3✔
102
        self.node_id() == other.node_id()
3✔
103
    }
3✔
104
}
105
impl Eq for SyncPeer {}
106

107
impl Ord for SyncPeer {
108
    fn cmp(&self, other: &Self) -> Ordering {
40✔
109
        let mut result = other
40✔
110
            .peer_metadata
40✔
111
            .claimed_chain_metadata()
40✔
112
            .accumulated_difficulty()
40✔
113
            .cmp(&self.peer_metadata.claimed_chain_metadata().accumulated_difficulty());
40✔
114
        if result == Ordering::Equal {
40✔
115
            match (self.latency(), other.latency()) {
37✔
116
                (None, None) => result = Ordering::Equal,
2✔
117
                // No latency goes to the end
118
                (Some(_), None) => result = Ordering::Less,
16✔
119
                (None, Some(_)) => result = Ordering::Greater,
×
120
                (Some(la), Some(lb)) => result = la.cmp(&lb),
19✔
121
            }
122
        }
3✔
123
        result
40✔
124
    }
40✔
125
}
126

127
impl PartialOrd for SyncPeer {
128
    fn partial_cmp(&self, other: &SyncPeer) -> Option<Ordering> {
40✔
129
        Some(self.cmp(other))
40✔
130
    }
40✔
131
}
132

133
#[cfg(test)]
134
mod test {
135
    #![allow(clippy::indexing_slicing)]
136
    use std::time::Duration;
137

138
    use rand::rngs::OsRng;
139
    use tari_common_types::chain_metadata::ChainMetadata;
140

141
    use super::*;
142

143
    mod sort_by_latency {
144
        use tari_common_types::types::FixedHash;
145
        use tari_comms::types::{CommsPublicKey, CommsSecretKey};
146
        use tari_crypto::keys::SecretKey;
147

148
        use super::*;
149

150
        // Helper function to generate a peer with a given latency
151
        fn generate_peer(latency: Option<usize>, accumulated_difficulty: Option<U512>) -> SyncPeer {
16✔
152
            let sk = CommsSecretKey::random(&mut OsRng);
16✔
153
            let pk = CommsPublicKey::from_secret_key(&sk);
16✔
154
            let node_id = NodeId::from_key(&pk);
16✔
155
            let latency_option = latency.map(|latency| Duration::from_millis(latency as u64));
16✔
156
            let peer_accumulated_difficulty = match accumulated_difficulty {
16✔
157
                Some(v) => v,
3✔
158
                None => 1.into(),
13✔
159
            };
160
            PeerChainMetadata::new(
16✔
161
                node_id,
16✔
162
                ChainMetadata::new(0, FixedHash::zero(), 0, 0, peer_accumulated_difficulty, 0).unwrap(),
16✔
163
                latency_option,
16✔
164
            )
165
            .into()
16✔
166
        }
16✔
167

168
        #[test]
169
        fn it_sorts_by_latency() {
1✔
170
            const DISTINCT_LATENCY: usize = 5;
171

172
            // Generate a list of peers with latency, adding duplicates
173
            let mut peers = (0..2 * DISTINCT_LATENCY)
1✔
174
                .map(|latency| generate_peer(Some(latency % DISTINCT_LATENCY), None))
10✔
175
                .collect::<Vec<SyncPeer>>();
1✔
176

177
            // Add peers with no latency in a few places
178
            peers.insert(0, generate_peer(None, None));
1✔
179
            peers.insert(DISTINCT_LATENCY, generate_peer(None, None));
1✔
180
            peers.push(generate_peer(None, None));
1✔
181

182
            // Sort the list; because difficulty is identical, it should sort by latency
183
            peers.sort();
1✔
184

185
            // Confirm that the sorted latency is correct: numerical ordering, then `None`
186
            for (i, peer) in peers[..2 * DISTINCT_LATENCY].iter().enumerate() {
10✔
187
                assert_eq!(peer.latency(), Some(Duration::from_millis((i as u64) / 2)));
10✔
188
            }
189
            for _ in 0..3 {
4✔
190
                assert_eq!(peers.pop().unwrap().latency(), None);
3✔
191
            }
192
        }
1✔
193

194
        #[test]
195
        fn it_sorts_by_pow() {
1✔
196
            let mut peers = Vec::new();
1✔
197

198
            let mut pow = U512::from(1);
1✔
199
            let new_peer = generate_peer(Some(1), Some(pow));
1✔
200
            peers.push(new_peer);
1✔
201
            pow = U512::from(100);
1✔
202
            let new_peer = generate_peer(Some(100), Some(pow));
1✔
203
            peers.push(new_peer);
1✔
204
            pow = U512::from(1000);
1✔
205
            let new_peer = generate_peer(Some(1000), Some(pow));
1✔
206
            peers.push(new_peer);
1✔
207

208
            // Sort the list;
209
            peers.sort();
1✔
210

211
            assert_eq!(
1✔
212
                peers[0].peer_metadata.claimed_chain_metadata().accumulated_difficulty(),
1✔
213
                1000.into()
1✔
214
            );
215
            assert_eq!(
1✔
216
                peers[1].peer_metadata.claimed_chain_metadata().accumulated_difficulty(),
1✔
217
                100.into()
1✔
218
            );
219
            assert_eq!(
1✔
220
                peers[2].peer_metadata.claimed_chain_metadata().accumulated_difficulty(),
1✔
221
                1.into()
1✔
222
            );
223
        }
1✔
224
    }
225
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc