Skip to main content

Code Review Report

Review pinned to v29.2

This review covers Bitcoin Knots v29.2.knots20251110. The current release, v29.3.knots20260508 (May 2026), additionally ships the BIP-110 (RDTS) consensus rules — enforced by the standard build on its activation schedule, with a non-enforcing build also published. Those rules are outside the scope of this review; see BIP-110 / RDTS Integration.

Subject: Bitcoin Knots v29.2.knots20251110 consensus-adjacent code Compared against: Bitcoin Core v29.0 Review date: January 2026 Reviewer: AI-assisted analysis (Claude, Anthropic)

Disclosure

This review was conducted using AI-assisted static code analysis. It is not a formal security audit. All findings should be independently verified using the commands provided. This review focuses on identifying consensus-related changes, not comprehensive security analysis.

Executive Summary

CategoryFiles ChangedLines AddedConsensus Changes Found
script/interpreter.cpp1+90None
validation.cpp1+591None
consensus/3+94None
script/bitcoinconsensus.*2+252None (restored Core code)

Conclusion: No consensus rule changes were identified in v29.2.knots20251110, the release under review. (v29.3's deliberate RDTS soft-fork deployment is outside this review's scope.) All modifications are either:

  1. Policy options (configurable relay behavior)
  2. Performance optimizations
  3. Restored Bitcoin Core code
  4. Build system/infrastructure

Methodology

Scope

Files reviewed (consensus-adjacent):

  • src/script/interpreter.cpp — Script execution
  • src/validation.cpp — Block/transaction validation
  • src/consensus/ — Consensus parameters
  • src/script/bitcoinconsensus.* — Consensus library

Process

# Repository setup
git clone https://github.com/bitcoinknots/bitcoin.git
cd bitcoin
git checkout v29.2.knots20251110
git remote add core https://github.com/bitcoin/bitcoin.git
git fetch core v29.0

# Generate diffs
git diff FETCH_HEAD..HEAD -- src/script/interpreter.cpp
git diff FETCH_HEAD..HEAD -- src/validation.cpp
git diff FETCH_HEAD..HEAD -- src/consensus/

Criteria

For each change, we asked:

  1. Does it modify consensus validation logic?
  2. Does it change consensus parameters (block size, etc.)?
  3. Could it cause a network fork?
  4. Is it policy (relay) or consensus (validation)?

Detailed Findings

1. script/interpreter.cpp

Lines changed: +90 insertions, -28 deletions

Finding 1.1: SigHashCache Performance Optimization

// NEW: Caching mechanism for signature hash computation
int SigHashCache::CacheIndex(int32_t hash_type) const noexcept
bool SigHashCache::Load(int32_t hash_type, ...) const noexcept
void SigHashCache::Store(int32_t hash_type, ...) noexcept

Assessment:Safe — Performance only

This adds caching for signature hash midstates. The actual hash computation is unchanged — same inputs produce identical outputs. This is a performance optimization that speeds up signature verification for transactions with multiple inputs.

Verification:

# The SignatureHash function produces identical results
# Only the caching layer is new
git diff FETCH_HEAD..HEAD -- src/script/interpreter.cpp | grep -A5 "SignatureHash"

Finding 1.2: Optional SIGHASH_ALL Requirement

// NEW: Optional policy check
if (m_require_sighash_all && nHashType != SIGHASH_ALL) {
return false;
}

Assessment:Safe — Policy option only

This adds an optional requirement that signatures use SIGHASH_ALL. Key points:

  • It's a more restrictive check, not a relaxation
  • Consensus does NOT require SIGHASH_ALL
  • Disabled by default
  • Only affects what the node relays, not what blocks it accepts

Finding 1.3: Critical Functions Unchanged

The following consensus-critical functions have no logic changes:

FunctionStatusNotes
EvalScript()✅ UnchangedCore script execution
VerifyScript()✅ UnchangedScript verification
OP_* implementations✅ UnchangedAll opcodes
SignatureHashSchnorr()✅ UnchangedTaproot signatures

Verification:

git diff FETCH_HEAD..HEAD -- src/script/interpreter.cpp | grep -E "EvalScript|VerifyScript|case OP_"
# Should return no changes to these functions

2. validation.cpp

Lines changed: +591 insertions, -210 deletions

This is the largest diff, but examination reveals all changes are policy options.

Finding 2.1: Database Write Randomization

// BEFORE (Core):
static constexpr std::chrono::hours DATABASE_WRITE_INTERVAL{1};

// AFTER (Knots):
static constexpr auto DATABASE_WRITE_INTERVAL_MIN{50min};
static constexpr auto DATABASE_WRITE_INTERVAL_MAX{70min};

Assessment:Safe — Performance/privacy improvement

Randomizes database write timing to prevent network-wide synchronization. Does not affect validation.

Finding 2.2: Configurable Policy Rejections

// NEW: ignore_rejects allows bypassing specific policy checks
const ignore_rejects_type& ignore_rejects = args.m_ignore_rejects;

// Example usage:
MaybeReject(TxValidationResult::TX_NOT_STANDARD, "tx-size-small");

Assessment:Safe — Policy flexibility only

The ignore_rejects mechanism allows node operators to bypass specific policy rejections. Critical observation:

  • These are relay/mempool policies, NOT consensus rules
  • Transactions rejected by policy are still consensus-valid
  • Your node accepts blocks containing these transactions regardless

Finding 2.3: New Policy Options

OptionPurposeConsensus Impact
SpkReuseModeAddress reuse detectionNone — privacy feature
minrelaymaturityCoin age requirementNone — relay policy
datacarrier_fullcountOP_RETURN countingNone — relay policy
RBFPolicyReplace-by-fee modesNone — relay policy
TRUCPolicyTransaction version handlingNone — relay policy

Verification:

# All policy options are in AcceptToMemoryPool path, NOT ConnectBlock
git diff FETCH_HEAD..HEAD -- src/validation.cpp | grep -B5 "ignore_rejects"

Finding 2.4: Script Verification Flags Safety

// Critical safety measure at line 758:
flags |= MANDATORY_SCRIPT_VERIFY_FLAGS; // for safety

Assessment:Safe — Explicit safety guarantee

Even when policy flags are relaxed, mandatory (consensus) flags are always preserved. This is an explicit safety measure ensuring consensus validation is never weakened.

Finding 2.5: Consensus Functions Unchanged

FunctionStatusNotes
CheckBlock()✅ UnchangedBlock structure validation
ContextualCheckBlock()✅ UnchangedBlock context validation
ConnectBlock()✅ UnchangedUTXO set updates
CheckTxInputs()✅ UnchangedInput validation
Consensus::CheckTransaction()✅ UnchangedTransaction validation

Verification:

git diff FETCH_HEAD..HEAD -- src/validation.cpp | grep -E "CheckBlock|ConnectBlock|CheckTxInputs"
# Verify no changes to these function implementations

3. consensus/ Directory

Lines changed: +94 insertions, -5 deletions

Finding 3.1: CMakeLists.txt (NEW FILE)

# Build configuration for libbitcoinconsensus
add_library(bitcoinconsensus
../script/bitcoinconsensus.cpp
...
)

Assessment:Safe — Build infrastructure only

This is build system configuration for the restored libbitcoinconsensus library. Contains no consensus logic.

Finding 3.2: merkle.cpp Optimization

// BEFORE:
if (hashes[pos] == hashes[pos + 1]) mutation = true;

// AFTER:
if (hashes[pos] == hashes[pos + 1]) {
mutation = true;
break; // <-- NEW: Early exit optimization
}

Assessment:Safe — Performance optimization

Adds early exit when mutation is detected. The function returns identical results — once mutation is found, there's no need to continue checking.

