diff --git a/crates/music-dht/src/database.rs b/crates/music-dht/src/database.rs index 9e250d0..ec803b3 100644 --- a/crates/music-dht/src/database.rs +++ b/crates/music-dht/src/database.rs @@ -228,12 +228,15 @@ impl Database { /// Returns non-expired replicas stored under `key`, including tombstones /// (they inform other peers about deletions). Capped at - /// [`MAX_RECORDS_PER_RESPONSE`]. + /// [`MAX_RECORDS_PER_RESPONSE`] with a deterministic order (freshest + /// replicas first), so an overfull bucket always returns the same + /// subset instead of an arbitrary one. pub async fn dht_records_by_key(&self, key: DhtKey, now_ms: u64) -> Result> { self.call(move |conn| { let mut stmt = conn.prepare( "SELECT payload FROM dht_records WHERE dht_key = ?1 AND expires_at_ms > ?2 + ORDER BY expires_at_ms DESC, artist_id LIMIT ?3", )?; let rows = stmt.query_map( diff --git a/crates/music-dht/src/message.rs b/crates/music-dht/src/message.rs index 61a8724..2008efc 100644 --- a/crates/music-dht/src/message.rs +++ b/crates/music-dht/src/message.rs @@ -13,7 +13,7 @@ pub const DHT_PROTOCOL_VERSION: u16 = 1; /// Maximum number of contacts in a single [`PeerExchange`]. pub const MAX_PEER_EXCHANGE_CONTACTS: usize = 32; /// Maximum number of records in a single [`FindValueResponse`]. -pub const MAX_RECORDS_PER_RESPONSE: usize = 100; +pub const MAX_RECORDS_PER_RESPONSE: usize = 256; /// Correlates a response with its request. #[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/crates/music-dht/src/service.rs b/crates/music-dht/src/service.rs index b776174..4b6331e 100644 --- a/crates/music-dht/src/service.rs +++ b/crates/music-dht/src/service.rs @@ -163,6 +163,9 @@ impl MusicDhtService { .data_dir(&config.data_dir) .network_id(config.network_id) .schema_id(SchemaId::from_name(SCHEMA_NAME)) + // A full FindValue response (MAX_RECORDS_PER_RESPONSE records + // with long names and artist lists) must fit into one frame. + .max_message_size(1024 * 1024) .request_timeout(config.transport_timeout); if let Some(rendezvous) = config.rendezvous.clone() { engine_builder = engine_builder.rendezvous(rendezvous);