Skip to content

net: turn hybrid v2 transport on by default - #241

Merged
djh58 merged 3 commits into
feature/pq-transportfrom
djh58/pq184-9-default-on
Oct 23, 2026
Merged

djh58 merged 3 commits into
feature/pq-transportfrom
djh58/pq184-9-default-on

Conversation

@djh58

@djh58 djh58 commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Part of #222 (R1). Stacked on #240; merges just before the release candidate is cut.

Release N ships hybrid v2 transport on by default. This PR makes that change and nothing else: the load-shedding threshold stays as it is (R3 decides it).

What changes

  • The default. DEFAULT_V2_PQ_TRANSPORT is now true. A node with v2 transport, also on by default, offers and accepts hybrid keys with every upgraded peer, unless -v2pqtransport=0, -nov2pqtransport or v2pqtransport=0 in qbit.conf switches it off. The setting reaches g_pq_transport_config through GetSetting, and from there the startup warnings, the startup line, every connection and getpqtransportinfo; nothing else reads it.
  • Warnings. No code change was needed: "has no effect because -v2transport=0" fires only for an ON value given explicitly, never for the default or an explicit 0. The non-numeric and double-negative warnings stay; -v2pqtransport=true now switches the feature off against the default, and says so.
  • Docs. The operator guide, the release note and the Bitcoin Core differences page say it is on by default and how to switch it off. The quick start starts its nodes without -v2pqtransport, so it shows the default. Upgrading and Rolling Back say that an upgrade switches it on, and that an operator who wants it off adds v2pqtransport=0 to qbit.conf before upgrading: v1.0.0 ignores the line there, but refuses any form of the option on its command line. The spec and the RPC and option help text don't state the default, so they don't change.

Tests

  • rpc_pqtransport.py starts from the default, switches the feature off with -v2pqtransport=0 and in qbit.conf, and checks precedence both ways. It checks each warning case, warns or doesn't, on the command line and in qbit.conf, and that getpqtransportinfo's status and enabled, the startup line and transport_pq_status on both sides of a connection agree for each -v2transport (0, 1) and -v2pqtransport (default, 0, 1).
  • p2p_v2_previous_release.py: a node with the default and v1.0.0 connect both ways, as legacy_peer over v2 with the same plain BIP324 session id on both sides, and over v1. v1.0.0 ignores v2pqtransport=0 or =1 in qbit.conf and refuses -v2pqtransport=0, -nov2pqtransport and -v2pqtransport=1 on its command line, as the guide says.
  • feature_pq_quickstart.py checks the default, the guide's new qbit.conf line and the command-line overrides, and that the quick start sets no -v2pqtransport.
  • rpc_net.py, p2p_v2_misbehaving.py and the contrib/pq-canary tools needed no change: they read the run mode or the node's own state, not the default.

Functional suite modes and CI

The run modes keep their meaning, as #212's G3 set them up for this change:

Mode Nodes get Covers CI job
default -v2transport=0 v1 between nodes; tests that start nodes with v2 get the new default (hybrid) most ci.yml jobs
--v2transport -v2transport=1 -v2pqtransport=0 the whole suite over plain v2 ci.yml ci-matrix "no IPC, i686, DEBUG"
--v2pqtransport -v2transport=1 -v2pqtransport=1 the whole suite hybrid ci-pq.yml pq-functional: nightly, and now on pull requests (below)

Both explicit values make each job keep its coverage whatever the default, also if the release-cut decision (R7) reverts this PR. ci/checks/test_ci_pq_contract.py now checks the node arguments the framework passes in each mode, and the help text and comments say what each mode means.

The hybrid suite on pull requests (ci: run the hybrid functional suite…)