Finding 3.3: validation.h Refactoring

// Refactored to accept CTransaction directly
inline int GetWitnessCommitmentIndex(const CTransaction& gentx)

// Original block version now wraps the transaction version
inline int GetWitnessCommitmentIndex(const CBlock& block)

Assessment:Safe — Code refactoring only

The logic is identical, just factored to be more flexible. The block version is now a wrapper that calls the transaction version.


4. script/bitcoinconsensus.* (Restored Library)

Lines changed: +252 insertions (two new files)

// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers

Assessment:Safe — Original Bitcoin Core code

This is restored Bitcoin Core code, not new Knots code. Key facts:

  • Written by Bitcoin Core developers
  • Reviewed when originally merged to Core
  • Used in production for years
  • Removed from Core v28, restored in Knots for compatibility
  • Provides bitcoinconsensus_verify_script() for external validators

Verification:

# Compare against historical Core version
git log --oneline core/v27.0 -- src/script/bitcoinconsensus.cpp | head -5
# Shows original Core commits

Risk Matrix

Change CategoryRisk LevelReasoning
Performance optimizationsNoneSame outputs, faster computation
Policy optionsNoneRelay only, consensus unchanged
Build systemNoneInfrastructure, no runtime effect
Restored Core codeNoneAlready reviewed, battle-tested
Consensus logicN/ANo changes found

Verification Commands

Run these commands to verify the findings yourself:

#!/bin/bash
# verify-consensus-changes.sh

git clone https://github.com/bitcoinknots/bitcoin.git
cd bitcoin
git checkout v29.2.knots20251110
git remote add core https://github.com/bitcoin/bitcoin.git
git fetch core v29.0

echo "=== 1. Check interpreter.cpp for EvalScript changes ==="
git diff FETCH_HEAD..HEAD -- src/script/interpreter.cpp | \
grep -E "^[+-].*EvalScript|^[+-].*VerifyScript" | head -20

echo -e "\n=== 2. Check validation.cpp for ConnectBlock changes ==="
git diff FETCH_HEAD..HEAD -- src/validation.cpp | \
grep -E "^[+-].*ConnectBlock|^[+-].*CheckBlock\(" | head -20

echo -e "\n=== 3. Verify MANDATORY_SCRIPT_VERIFY_FLAGS safety ==="
git diff FETCH_HEAD..HEAD -- src/validation.cpp | \
grep "MANDATORY_SCRIPT_VERIFY_FLAGS"

echo -e "\n=== 4. Check consensus parameters ==="
git diff FETCH_HEAD..HEAD -- src/consensus/consensus.h

echo -e "\n=== 5. Verify bitcoinconsensus is Core code ==="
head -10 src/script/bitcoinconsensus.cpp

Limitations

This review:

  • ✅ Examined consensus-adjacent code changes
  • ✅ Verified no consensus rule modifications
  • ✅ Confirmed policy vs consensus distinction
  • ❌ Did not audit all 36,000+ lines of Knots changes
  • ❌ Did not perform fuzzing or dynamic analysis
  • ❌ Did not mathematically prove correctness

For high-stakes deployments, consider commissioning a formal security audit from a firm specializing in Bitcoin.


Conclusion

After systematic review of all consensus-adjacent code in Bitcoin Knots v29.2, no consensus rule changes were identified in that release. The changes fall into well-defined categories:

  1. Policy options — Configurable relay behavior that doesn't affect block validation
  2. Performance optimizations — Same results, faster computation
  3. Restored Core code — Previously reviewed code brought back for compatibility

The claim that Knots contains "dangerous consensus changes" is not supported by examination of the v29.2 code. Knots v29.2 validates blocks identically to Bitcoin Core. The RDTS soft-fork deployment added in v29.3 is a deliberate, documented consensus feature — not a hidden change — and would need a separate review; see BIP-110 / RDTS Integration.


See Also