Skip to content

Commit d080863

Browse files
committed
feat: upgrade to Veilid 0.4.8 and
veilid-iroh-blobs v0.2.0 BREAKING CHANGE: Upgrade to Veilid 0.4.8 with breaking API changes - Upgrade veilid-core to v0.4.8 - Update veilid-iroh-blobs dependency to v0.2.0 (git tag) - Update all source files for Veilid 0.4.8 API compatibility - Fix breaking changes (VeilidConfigInner → VeilidConfig, CryptoKey → RouteId) - Switch from path dependency to git tag for veilid-iroh-blobs Dependencies: - veilid-core: v0.4.8 - veilid-iroh-blobs: v0.2.0 Version: 0.2.0
1 parent f03e301 commit d080863

File tree

8 files changed

+240
-194
lines changed

8 files changed

+240
-194
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
[package]
22
name = "save-dweb-backend"
3-
version = "0.1.3"
3+
version = "0.2.0"
44
edition = "2021"
55

66
[dependencies]
77
iroh = "0.24.0"
88
iroh-blobs = "0.24.0"
9-
veilid-core = { git = "https://gitlab.com/veilid/veilid.git", version = "0.4.3" }
10-
veilid-iroh-blobs = { git = "https://github.com/RangerMauve/veilid-iroh-blobs.git", version = "0.1.1" }
9+
veilid-core = { git = "https://gitlab.com/veilid/veilid.git", tag = "v0.4.8" }
10+
veilid-iroh-blobs = { git = "https://github.com/RangerMauve/veilid-iroh-blobs.git", tag = "v0.2.0" }
1111
tracing = "0.1"
1212
xdg = "2.4"
1313
tmpdir = "1"