With hybrid on by default, the only whole-suite v2 run on pull requests, the i686 job, is plain v2, so a hybrid-only regression would surface only nightly. Now:

  • Classifier. ci/checks/classify_merge_profile.py reports pq_functional_required. It is true whenever pq_unit_required is, and also for these hybrid paths that the PQ unit jobs don't cover:

    • src/init.cpp, the hybrid setting;
    • src/rpc/net.cpp, the hybrid RPC fields;
    • test/functional/rpc_net.py, whose hybrid checks run only in the hybrid suite;
    • test/functional/p2p_v2_*;
    • test/functional/test_framework/, the run modes and Python peers;
    • ci/test/00_setup_env_native_pq_functional.sh.

    The macOS and AArch64 unit jobs still start only for pq_unit_required.

  • Job. A new Full Validation job, PQ functional tests, calls ci-pq.yml with only pq-functional. It runs on the change itself, on GitHub-hosted ubuntu-24.04, when that output is true and the PR isn't a draft.

  • Gate. The Full Validation Gate needs the new job and checks it as it checks pq-unit, now through one function:

    • it must succeed when required;
    • it may be skipped when not;
    • a missing or other classifier output fails the gate.

    The Required Merge Gate waits only for the Full Validation Gate, so it needs no change.

  • Tests. test_pq_merge_gate_contract.py covers both jobs:

    • the call, and what ci-pq.yml then runs;
    • each job's condition;
    • the gate's needs, env and outcomes;
    • changed files traced from the classifier through classify-changes' outputs to each job and the gate;
    • that every path the classifier names exists.

This PR touches src/net.h, so once it is ready for review, its own Full Validation runs PQ functional tests / Functional tests with hybrid transport, and the gate logs PQ functional tests: success.

Verification

Run on this change on an earlier #240 head (814dc84eda). Since then, the parts below gained three test-only fixes: Windows line endings in rpc_pqtransport.py, the test-vector path in test_framework/v2_p2p.py, and the quick start's port substitution. This branch carries them as merged, with one line of this PR's rpc_pqtransport.py change adjusted to match the first. rpc_pqtransport.py, feature_pq_quickstart.py and the framework unit tests were rerun on this head.

  • Whole functional suite at -j 4, default and --v2pqtransport: 297 passed, 20 skipped (environmental), 1 failed in each.
    • The failure is wallet_listtransactions.py: its keypoolrefill(1000) exceeds the 30 s RPC timeout on the loaded test host.
    • It fails the same way on the base binary, and passes with --timeout-factor=4.
    • Before the rebase, the suite also ran in --v2transport and --v1transport, with the same result.
  • With v1.0.0 downloaded: p2p_v2_previous_release.py and tool_pq_canary.py pass in default, --v2transport and --v2pqtransport.
  • Unit: net_pq_tests, net_tests, argsman_tests, getarg_tests.
  • Checks and lints: ci/checks (157 tests with the CI commit), actionlint 1.7.12, lint-pq-doc-tokens.py, check-doc.py, ruff with the lint runner's rules, codespell.
  • Mutations caught, for the default:
    • dropping --v2transport's explicit -v2pqtransport=0;
    • warning for the default with -v2transport=0;
    • a startup line or RPC status that ignores -v2transport=0;
    • the default back to off.
  • Mutations caught, for the CI:
    • the new job removed from the gate's needs;
    • the job gated on pq_unit_required;
    • the gate passing a required job that was skipped;
    • src/init.cpp dropped from the classifier;
    • and 8 more (missing output mapping, wrong env binding, superset dropped, wrong jobs input, gate check removed, test framework dropped, drafts).
  • Still to run in CI: Full Validation, including the plain-v2 i686 job and the new PQ functional tests (the hybrid suite), and the previous-releases job.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@djh58
