feat(wire)!: standardize the DIG peer wire on native types, drop the chia bridge - #6
Merged
Merged
Conversation
wire_compatibility.rs asserts DigMessage encodes the same bytes as chia_protocol::Message. That is a relative proof: an upstream layout change moves both sides together and the test stays green while the live network breaks. These vectors are absolute hex literals captured on the chia 0.26 line -- the bytes DIG peers exchange today. They are the fixed reference the chia-protocol decoupling must be proven byte-identical against. Covers the DigMessage envelope (DIG-band and chia-band opcodes, present and absent id, a 320-byte payload that no narrower length prefix can encode), the RegisterPeer/RegisterAck bodies (both NodeType and both bool polarities), and the introducer bodies including the upstream TimestampedPeerInfo encoding. Proven load-bearing: flipping the id length prefix to little-endian fails two vectors. Co-Authored-By: Claude <noreply@anthropic.com>
The DIG peer wire is a native protocol, not a chia protocol carrying extra opcodes. Its payload and node-role types were sourced from chia-protocol, which made a chia version bump a breaking change to the DIG wire API and let chia types reach consumers with no chia traffic. - Add DIG-owned Bytes and NodeType. Both encodings are deliberately identical to the ones they replace (u32 big-endian length prefix; the frozen 1..=7 role discriminants), so peers on either type exchange the same frames. - Delete the four chia_protocol::Message bridge helpers. They were the on-ramp back onto the forked route: a consumer that could cheaply obtain a Message kept building one, and the closed ProtocolMessageTypes enum came back with it. Chia-band traffic goes through DigLink's typed send/request. - Replace the blanket pub use chia_protocol::* with three named re-exports. Deliberately KEPT, with the reasoning recorded in lib.rs so nobody removes them later as unfinished work: chia-traits/chia_streamable_macro (a trait and a derive macro -- neither carries the closed-enum problem this crate escapes, and replacing them would mean owning a serializer), and ChiaProtocolMessage / TimestampedPeerInfo / chia-sdk-client (genuine chia-full-node traffic). BREAKING CHANGE: DigMessage::data is dig_peer_protocol::Bytes, RegisterPeer's node_type is dig_peer_protocol::NodeType, the four chia Message conversions are gone, and chia_protocol is no longer glob re-exported. Byte-identity proven: all 9 absolute golden vectors pass unchanged. Co-Authored-By: Claude <noreply@anthropic.com>
SPEC.md 2.4 inverts from 'Interoperability with chia_protocol::Message' to 'No interoperability': the four bridge helpers are gone and the section now states why re-adding one is a regression rather than a convenience. Also pins NodeType's discriminants as normative and frozen, replaces the glob re-export row with the three named ones, and adds a rate-limit table pinned to absolute upstream values -- the module header already warned that a chia-protocol/chia-sdk-client version split silently collapses every Chia opcode to default_settings with no compile error, and nothing tested it. A silently permissive rate limiter is a DoS surface. The pin is deliberately not a comparison against V2_RATE_LIMITS: that would ask the same possibly-shifted enum for its own key and agree with itself. Bumps to 0.4.0 (0.x breaking = minor). No other branch or tag claims it. Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d
marked this pull request as ready for review
August 11, 2026 00:11
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.
DO NOT MERGE — gate round not yet run. Publishes to crates.io before dig-gossip can consume it (§3.6, release-first).
Standardizes the DIG peer wire on native DIG types and removes the on-ramps back to the forked route.
Blast radius checked
Every
chia*reference in everysrc/andtests/file, enumerated by grep on this tree, plus aread-only measurement of the downstream consumer (dig-gossip) via
git show origin/main:<path>.gitnexus index not built for this worktree — fell back to grep + direct read per §2.0 bound 2.
Risk: HIGH — this is a live network's wire format and a breaking API change to every consumer.
Byte-identity: proven, not asserted
Commit 1 pins 9 absolute golden vectors captured on the pre-change tree, as their own commit,
before a single type was touched. Commit 2 makes the change. All 9 pass unchanged.
The vectors are load-bearing: flipping the
DigMessageid length prefix to little-endian fails twoof them. They exist because
tests/wire_compatibility.rsis a relative proof — it comparesDigMessageagainstchia_protocol::Message, so an upstream layout change moves both sidestogether and it stays green while the network breaks.
No wire change. No coordination event. Shape breaks only.
What changed
BytesandNodeType. Encodings deliberately identical to what they replace: au32big-endian length prefix, and the frozen1..=7role discriminants. A byte naming no roleis refused, never defaulted — a zero byte is what a truncated buffer produces.
chia_protocol::Messagebridge helpers are deleted. They were the on-ramp back tothe fork: a consumer that could cheaply obtain a
Messagekept building one, and the closedProtocolMessageTypesenum came back with it.pub use chia_protocol::*is replaced by three named re-exports.Deliberately KEPT, with the reasoning recorded in
lib.rsRecorded in the crate so nobody "finishes the decoupling" later by removing a dependency that was
assessed and retained:
chia-traits+chia_streamable_macro— a trait and a derive macro. Neither has the propertythis crate escapes: no closed enum, no private-field wire authority. Replacing them means owning a
serializer — new surface and a fresh byte-identity risk — to buy nothing.
ChiaProtocolMessage,TimestampedPeerInfo,chia-sdk-client— genuine chia traffic. A DIGnode talks to chia full nodes too. Chia types for chia traffic is the design.
The rate-limit hazard, now tested
rate_limit.rs's header has always warned that achia-protocol/chia-sdk-clientversion splitsilently collapses every Chia opcode to
default_settings— a large loosening, no compileerror, no panic. Nothing tested it. A silently permissive rate limiter is a DoS surface.
Three tests added. The pin uses absolute literals (opcode byte + both limit numbers), not a
comparison against
V2_RATE_LIMITS: that would ask the same possibly-shifted enum for its own keyand agree with itself. Backed by a tighter-than-default guard (so a collapsed table is
distinguishable from a re-keyed one) and an entry-count floor.
The absolute pin immediately caught a transcription error of my own —
TransactionAckis in thetxmap, notother.Version
0.4.0. Breaking on a
0.xline is a minor bump.mainis 0.3.0, the only other branch(
feat/2228-dig-peer-link) also claims 0.3.0, and no tag claims 0.4.0 — no collision.Gates
cargo fmt --check,cargo clippy --all-targets --all-features -D warnings, andcargo test --all-featuresall exit 0, asserted by exit code rather than piped output.86 tests pass (68 lib + 9 golden + 5 inbound + 4 liveness).