Skip to content

WIP:nip-pip:packet protocol#1376

Open
RandyMcMillan wants to merge 1 commit into
rust-nostr:masterfrom
gnostr-org:952567/1869/370561/79c7e248/f25447ec-tests-nip-pip-round-trip
Open

WIP:nip-pip:packet protocol#1376
RandyMcMillan wants to merge 1 commit into
rust-nostr:masterfrom
gnostr-org:952567/1869/370561/79c7e248/f25447ec-tests-nip-pip-round-trip

Conversation

@RandyMcMillan

@RandyMcMillan RandyMcMillan commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

related nip proposal:

nostr-protocol/nips#2364

@RandyMcMillan RandyMcMillan requested a review from yukibtc as a code owner June 6, 2026 04:07
Copilot AI review requested due to automatic review settings June 6, 2026 04:07
@RandyMcMillan RandyMcMillan requested a review from TheAwiteb as a code owner June 6, 2026 04:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for the perfect_ip / PIP packet framing protocol to the nostr crate, including Nostr event encoding/decoding, manifests/repair requests, and example usage.

Changes:

  • Introduces nips::pip module with packet tree framing, XOR parity repair, and persistence helpers.
  • Exposes the PIP module via nips/mod.rs.
  • Adds a nip-pip example and updates dev-dependencies to support relay interactions in examples/tests.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.

File Description
crates/nostr/src/nips/pip.rs Implements packet tree slicing/parity, Nostr event conversion, integrity tracking, and tests for PIP/perfect_ip.
crates/nostr/src/nips/mod.rs Exposes the new pip module.
crates/nostr/examples/nip-pip.rs Adds a CLI example for publishing/reconstructing payloads via PIP events.
crates/nostr/Cargo.toml Adds nostr-sdk dev-dependency and registers the nip-pip example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/nostr/examples/nip-pip.rs Outdated
Comment on lines +194 to +199
for slice in batch.packets {
let event = packet_slice_to_event(&slice, &manifest.root)?.finalize(keys)?;
let event_id = event.id.to_string();

let output = client.send_event(&event).to([relay]).await?;
packet_event_ids.push(event.id.clone());
Comment thread crates/nostr/src/nips/pip.rs Outdated
Comment on lines +320 to +328
pub fn packet_slice_to_event(
slice: &ProtocolSlice,
) -> Result<EventBuilder, serde_json::Error> {
let type_tag = if slice.is_parity { "parity" } else { "data" };

Ok(EventBuilder::new(PIP_SLICE_KIND, serde_json::to_string(slice)?)
.tag(Tag::identifier(slice.id.clone()))
.tag(Tag::custom("seq", [slice.header.seq_num.to_string()]))
.tag(Tag::custom("path", [slice.id.clone()]))
Comment on lines +546 to +570
/// Recursively split a payload into MTU-safe slices and parity frames.
///
/// Leaf packets are emitted when the payload is at or below
/// [`MAX_LEAF_PAYLOAD`]. Internal nodes emit left, right, and parity frames in
/// a deterministic order so the manifest and sequence numbers line up exactly.
pub fn process_slice(id: String, data: Vec<u8>, seq: &mut u32) -> Vec<ProtocolSlice> {
if data.len() <= MAX_LEAF_PAYLOAD {
let slice = ProtocolSlice {
id,
header: Header {
seq_num: *seq,
total_packets: 0,
},
data,
is_parity: false,
};
*seq += 1;
return vec![slice];
}

let half = data.len() / 2;
let left_data = data[..half].to_vec();
let right_data = data[half..].to_vec();

let parity = calculate_parity(&left_data, &right_data);
Comment on lines +121 to +125
pub fn persist(&self, path: impl AsRef<Path>) -> io::Result<()> {
let encoded = serde_json::to_vec(&self.received_slices)
.map_err(|error| io::Error::new(io::ErrorKind::Other, error))?;
std::fs::write(path, encoded)
}
Comment thread crates/nostr/src/nips/pip.rs Outdated
Comment on lines +1113 to +1115
#[test]
fn dump_full_protocol_for_nocapture() {
use hashes::{Hash, sha1::Hash as Sha1Hash};
Comment on lines +16 to +17
use nostr::prelude::*;
use nostr_sdk::prelude::Client;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware - I will move all this

@codecov

codecov Bot commented Jun 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.19626% with 244 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.66%. Comparing base (2d14bf9) to head (a32b27e).

Files with missing lines Patch % Lines
crates/nostr/src/nips/pip.rs 77.19% 244 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1376      +/-   ##
==========================================
+ Coverage   72.43%   72.66%   +0.23%     
==========================================
  Files         202      203       +1     
  Lines       33143    34213    +1070     
==========================================
+ Hits        24007    24861     +854     
- Misses       9136     9352     +216     
Flag Coverage Δ
rust 72.66% <77.19%> (+0.23%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@RandyMcMillan

Copy link
Copy Markdown
Contributor Author

packet round trip: push -> fetch -> reconstruct

Untitled2.mov

@RandyMcMillan RandyMcMillan force-pushed the 952567/1869/370561/79c7e248/f25447ec-tests-nip-pip-round-trip branch 2 times, most recently from 7d85d61 to 9e9e727 Compare June 6, 2026 04:41
@RandyMcMillan RandyMcMillan force-pushed the 952567/1869/370561/79c7e248/f25447ec-tests-nip-pip-round-trip branch from 9e9e727 to a32b27e Compare June 6, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants