Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,23 @@ jobs:

- name: Create proto symlink for server
run: |
mkdir -p server/src/main/proto
ln -sf "$(pwd)/proto/difp.proto" server/src/main/proto/difp.proto
mkdir -p server/java/examples/src/main/proto
ln -sf "$(pwd)/proto/difp.proto" server/java/examples/src/main/proto/difp.proto

- name: Cache Gradle packages
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-server-${{ hashFiles('server/**/*.gradle*') }}
key: ${{ runner.os }}-gradle-server-${{ hashFiles('server/java/examples/**/*.gradle*') }}

- name: Make gradlew executable
run: chmod +x server/java/examples/gradlew

- name: Build server
working-directory: server
run: ./gradlew build --no-daemon
working-directory: server/java/examples
run: ./gradlew installDist --no-daemon

# ── 3. Build the Android example ─────────────────────────────────────────────
android:
Expand Down Expand Up @@ -81,6 +84,9 @@ jobs:
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-android-${{ hashFiles('examples/android/**/*.gradle*') }}

- name: Make gradlew executable
run: chmod +x examples/android/gradlew

- name: Build Android APK (debug)
working-directory: examples/android
run: ./gradlew assembleDebug --no-daemon
Expand All @@ -89,4 +95,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: difp-android-debug
path: examples/android/app/build/outputs/apk/debug/*.apk
path: examples/android/app/build/outputs/apk/debug/*.apk
226 changes: 225 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,225 @@
# DIFP-gRPC .
# DIFP-gRPC

> **Djowda Interconnected Food Protocol — gRPC Transport Profile**
> Specification v0.4 · Skull Implementation

[![License: CC-BY 4.0](https://img.shields.io/badge/License-CC--BY%204.0-green.svg)](https://creativecommons.org/licenses/by/4.0/)
[![Protocol](https://img.shields.io/badge/DIFP-v0.4-teal.svg)](https://djowda.com/difp/)
[![Status](https://img.shields.io/badge/status-skull%20preview-orange.svg)]()

This repository contains the **gRPC transport implementation** of [DIFP v0.4](https://djowda.com/difp/) — the Djowda Interconnected Food Protocol. It is an official working preview, not a production release. Every placeholder is clearly marked for incremental replacement.

---

## Repository layout

```
DIFP-gRPC/
├── proto/
│ └── difp.proto ← Single source of truth for the entire protocol
├── server/
│ └── java/
│ └── examples/ ← Gradle project root (build.gradle lives here)
│ ├── build.gradle
│ ├── gradlew.bat
│ └── src/main/
│ ├── java/io/grpc/examples/helloworld/
│ │ └── DifpNodeServer.java
│ └── proto/ ← symlink → ../../../../proto/difp.proto
├── examples/
│ └── android/ ← Android test client — open this in Android Studio
│ ├── build.gradle
│ ├── settings.gradle
│ └── app/src/main/
│ ├── java/com/djowda/difp/
│ │ └── MainActivity.java
│ └── res/layout/
│ └── activity_difp_test.xml
├── docs/
│ ├── architecture.md ← Skull roadmap & next iteration targets
│ └── proto-guide.md ← Wire format notes & message type reference
└── .github/
└── workflows/build.yml ← CI: compile proto → build server → build android
```

**The `proto/` directory is the single source of truth.** Both the server and the Android example symlink `difp.proto` from there — no copies, no drift.

---

## What is implemented (skull v0.4)

| DIFP Section | Coverage |
|---|---|
| §3 MinMax99 Grid | `geoToCellNumber`, `getNearbyCells` — bit-for-bit correct, validated against §3.3 vectors |
| §4 Component Identity | `RegisterComponent` RPC — computes cell ID, assigns DID, placeholder token |
| §5 Presence & Discovery | `QueryCell` RPC + `presence.*` stream handlers, in-memory store |
| §7 Trade Protocol | `trade.ask/offer/donate/accept/reject/complete/cancel` — all routed via bidirectional stream |
| §15 Message Envelope | `DifpEnvelope` with `oneof payload` covering all 30+ message types |
| §18 Node Pipeline | 6-step processing pipeline (crypto step marked TODO) |
| §24 Lobby Layer | `cellIdToLobbyId` — Layer 1 spatial addressing |
| §25-27 Registry | `DifpRegistryService` — in-memory lobby→node registry, all 4 RPCs |

### Placeholder functions

Every DB interaction is a clearly named placeholder:

```java
db_queryPresenceByCell() // → replace with PostGIS / Firebase spatial query
db_createTrade() // → replace with §9.1 atomic fan-out write
db_updateTradeStatus() // → replace with §9.2 atomic fan-out write
db_registerComponent() // → replace with auth provider + persistent store
db_upsertRegistryEntry() // → replace with Redis SADD or registry DB
```

---

## Quick start

### 1. Run the server

Navigate to the Gradle project root and build the distribution:

```powershell
cd server\java\examples
.\gradlew.bat installDist
```

Then launch the node:

```powershell
.\build\install\examples\bin\Difp-Node-Server
# INFO: Server started, listening on 50051
# INFO: [DB] Seeded 3 dummy presence records (Algiers cell 1,711,767,603)
```

### 2. Run the Android client

Open the folder `examples\android\` as a project in **Android Studio**.

Default connection settings (pre-filled in the UI):

| Field | Default | Notes |
|---|---|---|
| Host | `10.0.2.2` | Android emulator → host machine localhost |
| Port | `50051` | Matches the server default |
| Location | `36.7538, 3.0588` | Algiers — matches seeded dummy data |

Select a flow from the spinner and tap **Run Flow**:

| Flow | What it tests |
|---|---|
| `computeCell` | §3.3 reference vectors — shows ✅/❌ per city, no network needed |
| `register` | Unary RPC — registers a component, receives a real DID back |
| `queryCell` | Lists nearby participants from the in-memory seed data |
| `ping` | Bidirectional stream: `node.ping` → `node.pong` + RTT |
| `tradeAsk` | Full `trade.ask` envelope broadcast via stream |
| `registryQuery` | Lobby → node lookup via `DifpRegistryService` |

### 3. Connect emulator to local server (ADB port forwarding)

The Android emulator runs in an isolated network. You must forward the gRPC port from the emulator back to your machine **after** the emulator boots.

Open a terminal inside Android Studio and run:

```powershell
adb reverse tcp:50051 tcp:50051
```

If you have multiple devices or see a port conflict, find the emulator's ADB port first (shown in the emulator window title, e.g. `5554`) and use the specific serial:

```powershell
# Find connected devices
adb devices

# Forward for a specific emulator serial
adb -s emulator-5554 reverse tcp:50051 tcp:50051
```

> **If the connection still fails after the first launch**, try running the command again — the emulator sometimes resets port rules between boots. Run the app again after re-forwarding.

---

## Building from source

### Prerequisites

- JDK 17+
- Gradle 8+ (or use the included `gradlew.bat` wrapper — no install needed)
- Android Studio Hedgehog+ (for the Android example)
- `protoc` is **not** required locally — the Gradle protobuf plugin downloads it automatically

### Server

```powershell
cd server\java\examples

.\gradlew.bat installDist # compile proto + build distribution
.\gradlew.bat test # run reference vector tests

# Run the built distribution
.\build\install\examples\bin\Difp-Node-Server
```

### Android example

Open `examples\android\` in Android Studio and run via the IDE, or build from the command line:

```powershell
cd examples\android
.\gradlew.bat assembleDebug
# APK: app\build\outputs\apk\debug\app-debug.apk
```

---

## Proto update workflow

When `difp.proto` changes:

```powershell
# 1. Edit the canonical file
notepad proto\difp.proto # or your editor of choice

# 2. Rebuild both projects — symlinks mean no manual copy needed
cd server\java\examples ; .\gradlew.bat generateProto ; cd ..\..\..
cd examples\android ; .\gradlew.bat generateProto ; cd ..\..

# 3. Commit everything together
git add proto\difp.proto server\ examples\android\
git commit -m "proto: <describe the change>"
```

---

## Next iteration targets

1. **Stream broadcasting** — push `trade.ask` to all connected clients in the same cell
2. **Ed25519 signing** — §15.3 canonical hashing + signature verification
3. **Real DB** — replace placeholder functions with your storage backend
4. **Federation** — `registry.announce` to external registry nodes on startup (§25.4)
5. **PAD endpoints** — `/.well-known/difp/pad/latest` for catalog distribution (§22.5)
6. **TradeEngine** — accept/reject/complete flows with atomic §9 fan-out writes

See [`docs/architecture.md`](docs/architecture.md) for the full skull-to-production roadmap.

---

## Contributing

DIFP is an open protocol (CC-BY 4.0). Contributions to the gRPC transport profile are welcome:

- Bug reports and spec clarifications → open an Issue
- Client implementations in other languages → open a PR adding `examples/{language}/`
- Protocol questions → [spec@djowda.com](mailto:spec@djowda.com)

---

## License

**CC-BY 4.0** — free to implement, fork, and commercialize with attribution.
See [LICENSE](LICENSE) · [djowda.com/difp](https://djowda.com/difp/)
Loading