Protocol v2: trusted-peer push, truthful partials, split downloads

Three capabilities the iroh-blobs 0.103 line makes possible:

- Push (new API surface, protocol v2): `Push { hash, node_id }` hands
  fully-present content to a trusted peer, unprompted. Consent is
  mutual — the sender pushes only to peers it trusts, and the receiver
  (which now accepts connections unconditionally and gates per request)
  admits pushes only from peers *it* trusts, deferring with RateLimited
  while metered. An accepted push is pinned by the receiver (default
  policy, format inferred from the request ranges) once its transfer
  completes, and surfaces as a PushReceived event. Because QUIC writes
  are fire-and-forget, the sender confirms delivery by observing the
  receiver's bitfields (root + last hashseq child) before replying —
  Pushed { bytes } means verified received, not merely sent. New
  varde-ctl `push` command.

- Truthful partial presence: Status/List report bytes actually present
  and verified for partial blobs, from the store's bitfields via
  observe, instead of the old "0 until complete".

- Split downloads: multi-provider fetches stripe one request across
  providers (SplitStrategy::Split) instead of trying them serially.

Trusted peers may observe bitfields even when serving is disabled or
metered — bitfields are metadata, and push confirmation rides on them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-16 14:52:27 +02:00
parent ad69f7d884
commit 4033c0ffab
9 changed files with 474 additions and 33 deletions
+28 -1
View File
@@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize};
/// Version of the socket protocol described by this crate.
///
/// Bumped on incompatible changes; reported in [`GlobalStatus`].
pub const PROTOCOL_VERSION: u32 = 1;
pub const PROTOCOL_VERSION: u32 = 2;
/// A request from a client to the daemon. One JSON object per line.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
@@ -96,6 +96,18 @@ pub enum Request {
},
/// List trusted peers and their current connectivity.
PeerList {},
/// Push fully-present content to a trusted peer, unprompted.
///
/// Consent is mutual: this daemon only pushes to peers it trusts, and
/// the receiver only accepts pushes from peers *it* trusts. On the
/// receiving side an accepted push is recorded as a pin (default
/// policy), so the content survives gc and shows up in `List`.
Push {
/// Hash (hex) of the fully-present blob or HashSeq root to push.
hash: String,
/// The receiving peer's iroh NodeId (z-base-32).
node_id: String,
},
/// Drop all blobs not reachable from a pin. Explicit, never automatic.
Gc {},
/// Switch this connection to an event stream. The daemon acknowledges
@@ -240,6 +252,13 @@ pub enum ResponseData {
/// Number of blobs removed.
blobs_removed: u64,
},
/// Content was pushed to a peer. Reply to [`Request::Push`].
Pushed {
/// The pushed root hash (hex).
hash: String,
/// Payload bytes written to the peer.
bytes: u64,
},
}
/// Global daemon status.
@@ -334,6 +353,14 @@ pub enum Event {
/// The pinned root hash (hex).
hash: String,
},
/// A trusted peer pushed content to this daemon; it has been pinned
/// with the default policy.
PushReceived {
/// The pushed root hash (hex).
hash: String,
/// NodeId (z-base-32) of the pushing peer.
from: String,
},
/// A signed announcement was received on a subscribed discovery topic.
Announcement {
/// The announced HashSeq root (hex).