summaryrefslogtreecommitdiffstats
path: root/news/phase1-basic-network
diff options
context:
space:
mode:
authormurilo ijanc2026-03-24 21:41:06 -0300
committermurilo ijanc2026-03-24 21:41:06 -0300
commitf186b71ca51e83837db60de13322394bb5e6d348 (patch)
treecd7940eaa16b83d2cde7b18123411bfb161f7ebb /news/phase1-basic-network
downloadwebsite-f186b71ca51e83837db60de13322394bb5e6d348.tar.gz
Initial commit
Import existing tesseras.net website content.
Diffstat (limited to 'news/phase1-basic-network')
-rw-r--r--news/phase1-basic-network/index.html173
-rw-r--r--news/phase1-basic-network/index.html.gzbin0 -> 4056 bytes
2 files changed, 173 insertions, 0 deletions
diff --git a/news/phase1-basic-network/index.html b/news/phase1-basic-network/index.html
new file mode 100644
index 0000000..4852505
--- /dev/null
+++ b/news/phase1-basic-network/index.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>Phase 1: Nodes Find Each Other — Tesseras</title>
+ <meta name="description" content="Tesseras nodes can now discover peers, form a Kademlia DHT over QUIC, and publish and find tessera pointers across the network.">
+ <!-- Open Graph -->
+ <meta property="og:type" content="article">
+ <meta property="og:title" content="Phase 1: Nodes Find Each Other">
+ <meta property="og:description" content="Tesseras nodes can now discover peers, form a Kademlia DHT over QUIC, and publish and find tessera pointers across the network.">
+ <meta property="og:image" content="https://tesseras.net/images/social.jpg">
+ <meta property="og:image:width" content="1200">
+ <meta property="og:image:height" content="630">
+ <meta property="og:site_name" content="Tesseras">
+ <!-- Twitter Card -->
+ <meta name="twitter:card" content="summary_large_image">
+ <meta name="twitter:title" content="Phase 1: Nodes Find Each Other">
+ <meta name="twitter:description" content="Tesseras nodes can now discover peers, form a Kademlia DHT over QUIC, and publish and find tessera pointers across the network.">
+ <meta name="twitter:image" content="https://tesseras.net/images/social.jpg">
+ <link rel="stylesheet" href="https://tesseras.net/style.css?h=21f0f32121928ee5c690">
+
+
+ <link rel="alternate" type="application/atom+xml" title="Tesseras" href="https://tesseras.net/atom.xml">
+
+
+ <link rel="icon" type="image/png" sizes="32x32" href="https://tesseras.net/images/favicon.png?h=be4e123a23393b1a027d">
+
+</head>
+<body>
+ <header>
+ <h1>
+ <a href="https:&#x2F;&#x2F;tesseras.net/">
+ <img src="https://tesseras.net/images/logo-64.png?h=c1b8d0c4c5f93b49d40b" alt="Tesseras" width="40" height="40" class="logo">
+ Tesseras
+ </a>
+ </h1>
+ <nav>
+
+ <a href="https://tesseras.net/about/">About</a>
+ <a href="https://tesseras.net/news/">News</a>
+ <a href="https://tesseras.net/releases/">Releases</a>
+ <a href="https://tesseras.net/faq/">FAQ</a>
+ <a href="https://tesseras.net/subscriptions/">Subscriptions</a>
+ <a href="https://tesseras.net/contact/">Contact</a>
+
+ </nav>
+ <nav class="lang-switch">
+
+ <strong>English</strong> | <a href="/pt-br&#x2F;news&#x2F;phase1-basic-network&#x2F;">Português</a>
+
+ </nav>
+ </header>
+
+ <main>
+
+<article>
+ <h2>Phase 1: Nodes Find Each Other</h2>
+ <p class="news-date">2026-02-14</p>
+ <p>Tesseras is no longer a local-only tool. Phase 1 delivers the networking layer:
+nodes discover each other through a Kademlia DHT, communicate over QUIC, and
+publish tessera pointers that any peer on the network can find. A tessera
+created on node A is now findable from node C.</p>
+<h2 id="what-was-built">What was built</h2>
+<p><strong>tesseras-core</strong> (updated) — New network domain types: <code>TesseraPointer</code>
+(lightweight reference to a tessera's holders and fragment locations),
+<code>NodeIdentity</code> (node ID + public key + proof-of-work nonce), <code>NodeInfo</code>
+(identity + address + capabilities), and <code>Capabilities</code> (bitflags for what a
+node supports: DHT, storage, relay, replication).</p>
+<p><strong>tesseras-net</strong> — The transport layer, built on QUIC via quinn. The <code>Transport</code>
+trait defines the port: <code>send</code>, <code>recv</code>, <code>disconnect</code>, <code>local_addr</code>. Two adapters
+implement it:</p>
+<ul>
+<li><code>QuinnTransport</code> — real QUIC with self-signed TLS, ALPN negotiation
+(<code>tesseras/1</code>), connection pooling via DashMap, and a background accept loop
+that handles incoming streams.</li>
+<li><code>MemTransport</code> + <code>SimNetwork</code> — in-memory channels for deterministic testing
+without network I/O. Every integration test in the DHT crate runs against
+this.</li>
+</ul>
+<p>The wire protocol uses length-prefixed MessagePack: a 4-byte big-endian length
+header followed by an rmp-serde payload. <code>WireMessage</code> carries a version byte,
+request ID, and a body that can be a request, response, or protocol-level error.
+Maximum message size is 64 KiB.</p>
+<p><strong>tesseras-dht</strong> — A complete Kademlia implementation:</p>
+<ul>
+<li><em>Routing table</em>: 160 k-buckets with k=20. Least-recently-seen eviction,
+move-to-back on update, ping-check before replacing a full bucket's oldest
+entry.</li>
+<li><em>XOR distance</em>: 160-bit XOR metric with bucket indexing by highest differing
+bit.</li>
+<li><em>Proof-of-work</em>: nodes grind a nonce until <code>BLAKE3(pubkey || nonce)[..20]</code> has
+8 leading zero bits (~256 hash attempts on average). Cheap enough for any
+device, expensive enough to make Sybil attacks impractical at scale.</li>
+<li><em>Protocol messages</em>: Ping/Pong, FindNode/FindNodeResponse,
+FindValue/FindValueResult, Store — all serialized with MessagePack via serde.</li>
+<li><em>Pointer store</em>: bounded in-memory store with configurable TTL (24 hours
+default) and max entries (10,000 default). When full, evicts pointers furthest
+from the local node ID, following Kademlia's distance-based responsibility
+model.</li>
+<li><em>DhtEngine</em>: the main orchestrator. Handles incoming RPCs, runs iterative
+lookups (alpha=3 parallelism), bootstrap, publish, and find. The <code>run()</code>
+method drives a <code>tokio::select!</code> loop with maintenance timers: routing table
+refresh every 60 seconds, pointer expiry every 5 minutes.</li>
+</ul>
+<p><strong>tesd</strong> — A full-node binary. Parses CLI args (bind address, bootstrap peers,
+data directory), generates a PoW-valid node identity, binds a QUIC endpoint,
+bootstraps into the network, and runs the DHT engine. Graceful shutdown on
+Ctrl+C via tokio signal handling.</p>
+<p><strong>Infrastructure</strong> — OpenTofu configuration for two Hetzner Cloud bootstrap
+nodes (cx22 instances in Falkenstein, Germany and Helsinki, Finland). Cloud-init
+provisioning script creates a dedicated <code>tesseras</code> user, writes a config file,
+and sets up a systemd service. Firewall rules open UDP 4433 (QUIC) and restrict
+metrics to internal access.</p>
+<p><strong>Testing</strong> — 139 tests across the workspace:</p>
+<ul>
+<li>47 unit tests in tesseras-dht (routing table, distance, PoW, pointer store,
+message serialization, engine RPCs)</li>
+<li>5 multi-node integration tests (3-node bootstrap, 10-node lookup convergence,
+publish-and-find, node departure detection, PoW rejection)</li>
+<li>14 tests in tesseras-net (codec roundtrips, transport send/recv, backpressure,
+disconnect)</li>
+<li>Docker Compose smoke tests with 3 containerized nodes communicating over real
+QUIC</li>
+<li>Zero clippy warnings, clean formatting</li>
+</ul>
+<h2 id="architecture-decisions">Architecture decisions</h2>
+<ul>
+<li><strong>Transport as a port</strong>: the <code>Transport</code> trait is the only interface between
+the DHT engine and the network. Swapping QUIC for any other protocol means
+implementing four methods. All DHT tests use the in-memory adapter, making
+them fast and deterministic.</li>
+<li><strong>One stream per RPC</strong>: each DHT request-response pair uses a fresh
+bidirectional QUIC stream. No multiplexing complexity, no head-of-line
+blocking between independent operations. QUIC handles the multiplexing at the
+connection level.</li>
+<li><strong>MessagePack over Protobuf</strong>: compact binary encoding without code generation
+or schema files. Serde integration means adding a field to a message is a
+one-line change. Trade-off: no built-in schema evolution guarantees, but at
+this stage velocity matters more.</li>
+<li><strong>PoW instead of stake or reputation</strong>: a node identity costs ~256 BLAKE3
+hashes. This runs in under a second on any hardware, including a Raspberry Pi,
+but generating thousands of identities for a Sybil attack becomes expensive.
+No tokens, no blockchain, no external dependencies.</li>
+<li><strong>Iterative lookup with routing table updates</strong>: discovered nodes are added to
+the routing table as they're encountered during iterative lookups, following
+standard Kademlia behavior. This ensures the routing table improves
+organically as nodes interact.</li>
+</ul>
+<h2 id="what-comes-next">What comes next</h2>
+<ul>
+<li><strong>Phase 2: Replication</strong> — Reed-Solomon erasure coding over the network,
+fragment distribution, automatic repair loops, bilateral reciprocity ledger
+(no blockchain, no tokens)</li>
+<li><strong>Phase 3: API and Apps</strong> — Flutter mobile/desktop app via
+flutter_rust_bridge, GraphQL API (async-graphql), WASM browser node</li>
+<li><strong>Phase 4: Resilience and Scale</strong> — ML-DSA post-quantum signatures, advanced
+NAT traversal, Shamir's Secret Sharing for heirs, packaging for
+Alpine/Arch/Debian/FreeBSD/OpenBSD, CI on SourceHut</li>
+<li><strong>Phase 5: Exploration and Culture</strong> — public tessera browser, institutional
+curation, genealogy integration, physical media export</li>
+</ul>
+<p>Nodes can find each other. Next, they learn to keep each other's memories alive.</p>
+
+</article>
+
+ </main>
+
+ <footer>
+ <p>&copy; 2026 Tesseras Project. <a href="/atom.xml">News Feed</a> · <a href="https://git.sr.ht/~ijanc/tesseras">Source</a></p>
+ </footer>
+</body>
+</html>
diff --git a/news/phase1-basic-network/index.html.gz b/news/phase1-basic-network/index.html.gz
new file mode 100644
index 0000000..fe517f3
--- /dev/null
+++ b/news/phase1-basic-network/index.html.gz
Binary files differ