<feed xmlns='http://www.w3.org/2005/Atom'>
<title>npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/src/btfrv.h, branch main</title>
<subtitle>[no description]</subtitle>
<id>https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/atom?h=main</id>
<link rel='self' href='https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/'/>
<updated>2026-09-02T09:03:01+00:00</updated>
<entry>
<title>tunnel: report which stage failed instead of guessing the cause</title>
<updated>2026-09-02T09:03:01+00:00</updated>
<author>
<name>bitflash-maintainer</name>
<email>noreply@bitflash.invalid</email>
</author>
<published>2026-09-02T09:03:01+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/commit/?id=7c70eb4498e88725241493033edfe89554ff1b18'/>
<id>urn:sha1:7c70eb4498e88725241493033edfe89554ff1b18</id>
<content type='text'>
</content>
</entry>
<entry>
<title>rendezvous: bound the wait for a dial, so a dead path is noticed (#51)</title>
<updated>2026-07-30T16:38:12+00:00</updated>
<author>
<name>Bitflash</name>
<email>btf01@proton.me</email>
</author>
<published>2026-07-30T16:38:12+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/commit/?id=9f7141b28e2da9db7d7cb099d1f13f28742ff0fa'/>
<id>urn:sha1:9f7141b28e2da9db7d7cb099d1f13f28742ff0fa</id>
<content type='text'>
A node registers at a relay and waits to be dialled. The wait
had no bound, and ConnectTo() clears the socket timeout on
purpose -- a registration is idle by design and may sit for a
long time.

What that cannot survive is the path dying with neither end
saying so, which is the ordinary case and not the exotic one:
a NAT drops the idle mapping, a relay restarts, a route
changes. No FIN arrives, nothing becomes readable, and recv()
never returns. The thread stays alive and asleep, so
ThreadBtfAccept never reaches the `continue` that would
register again. The node is unreachable and every outward sign
says it is fine.

Caught on the bootstrap seed: 27 minutes without a block,
eight behind the network, relay reachable the whole time, and
a restart fixing it instantly. Nothing in the log marked the
moment it went deaf.

I tried TCP keepalive first and it does not work here. With
probes every 5s and a 2-probe limit, a socket whose replies
were being dropped was still ESTAB after four minutes with the
probe counter stuck at zero. It is measured, not assumed, and
that approach is not in this change.

So the bound is ours to enforce, at the one place that knows
what waiting means. RvServiceWaitPaired takes a timeout;
expiring is not an error but "nobody came, go round again",
which the loop above already handles. Cost is one reconnect
per relay per five minutes.

Verified by killing a registration's path silently -- dropping
only the relay's replies, so no RST or FIN is ever seen. With
a 60s bound for the test:

  rendezvous: no dial at 92.246.128.180:8434 within 60s
              (or it dropped us), re-registering

Registrations went 1 -&gt; 2 and the node carried on. Before this,
the same treatment left it blocked past four minutes with no
log line at all.

The socket goes back to blocking once a dial lands, because
from that point it is a data tunnel and a tunnel is allowed to
sit quiet between messages.</content>
</entry>
<entry>
<title>rendezvous: register and wait for a dial as separate steps (#30)</title>
<updated>2026-07-29T16:28:50+00:00</updated>
<author>
<name>Bitflash</name>
<email>btf01@proton.me</email>
</author>
<published>2026-07-29T16:28:50+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/commit/?id=997e511e120272e8f2ddd29716b486e597410f02'/>
<id>urn:sha1:997e511e120272e8f2ddd29716b486e597410f02</id>
<content type='text'>
A node could not become reachable. RvServiceRegister connected, sent its
'S'+pubkey header, and then blocked reading the relay's 0x01 byte -- which the
relay only writes when a client pairs with the service. So the call did not
return when the node was registered; it returned when somebody had already
dialled it.

ThreadBtfAccept called BtfSetActiveRelay after that. The result is a deadlock:

  - to be dialled, a node must publish a descriptor naming its meeting node
  - to publish, BtfActiveRelay() must be set
  - it is only set once somebody has dialled

Before #26 this was masked. BtfActiveRelay() fell back to
vBtfMeetingRelays[0], so a node always published something, and ThreadBtfAccept
picks its relay at random -- so it worked whenever the two happened to match,
roughly one time in the number of relays. That is the flakiness this project has
been chasing: not a bad relay, an advertisement that usually named the wrong one.

#26 removed the fallback, which was right on its own terms and turned an
unreliable heuristic into a reliable deadlock. This is the other half of that
change and they belong together.

RvServiceRegister now returns as soon as the relay has the service listed.
RvServiceWaitPaired does the blocking read. ThreadBtfAccept registers, advertises,
then waits. RvClientConnect is untouched -- a dialer blocking until it is paired
is correct.

Registration failure also had no log line at all, which is why this stayed
invisible: a node that never registered looked identical to one waiting quietly
for a peer. There are now lines for registering, failing over, and being dropped.

Verified: a fresh node reports `registered at 90.156.222.107:8434, waiting for a
dial` and then self-resolves with `meeting_node=90.156.222.107:8434` -- the relay
it is actually on. Two nodes on one machine reach each other.</content>
</entry>
<entry>
<title>Bitflash: fair-launch release</title>
<updated>2026-07-24T14:18:11+00:00</updated>
<author>
<name>Bitflash-sh</name>
<email>btf01@proton.me</email>
</author>
<published>2026-07-24T14:18:11+00:00</published>
<link rel='alternate' type='text/html' href='https://upleb.uk/npub1q9geyrch3feyczz242sxjaa05yczv50dlpug082sjln2kl0wrnxst0nrfa/bitflash/commit/?id=51d617e70f90a972185917ea0096c1ecef2bfa8b'/>
<id>urn:sha1:51d617e70f90a972185917ea0096c1ecef2bfa8b</id>
<content type='text'>
Satoshi's bitcoin-0.1.0 reborn with RandomX CPU proof of work, anonymous .btf
addressing over Nostr with CGNAT rendezvous, automatic peer discovery, a
headless Linux node, and Windows GUI wallet. Fair launch, no premine, 21M cap.

</content>
</entry>
</feed>
