Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/assignments/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2021"
[features]
reader = ["serde_json", "ouroboros"]
builder = ["base64", "curve25519-dalek", "hmac", "serde_json", "url"]
mvcc-chunks = []

[dependencies]
anyhow = { version = "1.0" }
Expand All @@ -25,3 +26,5 @@ url = { version = "2.5.0", optional = true }

[dev-dependencies]
rand = "0.8.5"
# Tests validate NetworkState JSON compatibility without requiring the reader feature.
serde_json = "1.0"
13 changes: 12 additions & 1 deletion crates/assignments/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ pub enum WorkerStatus {

#[derive(Serialize, Deserialize)]
pub struct NetworkAssignment {
pub url: Option<String>, // deprecated
/// Deprecated: use `fb_url` or `fb_url_v1` instead.
#[deprecated(note = "use fb_url or fb_url_v1 instead")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
pub fb_url: Option<String>,
Comment thread
toschoosqd marked this conversation as resolved.
pub fb_url_v1: Option<String>,
pub id: String,
Expand All @@ -21,4 +24,12 @@ pub struct NetworkAssignment {
pub struct NetworkState {
pub network: String,
pub assignment: NetworkAssignment,

#[cfg(feature = "mvcc-chunks")]
Comment thread
toschoosqd marked this conversation as resolved.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub worker_assignment: Option<NetworkAssignment>,

#[cfg(feature = "mvcc-chunks")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub portal_assignment: Option<NetworkAssignment>,
}
98 changes: 98 additions & 0 deletions crates/assignments/tests/network_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use sqd_assignments::NetworkState;

const LEGACY_STATE: &str = r#"{
"network": "testnet",
"assignment": {
"url": "",
"fb_url": "https://example.test/legacy.fb.0.gz",
"fb_url_v1": "https://example.test/legacy.fb.1.gz",
"id": "2026-06-09T12:00:00_LEGACY",
"effective_from": 1781000000
}
}"#;

#[test]
fn legacy_network_state_deserializes() {
let state: NetworkState = serde_json::from_str(LEGACY_STATE).unwrap();

assert_eq!(state.network, "testnet");
assert_eq!(state.assignment.id, "2026-06-09T12:00:00_LEGACY");

#[cfg(feature = "mvcc-chunks")]
{
assert!(state.worker_assignment.is_none());
assert!(state.portal_assignment.is_none());
}
}

#[allow(deprecated)]
#[test]
fn deprecated_assignment_url_defaults_and_skips_when_absent() {
let state: NetworkState = serde_json::from_str(
r#"{
"network": "testnet",
"assignment": {
"fb_url": "https://example.test/legacy.fb.0.gz",
"fb_url_v1": "https://example.test/legacy.fb.1.gz",
"id": "legacy",
"effective_from": 1781000000
}
}"#,
)
.unwrap();

assert!(state.assignment.url.is_none());

let serialized = serde_json::to_value(state).unwrap();
assert!(serialized["assignment"].get("url").is_none());
}

#[cfg(feature = "mvcc-chunks")]
#[test]
fn split_network_state_deserializes() {
let state: NetworkState = serde_json::from_str(
r#"{
"network": "testnet",
"assignment": {
"url": "",
"fb_url": "https://example.test/legacy.fb.0.gz",
"fb_url_v1": "https://example.test/legacy.fb.1.gz",
"id": "legacy",
"effective_from": 1781000000
},
"worker_assignment": {
"url": "",
"fb_url": "https://example.test/worker.fb.0.gz",
"fb_url_v1": "https://example.test/worker.fb.1.gz",
"id": "worker",
"effective_from": 1781000000
},
"portal_assignment": {
"url": "",
"fb_url": "https://example.test/portal.fb.0.gz",
"fb_url_v1": "https://example.test/portal.fb.1.gz",
"id": "portal",
"effective_from": 1781000000
}
}"#,
)
.unwrap();

assert_eq!(state.assignment.id, "legacy");
assert_eq!(state.worker_assignment.unwrap().id, "worker");
assert_eq!(state.portal_assignment.unwrap().id, "portal");
}

#[cfg(feature = "mvcc-chunks")]
#[test]
fn absent_split_assignments_stay_omitted_after_json_round_trip() {
let state: NetworkState = serde_json::from_str(LEGACY_STATE).unwrap();

let serialized = serde_json::to_string(&state).unwrap();
let round_tripped: NetworkState = serde_json::from_str(&serialized).unwrap();
let value = serde_json::to_value(round_tripped).unwrap();

assert!(value.get("assignment").is_some());
assert!(value.get("worker_assignment").is_none());
assert!(value.get("portal_assignment").is_none());
}
5 changes: 3 additions & 2 deletions crates/transport/src/behaviour/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,9 @@ impl BaseBehaviour {
pub fn find_and_dial(&mut self, peer_id: PeerId) {
if self.inner.address_cache.contains(&peer_id) {
log::debug!("Dialing peer {peer_id} using cached address");
self.pending_events
.push_back(ToSwarm::Dial { opts: peer_id.into() });
self.pending_events.push_back(ToSwarm::Dial {
opts: DialOpts::peer_id(peer_id).build(),
});
} else if self.ongoing_lookups.contains_left(&peer_id) {
log::debug!("Query for peer {peer_id} already ongoing");
} else {
Expand Down
Loading