Skip to content

dash: parameterized min-protocol-version ratchet gate + KAT (#643, option a) - #646

Merged
frstrtr merged 1 commit into
masterfrom
dash/643-minproto-ratchet-gate
Jul 7, 2026
Merged

dash: parameterized min-protocol-version ratchet gate + KAT (#643, option a)#646
frstrtr merged 1 commit into
masterfrom
dash/643-minproto-ratchet-gate

Conversation

@frstrtr

@frstrtr frstrtr commented Jul 6, 2026

Copy link
Copy Markdown
Owner

SAFE-ADDITIVE leaf for the DASH v36 min-protocol-version ratchet (#643), option (a) per integrator concurrence 2026-07-06.

What

  • src/impl/dash/min_protocol_gate.hpp — dash::MinProtocolGate, a per-instance reject-if-proto<floor policy. Floor defaults to SharechainConfig::MINIMUM_PROTOCOL_VERSION (1700, oracle accept-all).
  • test/test_dash_min_protocol_gate.cpp — KAT, 3/3 (local ctest from build/).
  • Registered in test/CMakeLists.txt + both build.yml --target allowlists.

Why it is not consensus-bearing

At the default floor (1700) the gate is a NO-OP: a peer advertising protocol=1700 MUST be accepted. It commits NO premature v36 constant — the ratchet value stays a one-line operator knob set at G2-migration time (DASH share ver 16->36 is older-than-v35; the floor is a chosen constant, not oracle-derived).

Isolation

Fenced to src/impl/dash/. Touches NO shared bitcoin_family/core version-handshake types (per-coin isolation-primitive boundary). Live wiring into NodeImpl::handle_version rides reception slice B (S8-gated), out of scope here.

KAT invariants pinned

  1. Default floor == oracle accept-all; peer at 1700 accepted (explicit no-op assertion).
  2. Below-floor rejected at the >= boundary (floor-1 out, floor in).
  3. Ratchet is a settable per-instance member — raising it rejects old-floor peers while the default gate stays inert.

Add dash::MinProtocolGate, a per-instance reject-if-proto<floor policy for
the version handshake. Floor defaults to SharechainConfig::MINIMUM_PROTOCOL_VERSION
(1700, oracle accept-all) so the leaf is a NO-OP at default and commits no
premature v36 constant; the ratchet value stays a one-line operator knob set at
G2-migration time. Fenced to src/impl/dash/ (no shared bitcoin_family/core
handshake types touched). Live wiring into handle_version rides reception slice B.

KAT (test_dash_min_protocol_gate, 3/3) pins: peer at floor=1700 MUST be accepted
(no-op), below-floor rejected at the >= boundary, and the floor is a settable
per-instance member (ratchet mechanism works while default stays inert).
frstrtr added a commit that referenced this pull request Jul 7, 2026
… reachable

The slice-A handle() was a no-op that dropped all inbound messages, leaving the
new handle_version() reception (and its live #646 min-protocol gate) unreachable
-- a dormant seam. Route the unknown-peer version handshake into handle_version()
(mirrors pool::NodeBridge), close on self/dup, and mark the peer stable on the
negotiated type. Full Legacy/Actual established-peer dispatch rides a later
slice. This makes the #646 discrimination genuinely live on the handshake path.
test_dash_node 9/9.
@frstrtr
frstrtr merged commit 43f8c5e into master Jul 7, 2026
24 checks passed
frstrtr added a commit that referenced this pull request Jul 7, 2026
…to gate) (#649)

* dash: parameterized min-protocol-version ratchet gate + KAT (#643)

Add dash::MinProtocolGate, a per-instance reject-if-proto<floor policy for
the version handshake. Floor defaults to SharechainConfig::MINIMUM_PROTOCOL_VERSION
(1700, oracle accept-all) so the leaf is a NO-OP at default and commits no
premature v36 constant; the ratchet value stays a one-line operator knob set at
G2-migration time. Fenced to src/impl/dash/ (no shared bitcoin_family/core
handshake types touched). Live wiring into handle_version rides reception slice B.

KAT (test_dash_min_protocol_gate, 3/3) pins: peer at floor=1700 MUST be accepted
(no-op), below-floor rejected at the >= boundary, and the floor is a settable
per-instance member (ratchet mechanism works while default stays inert).

* dash: S8 node slice-B version-handshake reception (fires #646 min-proto gate)

Replace the slice-A no-op handle_version stub in dash::NodeImpl with the real
version-handshake reception, mirroring the ltc::NodeImpl reference reconciled to
DASH s header-only pool node. Parses message_version, guards self- and duplicate
connections, and fires the #646 min-protocol ratchet gate as a LIVE per-instance
discrimination (default floor 1700 = oracle accept-all no-op; operator lifts it
at G2-migration). Registers the peer and returns the negotiated legacy/actual
connection type for the G2 dual-pool. This flips the G2 dual-pool from a dormant
seam to a live cross-peer reception. test_dash_node 9/9.

* dash: wire NodeImpl::handle() version routing so slice-B reception is reachable

The slice-A handle() was a no-op that dropped all inbound messages, leaving the
new handle_version() reception (and its live #646 min-protocol gate) unreachable
-- a dormant seam. Route the unknown-peer version handshake into handle_version()
(mirrors pool::NodeBridge), close on self/dup, and mark the peer stable on the
negotiated type. Full Legacy/Actual established-peer dispatch rides a later
slice. This makes the #646 discrimination genuinely live on the handshake path.
test_dash_node 9/9.

---------

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jul 10, 2026
node.cpp reception bodies landed (#656/#657), so dash::Node
(NodeBridge<NodeImpl,Legacy,Actual>) is fully linkable. Link the dash
OBJECT lib into c2pool-dash and replace the NOTE-only report_peering stub
with a real bind: --run now constructs dash::Config + dash::Node and calls
core::Server::listen(port), opening an actual sharechain P2P socket
(default 8999/testnet 18999, --listen [HOST:]PORT override; --connect
suppresses inbound). PREFIX kept as a per-coin isolation primitive from
the frstrtr/p2pool-dash oracle constants.

Inbound reception (version handshake + #646 min-proto gate) is live via
node.cpp. Active outbound dialing of addnode/connect seeds rides the
download/outbound slice (dash::NodeImpl has no start_outbound_connections
yet); seeds are registered in the addr store. dashd-RPC submitblock
fallback untouched.

Verified: c2pool-dash --run --testnet --listen 29777 -> ss shows
LISTEN 0.0.0.0:29777 held by c2pool-dash; Factory started for port 29777.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
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