Skip to content

Commit 33f1582

Browse files
authored
feat: Remove endpoint from protocol constructor. (#181)
## Description Remove endpoint from protocol constructor. It was only needed for creating tickets, which is used almost nowhere. To serve a protocol you just need the store, nothing else. If you want to create a BlobTicket, just do it manually. ## Breaking Changes BlobsProtocol::new now takes just store and events BlobsProtocol::endpoint is removed BlobsProtocol::ticket is removed api::TempTag::inner is removed api::TempTag::hash returns a value instead of a reference api::TempTag::format returns a value instead of a reference api::TempTag::hash_and_format returns a value instead of a reference ## Notes & open questions None ## Change checklist - [ ] Self-review. - [ ] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [ ] Tests if relevant. - [ ] All breaking changes documented.
1 parent 9e4478e commit 33f1582

28 files changed

+338
-274
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ tokio = { version = "1.43.0", features = ["full"] }
2727
tokio-util = { version = "0.7.13", features = ["full"] }
2828
tracing = "0.1.41"
2929
iroh-io = "0.6.1"
30-
rand = "0.8.5"
30+
rand = "0.9.2"
3131
hex = "0.4.3"
3232
serde = "1.0.217"
3333
postcard = { version = "1.1.1", features = ["experimental-derive", "use-std"] }

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Here is a basic example of how to set up `iroh-blobs` with `iroh`:
3434

3535
```rust,no_run
3636
use iroh::{protocol::Router, Endpoint};
37-
use iroh_blobs::{store::mem::MemStore, BlobsProtocol};
37+
use iroh_blobs::{store::mem::MemStore, BlobsProtocol, ticket::BlobTicket};
3838
3939
#[tokio::main]
4040
async fn main() -> anyhow::Result<()> {
@@ -44,15 +44,19 @@ async fn main() -> anyhow::Result<()> {
4444
4545
// create a protocol handler using an in-memory blob store.
4646
let store = MemStore::new();
47-
let blobs = BlobsProtocol::new(&store, endpoint.clone(), None);
47+
let tag = store.add_slice(b"Hello world").await?;
48+
49+
let _ = endpoint.online().await;
50+
let addr = endpoint.node_addr();
51+
let ticket = BlobTicket::new(addr, tag.hash, tag.format);
4852
4953
// build the router
54+
let blobs = BlobsProtocol::new(&store, None);
5055
let router = Router::builder(endpoint)
51-
.accept(iroh_blobs::ALPN, blobs.clone())
56+
.accept(iroh_blobs::ALPN, blobs)
5257
.spawn();
5358
54-
let tag = blobs.add_slice(b"Hello world").await?;
55-
println!("We are now serving {}", blobs.ticket(tag).await?);
59+
println!("We are now serving {}", ticket);
5660
5761
// wait for control-c
5862
tokio::signal::ctrl_c().await;

examples/common/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ pub fn get_or_generate_secret_key() -> Result<SecretKey> {
99
use std::{env, str::FromStr};
1010

1111
use anyhow::Context;
12-
use rand::thread_rng;
1312
if let Ok(secret) = env::var("IROH_SECRET") {
1413
// Parse the secret key from string
1514
SecretKey::from_str(&secret).context("Invalid secret key format")
1615
} else {
1716
// Generate a new random key
18-
let secret_key = SecretKey::generate(&mut thread_rng());
17+
let secret_key = SecretKey::generate(&mut rand::rng());
1918
println!(
2019
"Generated new secret key: {}",
2120
hex::encode(secret_key.to_bytes())

examples/custom-protocol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ async fn listen(text: Vec<String>) -> Result<()> {
100100
proto.insert_and_index(text).await?;
101101
}
102102
// Build the iroh-blobs protocol handler, which is used to download blobs.
103-
let blobs = BlobsProtocol::new(&store, endpoint.clone(), None);
103+
let blobs = BlobsProtocol::new(&store, None);
104104

105105
// create a router that handles both our custom protocol and the iroh-blobs protocol.
106106
let node = Router::builder(endpoint)

examples/expiring-tags.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,14 @@ async fn main() -> anyhow::Result<()> {
162162
let expires_at = SystemTime::now()
163163
.checked_add(Duration::from_secs(10))
164164
.unwrap();
165-
create_expiring_tag(&store, &[*a.hash(), *b.hash()], "expiring", expires_at).await?;
165+
create_expiring_tag(&store, &[a.hash(), b.hash()], "expiring", expires_at).await?;
166166

167167
// add a single blob and tag it with an expiry date 60 seconds in the future
168168
let c = batch.add_bytes("blob 3".as_bytes()).await?;
169169
let expires_at = SystemTime::now()
170170
.checked_add(Duration::from_secs(60))
171171
.unwrap();
172-
create_expiring_tag(&store, &[*c.hash()], "expiring", expires_at).await?;
172+
create_expiring_tag(&store, &[c.hash()], "expiring", expires_at).await?;
173173
// batch goes out of scope, so data is only protected by the tags we created
174174
}
175175

examples/limit.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::{
2121
use anyhow::Result;
2222
use clap::Parser;
2323
use common::setup_logging;
24-
use iroh::{protocol::Router, NodeAddr, NodeId, SecretKey, Watcher};
24+
use iroh::{protocol::Router, NodeAddr, NodeId, SecretKey};
2525
use iroh_blobs::{
2626
provider::events::{
2727
AbortReason, ConnectMode, EventMask, EventSender, ProviderMessage, RequestMode,
@@ -31,7 +31,7 @@ use iroh_blobs::{
3131
ticket::BlobTicket,
3232
BlobFormat, BlobsProtocol, Hash,
3333
};
34-
use rand::thread_rng;
34+
use rand::rng;
3535

3636
use crate::common::get_or_generate_secret_key;
3737

@@ -255,7 +255,7 @@ async fn main() -> Result<()> {
255255
let mut allowed_nodes = allowed_nodes.into_iter().collect::<HashSet<_>>();
256256
if secrets > 0 {
257257
println!("Generating {secrets} new secret keys for allowed nodes:");
258-
let mut rand = thread_rng();
258+
let mut rand = rng();
259259
for _ in 0..secrets {
260260
let secret = SecretKey::generate(&mut rand);
261261
let public = secret.public();
@@ -357,9 +357,9 @@ async fn setup(store: MemStore, events: EventSender) -> Result<(Router, NodeAddr
357357
.secret_key(secret)
358358
.bind()
359359
.await?;
360-
let _ = endpoint.home_relay().initialized().await;
361-
let addr = endpoint.node_addr().initialized().await;
362-
let blobs = BlobsProtocol::new(&store, endpoint.clone(), Some(events));
360+
endpoint.online().await;
361+
let addr = endpoint.node_addr();
362+
let blobs = BlobsProtocol::new(&store, Some(events));
363363
let router = Router::builder(endpoint)
364364
.accept(iroh_blobs::ALPN, blobs)
365365
.spawn();

examples/mdns-discovery.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ async fn accept(path: &Path) -> Result<()> {
6868
.await?;
6969
let builder = Router::builder(endpoint.clone());
7070
let store = MemStore::new();
71-
let blobs = BlobsProtocol::new(&store, endpoint.clone(), None);
71+
let blobs = BlobsProtocol::new(&store, None);
7272
let builder = builder.accept(iroh_blobs::ALPN, blobs.clone());
7373
let node = builder.spawn();
7474

@@ -87,7 +87,7 @@ async fn accept(path: &Path) -> Result<()> {
8787
}
8888

8989
async fn connect(node_id: PublicKey, hash: Hash, out: Option<PathBuf>) -> Result<()> {
90-
let key = SecretKey::generate(rand::rngs::OsRng);
90+
let key = SecretKey::generate(&mut rand::rng());
9191
// todo: disable discovery publishing once https://github.com/n0-computer/iroh/issues/3401 is implemented
9292
let discovery = MdnsDiscovery::builder();
9393

examples/random_store.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{env, path::PathBuf, str::FromStr};
22

33
use anyhow::{Context, Result};
44
use clap::{Parser, Subcommand};
5-
use iroh::{SecretKey, Watcher};
5+
use iroh::{discovery::static_provider::StaticProvider, SecretKey};
66
use iroh_base::ticket::NodeTicket;
77
use iroh_blobs::{
88
api::downloader::Shuffled,
@@ -93,7 +93,7 @@ pub fn get_or_generate_secret_key() -> Result<SecretKey> {
9393
SecretKey::from_str(&secret).context("Invalid secret key format")
9494
} else {
9595
// Generate a new random key
96-
let secret_key = SecretKey::generate(&mut rand::thread_rng());
96+
let secret_key = SecretKey::generate(&mut rand::rng());
9797
let secret_key_str = hex::encode(secret_key.to_bytes());
9898
println!("Generated new random secret key");
9999
println!("To reuse this key, set the IROH_SECRET={secret_key_str}");
@@ -204,20 +204,20 @@ async fn provide(args: ProvideArgs) -> anyhow::Result<()> {
204204
println!("Using store at: {}", path.display());
205205
let mut rng = match args.common.seed {
206206
Some(seed) => StdRng::seed_from_u64(seed),
207-
None => StdRng::from_entropy(),
207+
None => StdRng::from_rng(&mut rand::rng()),
208208
};
209209
let blobs = create_random_blobs(
210210
&store,
211211
args.num_blobs,
212-
|_, rand| rand.gen_range(1..=args.blob_size),
212+
|_, rand| rand.random_range(1..=args.blob_size),
213213
&mut rng,
214214
)
215215
.await?;
216216
let hs = add_hash_sequences(
217217
&store,
218218
&blobs,
219219
args.hash_seqs,
220-
|_, rand| rand.gen_range(1..=args.hash_seq_size),
220+
|_, rand| rand.random_range(1..=args.hash_seq_size),
221221
&mut rng,
222222
)
223223
.await?;
@@ -238,11 +238,11 @@ async fn provide(args: ProvideArgs) -> anyhow::Result<()> {
238238
.bind()
239239
.await?;
240240
let (dump_task, events_tx) = dump_provider_events(args.allow_push);
241-
let blobs = iroh_blobs::BlobsProtocol::new(&store, endpoint.clone(), Some(events_tx));
241+
let blobs = iroh_blobs::BlobsProtocol::new(&store, Some(events_tx));
242242
let router = iroh::protocol::Router::builder(endpoint.clone())
243243
.accept(iroh_blobs::ALPN, blobs)
244244
.spawn();
245-
let addr = router.endpoint().node_addr().initialized().await;
245+
let addr = router.endpoint().node_addr();
246246
let ticket = NodeTicket::from(addr.clone());
247247
println!("Node address: {addr:?}");
248248
println!("ticket:\n{ticket}");
@@ -265,10 +265,14 @@ async fn request(args: RequestArgs) -> anyhow::Result<()> {
265265
.unwrap_or_else(|| tempdir.as_ref().unwrap().path().to_path_buf());
266266
let store = FsStore::load(&path).await?;
267267
println!("Using store at: {}", path.display());
268-
let endpoint = iroh::Endpoint::builder().bind().await?;
268+
let sp = StaticProvider::new();
269+
let endpoint = iroh::Endpoint::builder()
270+
.discovery(sp.clone())
271+
.bind()
272+
.await?;
269273
let downloader = store.downloader(&endpoint);
270274
for ticket in &args.nodes {
271-
endpoint.add_node_addr(ticket.node_addr().clone())?;
275+
sp.add_node_info(ticket.node_addr().clone());
272276
}
273277
let nodes = args
274278
.nodes

examples/transfer-collection.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
use std::collections::HashMap;
99

1010
use anyhow::{Context, Result};
11-
use iroh::{
12-
discovery::static_provider::StaticProvider, protocol::Router, Endpoint, NodeAddr, Watcher,
13-
};
11+
use iroh::{discovery::static_provider::StaticProvider, protocol::Router, Endpoint, NodeAddr};
1412
use iroh_blobs::{
1513
api::{downloader::Shuffled, Store, TempTag},
1614
format::collection::Collection,
@@ -38,7 +36,7 @@ impl Node {
3836

3937
// this BlobsProtocol accepts connections from other nodes and serves blobs from the store
4038
// we pass None to skip subscribing to request events
41-
let blobs = BlobsProtocol::new(&store, endpoint.clone(), None);
39+
let blobs = BlobsProtocol::new(&store, None);
4240
// Routers group one or more protocols together to accept connections from other nodes,
4341
// here we're only using one, but could add more in a real world use case as needed
4442
let router = Router::builder(endpoint)
@@ -54,7 +52,8 @@ impl Node {
5452
// get address of this node. Has the side effect of waiting for the node
5553
// to be online & ready to accept connections
5654
async fn node_addr(&self) -> Result<NodeAddr> {
57-
let addr = self.router.endpoint().node_addr().initialized().await;
55+
self.router.endpoint().online().await;
56+
let addr = self.router.endpoint().node_addr();
5857
Ok(addr)
5958
}
6059

@@ -80,14 +79,14 @@ impl Node {
8079

8180
let collection_items = collection_items
8281
.iter()
83-
.map(|(name, tag)| (name.to_string(), *tag.hash()))
82+
.map(|(name, tag)| (name.to_string(), tag.hash()))
8483
.collect::<Vec<_>>();
8584

8685
let collection = Collection::from_iter(collection_items);
8786

8887
let tt = collection.store(&self.store).await?;
89-
self.store.tags().create(*tt.hash_and_format()).await?;
90-
Ok(*tt.hash())
88+
self.store.tags().create(tt.hash_and_format()).await?;
89+
Ok(tt.hash())
9190
}
9291

9392
/// retrieve an entire collection from a given hash and provider

0 commit comments

Comments
 (0)