Skip to content

rpc, init: -v2pqtransport, startup line, getpqtransportinfo, peer fields, -netinfo and GUI (#184 part 6) #209

Closed

Description

@djh58

Part 6 of 9 · #184 · Size L · Base 1.x.x · Needs part 2 (#186), part 4 (#199), part 5 (#206) · Unblocks part 7 (#212), part 8 (#215)

Consolidates work items F5 (#209) and F6 (#210), each formerly its own sub-issue. Their full text is below as sections; the closed issues point here.

Goal

Operator controls and visibility: -v2pqtransport (default off until part 9), the test options and the startup line; getpqtransportinfo, the getpeerinfo and getnetworkinfo fields, 2p in -netinfo, and the GUI string.

Work items

In suggested commit order. Each item is a section below.

  • F5 · init: add -v2pqtransport, the test options and the startup line
  • F6 · rpc: add getpqtransportinfo and hybrid transport fields; -netinfo and GUI

Starting early

  • F5 can start once part 4 merges, alongside part 5.
  • F6 needs part 5's statistics.

F5 · init: add -v2pqtransport, the test options and the startup line

Needs E3 (#199).

Goal

Make the feature configurable, default off until R1 (#222), through one immutable effective configuration, with a startup line that shows the state and test hooks for the functional tests.

Context

  • The -v2transport path to follow: registered at src/init.cpp:567 and read at :971, then CConnman::Options, CNodeOptions (src/net.h:673), MakeTransport (src/net.cpp:3802-3808) and the V2Transport constructors. Also src/net.h:667,1065 and src/init.cpp:2097.
  • Every qbit boolean option parses true as 0 (src/common/args.cpp:78-83); negation is normalized at :129-140.
  • -test options are listed in TEST_OPTIONS_DOC (src/common/args.cpp:743) and are regtest only (src/init.cpp:1095-1098).

Scope

  • DEFAULT_V2_PQ_TRANSPORT = false. R1 (release: hybrid v2 transport release gate and default-on (#184 part 9) #222) changes it.
  • One immutable configuration, computed from the same effective ArgsManager values used for startup warnings and RPC:
    struct PQTransportConfig {
        bool v2_enabled{false};
        bool pq_requested{false};
        bool fail_first_packet{false};
        bool Enabled() const noexcept { return v2_enabled && pq_requested; }
    };
    // CConnman::Options: PQTransportConfig m_pq;   CNodeOptions: V2PQOptions pq; std::optional<PQEndpointKey> pq_endpoint;
    static std::unique_ptr<Transport> MakeTransport(NodeId id, const CNodeOptions& options, bool inbound) noexcept;
    Inbound transports get NEGOTIATE only when the configuration is enabled; outbound transports also check F3's fallback set.
  • -v2pqtransport. It has no effect when -v2transport=0, and -help lists it.
    • An explicit -v2pqtransport=1 with -v2transport=0 raises an InitWarning on the console and in the GUI: -v2pqtransport=1 has no effect because -v2transport=0. Set -v2transport=1 to use hybrid post-quantum v2 transport. An explicit 0, or the default, never warns.
    • A non-numeric value raises an InitWarning that names the effective setting, so v2pqtransport=true, which parses as 0, can't silently switch the feature off. Inspect the effective SettingsValue: an empty value means true, negated booleans are valid, and explicit strings must parse completely as integers, so true, 1abc and overflow warn. Don't change InterpretBool globally.
  • -mlkemportable, hidden, debug category, all chains: forces portable C by calling mlkem::InitializeRuntime(true) before any networking object exists. It is the field escape hatch if native code misbehaves on some CPU family.
  • Test options, in TEST_OPTIONS_DOC in its snake_case style, regtest only:
    • -test=pq_fail_first_packet sets corrupt_shared_secret on every hybrid handshake while set;
    • -test=mlkem_portable forces portable C.
  • Startup line, always logged, naming the active backends:
    • v2 pq: enabled arith=<…> keccak=<…>
    • v2 pq: disabled (-v2pqtransport=0) arith=<…> keccak=<…>
    • v2 pq: disabled (-v2transport=0) arith=<…> keccak=<…> when v2 is off, whatever the PQ switch says.

Tests

New test/functional/rpc_pqtransport.py (F6 adds the RPC cases to the same file):

  • test_configuration:
    • the command line, qbit.conf, -no… and restart toggles, observed through a live connection between two nodes (v2 pq: switched in the debug log);
    • an explicit contradictory pair gives the exact warning, and an explicit 0, or -v2transport=0 alone, gives none;
    • a non-numeric value gives its warning;
    • -help lists the option;
    • assert_debug_log checks each of the three startup lines.
  • test_portable_options: -mlkemportable and -test=mlkem_portable each make the startup line report portable for both backends; a non-regtest chain rejects the test options; nodes started with each test option print nothing to stderr.

Acceptance criteria

  • The tests pass, the default stays off, and the existing functional suite is unchanged.

Suggested commit: init: add -v2pqtransport and hybrid transport test options.


F6 · rpc: add getpqtransportinfo and hybrid transport fields; -netinfo and GUI

Needs F2 (#206), F3 (#206), F4 (#206), F5, B3 (#186).

Goal

Everything an operator or monitoring script needs to see the feature, using the exact RPC contract in #184.

Scope

  • getpqtransportinfo, a new RPC that matches the schema in p2p: add hybrid post-quantum key exchange (ML-KEM-1024) to BIP324 v2 transport #184 field for field. Every field is always present, empty collections are [], status values are tokens, instance_id is 64 lowercase hex characters, and ring entries are oldest first. It includes load_shedding (F4), the inbound shed count, fallback_set and failure_streaks (F3). Write the help text.
  • getpeerinfo gains transport_pq (bool) and transport_pq_status (pending, hybrid, legacy_peer, fallback, off or v1).
    • transport_protocol_type keeps its values (detecting until confirmation, then v2), because -netinfo, the GUI and the functional tests compare against "v2".
    • session_id is the hybrid session id when transport_pq is true.
  • getnetworkinfo gains connections_pq next to connections_in and connections_out (src/rpc/net.cpp:792-794). It counts transport_pq=true over exactly the peers getpeerinfo shows:
    • factor getpeerinfo's visibility filter (src/rpc/net.cpp:208-223) into a shared helper;
    • don't use ForEachNode (src/net.cpp:3642), which only sees fully connected nodes.
  • Fuzz. src/test/fuzz/rpc.cpp: add getpqtransportinfo to the safe list (:390-398) in the same commit as the RPC, because the fuzz initializer aborts on unclassified commands.
  • Docs. doc/rpc/annotations/v30.2-delta.yml.
  • -netinfo (src/bitcoin-cli.cpp:589-596, a 2-character %2s column) shows 2p for hybrid peers, and its help legend explains 2p. A server that doesn't return transport_pq, such as v1.0.0, counts as not hybrid, the way -netinfo treats other missing fields (:557).
  • GUI. The peer-details transport reads v2 (hybrid post-quantum) (src/qt/rpcconsole.cpp:492-496).

Tests

Extend test/functional/rpc_pqtransport.py (from F5). Two nodes with -test=pq_fail_first_packet on one side produce failures in both directions, and legacy Python v2 peers that disconnect early produce abandoned.

Test Setup Expect
test_counts One isolated scenario per restart, or snapshot deltas Exact per-direction counts, including switched plus a failure on one connection
test_rings Keep one outbound failure; create 300 inbound failures Outbound entry kept; inbound holds 256; dropped +44; sequences contiguous per ring
test_abandoned Offer received; no authenticated version; close or time out One abandoned; no switched
test_connection_count One hybrid and one legacy peer; then the switch off connections_pq == 1 == count(transport_pq) with a stable peer set; 0 when off
test_states Switch off, switch on, fallback Every getpqtransportinfo field; instance_id changes on restart

Also:

  • rpc_net.py (:148): the exact getpeerinfo dict gains both fields. An ordinary Python peer stays legacy even in whole-suite PQ mode (G3).
  • interface_bitcoin_cli.py: with one hybrid and one legacy peer, -netinfo shows 2p and 2, and the legend explains 2p.
  • p2p_v2_previous_release.py (B3): this release's qbit-cli -netinfo against a v1.0.0 node shows 2 without errors.

Acceptance criteria

  • The tests pass, and the rpc fuzz target runs.
  • The help text and the annotations are updated.

Suggested commit: rpc: expose hybrid transport state and diagnostics.


One pull request against 1.x.x closes this issue. The shared contract is the Design section of #184; change it there first if needed.

Activity

  1. added
    enhancementNew feature or request
    pq-transportHybrid post-quantum v2 transport (#184)
    on Oct 5, 2026
  2. changed the title [-]init: add -v2pqtransport, the test options and the startup line (#184 F5)[/-] [+]rpc, init: -v2pqtransport, startup line, getpqtransportinfo, peer fields, -netinfo and GUI (#184 part 6)[/+] on Oct 5, 2026
  3. djh58 commented on Oct 23, 2026

    @djh58
    MemberAuthor

    Done in #236, merged into feature/pq-transport as 9e2e884. It reaches 1.1.0 with #233 and ships in 1.1.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpq-transportHybrid post-quantum v2 transport (#184)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions