We spent the last 24 hours inside the BSV node source code.
Here's what we found and how it changed everything for our SPV nodes.
It started with a simple question: why do our bridges keep losing peers?
But before we even got to the source code, we checked something more basic. The DNS seeds. Every BSV node uses these to find its first peers on the network.
Six seeds hardcoded in the software. We queried all six tonight:
seed.bitcoinsv.io — 3 peers
dnsseed.bitcoinsv.io — dead. Domain doesn't exist.
seed.cascharia.com — resolves but returns nothing.
dnsseed.cascharia.com — resolves but returns nothing.
seed.satoshisvision.network — 2 peers.
dnsseed.satoshisvision.netwo… — dead. Domain doesn't exist.
Five peers. Total. From the entire official peer discovery infrastructure. Two seeds abandoned. Two empty. If you're a new node trying to join BSV today, this is what greets you. We had to build our own peer discovery — good-peer persistence files, addr exchange between connected peers, federation mesh discovery across our bridges.
So we were already working with a skeleton crew. Then we opened src/net/net.cpp and found AttemptToEvictConnection — the algorithm BSV nodes use to decide who stays and who gets kicked. Five protection layers:
Best ping time — 8 peers protected Novel tx relay — 4 peers protected Recent block relay — 4 peers protected Longest connected — 50% of remaining protected Netgroup diversity — 4 peers protected
The key was layer 2. A field called nLastTXTime. It only updates when you deliver a transaction the node has never seen before. First relayer wins. Everyone else gets nothing.
Our bridges were receiving transactions from the federation mesh, storing them, logging them... and never relaying them to BSV peers. Zero novel relay credit. Zero protection from eviction. We were invisible.
Then we checked what height we were advertising in our version handshake. Hardcoded at block 930,000. Chain tip was at 945,500. Every BSV node we connected to saw us as 15,000 blocks behind. We looked dead on arrival.
Then we found our maintain cycle. 145 addresses, staggered in batches of 4 with 2-second delays. That's 73 seconds per full cycle. Timer fires every 60 seconds. Three overlapping cycles running simultaneously. 435 connection attempts per minute hammering the few BSV nodes that exist.
We checked addrman.cpp to understand how nodes handle that kind of spam. GetChance() applies a 99% penalty to any peer retried within 10 minutes. Three failed attempts on a new node and you're marked "terrible." We were marking ourselves terrible on every node in the network.
Four fixes. All from reading the source code that nobody reads.
Fix 1 — Connect to one peer first. Sync headers to chain tip. Then connect to the rest advertising real height. Stop looking 15,000 blocks behind.
Fix 2 — When we receive a tx inventory announcement, relay it immediately to all other peers. Fetch the full transaction in parallel. First relayer wins the nLastTXTime credit that protects you from eviction. We were waiting to download the entire tx before telling anyone.
Fix 3 — Transactions arriving on the federation mesh now get relayed to BSV peers. This was the biggest gap. Our entire federation traffic — every transaction flowing between bridges — was being logged but never forwarded to the BSV network. Zero novel relay credit from the thing we built.
Fix 4 — Concurrency guard on the maintain cycle. 20 address cap per cycle. Base cooldown raised from 5 seconds to 2 minutes. Exponential backoff. Peers demoted after 3 consecutive failures. Stop hammering the network.
Results on the first bridge: novel relay acceptance went from 0% to 98%. Peers that used to drop us in minutes are staying connected. The reconnect storm — 20 failed connections every 60 seconds — dropped to zero.
Five peers from DNS seeds. Two dead domains. Two empty responses. A peer eviction system that punishes you for not relaying novel transactions. And a network that marks you terrible after three failed connection attempts.
The source code doesn't lie. We read it, understood what the network actually wants from us, and built for that. New version coming after we finish testing across all seven bridges.