Patch Overview
What changes are needed to add Ladder Script to Bitcoin Core
~1,600Lines Patched
32Files Modified
~21,900New Code (Rung Lib)
38New Files
Ladder Script adds a self-contained library (
src/rung/) to Bitcoin Core plus a single boundary header (src/rung_shims.h). The patch to existing Core code is approximately 1,600 lines across 32 modified files — routing, type definitions, build wiring. The bulk of the implementation (~21,900 lines across 38 new library files in src/rung/ plus the src/rung_shims.h boundary header) does not touch existing Core code. Per-section walkthrough: Annotated Patch and Annotated Library.Patch to Existing Bitcoin Core
These are the only modifications to existing Bitcoin Core files. Each change is surgical and additive.
| File | Change | Lines |
|---|---|---|
| validation.cpp | Route v4 RUNG_TX inputs to rung::VerifyRungTx. Tx-level CheckRungTxLevel hook. RBF replacement extension for QABIO priming. DisconnectBlock handles the synthetic root coin entry. Three per-tx caches (SharedTree, QABO sig, PQ_BATCH) plumbed through CScriptCheck. | +389 |
| primitives/transaction.h | RUNG_TX_VERSION = 4. Three new tx fields: conditions_root, qabi_block, aggregated_sig. TX_MLSC wire format with flag byte 0x02 and value-only output encoding. DATA_RETURN signalled by nValue == 0. | +210 |
| compressor.cpp | Special script type 0x06 for MLSC outputs — compresses to a single byte (root recovered from synthetic UTXO entry at spend time). 8–12× smaller per-coin chainstate cost. | +68 |
| validation.h | Three thread-safe per-tx cache wrappers (SharedTreeCache, QABOSigCache, PQBatchCache). CScriptCheck constructor extended with four defaulted parameters. | +54 |
| pubkey.cpp | XOnlyPubKey::ComputeLadderTweakHash / CheckLadderTweak / CreateLadderTweak — key-tweak scheme using tag "LadderTweak/v1". | +35 |
| core_write.cpp | Pretty-print MLSC scriptPubKeys (0xDF || root) instead of OP_UNKNOWN. Mark MLSC scripts as type "mlsc" in ScriptToUniv. | +42 |
| rpc/mining.cpp | Log generatetoaddress maxtries-exhausted early exit. Document maxtries as the shared budget it actually is. | +18 |
| script/script.h | Extend IsUnspendable() to recognise MLSC DATA_RETURN outputs (size 34–73 with 0xDF prefix). Keeps DATA_RETURN out of the UTXO set. | +17 |
| key.cpp | CKey::SignSchnorrLadder — Schnorr signer that applies the LadderTweak before signing. | +17 |
| rpc/client.cpp | CLI argument-type entries for ladder + QABIO RPCs (numeric/array/object positional args). | +16 |
| script/interpreter.cpp | Precompute ladder-specific sighash caches for v4 transactions. Reuses BIP-141/341 single-SHA256 hash fields. | +14 |
| policy/policy.cpp | Route v4 transactions to rung::IsStandardRungTx. Bypass standard input/witness checks for MLSC inputs. | +28 |
| coins.cpp | Write the synthetic root coin entry at (txid, MLSC_ROOT_VOUT = 0xFFFFFFFF) for every v4 tx. Enables per-coin compression to 1 byte. | +127 |
| pubkey.h | Declarations for XOnlyPubKey ladder-tweak methods. | +9 |
| rpc/util.cpp | Recursive serialiser for OBJ / OBJ_USER_KEYS RPC arg help text. Fix for ladder RPC nested-object schemas hitting NONFATAL_UNREACHABLE. | +9 |
| script/script_error.{h,cpp} | SCRIPT_ERR_LADDER_INVALID_WITNESS + SCRIPT_ERR_LADDER_EVAL_FALSE error codes and strings. | +8 |
| CMakeLists.txt + test/CMakeLists.txt | Wire bitcoin_rung into bitcoin_common, bitcoin_node, bitcoind, and test_bitcoin. | +7 |
| rpc/mempool.cpp | Skip burn-amount check for MLSC outputs in sendrawtransaction and submitpackage. | +21 |
| script/interpreter.h | SigVersion::LADDER = 4. m_ladder_ready flag on PrecomputedTransactionData. | +4 |
| coins.h | MLSC_ROOT_VOUT = 0xFFFFFFFF sentinel constant; helpers + accessors for the synthetic root coin entry that coins.cpp writes per v4 tx. | +44 |
| primitives/transaction.cpp | Constructor plumbing for the three new tx fields. | +3 |
| rpc/register.h | RegisterRungRPCCommands hook. | +3 |
| key.h | Declaration for SignSchnorrLadder. | +3 |
| compressor.h | nSpecialScripts bumped 6 → 7. | +1 |
| rpc/rawtransaction.cpp | Surface v4 RUNG_TX fields in decoderawtransaction / getrawtransaction verbose output (conditions_root, qabi_block, aggregated_sig, MLSC scriptPubKey). | +28 |
| core_read.cpp | Parse v4-only fields when reading raw transactions through the DecodeTx path. | +23 |
| undo.h | Carry the synthetic MLSC root coin in block undo data so DisconnectBlock can restore it. | +20 |
| wallet/rpc/spend.cpp + wallet/feebumper.h | Skip MLSC-output dust / fee-bump policy paths for v4 transactions. | +20 |
| core_io.h | Forward declaration for the v4 raw-tx parser hook. | +1 |
| test/coins_tests.cpp + test/transaction_tests.cpp + test/txvalidationcache_tests.cpp | Test surface adjustments for the synthetic root coin entry and the new CScriptCheck defaulted parameters. | +25 |
New Rung Library (src/rung/)
Self-contained library. No modifications to existing Bitcoin Core code. Builds as libbitcoin_rung.a.
| File | Lines | Purpose |
|---|---|---|
| rpc.cpp | 4,857 | All 21 RPCs: createrungtx, signrungtx, signladder, parseladder/formatladder, decoderung, createrung, serialiseconditions, validateladder, computectvhash, computemutation, computesighash, generatepqkeypair, pqpubkeycommit, extractadaptorsecret, verifyadaptorpresig, qabi_buildblock/blockinfo/authchain/sighash/signqabo. |
| descriptor.cpp | Descriptor language: ParseDescriptor, FormatDescriptor, recursive-descent parser with resource limits. Round-trip per block type. | 2,151 |
| evaluator.cpp | 1,730 | VerifyRungTx entry point, EvalLadder (OR), EvalRung (AND), EvalBlock dispatch, RegisterBlock, CheckRungTxLevel, MLSC proof verification. |
| types.h | 1,693 | RungBlockType enum (65 active types across 11 families), RungDataType (11 condition data types), structural types, BlockTypeInfo registry, ImplicitFieldLayout tables, MICRO_HEADER_TABLE. |
| conditions.cpp | 1,384 | MLSC Merkle tree (leaves, proofs, sorted-pair interior hashing, LadderLeaf/v1 + LadderInternal/v1 tagged hashes), VerifyMLSCProof, CreateMLSCScript, value commitment, merkle_pub_key folding. |
| serialize.cpp | 1,130 | Wire format: micro-headers, implicit fields, DeserializeLadderWitness, SerializeLadderWitness, anti-spam enforcement, diff-witness mode. |
| blocks/qabi.cpp | 982 | QABI_PRIME + QABI_SPEND + PQ_BATCH evaluators. Per-tx QABOSigCache and PQBatchCache consumers. |
| block_helpers.cpp | 648 | Cross-family helpers: FetchLadderSighash, mutation specs (RECURSE_MODIFIED), expected-root computation, hash-preimage binding, numeric field encoding. |
| api.h | 560 | Library public surface: LadderTxView, LadderSigChecker, LadderEvalContext, VerifyRungTx, LadderScriptError. The only header Core code includes. |
| qabi.cpp | 484 | QABIO state types: QABIBlock, QABIEntry, ComputeQABIRoot, auth-chain helpers, SIGHASH_QABO. |
| blocks/plc.cpp | 437 | PLC family (14 blocks): hysteresis, timers, latches, counters, COMPARE, sequencer, one-shot, RATE_LIMIT, COSIGN. |
| evaluator.h | 406 | Per-tx caches (SharedTreeCache, QABOSigCache, PQBatchCache), RungEvalContext, EvalResult. |
| blocks/recursion.cpp | 351 | Recursion family (6 blocks): RECURSE_SAME/UNTIL/COUNT/SPLIT/MODIFIED/DECAY. |
| blocks/legacy.cpp | 349 | Legacy family (7 blocks): wrapped P2PK / P2PKH / P2SH / P2WPKH / P2WSH / P2TR / P2TR_SCRIPT. |
| policy.cpp | 341 | Mempool policy: IsStandardRungTx, family predicates, QABIO Replace-By-Depth. |
| blocks/compound.cpp | 332 | Compound family (7 blocks): TIMELOCKED_SIG, HTLC, HASH_SIG, PTLC, CLTV_SIG, TIMELOCKED_MULTISIG, ANCHOR_FEE. |
| blocks/governance.cpp | 329 | Governance family (7 blocks): EPOCH_GATE, WEIGHT_LIMIT, INPUT_COUNT, OUTPUT_COUNT, RELATIVE_VALUE, ACCUMULATOR, OUTPUT_CHECK. |
| blocks/sig.cpp | 279 | Signature family (5 blocks): SIG, MULTISIG, ADAPTOR_SIG, MUSIG_THRESHOLD, KEY_REF_SIG. |
| qabi.h + blocks/anchor.cpp + sighash.cpp + blocks/covenant.cpp + adaptor.cpp + serialize.h + descriptor.h + pq_verify.cpp + blocks/timelock.cpp + block_helpers.h + blocks/hash.cpp + write_helpers.h + conditions.h + policy.h + block_dispatch.h + sighash.h + adaptor.h + pq_verify.h + types.cpp + CMakeLists.txt | 3,134 | Smaller files: QABIO header (279), Anchor family (275), SignatureHashLadder + key-path sighash (265), Covenant family (240, CTV/VAULT_LOCK/AMOUNT_LOCK), adaptor signatures for PTLC (188), serialise header (174), descriptor header (181), liboqs PQ wrapper (149), Timelock family (161), helper headers (block_helpers.h 126 + write_helpers.h 103), Hash family (121, TAGGED_HASH/HASH_GUARDED), block dispatch registry (81), conditions header (401), policy header (81), small headers (sighash.h 66, adaptor.h 58, pq_verify.h 52), types.cpp (RungField::IsValid, 46), CMake build target (98). |
Plus the boundary header src/rung_shims.h (363 lines, in src/ not src/rung/) — the only file where Core types meet library types.
Test Coverage
| Layer | Count | What |
|---|---|---|
| Boost unit tests | 665 | All in src/test/rung_tests.cpp, organised into multiple Boost test suites (rung_tests, tx_mlsc_tests, qabi_tests, utxo_dedup_tests, anchor_fee_type_tests, keypath_domain_tests). Block evaluation, serialisation, sighash, conditions, policy, MLSC proofs, field validation, multi-party scale tests up to N=3,000. Includes the F12–F26 regression tests and the in-process VerifyRungTx stress mirror of the libFuzzer harness. |
| Functional tests | 143 | 15 files / ~143 distinct test methods on regtest: the original suite (feature_rung_tx, feature_rung_p2p, feature_rung_legacy, feature_rung_fuzz, feature_rung_pq_batch + _stress, feature_qabi, feature_qabi_size, feature_deferred_vectors, feature_rung_anti_embedding) plus the activation-gate vector triad (feature_rung_tx_vectors, feature_rung_tx_neg_vectors, feature_rung_tx_spend_vectors) and the new descriptor round-trip + sighash-vector verifiers (feature_rung_descriptor_roundtrip, feature_rung_sighash_vectors). |
| Live signet | 36+ | ~36 distinct fund + spend patterns exercised end-to-end against the public ladder-script.org signet, plus 400,000+ remote-fuzz mutation iterations against the same node with 0 anomalies (as of v30.0-ladder-0.23). |
| TLA+ formal specs | 27 | 10 general evaluation, 10 per-family block evaluators, 7 specialised invariants. Covers wire format, anti-spam, Merkle proofs, sighash binding, covenant termination, cross-input rules. |
Reproduce these numbers
The numbers above are derived from the live tree. To regenerate any of them:
git diff v30.0..HEAD -- src/
The authoritative diff against upstream Bitcoin Core v30.0. Patched-line counts come from
--numstat; modified-vs-new file split comes from git cat-file -e v30.0:<path>../build/bin/test_bitcoin --list_content | grep -c '^ '
Boost unit test count (665 across all ladder suites:
grep -c '^BOOST_AUTO_TEST_CASE' src/test/rung_tests.cpp). Functional test count = grep -c '^ def test_\|^def vec_\|^def spend_\|^def fuzz_' test/functional/feature_rung*.py test/functional/feature_qabi*.py test/functional/feature_deferred_vectors.py.find spec -name '*.tla' | wc -l
TLA+ spec count (27). The specs themselves live under
spec/.Per-section narrative for every patched file is in the Annotated Patch. Per-file walkthrough of every library file is in the Annotated Library.