prepared release
CI / check (push) Successful in 5m17s

This commit is contained in:
Ultradesu
2026-07-26 03:48:30 +03:00
parent a9012351dc
commit c6b2a066b4
36 changed files with 590 additions and 4801 deletions
+5
View File
@@ -2,6 +2,11 @@
name = "federation-net"
version = "0.1.0"
description = "Generic peer-to-peer networking engine built on Iroh"
readme = "README.md"
documentation = "https://docs.rs/federation-net"
repository.workspace = true
keywords = ["p2p", "iroh", "quic", "networking", "dht"]
categories = ["network-programming", "asynchronous"]
edition.workspace = true
license.workspace = true
rust-version.workspace = true
+13
View File
@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
+114
View File
@@ -0,0 +1,114 @@
# federation-net
`federation-net` is a generic Rust networking engine for equal peers, built on
[iroh](https://iroh.computer). It establishes authenticated QUIC connections
through NATs, exchanges typed application messages, and exposes direct byte
streams for additional protocols.
The crate contains no music or application database logic. Applications own
their message schema and persistent domain state.
## Capabilities
- Persistent Ed25519/iroh identity.
- Self-contained, versioned peer tickets.
- Optional peer rendezvous through BEP44 records in the BitTorrent Mainline
DHT.
- Network and message-schema isolation during handshake.
- Typed bidirectional messages with bounded framing and backpressure.
- Application-defined ALPN byte streams.
- Connection path and traffic statistics.
- Graceful disconnect and shutdown events.
## Basic usage
```rust,no_run
use federation_net::{NetworkConfig, NetworkEngine, NetworkEvent, NetworkId, SchemaId};
#[derive(Debug, serde::Serialize, serde::Deserialize)]
enum Message {
Ping { nonce: u64 },
}
# async fn run() -> federation_net::Result<()> {
let config = NetworkConfig::builder()
.data_dir("./peer-a")
.network_id(NetworkId::from_name("example-network"))
.schema_id(SchemaId::from_name("example-message-v1"))
.build()?;
let (engine, mut events) = NetworkEngine::<Message>::start(config).await?;
println!("share this ticket: {}", engine.ticket().await?);
while let Some(event) = events.recv().await {
if let NetworkEvent::PeerConnected { peer_id, .. } = event {
engine.send(peer_id, &Message::Ping { nonce: 1 }).await?;
}
}
engine.shutdown().await
# }
```
## Network and schema IDs
`NetworkId` selects an independent peer network. `SchemaId` selects the wire
format of the application's typed messages. Both are checked during the
application handshake; peers with mismatched values are rejected before
domain messages are decoded.
Treat a backwards-incompatible message change as a schema change. Derive a new
schema ID instead of attempting to decode incompatible payloads under the old
identifier.
## Discovery
Rendezvous is optional. When enabled, peers publish signed, expiring endpoint
records into a network-specific BEP44 record in the public Mainline DHT. A
shared network ID is enough to discover current participants; no
Frid-operated registry is involved.
```rust,no_run
# use federation_net::{NetworkConfig, NetworkId, RendezvousConfig, SchemaId};
# fn config() -> federation_net::Result<()> {
let config = NetworkConfig::builder()
.data_dir("./peer-a")
.network_id(NetworkId::from_name("example-network"))
.schema_id(SchemaId::from_name("example-message-v1"))
.rendezvous(RendezvousConfig::default())
.build()?;
# drop(config);
# Ok(())
# }
```
The rendezvous record is discoverable by anyone who knows the network ID. It
provides discovery, not authorization. Applications that need restricted
membership must implement and enforce that policy in their own protocol.
Without rendezvous, peers can connect through tickets and operate on isolated
networks.
## Byte streams
Applications may register additional ALPNs in `NetworkConfig` and accept or
open authenticated streams through the same endpoint. This is how higher
layers add catalog, audio, or synchronization protocols without putting large
payloads into the typed message channel.
## Events and backpressure
The bounded event channel reports connection, disconnection, decoded message,
and protocol-error events. Consumers must drain it continuously. The engine
applies backpressure instead of allowing unbounded memory growth.
Per-connection protocol failures are reported without stopping the engine.
## Verification
From the workspace root:
```bash
cargo test -p federation-net
cargo clippy -p federation-net --all-targets -- -D warnings
```