Skip to content

test: private-mesh overlay functional harness - #671

Merged
reardencode merged 12 commits into
masterfrom
test/overlay-functional
Sep 22, 2026
Merged

reardencode merged 12 commits into
masterfrom
test/overlay-functional

Conversation

@rearden-grok

@rearden-grok rearden-grok Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Labeled/nightly overlay-functional job starts a private TestingTorNetwork, an i2pd netid 16 mesh (no public reseed), and a two-node cjdns TUN, then runs feature-gated run_p2p journeys. Default cargo test stays fake SOCKS/SAM/control.
  • Five journeys: Tor onion P2P v2, Electrum/Esplora HS via SOCKS .onion, I2P SAM STREAM CONNECT + silent FORWARD, cjdns TUN getpeerinfo net=cjdns, ephemeral isolated broadcast (standing session must not INV).
  • Production pins the live path: SAM STREAM FORWARD … SILENT=true (otherwise i2pd prefixes the dest onto Bitcoin TCP), STREAM CONNECT/FORWARD retries on early EOF, 90s I2P IBD dial, inbound fc00::/8 labeled cjdns.

Test plan

  • ./scripts/overlay-functional/run.sh.test.sh
  • ./scripts/overlay-functional/run.sh (5 passed)
  • cargo test -p rbitcoin-net --lib filters: i2p_sam, i2p_connect_timeout, inbound_fc00
  • local fmt / clippy -D warnings / deny / ast-grep / ci-os-smoke / nixos-module-eval
  • GitHub Actions required checks + labeled overlay-functional

Made with Cursor

Follow-up

A green overlay run has to exercise the paths a real privacy-network peer uses:

  • Core I2P addrv2 rows use port 0 (SAM 3.1). Those rows are learned, and --i2p-accept-incoming publishes and gossips {b32}.b32.i2p:0 (SHA256 of the public Destination, not the private key).
  • New sessions are Ed25519 with an ECIES leaseset. A dropped SAM session re-issues STREAM FORWARD. STREAM CONNECT stays non-silent: i2pd suppresses the status line when CONNECT is silent, and the dial blocks.
  • A --cjdns-reachable listen on fc00::/8 is advertised without a separate --external-ip.
  • The one-shot Tor broadcast reads the mempool with try_get_tx. get_tx panics on a tokio worker, so the local tx never left the node.

Local ./scripts/overlay-functional/run.sh (all five journeys) passed after these fixes.

rearden-grok Bot and others added 2 commits September 21, 2026 08:26
SAM FORWARD without SILENT=true prefixes the remote dest onto the local
TCP stream, so BIP324 never starts. Retry STREAM CONNECT/FORWARD on
early EOF, give I2P IBD 90s, and classify inbound fc00 as cjdns.

Co-authored-by: Cursor <cursoragent@cursor.com>
Labeled/nightly job starts a TestingTorNetwork, an i2pd netid-16 mesh,
and a two-node cjdns TUN, then runs feature-gated run_p2p journeys.
Default cargo test stays fake SOCKS/SAM/control.

Co-authored-by: Cursor <cursoragent@cursor.com>
@rearden-grok rearden-grok Bot added the overlay-functional Run private Tor/i2pd/cjdns overlay functional harness label Sep 21, 2026
rearden-grok Bot and others added 2 commits September 21, 2026 08:31
GitHub Actions was cancelling cjdroute core immediately: `sudo cjdroute
<conf &` often gets a closed stdin, so the Angel never finishes TUN
setup. Open the conf inside the sudo child instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
GitHub-hosted runners bring the TUN up but ICMP through cjdns does not
complete. Bind UDP on 0.0.0.0 and wait for TCP between the two fc00
addresses — the same path the product uses.

Co-authored-by: Cursor <cursoragent@cursor.com>
Comment thread crates/rbitcoin-test/src/overlay.rs Dismissed
rearden-grok Bot and others added 2 commits September 21, 2026 08:54
After catch-up the standing --connect redial used a hardcoded 8s cap, so
GHA I2P STREAM CONNECT died even when IBD had already synced.

Co-authored-by: Cursor <cursoragent@cursor.com>
Without --nobg the client returns after spawn and GHA reaps a TUN before
the cjdns journey; wait for each iface and re-bind after a settle.

Co-authored-by: Cursor <cursoragent@cursor.com>
SAM 3.1 has no ports, so Bitcoin Core gossips I2P with port 0.
Dropping that port made every Core I2P addrv2 row disappear from
AddrMan, so an I2P-only node never dialed the public overlay.
--i2p-accept-incoming persisted a key and forwarded streams, but never
told peers or getnetworkinfo the .b32.i2p address, so the wider network
could not find the listener. Publish the SHA256 of the public
Destination (private key stripped) as SAM 3.1 port 0, including when
discover is off.

The overlay journey dials that published name. Drop the 180s run cap so
a slow private-mesh tunnel is not killed before the journey finishes.
A transient SAM session without SIGNATURE_TYPE=7 is DSA-SHA1, and
without leaseSetEncType=4 the leaseset is not ECIES. Current routers
and Bitcoin Core peers do not reach that destination. STREAM CONNECT
now sets SILENT=true so a router cannot prefix the remote dest onto
the Bitcoin byte stream. If i2pd drops the session, the replacement
session issues STREAM FORWARD again; otherwise inbound dies while
outbound dials recover.
--cjdns-reachable made fc00 routable only when the operator also set
--external-ip, so a node bound to its TUN address never told peers
where it was. Add that bind to the advertised set. The overlay journey
requires it on getnetworkinfo.
i2pd sets the silent flag before it writes STREAM STATUS, and that
flag suppresses the reply on CONNECT. The dial then blocks forever
waiting for RESULT=OK. FORWARD still sends the status line when
silent, and that is the command that would otherwise prefix the
peer destination onto the Bitcoin stream.
The one-shot Tor broadcast task runs on a tokio worker. get_tx asserts
that thread must not take the mempool lock, so the task panicked and
the local transaction never left the node. try_get_tx is the
non-blocking read.
@reardencode
reardencode merged commit fa310a8 into master Sep 22, 2026
20 of 21 checks passed
@rearden-grok
rearden-grok Bot deleted the test/overlay-functional branch September 22, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

overlay-functional Run private Tor/i2pd/cjdns overlay functional harness

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants