Skip to content

Implement MVP: distributed P2P storage with E2E encryption and RS erasure coding#18

Open
keanu-thakalath wants to merge 1 commit intomainfrom
distribute-shards-to-peers
Open

Implement MVP: distributed P2P storage with E2E encryption and RS erasure coding#18
keanu-thakalath wants to merge 1 commit intomainfrom
distribute-shards-to-peers

Conversation

@keanu-thakalath
Copy link
Copy Markdown
Contributor

Summary

  • Uploading node stores zero shards locally — all data lives exclusively on peer nodes. Fixed a latent peer-ID mismatch bug (Manifest.Replicas() returned ed25519 pubkey hex strings but c.peers was keyed by IP:port) that was invisible before because download always short-circuited on local shard lookups.
  • End-to-end encryption: per-file AES-GCM key, wrapped with HKDF-SHA256 over the owner's ed25519 seed, stored in the manifest.
  • Reed-Solomon 4+2 erasure coding: any 4 of 6 shards reconstruct the file. With 3 peers each holding 2 shards, any single peer failure is tolerated.
  • CRDT manifest (BoltDB-backed): grow-only replica set, monotone tombstone with LWW tiebreak — merge is commutative, associative, and idempotent regardless of operation order.
  • Signed P2P data ops: SignedStoreRequest/Ack, SignedDeleteRequest, unsigned GetRequest/Response; all signed messages verified with ed25519 + ±5 min clock-skew check.
  • App-layer UDP fragmentation for shards exceeding macOS's net.inet.udp.maxdgram (9216 bytes): 4 KB payload chunks, safely under limit after JSON/base64 encoding.
  • Multi-daemon support via MOSAIC_SOCKET env var.
  • All 20 CLI commands implemented with real business logic (replaced stubs).

Test plan

  • TestFourNodeRedundancy: 4-node cluster; owner uploads, B/C/D each hold 2 shards; killing any single peer → byte-identical reconstruction from remaining 4 shards (3 sub-tests: B_down, C_down, D_down)
  • TestUploadDownload_TwoNodes: asserts owner.Store.UsedBytes() == 0 (all shards on peer); download fetches everything over P2P; large-file chunked transport (~480 KB)
  • Race detector clean: go test ./... -race -timeout 180s
  • go build ./... and go vet ./... clean

Shards are now distributed exclusively across peers — the uploading node
stores nothing locally. Any peer failure is tolerated as long as
DataShards (4) of the 6 RS shards remain reachable.

Core additions
- identity: persistent ed25519 keypair (identity.key, 0600)
- crypto: AES-GCM file encryption + HKDF key wrapping
- storage: content-addressed ShardStore with two-level fanout
- manifest: state-based CRDT (G-set replicas, monotone tombstone, LWW)
  backed by BoltDB; merge is commutative, associative, idempotent
- api/signed: SignedStoreRequest/Ack, SignedDeleteRequest, GetRequest/Response
- p2p/data_ops: request/response correlation via per-hash waiter channels;
  pubkeyToPeerID resolver bridges manifest replica IDs (ed25519 hex) to
  connection peer IDs (IP:port); DataHandler callback interface
- p2p/chunked: transparent app-layer fragmentation for datagrams >8 KB
  (chunkPayloadBytes=4096 stays safely under macOS net.inet.udp.maxdgram)
- daemon/app: App singleton wiring identity, store, manifest, P2P client
- daemon/operations: UploadFile / DownloadFile / DeleteFile with real logic
- daemon/handlers: all 20 CLI commands implemented (replaces stubs)
- daemon/server: rewritten to use App; MOSAIC_SOCKET env for multi-daemon

Tests
- TestFourNodeRedundancy: 4-node cluster (A uploads, B/C/D each hold 2
  shards); killing any single peer still allows byte-identical reconstruction
  via RS repair from the remaining 4 shards
- TestUploadDownload_TwoNodes: asserts owner.Store.UsedBytes()==0 (all
  shards live on the peer)
- Race detector clean across all packages
@keanu-thakalath keanu-thakalath force-pushed the distribute-shards-to-peers branch from e80c9cf to 6a6d8b4 Compare April 29, 2026 06:41
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.

1 participant