N-1 — Network Isolation

b3chain must be a fully separate P2P network from Bitcoin. Different magic bytes, different DNS seeds, different default port. A b3chaind talking to a Bitcoin node must immediately disconnect, and vice versa.

Script: audit-network-isolation.py Runtime: ~3 s Status: 15 / 15 PASS

1. Magic-bytes table

Chainb3chain magicBitcoin magic
mainnetb3 c0 01 0df9 be b4 d9
testnetb3 c1 02 0e0b 11 09 07
testnet41c 16 3f 281c 16 3f 28 (intentionally identical — testnet4 is rarely used)
regtestb3 c2 03 0ffa bf b5 da

The audit accepts the testnet4 collision (testnet4 is a developer network that doesn't autoconnect to public peers). Mainnet, testnet, and regtest must all be unique vs Bitcoin.

2. What is being audited

  • Static. Every pchMessageStart[*] = 0x..; block in src/kernel/chainparams.cpp is parsed and checked against the Bitcoin magics table.
  • Static. The DNS seed list contains zero forbidden hosts (seed.bitcoin.sipa.be, dnsseed.bluematt.me, etc.).
  • Static. Mainnet's CMainParams body explicitly calls vFixedSeeds.clear() and vSeeds.clear() — preventing accidentally inheriting Bitcoin's seed lists.
  • Functional. A live regtest node must drop / ignore a connection that opens with the Bitcoin mainnet magic, and accept one that opens with the b3chain regtest magic.

3. Why it matters

Two kinds of disasters this prevents:

  1. Cross-chain peering. If b3chain accepted Bitcoin magic, the first b3chain mainnet node we deploy would be flooded with connections from honest Bitcoin nodes. They would then receive unparseable b3chain data, log errors, and (depending on the version) disconnect us — or, worse, accept our headers.
  2. Address collisions. If users could mistake b3chain addresses for Bitcoin addresses, they would lose money. Distinct bech32 HRPs (b3, tb3, b3rt) and base58 prefixes prevent that. See also W-1.

4. How to run

cd b3chain
python3 contrib/testing/audit/audit-network-isolation.py

5. Expected output

[N-1] Network isolation (magic, DNS seeds)
========================================================================
  PASS  [N-1] found 4 explicit magic-start declarations
  PASS  [N-1] magic b3c0010d != Bitcoin mainnet magic
  PASS  [N-1] magic b3c0010d not a Bitcoin mainnet/regtest/signet magic
  PASS  [N-1] magic b3c1020e != Bitcoin mainnet magic
  PASS  [N-1] magic b3c1020e not a Bitcoin mainnet/regtest/signet magic
  PASS  [N-1] magic 1c163f28 != Bitcoin mainnet magic
  PASS  [N-1] magic 1c163f28 not a Bitcoin mainnet/regtest/signet magic
  PASS  [N-1] magic b3c2030f != Bitcoin mainnet magic
  PASS  [N-1] magic b3c2030f not a Bitcoin mainnet/regtest/signet magic
  PASS  [N-1] no forbidden Bitcoin DNS seeds present
  PASS  [N-1] mainnet calls vFixedSeeds.clear()
  PASS  [N-1] mainnet calls vSeeds.clear()

  Spawning regtest node and probing P2P port with Bitcoin magic...
  PASS  [N-1] node disconnects/ignores Bitcoin mainnet magic on P2P port
  PASS  [N-1] sanity: correct b3chain regtest magic gets a reply
  PASS  [N-1] getnetworkinfo responds with networkactive flag
------------------------------------------------------------------------
  15/15 checks passed in 3.2s
AUDIT RESULT: PASS  [N-1]

6. Source files

The problem in one sentence

If a B3Chain node accidentally peers with a Bitcoin node, the Bitcoin node's headers can poison the B3Chain node's view of the chain — even though the chains will never converge — wasting bandwidth and confusing operators.

The theory

Two pieces of data make a node a B3Chain node rather than a Bitcoin node:

  1. Magic bytes — the four-byte network identifier sent at the start

of every P2P message. Bitcoin mainnet uses f9beb4d9. Anything else, B3Chain ignores.

  1. DNS seeds — the bootstrap addresses a node uses on first start.

Bitcoin's seeds (e.g. seed.bitcoin.sipa.be) return Bitcoin nodes; B3Chain's seeds (when set) must return B3Chain nodes only.

Both are constants in src/kernel/chainparams.cpp. A copy-paste error that left a Bitcoin seed in the B3Chain mainnet vSeeds list would silently funnel new nodes into trying to talk to the Bitcoin network on every start.

Hands-on demo

python3 contrib/testing/audit/audit-network-isolation.py

The script:

  1. Spawns a regtest node, sends a Bitcoin mainnet version message

with magic f9beb4d9. Expects the connection to be dropped without acknowledgment.

  1. Reads chainparams.cpp and verifies that the mainnet vSeeds

vector contains zero hostnames matching the Bitcoin seed pattern (bitcoin, bluematt, dashjr, etc.) and zero entries from Bitcoin's chainparams.cpp directly.

Exercise

Edit src/kernel/chainparams.cpp, in the MAIN chain branch, add a line:

vSeeds.emplace_back("seed.bitcoin.sipa.be");

Rebuild and re-run the audit. Expected output:

  FAIL  [N-1] mainnet vSeeds contains 'seed.bitcoin.sipa.be' (Bitcoin seed)
AUDIT RESULT: FAIL  [N-1]

Why magic bytes alone don't save you

Even if your node correctly rejects Bitcoin's magic bytes at the wire protocol, you still want it to never try to connect to a Bitcoin node, because:

  • Many port scanners flag the connection attempt and your IP gets on

block lists.

  • The Bitcoin node may waste CPU on the handshake before disconnecting.
  • Your operator sees noise in their logs and starts to mistrust the

software.

So the audit checks both layers.

Further reading

  • Bitcoin Core network constants: src/kernel/chainparams.cpp

in bitcoin/bitcoin

  • BIP-37 connection-bloom filter (early example of cross-chain

protocol-level confusion concerns): github.com/bitcoin/bips/blob/master/bip-0037.mediawiki

  • Tor exit-node policy notes — same principle: networks should refuse

to forward traffic that doesn't belong to them.