Skip to content

Commit e5cc3b0

Browse files
Get rid of BigUInt
1 parent a7b6d44 commit e5cc3b0

File tree

4 files changed

+38
-27
lines changed

4 files changed

+38
-27
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ path = "src/parser_tester.rs"
2020
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
2121

2222
[dependencies]
23-
num = { version = "^0.4", features = ["alloc"] }
23+
num = { version = "^0.4" }
2424
bendy = { version = "^0.3" }
2525
juicy_bencode = "^0.1"
2626
rand = { version = "^0.8", features = ["small_rng"] }

src/dht_service.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,6 @@ mod tests {
194194
dht_service::DhtV4,
195195
domain_knowledge::{InfoHash, NodeId},
196196
};
197-
use num::{BigUint, Num};
198197
use opentelemetry::global;
199198
use rand::RngCore;
200199
use std::{net::SocketAddrV4, str::FromStr, sync::Once};
@@ -292,13 +291,7 @@ mod tests {
292291
)
293292
.await?;
294293

295-
let info_hash = BigUint::from_str_radix("233b78ca585fe0a8c9e8eb4bda03f52e8b6f554b", 16).unwrap();
296-
let info_hash = info_hash.to_bytes_be();
297-
298-
let mut stupid = [0u8; 20];
299-
stupid.copy_from_slice(&info_hash[0..20]);
300-
301-
let info_hash = InfoHash(stupid);
294+
let info_hash = InfoHash::from_hex_str("233b78ca585fe0a8c9e8eb4bda03f52e8b6f554b");
302295

303296
let client = dht.client();
304297
let (token, peers) = client.get_peers(info_hash).await?;

src/dht_service/dht_client.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use crate::{
55
our_error::{naur, OurError},
66
utils::ParSpawnAndAwait,
77
};
8-
use num::BigUint;
9-
use std::{collections::HashSet, net::SocketAddrV4, ops::BitXor, sync::Arc, time::Duration};
8+
use std::{collections::HashSet, net::SocketAddrV4, sync::Arc, time::Duration};
109
use tokio::time::timeout;
1110
use tracing::warn;
1211
use tracing::{instrument, trace};
@@ -118,10 +117,7 @@ impl DhtHandle {
118117
let mut sorted_by_distance: Vec<_> = returned_nodes
119118
.into_iter()
120119
.map(|node| {
121-
let node_id = BigUint::from_bytes_be(node.id().as_bytes());
122-
let our_id = BigUint::from_bytes_be(self.our_id.as_bytes());
123-
let distance = our_id.bitxor(node_id);
124-
120+
let distance = node.id().dist(&self.our_id);
125121
(node, distance)
126122
})
127123
.collect();

src/domain_knowledge.rs

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ use num::{traits::ops::bytes, BigUint};
33
use smallvec::SmallVec;
44
use std::{fmt::Debug, net::SocketAddrV4};
55

6+
const NODE_ID_LEN: usize = 20;
7+
68
#[derive(PartialEq, Eq, Hash, Clone, Copy, PartialOrd, Ord)]
7-
pub struct NodeId(pub [u8; 20]);
9+
pub struct NodeId(pub [u8; NODE_ID_LEN]);
810

911
impl Debug for NodeId {
1012
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -16,13 +18,13 @@ impl Debug for NodeId {
1618
}
1719

1820
impl NodeId {
19-
/// Panics if the length is not exactly 20
21+
/// Panics if the length is not exactly NODE_ID_LEN
2022
pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
21-
if bytes.len() != 20 {
22-
panic!("Node id must be exactly 20 bytes");
23+
if bytes.len() != NODE_ID_LEN {
24+
panic!("Node id must be exactly {NODE_ID_LEN} bytes");
2325
}
2426

25-
let mut arr = [0u8; 20];
27+
let mut arr = [0u8; NODE_ID_LEN];
2628
arr.copy_from_slice(bytes);
2729
NodeId(arr)
2830
}
@@ -37,9 +39,9 @@ impl NodeId {
3739
our_id ^ node_id
3840
}
3941

40-
pub fn dist(&self, rhs: &Self) -> [u8; 20] {
41-
let mut dist = [0u8; 20];
42-
for i in 0..20 {
42+
pub fn dist(&self, rhs: &Self) -> [u8; NODE_ID_LEN] {
43+
let mut dist = [0u8; NODE_ID_LEN];
44+
for i in 0..NODE_ID_LEN {
4345
dist[i] = self.0[i] ^ rhs.0[i]
4446
}
4547
dist
@@ -74,22 +76,42 @@ impl ToBencode for NodeId {
7476
// }
7577

7678
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
77-
pub struct InfoHash(pub [u8; 20]);
79+
pub struct InfoHash(pub [u8; NODE_ID_LEN]);
7880

7981
impl InfoHash {
82+
/// Panics if `bytes` is not 20 bytes in length
8083
pub fn from_bytes_unchecked(bytes: &[u8]) -> Self {
81-
if bytes.len() != 20 {
82-
panic!("Info hash must be exactly 20 bytes");
84+
if bytes.len() != NODE_ID_LEN {
85+
panic!("Info hash must be exactly {NODE_ID_LEN} bytes");
8386
}
8487

85-
let mut arr = [0u8; 20];
88+
let mut arr = [0u8; NODE_ID_LEN];
8689
arr.copy_from_slice(bytes);
8790
InfoHash(arr)
8891
}
8992

9093
pub fn as_bytes(&self) -> &[u8] {
9194
&self.0
9295
}
96+
97+
pub fn from_hex_str(str: &str) -> Self {
98+
if str.len() != NODE_ID_LEN * 2 {
99+
panic!("Info hash must be exactly {NODE_ID_LEN} bytes");
100+
}
101+
if !str.is_ascii() {
102+
panic!("input has non ascii characters");
103+
}
104+
105+
let mut arr = [0u8; NODE_ID_LEN];
106+
let mut i = 0;
107+
while i != str.len() {
108+
let bytes = &str[i..i + 2];
109+
arr[i >> 1] = u8::from_str_radix(bytes, 16).expect("input string must be consist of soley hex digits");
110+
i <<= 1;
111+
}
112+
113+
Self(arr)
114+
}
93115
}
94116

95117
impl Debug for InfoHash {

0 commit comments

Comments
 (0)