BIP-155 addrv2 + Remove Tor v2 (OnionCat) support#2
Open
BIP-155 addrv2 + Remove Tor v2 (OnionCat) support#2
Conversation
Research-based implementation plan incorporating lessons learned from: - Bitcoin Core PRs #19031, #19954, #20119, #20564 - Zcash issues zcash#5277, zcash#3051 Key issues addressed in plan: - sendaddrv2 timing (send before verack, not after) - Protocol version gating (don't send to old nodes) - Address relay black holes prevention - peers.dat migration strategy - Spam prevention for unknown network types 4-phase implementation over ~4 weeks: 1. Data structures 2. Protocol messages 3. Address manager 4. Testing & hardening 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Bump protocol version to 170012 - Add sendaddrv2/addrv2 message handlers - Add BIP155Network enum and address size constants - Implement address serialization for variable-length addresses - Add m_wants_addrv2 flag for peer negotiation - Update address relay logic for addrv2-aware peers - Add -enablebip155 config flag (default: on) - Backward compatible with protocol 170011 peers Tested: Tor v3 onion address advertised, legacy peers receive legacy addr format, unexpected sendaddrv2 from old peers rejected. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Accept sendaddrv2 at any time from 170012+ peers, not just before verack. This improves compatibility with implementations that may send sendaddrv2 slightly after verack while still rejecting it from old protocol versions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When -proxy or -onion is set, also configure NET_TORV3 network: - Set proxy for Tor v3 connections - Mark NET_TORV3 as reachable (not limited) This allows the node to make outbound connections to Tor v3 onion addresses and properly display them in getnetworkinfo. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit completes the BIP-155 implementation by adding proper serialization support for variable-length addresses in peers.dat, enabling Tor v3 addresses to persist across node restarts. Changes aligned with Bitcoin Core's approach (PR #19954, #20284): peers.dat format versioning: - Format byte 0: version (V0_HISTORICAL, V1_DETERMINISTIC, V3_BIP155) - Format byte 1: INCOMPATIBILITY_BASE(32) + lowest_compatible_version - Old nodes see keysize=35 (not 32), fail gracefully with "Incorrect keysize in addrman deserialization" - New nodes detect format and use addrv2 when format >= V3_BIP155 Serialization changes: - src/serialize.h: Add SER_ADDRV2 flag for address serialization - src/netbase.h: CNetAddr/CService serialize in BIP155 format when SER_ADDRV2 flag is set (network_id + CompactSize len + variable addr) - src/protocol.h: CAddress uses CompactSize for services in addrv2 - src/addrman.h: CAddrMan Serialize/Unserialize handle both legacy and addrv2 formats with proper version detection Migration behavior: - Read: Detects old format (keysize=32) and reads legacy 16-byte addrs - Write: Always writes V3_BIP155 format with addrv2 addresses - Backward: Old nodes reject new peers.dat, create fresh database This enables Zclassic nodes to store and relay Tor v3 onion addresses (.onion 56-char), making Zclassic one of the first Zcash-based coins to fully implement BIP-155. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Build fixes for the BIP-155 peers.dat implementation:
1. Replace static const with enum for INCOMPATIBILITY_BASE
- static const/constexpr class members require out-of-line definitions
when ODR-used (passed to strprintf varargs)
- Using anonymous enum avoids linker "undefined symbol" errors
- Removed FILE_FORMAT and LOWEST_COMPATIBLE, use V3_BIP155 directly
2. Fix CDataStream buffer access
- CDataStream doesn't have data() method (unlike std::vector)
- Use &ssAddr[0] instead of ssAddr.data() for write() calls
3. Add explicit int casts in strprintf
- Enum values passed to varargs need explicit casting to avoid
format specifier warnings
Tested: peers.dat now correctly writes V3_BIP155 format (03 23 header)
verified by xxd after flush - old format was (01 20), new is (03 23).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Two critical bugs were causing peers.dat load failures after addrv2 flush:
1. Missing nVersion read in addrv2 Unserialize (addrman.h)
- CAddress with SER_DISK serializes: nVersion(4) + nTime(4) + nServices + CService
- The addrv2 parsing code was missing the nVersion read, causing stream
position misalignment and "ReadCompactSize(): size too large" errors
- Fixed by adding `int nAddrVersion; s >> nAddrVersion;` before nAddrTime
2. m_net field not set after legacy format deserialization (netbase.h)
- When loading legacy peers.dat, CNetAddr::m_net remained at default NET_IPV4
- This caused GetBIP155Network() to return BIP155_IPV4 for all addresses
- IPv6 addresses were incorrectly serialized as 4-byte IPv4, corrupting data
- Fixed by detecting network type from IP content after legacy FLATDATA read:
IsIPv4() -> NET_IPV4, IsTor() -> NET_ONION, else -> NET_IPV6
Testing verified:
- Legacy peers.dat (01 20) loads correctly, sets proper m_net values
- Addrv2 peers.dat (03 23) written on flush with correct network IDs
- Addrv2 peers.dat reloads correctly (tested with 2059 addresses)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documentation updates:
- doc/bips.md: Add BIP-155 to list of implemented BIPs for Zclassic v2.1.2
- doc/BIP-155-IMPLEMENTATION-PLAN.md:
- Document Bitcoin Core compatible peers.dat versioning scheme
- Add upgrade instructions with mandatory peers.dat backup step
- Document rollback procedures
- List critical bug fixes (nVersion read, m_net detection)
peers.dat format details:
- Legacy format: [magic][0x01][0x20]... (format=1, compat=32)
- BIP155 format: [magic][0x03][0x23]... (format=3, compat=35)
- Versioning uses INCOMPATIBILITY_BASE(32) + lowest_compatible
- Old nodes reject new format gracefully ("Corrupt peers.dat")
- New nodes can read both legacy and addrv2 formats
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Mark implementation as tested on macOS ARM64 only - Add TODO items for Linux and Windows testing - Add requirement for extended testnet validation before mainnet release - Document additional test results (peers.dat migration cycle) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove pchOnionCat constant and all OnionCat IPv6 prefix handling - Remove v2 .onion (16-char) address parsing in SetSpecial() - Remove v2 ToStringIP() encoding - Unify IsTor() to just call IsTorV3() - Remove NET_ONION enum, add compatibility alias to NET_TORV3 - Remove ADDR_TORV2_SIZE constant - Update BIP155 handling to reject TORV2 addresses - Update tests to use v3 onion addresses instead of OnionCat Tor v2 has been deprecated since October 2021 and fully removed from the Tor network. This cleanup removes ~30 lines of dead code and simplifies the codebase for easier maintenance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove #define NET_ONION NET_TORV3 compatibility alias - Replace all NET_ONION references with NET_TORV3 in: - src/netbase.h (serialization) - src/netbase.cpp (ParseNetwork, GetNetwork, GetGroup) - src/init.cpp (proxy setup - cleaned up duplicate calls) - src/torcontrol.cpp (Tor authentication) - src/test/netbase_tests.cpp (v3 onion tests) - Update BIP-155 documentation to v3.0 - Regenerate cleanup diagram with better layout 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Shows NET_ONION completely removed (not just aliased) - Includes verification: grep NET_ONION = 0 results - Documents all files modified with NET_TORV3 references 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NET_TORV3only (no aliases)Changes
BIP-155 Implementation
sendaddrv2message exchange during version handshakeOnion v2 Removal (Complete)
pchOnionCat[]constant (FD87:D87E:EB43 prefix)SetSpecial()ToStringIP()#define NET_ONION NET_TORV3aliasIsTor()to callIsTorV3()Files Modified
src/netbase.hsrc/netbase.cppsrc/init.cppsrc/torcontrol.cppsrc/net.h/src/net.cppsrc/addrman.h/src/addrman.cppsrc/test/netbase_tests.cppdoc/BIP-155-IMPLEMENTATION-PLAN.mdVerification
Test plan
grep NET_ONIONreturns 0 results (clean codebase)🤖 Generated with Claude Code