···11+Feature: Flower-Iroh Funnel Integration
22+33+ In order to enable federated learning across NAT boundaries
44+ As a system operator
55+ I want to route Flower gRPC communications through Iroh tunnels
66+77+ Background:
88+ Given Flower operates as a hub-and-spoke federated learning framework
99+ And Flower nodes communicate via gRPC using protobuf messages
1010+ And Iroh provides P2P connections with NAT traversal and encryption
1111+1212+ Scenario: Flower Framework Architecture
1313+ In order to coordinate distributed model training
1414+ As a Flower deployment
1515+ I want to understand the framework's component topology
1616+1717+ Given Flower uses a hub-and-spoke topology centered on a SuperLink server
1818+ When organizing federated learning workloads
1919+ Then the framework consists of three primary components:
2020+ | Component | Role |
2121+ | SuperLink | Long-running server that forwards tasks |
2222+ | SuperNode | Client coordinating client training |
2323+ | ServerApp | Short-lived process with project code |
2424+ And communication flows through well-defined API ports
2525+ | API | Port | Purpose |
2626+ | Fleet API | 9092 | SuperNode to SuperLink messaging |
2727+ | ServerAppIo API | 9091 | ServerApp to SuperLink run management |
2828+ | ClientAppIo API | 9094 | ClientApp to SuperNode FAB retrieval |
2929+ | Control API | 9093 | CLI to SuperLink user interaction |
3030+3131+ Scenario: Iroh Framework Architecture
3232+ In order to establish peer connections across NAT boundaries
3333+ As an Iroh deployment
3434+ I want to leverage QUIC-based hole-punching and relay fallback
3535+3636+ Given Iroh dials by public key rather than IP address
3737+ When establishing connections
3838+ Then the framework uses a multi-tier connection strategy:
3939+ | Strategy | Condition |
4040+ | Direct P2P | When hole-punching succeeds |
4141+ | Home Relay | When both endpoints have relays |
4242+ | Public Relay | When NAT traversal fails |
4343+ And all traffic is encrypted via QUIC with TLS
4444+ And protocol negotiation uses ALPN for stream multiplexing
4545+4646+ Scenario: Flower-Iroh Funnel Design
4747+ In order to route Flower gRPC through Iroh tunnels
4848+ As a system architect
4949+ I want to design a sidecar proxy architecture
5050+5151+ Given Flower communicates via gRPC on HTTP/2
5252+ And Iroh provides QUIC-based transport with NAT traversal
5353+ When integrating the frameworks
5454+ Then the funnel package structure follows:
5555+ | Component | Responsibility |
5656+ | grpc_server.rs | gRPC server (Flower protocol terminator)|
5757+ | tunnel.rs | Iroh tunnel management |
5858+ | protocol.rs | Protocol translation layer |
5959+ | address_lookup/ | Address resolution service |
6060+ And the communication flow operates as:
6161+ | Step | Description |
6262+ | Flower Client | Initiates gRPC to funnel |
6363+ | Funnel (Iroh endpoint) | Terminates gRPC, publishes endpoint |
6464+ | Iroh tunnel | Encrypts, traverses NAT via QUIC |
6565+ | Peer Funnel | Terminates Iroh, forwards to Flower |
6666+ | Flower Server | Receives gRPC from peer funnel |
6767+6868+ Scenario: Funnel API Design
6969+ In order to provide a clean library interface
7070+ As a Rust developer
7171+ I want to expose a typed API for tunnel management
7272+7373+ Given the funnel is a Rust package named flower-iroh-funnel
7474+ When consuming the library
7575+ Then the public interface provides:
7676+ | Method | Returns | Purpose |
7777+ | Funnel::new() | Result<Self, Error> | Initialize with config |
7878+ | Funnel::serve() | Result<(), Error> | Start gRPC server |
7979+ | Funnel::connect_to_peer | Result<PeerConn, Err>| Connect to remote peer |
8080+ | Funnel::endpoint_id | EndpointId | Local iroh endpoint identity |
8181+ And configuration includes:
8282+ | Field | Type | Purpose |
8383+ | alpn | Vec<u8> | Protocol negotiation bytes |
8484+ | relay_mode | RelayMode | NAT traversal strategy |
8585+ | bind_addr | SocketAddr | Local bind address |
8686+ | flower_grpc_addr | SocketAddr | Flower gRPC listen address |
8787+8888+ Scenario: Cross-Platform Support
8989+ In order to support deployment across major platforms
9090+ As an operator
9191+ I want the funnel to operate on macOS, Windows, and Linux
9292+9393+ Given Iroh's QUIC transport is cross-platform
9494+ When deploying the funnel
9595+ Then full support is available on:
9696+ | Platform | Status |
9797+ | macOS | Full |
9898+ | Windows | Full |
9999+ | Linux | Full |
100100+ And platform detection uses cfg(target_os) conditionals
101101+102102+ Scenario: Dependencies
103103+ In order to build the funnel package
104104+ As a Rust developer
105105+ I want to declare the correct dependencies
106106+107107+ Given the funnel requires both gRPC and P2P capabilities
108108+ When configuring Cargo.toml
109109+ Then the dependencies are:
110110+ | Crate | Version | Purpose |
111111+ | iroh | 0.98 | P2P connectivity and NAT traversal|
112112+ | tokio | 1 | Async runtime with full features |
113113+ | tonic | 0.12 | gRPC server implementation |
114114+ | prost | 0.12 | Protocol buffer code generation |
115115+ | serde | 1 | Serialization with derive support |
+119
COVEN.md
···11+Understanding:
22+33+- Flower is a federated learning framework with Python/gRPC communication
44+- Flower nodes communicate via gRPC using protobuf messages (PullAppInputs, PushAppOutputs, etc.)
55+- Iroh provides P2P connections with NAT traversal and encryption via endpoint IDs
66+- The goal is a Rust "funnel" that routes Flower gRPC through Iroh tunnels
77+88+Flower should wrap well with Iroh because:
99+1010+1. Clean abstraction boundary - Flower's GrpcAdapter provides a clear interface (grpc_adapter() context manager returns send/receive callables) that could be replaced with iroh endpoints
1111+2. Standard protocol - gRPC uses HTTP/2 which iroh can leverage for QUIC-based hole-punching
1212+3. Separated concerns - Message serialization (protobuf), transport (gRPC), and application logic are modular
1313+4. Simpler message model - Request-response pattern maps well to iroh's bidirectional QUIC streams
1414+1515+Let me ask a clarifying question to ensure I understand the architecture correctly:
1616+1717+# Questions
1818+1919+Which Flower communication pattern should the Iroh funnel support? The Flower architecture has multiple communication paths: (1) Client→Server gRPC (2) ServerApp→ClientApp gRPC (3) Node-to-Node communication via Fleet protocol. Which should the funnel wrap?
2020+**Both layers**
2121+2222+# Questions
2323+2424+How should the Iroh funnel integrate with existing Flower deployments? Should it be a sidecar proxy that Flower nodes connect through, or an embedded library that replaces Flower transport directly?
2525+**Sidecar proxy (Recommended)**
2626+Now I have a clear picture. Let me present the comprehensive plan.
2727+2828+---
2929+3030+Plan: Flower-Iroh Funnel Package
3131+Overview
3232+Create a modular Rust package called flower-iroh-funnel that acts as a sidecar proxy, wrapping Flower gRPC communications with Iroh for NAT traversal and encryption.
3333+Package Structure
3434+flower-iroh-funnel/
3535+├── Cargo.toml # Workspace member
3636+├── src/
3737+│ ├── lib.rs # Library interface
3838+│ ├── proxy.rs # Main proxy logic
3939+│ ├── grpc_server.rs # gRPC server (terminator)
4040+│ ├── tunnel.rs # Iroh tunnel management
4141+│ ├── protocol.rs # Protocol translation
4242+│ └── address_lookup/ # Address resolution
4343+├── examples/
4444+│ ├── simple_proxy.rs # Basic proxy example
4545+└── tests/
4646+└── integration.rs
4747+Key Components
4848+4949+1. gRPC Server (Terminator)
5050+5151+- Listens on Flower gRPC port
5252+- Accepts connections from Flower clients
5353+- Translates gRPC messages to Iroh stream format
5454+- Publishes its endpoint via Iroh address lookup
5555+5656+2. Iroh Tunnel Layer
5757+5858+- Manages Iroh connections to peer funnels
5959+- Provides NAT traversal via relay/hole punching
6060+- Encrypts all traffic with Iroh's QUIC+TLS
6161+- Maps Flower node IDs to Iroh endpoint IDs
6262+6363+3. Protocol Translation
6464+6565+- Converts Flower protobuf messages to Iroh streams
6666+- Handles streaming request/response patterns
6767+- Maintains message ordering and delivery confirmation
6868+6969+4. Address Lookup
7070+7171+- Publishes Flower node info via Iroh's address lookup
7272+- Resolves Flower node IDs to Iroh endpoints
7373+- Supports DNS and pkarr integration
7474+ API Design
7575+ // Library interface
7676+ pub struct Funnel {
7777+ inner: Arc<FunnelInner>,
7878+ }
7979+ impl Funnel {
8080+ pub async fn new(config: FunnelConfig) -> Result<Self, FunnelError>;
8181+8282+ pub async fn serve(&self) -> Result<(), FunnelError>;
8383+8484+ pub async fn connect_to_peer(&self, node_id: &NodeId) -> Result<PeerConnection, ConnectError>;
8585+8686+ pub fn endpoint_id(&self) -> EndpointId;
8787+8888+ }
8989+ pub struct FunnelConfig {
9090+ pub alpn: Vec<u8>,
9191+ pub relay_mode: RelayMode,
9292+ pub bind_addr: SocketAddr,
9393+ pub flower_grpc_addr: SocketAddr,
9494+ }
9595+ Communication Flow
9696+ Flower Client → gRPC → Funnel (Iroh endpoint) → Iroh tunnel → Peer Funnel → gRPC → Flower Server
9797+ Cross-Platform Support
9898+9999+- macOS: Full support via Iroh's QUIC transport
100100+- Windows: Full support via Iroh's QUIC transport
101101+- Linux: Full support via Iroh's QUIC transport
102102+- Platform detection via cfg(target_os) conditionals
103103+ Dependencies
104104+ [dependencies]
105105+ iroh = "0.98"
106106+ tokio = { version = "1", features = ["full"] }
107107+ serde = { version = "1", features = ["derive"] }
108108+ tonic = "0.12" # gRPC server
109109+ prost = "0.12"
110110+ Next Steps
111111+112112+1. Create the Rust crate structure
113113+2. Implement the gRPC server (Flower protocol terminator)
114114+3. Implement Iroh tunnel management
115115+4. Add protocol translation layer
116116+5. Add address lookup integration
117117+6. Test with existing Flower deployments
118118+119119+---