djh58 added this pull request to stack #232 October 22, 2026 19:11
@djh58 djh58 added the pq-transport Hybrid post-quantum v2 transport (#184) label Oct 22, 2026
@djh58

djh58 commented Oct 22, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-22T21:28:21.361319Z c3501bf Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 549c1a4432

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@djh58
djh58 marked this pull request as ready for review October 22, 2026 21:25
@djh58
djh58 force-pushed the djh58/pq184-9-default-on branch from 549c1a4 to e30efc0 Compare October 22, 2026 21:25
Base automatically changed from djh58/pq184-8-docs to feature/pq-transport October 22, 2026 21:26
djh58 added 3 commits October 22, 2026 17:26
Release N ships hybrid v2 transport on by default (#222, R1).
DEFAULT_V2_PQ_TRANSPORT is now true: a node with v2 transport, also on
by default, offers and accepts hybrid keys unless -v2pqtransport=0,
-nov2pqtransport or v2pqtransport=0 in qbit.conf switches it off.

The startup warnings need no change: "has no effect because
-v2transport=0" fires only for an ON value given explicitly (1, an
empty value, a non-numeric value read as 1, or a double negative),
never for the default or an explicit 0. rpc_pqtransport.py now checks
each case, including a non-numeric value with -v2transport=0, which is
read as 0 and must not report the contradiction, and the same settings
in qbit.conf.

Tests that assumed the old default:
- rpc_pqtransport.py starts from the default, switches it off with
  -v2pqtransport=0 and in qbit.conf, checks precedence both ways, and
  checks that getpqtransportinfo, the startup line and
  transport_pq_status agree for each -v2transport (0, 1) and
  -v2pqtransport (default, 0, 1).
- p2p_v2_previous_release.py: a node with the default and v1.0.0
  connect both ways, as legacy_peer over v2 and over v1, and v1.0.0
  ignores v2pqtransport in qbit.conf but refuses it on its command
  line, as the operator guide says.

The functional suite's run modes keep their meaning, as #212's G3 set
them up for this change: the default mode runs v1 between nodes, and
tests that start nodes with v2 now get hybrid; plain --v2transport (the
i686 job of ci.yml) passes -v2pqtransport=0, and --v2pqtransport
(pq-functional) -v2pqtransport=1, explicitly, so both jobs keep their
coverage whatever the default, also if the release-cut decision reverts
this commit. ci/checks now checks each mode's node arguments, and the
help text and comments say what each mode means.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The operator guide, the release note and the Bitcoin Core differences
page say the feature is on by default, and how to switch it off. The
quick start starts its nodes without -v2pqtransport, so it shows the
default, and Switch It On or Off gives v2pqtransport=0, with
v2pqtransport=1 as the explicit form. Upgrading and Rolling Back say
that an upgrade switches it on; that an operator who wants it off adds
v2pqtransport=0 to qbit.conf before upgrading, since v1.0.0 ignores it
there but refuses any form of it on its command line; and that a node
that never set the option has nothing to remove before a rollback.

feature_pq_quickstart.py checks the default, the guide's new qbit.conf
line and the command-line overrides, and that the quick start sets no
-v2pqtransport.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ransport

With hybrid v2 transport on by default, the only whole-suite v2 run on
pull requests, the i686 job, is plain v2: a regression that only the
hybrid suite catches would surface nightly, through ci-pq.yml's
pq-functional job.

The classifier gets a pq_functional_required output: true whenever
pq_unit_required is, and for the hybrid transport paths the PQ unit
jobs neither build nor run: src/init.cpp (the hybrid setting),
src/rpc/net.cpp (the hybrid RPC fields), rpc_net.py (whose hybrid
checks run only in the hybrid suite), the p2p_v2_*.py tests, the test
framework (the run modes and the Python peers), and the job's own
setup. The macOS and AArch64 unit jobs still start only for
pq_unit_required.

A new pq-functional job of Full Validation calls ci-pq.yml with only
pq-functional on the change itself, on its GitHub-hosted ubuntu-24.04
runner, when that output is true and the pull request is not a draft.
The Full Validation Gate needs it and treats it as it treats pq-unit,
now through one function: it must succeed when required, may be
skipped when not, and a missing or other classifier output fails the
gate. The Required Merge Gate waits for the Full Validation Gate, so it
needs no change.

test_pq_merge_gate_contract.py checks both jobs: the call and what
ci-pq.yml then runs, each job's condition, the gate's needs, env and
outcomes, and changed files traced through classify-changes' outputs
to each job's condition and the gate; and that every path the
classifier names exists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@djh58
djh58 force-pushed the djh58/pq184-9-default-on branch from e30efc0 to c3501bf Compare October 22, 2026 21:26
@djh58

djh58 commented Oct 22, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: c3501bf4ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@djh58
djh58 merged commit 4d4b11a into feature/pq-transport Oct 23, 2026
64 of 68 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pq-transport Hybrid post-quantum v2 transport (#184)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant