Skip to content

Commit 2eb5404

Browse files
committed
Refactor SignedAnnounce
1 parent 6193380 commit 2eb5404

File tree

6 files changed

+54
-40
lines changed

6 files changed

+54
-40
lines changed

content-discovery/Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

content-discovery/iroh-mainline-content-discovery-cli/src/main.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use clap::Parser;
1111
use futures::StreamExt;
1212
use iroh_mainline_content_discovery::{
1313
create_quinn_client,
14-
protocol::{AbsoluteTime, Announce, AnnounceKind, Query, QueryFlags, ALPN},
14+
protocol::{AbsoluteTime, Announce, AnnounceKind, Query, QueryFlags, SignedAnnounce, ALPN},
1515
to_infohash,
1616
};
1717
use iroh_net::{
@@ -78,7 +78,8 @@ async fn announce(args: AnnounceArgs) -> anyhow::Result<()> {
7878
content,
7979
timestamp,
8080
};
81-
iroh_mainline_content_discovery::announce(connection, announce, &key).await?;
81+
let signed_announce = SignedAnnounce::new(announce, &key)?;
82+
iroh_mainline_content_discovery::announce(connection, signed_announce).await?;
8283
println!("done");
8384
Ok(())
8485
}
@@ -101,9 +102,9 @@ async fn query(args: QueryArgs) -> anyhow::Result<()> {
101102
"querying tracker {} for content {}",
102103
args.tracker, args.content
103104
);
104-
for peer in res.hosts {
105-
if let Ok(announce) = peer.verify() {
106-
println!("{}: {:?}", announce.host, announce.kind);
105+
for sa in res.hosts {
106+
if sa.verify().is_ok() {
107+
println!("{}: {:?}", sa.announce.host, sa.announce.kind);
107108
} else {
108109
println!("invalid announce");
109110
}
@@ -134,8 +135,8 @@ async fn query_dht(args: QueryDhtArgs) -> anyhow::Result<()> {
134135
);
135136
while let Some(item) = stream.next().await {
136137
match item {
137-
Ok(signed_announce) => {
138-
if let Ok(announce) = signed_announce.verify() {
138+
Ok(announce) => {
139+
if announce.verify().is_ok() {
139140
println!("found verified provider {}", announce.host);
140141
} else {
141142
println!("found unverified provider");

content-discovery/iroh-mainline-content-discovery/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ futures = { version = "0.3.25", optional = true }
2626
rcgen = { version = "0.12.0", optional = true }
2727
rustls = { version = "0.21", optional = true }
2828
genawaiter = { version = "0.99.1", features = ["futures03"], optional = true }
29+
serde-big-array = "0.5.1"
2930

3031
[features]
3132
client = ["iroh-pkarr-node-discovery", "mainline", "quinn", "tracing", "anyhow", "rcgen", "genawaiter", "rustls", "futures", "postcard"]

content-discovery/iroh-mainline-content-discovery/src/client.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ use std::{
88

99
use futures::{future::BoxFuture, FutureExt, Stream, StreamExt};
1010
use iroh_bytes::HashAndFormat;
11-
use iroh_net::{key::SecretKey, MagicEndpoint, NodeId};
11+
use iroh_net::{MagicEndpoint, NodeId};
1212
use iroh_pkarr_node_discovery::PkarrNodeDiscovery;
1313
use mainline::common::{GetPeerResponse, StoreQueryMetdata};
1414

1515
use crate::protocol::{
16-
Announce, Query, QueryResponse, Request, Response, SignedAnnounce, ALPN, REQUEST_SIZE_LIMIT,
16+
Query, QueryResponse, Request, Response, SignedAnnounce, ALPN, REQUEST_SIZE_LIMIT,
1717
};
1818

1919
/// Announce to a tracker.
@@ -26,12 +26,10 @@ use crate::protocol::{
2626
/// `kind` is the kind of the announcement. We can claim to have the complete data or only some of it.
2727
pub async fn announce(
2828
connection: quinn::Connection,
29-
args: Announce,
30-
secret_key: &SecretKey,
29+
signed_announce: SignedAnnounce,
3130
) -> anyhow::Result<()> {
3231
let (mut send, mut recv) = connection.open_bi().await?;
3332
tracing::debug!("opened bi stream");
34-
let signed_announce = SignedAnnounce::new(args, secret_key)?;
3533
let request = Request::Announce(signed_announce);
3634
let request = postcard::to_stdvec(&request)?;
3735
tracing::debug!("sending announce");

content-discovery/iroh-mainline-content-discovery/src/protocol.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
//! The protocol for communicating with the tracker.
22
use std::{
3-
ops::Sub,
3+
ops::{Deref, Sub},
44
time::{Duration, SystemTime},
55
};
66

77
use iroh_bytes::HashAndFormat;
88
use iroh_net::NodeId;
99
use serde::{Deserialize, Serialize};
10+
use serde_big_array::BigArray;
1011

1112
/// The ALPN string for this protocol
1213
pub const ALPN: &[u8] = b"n0/tracker/1";
@@ -74,7 +75,7 @@ impl Into<SystemTime> for AbsoluteTime {
7475
///
7576
/// A peer can announce having some data, but it should also be able to announce
7677
/// that another peer has the data. This is why the peer is included.
77-
#[derive(Debug, Clone, Serialize, Deserialize)]
78+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
7879
pub struct Announce {
7980
/// The peer that supposedly has the data.
8081
pub host: NodeId,
@@ -87,35 +88,42 @@ pub struct Announce {
8788
}
8889

8990
/// A signed announce.
90-
#[derive(Debug, Clone, Serialize, Deserialize)]
91+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
9192
pub struct SignedAnnounce {
92-
/// Postcard-encoded announce
93-
pub announce_bytes: Vec<u8>,
93+
/// Announce.
94+
pub announce: Announce,
9495
/// Signature of the announce, signed by the host of the announce.
95-
pub signature: Vec<u8>,
96+
///
97+
/// The signature is over the announce, serialized with postcard.
98+
#[serde(with = "BigArray")]
99+
pub signature: [u8; 64],
100+
}
101+
102+
impl Deref for SignedAnnounce {
103+
type Target = Announce;
104+
105+
fn deref(&self) -> &Self::Target {
106+
&self.announce
107+
}
96108
}
97109

98110
impl SignedAnnounce {
99111
/// Create a new signed announce.
100112
pub fn new(announce: Announce, secret_key: &iroh_net::key::SecretKey) -> anyhow::Result<Self> {
101-
let announce = postcard::to_allocvec(&announce)?;
102-
let signature = secret_key.sign(&announce).to_vec();
113+
let announce_bytes = postcard::to_allocvec(&announce)?;
114+
let signature = secret_key.sign(&announce_bytes).to_bytes();
103115
Ok(Self {
104-
announce_bytes: announce,
116+
announce,
105117
signature,
106118
})
107119
}
108120

109-
pub fn announce(&self) -> anyhow::Result<Announce> {
110-
Ok(postcard::from_bytes(&self.announce_bytes)?)
111-
}
112-
113121
/// Verify the announce, and return the announce if it's valid.
114-
pub fn verify(&self) -> anyhow::Result<Announce> {
115-
let announce = self.announce()?;
116-
let signature = iroh_net::key::Signature::from_slice(&self.signature)?;
117-
announce.host.verify(&self.announce_bytes, &signature)?;
118-
Ok(announce)
122+
pub fn verify(&self) -> anyhow::Result<()> {
123+
let announce_bytes = postcard::to_allocvec(&self.announce)?;
124+
let signature = iroh_net::key::Signature::from_bytes(&self.signature);
125+
self.announce.host.verify(&announce_bytes, &signature)?;
126+
Ok(())
119127
}
120128
}
121129

content-discovery/iroh-mainline-tracker/src/tracker.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,7 @@ impl From<SignedAnnounce> for PeerInfo {
121121

122122
impl PeerInfo {
123123
fn last_announced(&self) -> AbsoluteTime {
124-
self.signed_announce
125-
.announce()
126-
.ok()
127-
.map(|x| x.timestamp)
128-
.unwrap_or_default()
124+
self.signed_announce.timestamp
129125
}
130126
}
131127

@@ -402,15 +398,15 @@ impl Tracker {
402398

403399
fn handle_announce(&self, signed_announce: SignedAnnounce) -> anyhow::Result<()> {
404400
tracing::info!("got announce");
405-
let announce = signed_announce.verify()?;
406-
tracing::info!("verified announce: {:?}", announce);
401+
signed_announce.verify()?;
402+
tracing::info!("verified announce: {:?}", signed_announce);
407403
let mut state = self.0.state.write().unwrap();
408-
let content = announce.content;
404+
let content = signed_announce.content;
409405
let entry = state.announce_data.entry(content).or_default();
410406
let peer_info = entry
411-
.entry(announce.kind)
407+
.entry(signed_announce.kind)
412408
.or_default()
413-
.entry(announce.host)
409+
.entry(signed_announce.host)
414410
.or_insert(PeerInfo::from(signed_announce.clone()));
415411
peer_info.signed_announce = signed_announce.clone();
416412
if let Some(path) = &self.0.options.announce_data_path {

0 commit comments

Comments
 (0)