src/backend.rs

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use tokio::sync::{
2525
use tracing::info;
2626
use url::Url;
2727
use veilid_core::{
28-
api_startup_config, vld0_generate_keypair, CryptoKey, CryptoSystem, CryptoSystemVLD0,
29-
CryptoTyped, DHTSchema, KeyPair, ProtectedStore, RoutingContext, SharedSecret, TypedKey,
30-
UpdateCallback, VeilidAPI, VeilidConfigInner, VeilidConfigProtectedStore, VeilidUpdate,
28+
api_startup_config, PublicKey, SecretKey, RecordKey, CryptoSystem,
29+
CryptoTyped, DHTSchema, KeyPair, ProtectedStore, RoutingContext, SharedSecret, TypedRecordKey,
30+
UpdateCallback, VeilidAPI, VeilidConfig, VeilidConfigProtectedStore, VeilidUpdate,
3131
CRYPTO_KEY_LENGTH, CRYPTO_KIND_VLD0,
3232
};
3333
use veilid_iroh_blobs::iroh::VeilidIrohBlobs;
@@ -36,14 +36,14 @@ use xdg::BaseDirectories;
3636

3737
#[derive(Serialize, Deserialize, Debug)]
3838
pub struct KnownGroupList {
39-
groups: Vec<CryptoKey>,
39+
groups: Vec<RecordKey>,
4040
}
4141

4242
pub struct BackendInner {
4343
path: PathBuf,
4444
veilid_api: Option<VeilidAPI>,
4545
update_rx: Option<broadcast::Receiver<VeilidUpdate>>,
46-
groups: HashMap<CryptoKey, Box<Group>>,
46+
groups: HashMap<RecordKey, Box<Group>>,
4747
pub iroh_blobs: Option<VeilidIrohBlobs>,
4848
on_new_route_callback: Option<OnNewRouteCallback>,
4949
}
@@ -54,7 +54,7 @@ impl BackendInner {
5454

5555
let info = KnownGroupList { groups };
5656

57-
println!("Saving group IDs {:?}", info);
57+
println!("Saving group IDs {info:?}");
5858
let data =
5959
serde_cbor::to_vec(&info).map_err(|e| anyhow!("Failed to serialize keypair: {}", e))?;
6060
self.veilid()?
@@ -160,16 +160,17 @@ impl Backend {
160160
let mut inner = backend.inner.lock().await;
161161

162162
// Initialize iroh_blobs
163-
inner.iroh_blobs = Some(VeilidIrohBlobs::new(
164-
veilid_api.clone(),
165-
routing_context,
163+
let config = veilid_iroh_blobs::iroh::VeilidIrohBlobsConfig {
164+
veilid: veilid_api.clone(),
165+
router: routing_context,
166166
route_id_blob,
167167
route_id,
168-
inner.update_rx.as_ref().unwrap().resubscribe(),
168+
updates: inner.update_rx.as_ref().unwrap().resubscribe(),
169169
store,
170-
Some(on_disconnected_callback), // TODO: Notify application of route closure?
171-
Some(on_new_route_callback),
172-
));
170+
on_route_disconnected_callback: Some(on_disconnected_callback), // TODO: Notify application of route closure?
171+
on_new_route_callback: Some(on_new_route_callback),
172+
};
173+
inner.iroh_blobs = Some(VeilidIrohBlobs::new(config));
173174

174175
drop(inner);
175176

@@ -229,16 +230,17 @@ impl Backend {
229230
});
230231

231232
// Initialize iroh_blobs
232-
inner.iroh_blobs = Some(VeilidIrohBlobs::new(
233-
veilid_api.clone(),
234-
routing_context,
233+
let config = veilid_iroh_blobs::iroh::VeilidIrohBlobsConfig {
234+
veilid: veilid_api.clone(),
235+
router: routing_context,
235236
route_id_blob,
236237
route_id,
237-
update_rx.resubscribe(),
238+
updates: update_rx.resubscribe(),
238239
store,
239-
None, // TODO: Notify application of route closure?
240-
Some(on_new_route_callback),
241-
));
240+
on_route_disconnected_callback: None, // TODO: Notify application of route closure?
241+
on_new_route_callback: Some(on_new_route_callback),
242+
};
243+
inner.iroh_blobs = Some(VeilidIrohBlobs::new(config));
242244

243245
drop(inner);
244246

@@ -300,7 +302,7 @@ impl Backend {
300302
.get(CRYPTO_KIND_VLD0)
301303
.ok_or_else(|| anyhow!("Unable to init crypto system"));
302304

303-
let record_key = TypedKey::new(CRYPTO_KIND_VLD0, keys.id);
305+
let record_key = TypedRecordKey::new(CRYPTO_KIND_VLD0, keys.id);
304306
// First open the DHT record
305307
let dht_record = routing_context
306308
.open_dht_record(record_key.clone(), None) // Don't pass a writer here yet
@@ -385,7 +387,7 @@ impl Backend {
385387
Ok(group)
386388
}
387389

388-
pub async fn get_group(&self, record_key: &CryptoKey) -> Result<Box<Group>> {
390+
pub async fn get_group(&self, record_key: &RecordKey) -> Result<Box<Group>> {
389391
let mut inner = self.inner.lock().await;
390392
if let Some(group) = inner.groups.get(record_key) {
391393
return Ok(group.clone());
@@ -409,7 +411,7 @@ impl Backend {
409411
// Use the owner key from the DHT record as the default writer
410412
let owner_key = retrieved_keypair.public_key; // Call the owner() method to get the owner key
411413
let owner_secret = retrieved_keypair.secret_key;
412-
let record_key = TypedKey::new(CRYPTO_KIND_VLD0, *record_key);
414+
let record_key = TypedRecordKey::new(CRYPTO_KIND_VLD0, *record_key);
413415

414416
let owner = owner_secret.map(|secret| KeyPair::new(owner_key, secret));
415417

@@ -448,7 +450,7 @@ impl Backend {
448450
Ok(())
449451
}
450452

451-
pub async fn list_known_group_ids(&self) -> Result<Vec<CryptoKey>> {
453+
pub async fn list_known_group_ids(&self) -> Result<Vec<RecordKey>> {
452454
let mut inner = self.inner.lock().await;
453455
let veilid = inner.veilid()?;
454456
let data = veilid
@@ -461,7 +463,7 @@ impl Backend {
461463
Ok(info.groups)
462464
}
463465

464-
pub async fn close_group(&self, key: CryptoKey) -> Result<()> {
466+
pub async fn close_group(&self, key: RecordKey) -> Result<()> {
465467
let mut inner = self.inner.lock().await;
466468
if let Some(group) = inner.groups.remove(&key) {
467469
group.close().await.map_err(|e| anyhow!(e))?;
@@ -540,23 +542,45 @@ fn find_query(url: &Url, key: &str) -> Result<String> {
540542
Err(anyhow!("Unable to find parameter {} in URL {:?}", key, url))
541543
}
542544

543-
pub fn crypto_key_from_query(url: &Url, key: &str) -> Result<CryptoKey> {
545+
pub fn record_key_from_query(url: &Url, key: &str) -> Result<RecordKey> {
546+
let value = find_query(url, key)?;
547+
let bytes = hex::decode(value)?;
548+
let mut key_vec: [u8; 32] = [0; 32];
549+
key_vec.copy_from_slice(bytes.as_slice());
550+
Ok(RecordKey::new(key_vec))
551+
}
552+
553+
pub fn public_key_from_query(url: &Url, key: &str) -> Result<PublicKey> {
544554
let value = find_query(url, key)?;
545555
let bytes = hex::decode(value)?;
546-
let mut key_vec: [u8; CRYPTO_KEY_LENGTH] = [0; CRYPTO_KEY_LENGTH];
556+
let mut key_vec: [u8; 32] = [0; 32];
547557
key_vec.copy_from_slice(bytes.as_slice());
558+
Ok(PublicKey::new(key_vec))
559+
}
548560

549-
let key = CryptoKey::from(key_vec);
550-
Ok(key)
561+
pub fn secret_key_from_query(url: &Url, key: &str) -> Result<SecretKey> {
562+
let value = find_query(url, key)?;
563+
let bytes = hex::decode(value)?;
564+
let mut key_vec: [u8; 32] = [0; 32];
565+
key_vec.copy_from_slice(bytes.as_slice());
566+
Ok(SecretKey::new(key_vec))
567+
}
568+
569+
pub fn shared_secret_from_query(url: &Url, key: &str) -> Result<SharedSecret> {
570+
let value = find_query(url, key)?;
571+
let bytes = hex::decode(value)?;
572+
let mut key_vec: [u8; 32] = [0; 32];
573+
key_vec.copy_from_slice(bytes.as_slice());
574+
Ok(SharedSecret::new(key_vec))
551575
}
552576

553577
pub fn parse_url(url_string: &str) -> Result<CommonKeypair> {
554578
let url = Url::parse(url_string)?;
555579

556-
let id = crypto_key_from_query(&url, URL_DHT_KEY)?;
557-
let encryption_key = crypto_key_from_query(&url, URL_ENCRYPTION_KEY)?;
558-
let public_key = crypto_key_from_query(&url, URL_PUBLIC_KEY)?;
559-
let secret_key = Some(crypto_key_from_query(&url, URL_SECRET_KEY)?);
580+
let id = record_key_from_query(&url, URL_DHT_KEY)?;
581+
let encryption_key = shared_secret_from_query(&url, URL_ENCRYPTION_KEY)?;
582+
let public_key = public_key_from_query(&url, URL_PUBLIC_KEY)?;
583+
let secret_key = Some(secret_key_from_query(&url, URL_SECRET_KEY)?);
560584

561585
Ok(CommonKeypair {
562586
id,

src/common.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use std::{path::Path, path::PathBuf, sync::Arc};
77
use tokio::sync::broadcast::{self, Receiver};
88
use url::Url;
99
use veilid_core::{
10-
CryptoKey, CryptoSystem, CryptoSystemVLD0, CryptoTyped, DHTRecordDescriptor, KeyPair, Nonce,
10+
PublicKey, SecretKey, RecordKey, CryptoSystem, CryptoTyped, DHTRecordDescriptor, KeyPair, Nonce,
1111
ProtectedStore, RouteId, RoutingContext, Sequencing, SharedSecret, Stability, UpdateCallback,
12-
VeilidAPI, VeilidConfigInner, VeilidUpdate, CRYPTO_KIND_VLD0, VALID_CRYPTO_KINDS,
12+
VeilidAPI, VeilidConfig, VeilidUpdate, CRYPTO_KIND_VLD0, VALID_CRYPTO_KINDS,
1313
};
1414

1515
use crate::constants::ROUTE_ID_DHT_KEY;
@@ -29,7 +29,7 @@ pub async fn make_route(veilid: &VeilidAPI) -> Result<(RouteId, Vec<u8>)> {
2929
if let Ok(value) = result {
3030
return Ok(value);
3131
} else if let Err(e) = &result {
32-
eprintln!("Failed to create route: {}", e);
32+
eprintln!("Failed to create route: {e}");
3333
}
3434
}
3535
Err(anyhow!("Unable to create route, reached max retries"))
@@ -62,20 +62,29 @@ pub async fn init_veilid(
6262

6363
//println!("Wait for veilid network");
6464

65-
while let Ok(update) = rx.recv().await {
66-
if let VeilidUpdate::Attachment(attachment_state) = update {
67-
if attachment_state.public_internet_ready && attachment_state.state.is_attached() {
68-
println!("Public internet ready!");
69-
break;
65+
// Use a timeout to avoid hanging forever
66+
let timeout_duration = tokio::time::Duration::from_secs(60);
67+
let result = tokio::time::timeout(timeout_duration, async {
68+
while let Ok(update) = rx.recv().await {
69+
if let VeilidUpdate::Attachment(attachment_state) = update {
70+
if attachment_state.public_internet_ready && attachment_state.state.is_attached() {
71+
println!("Public internet ready!");
72+
return Ok(());
73+
}
7074
}
7175
}
72-
}
76+
Err(anyhow!("Update channel closed before network ready"))
77+
}).await;
7378

74-
Ok((veilid, rx))
79+
match result {
80+
Ok(Ok(())) => Ok((veilid, rx)),
81+
Ok(Err(e)) => Err(e),
82+
Err(_) => Err(anyhow!("Timeout waiting for Veilid network to become ready")),
83+
}
7584
}
7685

77-
pub fn config_for_dir(base_dir: PathBuf, namespace: String) -> VeilidConfigInner {
78-
VeilidConfigInner {
86+
pub fn config_for_dir(base_dir: PathBuf, namespace: String) -> VeilidConfig {
87+
VeilidConfig {
7988
program_name: "save-dweb-backend".to_string(),
8089
namespace,
8190
protected_store: veilid_core::VeilidConfigProtectedStore {
@@ -101,9 +110,9 @@ pub fn config_for_dir(base_dir: PathBuf, namespace: String) -> VeilidConfigInner
101110

102111
#[derive(Serialize, Deserialize, Clone)]
103112
pub struct CommonKeypair {
104-
pub id: CryptoKey,
105-
pub public_key: CryptoKey,
106-
pub secret_key: Option<CryptoKey>,
113+
pub id: RecordKey,
114+
pub public_key: PublicKey,
115+
pub secret_key: Option<SecretKey>,
107116
pub encryption_key: SharedSecret,
108117
}
109118

@@ -117,7 +126,7 @@ impl CommonKeypair {
117126
Ok(())
118127
}
119128

120-
pub async fn load_keypair(protected_store: &ProtectedStore, id: &CryptoKey) -> Result<Self> {
129+
pub async fn load_keypair(protected_store: &ProtectedStore, id: &RecordKey) -> Result<Self> {
121130
let keypair_data = protected_store
122131
.load_user_secret(id.to_string())
123132
.map_err(|_| anyhow!("Failed to load keypair"))?
@@ -129,21 +138,21 @@ impl CommonKeypair {
129138
}
130139

131140
pub trait DHTEntity {
132-
fn get_id(&self) -> CryptoKey;
141+
fn get_id(&self) -> RecordKey;
133142
fn get_encryption_key(&self) -> SharedSecret;
134143
fn get_routing_context(&self) -> RoutingContext;
135144
fn get_veilid_api(&self) -> VeilidAPI;
136145
fn get_dht_record(&self) -> DHTRecordDescriptor;
137-
fn get_secret_key(&self) -> Option<CryptoKey>;
146+
fn get_secret_key(&self) -> Option<SecretKey>;
138147

139148
// Default method to get the owner key
140-
fn owner_key(&self) -> CryptoKey {
141-
self.get_dht_record().owner().clone()
149+
fn owner_key(&self) -> PublicKey {
150+
*self.get_dht_record().owner()
142151
}
143152

144153
// Default method to get the owner secret
145-
fn owner_secret(&self) -> Option<CryptoKey> {
146-
self.get_dht_record().owner_secret().cloned()
154+
fn owner_secret(&self) -> Option<SecretKey> {
155+
self.get_dht_record().owner_secret().copied()
147156
}
148157

149158
fn encrypt_aead(&self, data: &[u8], associated_data: Option<&[u8]>) -> Result<Vec<u8>> {
@@ -153,8 +162,8 @@ pub trait DHTEntity {
153162
.get(CRYPTO_KIND_VLD0)
154163
.ok_or_else(|| anyhow!("Unable to init crypto system"))?;
155164
let nonce = crypto_system.random_nonce();
156-
let mut buffer = Vec::with_capacity(nonce.as_slice().len() + data.len());
157-
buffer.extend_from_slice(nonce.as_slice());
165+
let mut buffer = Vec::with_capacity(nonce.bytes.len() + data.len());
166+
buffer.extend_from_slice(&nonce.bytes);
158167
let encrypted_chunk = crypto_system
159168
.encrypt_aead(data, &nonce, &self.get_encryption_key(), associated_data)
160169
.map_err(|e| anyhow!("Failed to encrypt data: {}", e))?;
@@ -262,7 +271,7 @@ pub trait DHTEntity {
262271
let route_id = match veilid.import_remote_private_route(route_id_blob) {
263272
Ok(route) => route,
264273
Err(e) => {
265-
eprintln!("Failed to import remote private route: {:?}", e);
274+
eprintln!("Failed to import remote private route: {e:?}");
266275
return Err(e.into());
267276
}
268277
};
@@ -272,18 +281,18 @@ pub trait DHTEntity {
272281
.app_message(veilid_core::Target::PrivateRoute(route_id), message)
273282
.await
274283
{
275-
eprintln!("Failed to send message: {:?}", e);
284+
eprintln!("Failed to send message: {e:?}");
276285
return Err(e.into());
277286
}
278287

279288
Ok(())
280289
}
281290

282-
fn get_write_key(&self) -> Option<CryptoKey> {
291+
fn get_write_key(&self) -> Option<PublicKey> {
283292
unimplemented!("WIP")
284293
}
285294

286-
async fn members(&self) -> Result<Vec<CryptoKey>> {
295+
async fn members(&self) -> Result<Vec<PublicKey>> {
287296
unimplemented!("WIP")
288297
}
289298

0 commit comments

Comments
 (0)