Skip to content

Cross-Node Test Results: Core v30.2, Knots v29.3, Libre v30.2 #5

Description

@8144225309

Cross-Node Test Results: Core v30.2, Knots v29.3, Libre v30.2

Full btcaaron core_test suite run against 3 Bitcoin node implementations on the same dedicated VPS (16GB RAM, 4-core Xeon, Debian). This is the second run — first was v29-era nodes. Upgrading to v30 surfaced one new divergence and resolved another.

Node Version Pass Rate
Core v30.2.0 22/22
Knots v29.3.knots20260210 19/22 (3 musig() failures)
Libre libre-relay-v30.2-2 22/22

0 consensus divergences. 0 string-level divergences.


Regtest Results — 16/16 PASS (all 3 nodes)

Test Cases Core Knots Libre
tutorial_tx_policy_consensus 3 ALL PASS ALL PASS ALL PASS
task2_controlblock_mutation_matrix 5 ALL PASS ALL PASS ALL PASS
task3_sig_output_correctness_matrix 4 ALL PASS ALL PASS ALL PASS
task4_policy_consensus_split_matrix 4 ALL PASS ALL PASS ALL PASS

All three nodes fully synced (initialblockdownload: false), each ran its own isolated regtest instance. Zero differences in transaction acceptance/rejection, Taproot validation, control block verification, Schnorr signatures, fee policy enforcement, or consensus mining.


Mainnet Descriptor Results — musig() Divergence

Tests 5 & 6 (per node)

Case Core Knots Libre
valid_plain_pk_timelock PASS PASS PASS
invalid_nested_pk_musig PASS FAIL* PASS
nonstandard_candidate_policy_deferred PASS PASS PASS
control_musig_keypath PASS FAIL* PASS
control_miniscript_plain_pk PASS PASS PASS
target_pk_musig_nested PASS FAIL* PASS

Test 7: Cross-Instance Consistency (all 3 simultaneously)

Case Core Knots Libre Consistent?
control/musig_keypath OK ERR_OTHER OK DIVERGENT
control/plain_pk_timelock OK OK OK YES
target/nested_pk_musig ERR_INVALID_MUSIG ERR_OTHER ERR_INVALID_MUSIG DIVERGENT

Divergence Analysis

BIP-390 musig() Descriptors — Genuine Gap

Knots' 3 failures are all musig() descriptor cases. This is not a parsing quirk — Core PR #31244 ("descriptors: MuSig2") merged into master on 2025-07-31, after v29.0 shipped (2025-04-15), and landed in v30.0. No v30-based Knots release exists yet. The musig() descriptor code simply isn't in Knots' source tree.

Verified empirically via getdescriptorinfo:

# tr(musig(key1,key2,key3)) — valid BIP-390 keypath descriptor
Core v30.2:  SUCCESS (descriptor with checksum, issolvable=true)
Knots v29.3: ERROR   ("key 'musig(...)' is not valid")
Libre v30.2: SUCCESS (descriptor with checksum, issolvable=true)

# pk(musig(key1,key2)) nested in script leaf — invalid musig usage
Core v30.2:  REJECTED ("Invalid musig() expression")    ← musig-aware
Knots v29.3: REJECTED ("key '...' is not valid")         ← generic
Libre v30.2: REJECTED ("Invalid musig() expression")    ← musig-aware

Impact: Tooling targeting Core v30.2+ or Libre v30.2+ can use musig() descriptors for watchonly wallets, address generation, and PSBT workflows. Same workflows will fail on Knots until a v30-based release ships.


What Changed: v29 vs v30

Node Previous Current
Core v29.0.0 v30.2.0
Knots v29.2.knots20251110 v29.3.knots20260210
Libre libre-relay-v29.1-1 libre-relay-v30.2-2
  1. NEW: BIP-390 musig() descriptors — Core and Libre now parse and validate musig() key expressions. Not present in v29. Knots still on v29 codebase.

  2. NEW: musig-aware error classification — Core/Libre v30.2 return specific Invalid musig() expression errors for invalid musig usage, vs generic key-parsing failures. btcaaron's Task 7 can now distinguish "musig aware but rejecting" from "doesn't know what musig is."

  3. RESOLVED: reject-reason string convergence — In v29, Core/Libre used mandatory-script-verify-flag-failed while Knots used mempool-script-verify-flag-failed. Core v30.2 adopted the mempool- prefix. All three now match.

  4. UNCHANGED: regtest consensus — 16/16 PASS on all three, both runs. No regressions.


Untested Policy Boundaries

The suite probes consensus-level Taproot behavior. Known policy divergences in untested areas that would likely surface additional findings:

  • OP_RETURN / datacarrier limits — Knots defaults to 42, Core uses 83
  • Dust thresholds — Libre may accept lower dust amounts
  • Bare multisig relay — Knots may reject what Core/Libre relay
  • Full-RBF policy — Libre adopted full-RBF early
  • Non-standard script relay — varying policies across implementations

Operator Notes

  • btcrun + btcaaron installed cleanly with pip install -e .
  • Minor btcrun config gap: no port= directive in generated config, so a second regtest silently fails if port 18444 is already bound
  • All regtest tests ran in under 30 seconds per node
  • Test date: 2026-03-08, Tester: pirq

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions