Skip to content

feat(wire)!: standardize the DIG peer wire on native types, drop the chia bridge - #6

Merged
MichaelTaylor3d merged 3 commits into
mainfrom
chore/chia-036-dig-peer-protocol
Aug 11, 2026
Merged

feat(wire)!: standardize the DIG peer wire on native types, drop the chia bridge#6
MichaelTaylor3d merged 3 commits into
mainfrom
chore/chia-036-dig-peer-protocol

Conversation

@MichaelTaylor3d

@MichaelTaylor3d MichaelTaylor3d commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

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 every src/ and tests/ file, enumerated by grep on this tree, plus a
read-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 DigMessage id length prefix to little-endian fails two
of them. They exist because tests/wire_compatibility.rs is a relative proof — it compares
DigMessage against chia_protocol::Message, so an upstream layout change moves both sides
together and it stays green while the network breaks.

No wire change. No coordination event. Shape breaks only.

What changed

  • DIG-owned Bytes and NodeType. Encodings deliberately identical to what they replace: a
    u32 big-endian length prefix, and the frozen 1..=7 role discriminants. A byte naming no role
    is refused, never defaulted — a zero byte is what a truncated buffer produces.
  • The four chia_protocol::Message bridge helpers are deleted. They were the on-ramp back to
    the fork: a consumer that could cheaply obtain a Message kept building one, and the closed
    ProtocolMessageTypes enum came back with it.
  • The blanket pub use chia_protocol::* is replaced by three named re-exports.

Deliberately KEPT, with the reasoning recorded in lib.rs

Recorded 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 property
    this 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 DIG
    node 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 a chia-protocol/chia-sdk-client version split
silently collapses every Chia opcode to default_settings — a large loosening, no compile
error, 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 key
and 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 — TransactionAck is in the
tx map, not other.

Version

0.4.0. Breaking on a 0.x line is a minor bump. main is 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, and
cargo test --all-features all exit 0, asserted by exit code rather than piped output.
86 tests pass (68 lib + 9 golden + 5 inbound + 4 liveness).

MichaelTaylor3d and others added 3 commits August 10, 2026 16:41
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 MichaelTaylor3d changed the title test(wire): pin golden wire vectors ahead of the chia-protocol decoupling feat(wire)!: standardize the DIG peer wire on native types, drop the chia bridge Aug 11, 2026
@MichaelTaylor3d
MichaelTaylor3d marked this pull request as ready for review August 11, 2026 00:11
@MichaelTaylor3d
MichaelTaylor3d merged commit f193c6e into main Aug 11, 2026
9 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the chore/chia-036-dig-peer-protocol branch August 11, 2026 00:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant