Files
chia-blockchain/.cursor/context/testing/blockchain.md
T
Almog De PazandGitHub 346fb9a0cf Add Bugbot review context, update context (#21113)
* Add Bugbot consensus review context

Document the validation-state and sub-epoch-summary invariant so automated PR review has the same consensus context as local agents.

* Route Bugbot to repository context docs

Keep Bugbot guidance focused on subsystem context routing so automated reviews use the same module map as local agents.

* Add generated repository context docs

Include the expanded module context map and route Bugbot to the same subsystem docs used by local agents.

* Add EDC agent context pointer

Include the generated EDC agent guidance alongside the Cursor agent context docs.

* Fold EDC guidance into AGENTS

Keep agent context entrypoints consolidated in AGENTS.md and remove the separate EDC pointer.

* Remove generator name from agent guidance

Keep AGENTS.md focused on repository context locations rather than the tooling used to produce them.

* Consolidate context corpus into one source-verified canonical set

- Normalize all subsystem docs to canonical names without chia- prefix,
  removing the split between old and new-dominant corpora.
- Merge new-dominant content into consensus.md, full-node.md, wallet.md;
  split networking.md into server.md, protocols.md, apis.md; add types.md.
- Rename 15 genuinely-new subsystem docs; fold chia-root.md into
  architecture-overview.md.
- Remove filter-branch leakage (filter_challenge, predictable filter,
  protocol 0.0.38) from types.md, protocols.md, harvester.md.
- Correct factual inaccuracies: /push_tx vs wallet queue semantics,
  Err sign/ban policy, protocol import-time coverage, server peer-serving,
  address-manager mutation rule, wallet tx-store rollback, ValidationState
  speculative advancement, block-creation default, MempoolItem fallback.
- Replace unreachable verification SHA with PR-head commit.
- Consolidate test guidance into one small router plus 12 on-demand
  testing/ docs; remove duplicate auto-attached test guides.
- Make INDEX.md the authoritative routing manifest; update BUGBOT.md,
  AGENTS.md, and context-routing.mdc to reference one canonical corpus.
- Replace context-chia-*.mdc rules with canonical narrow rules; remove
  recursive .cursor/** rule and consolidate duplicate tooling rules.
- Tighten clvm-execution.md: remove stale cost_calculator.py reference,
  fix block-creation default, replace opcode catalogue with pointer.

* Trim redundant context and testing docs after value audit

- Trim benchmarks.md: remove per-script Workload Groups narration that is
  obvious from opening each script; keep fidelity, coupling, and fragility
  sections.
- Trim testing/patterns.md: slim to the module-by-module setup map and
  layered-assertion list; remove block/tx/assertion how-to that duplicates
  per-area testing docs.
- Trim testing/full-node.md: slim to starter template and sync-convergence
  tip; remove fixture list and assertion patterns duplicated by patterns.md
  and architecture.md.
- Fold testing/service-wiring.md per-cluster correlation details into
  testing/architecture.md; delete service-wiring.md (high overlap with
  architecture.md).
- Fix protocols.md: correct NewSignagePointHarvester2 message-ID wording
  (ID reassigned to 66, not literally the same ID).
- Update INDEX.md and testing-guide.mdc router to reflect service-wiring.md
  removal.

* Fix verification SHA to reference the main source baseline

The docs were verified against source at PR base 24db9ad390 (origin/main),
not a5647a9327 (the original PR head, which only adds context docs and is
not a meaningful source baseline). The chia/ source tree is identical across
both commits since the PR changes no production code.

* Fix remaining V2 filter-branch leakage in harvester.md and types.md

- harvester.md: replace calculate_effective_plot_filter_bits() and
  calculate_min_plot_strength() (filter-branch-only) with the actual main
  source path: calculate_prefix_bits() with NUMBER_ZERO_BITS_PLOT_FILTER_V2
  and height adjustments, then passes_plot_filter(); strength bounds checked
  by check_plot_param() against MIN_PLOT_STRENGTH/MAX_PLOT_STRENGTH.
- harvester.md: use meta_group (actual PartialProofsData field name) instead
  of "meta group".
- types.md: correct that candidate height feeds prefix-bit reductions for
  both V1 and V2, not just V1; calculate_prefix_bits() branches on V1/V2
  constants and height thresholds.
2026-07-27 07:26:41 -07:00

10 KiB

chia-tests-blockchain

Verified: 2026-07-12 against 24db9ad390. If source contradicts this doc, trust source and update the doc.

Scope: chia/_tests/blockchain/. This is distilled architectural context for future audit or implementation agents. It intentionally omits test inventory and obvious fixture descriptions.

When To Read This

Read this for consensus/blockchain tests, block prevalidation/add-block helpers, fork/reorg tests, generator-reference tests, hard-fork commitment tests, and persistent block-fixture validation.

Module Role

These tests are the executable regression spec for consensus block acceptance. They sit below full-node sync orchestration but above pure consensus helpers: most tests construct real FullBlock objects with BlockTools, pass them through production pre-validation/body-validation/add paths, and assert the exact AddBlockResult or Err that protects chain-state invariants.

The suite is not only checking small helpers. It validates that production sequencing remains coherent across:

  • finished header validation and VDF/POS/slot rules;
  • block body validation, CLVM condition handling, and coin-store transitions;
  • fork choice, reorg replay, and ForkInfo accounting;
  • AugmentedBlockchain overlay behavior used by batch validation;
  • generator-ref lookup across canonical and fork branches;
  • hard-fork commitment behavior for header MMR and sub-epoch challenge roots.

Primary Harness Contract

blockchain_test_utils._validate_and_add_block() is the central abstraction. Treat it as a miniature full-node block-add pipeline, not as a loose assertion helper:

  • It wraps the target Blockchain in AugmentedBlockchain unless the caller supplies a shared overlay.
  • It computes current SSI/difficulty using get_next_sub_slot_iters_and_difficulty(...).
  • It finds the previous sub-epoch summary block for validation state.
  • It runs pre_validate_block(...) unless skip_prevalidation=True.
  • It passes the prevalidated overlay BlockRecord into Blockchain.add_block(...).
  • It checks the BlockStore main-chain invariant before and after each add.

skip_prevalidation=True is deliberate in malformed-body tests where the mutation would fail before the body code under test. In that mode, the helper fabricates PreValidationResult and signature conditions, so the test is no longer exercising header/CLVM prevalidation.

State Invariants Under Test

The suite repeatedly defends these consensus invariants:

  • Canonical chain has exactly one in_main_chain block at each height from genesis to peak.
  • Peak selection follows weight first, then lower total_iters on equal weight.
  • Main-chain extension and fork validation require coherent ForkInfo: peak_height, peak_hash, fork_height, block_hashes, additions, and removals must describe the branch being validated.
  • Coin state is fork-relative, not just DB-relative. A coin may be canonical before the fork, created on the fork, ephemeral inside the same block, or invalid because it only exists on the abandoned branch.
  • Transaction-block timestamp and previous transaction-block context drive timelocks, not necessarily the current peak height.
  • Generator references must resolve on the same branch as the block being validated and must not cross forks.
  • Post-HF2 header MMR/challenge-root commitments are gated by pre-signage-point transaction height, not naïve candidate height.

Test Taxonomy

test_blockchain.py is the broad consensus regression file. Its structure mirrors the production validation pipeline: genesis/slot/header checks first, then prevalidation, body validation, reorg behavior, generator lookup, and direct ForkInfo accounting.

Header validation tests mutate otherwise valid blocks with recursive_replace(...), then repair dependent hashes/signatures as needed so the intended check is reached. Common targets include bad previous hash, PoSpace, sub-slot challenge hashes, ICC/CC/RC VDFs, signage point/index constraints, deficit/SES rules, pool target signatures, foliage presence, timestamp ordering, height/weight, reward block hashes, and overflow/empty-slot cases.

Body validation tests build real spend bundles from WalletTool and assert transaction-state failures: missing or contradictory tx fields, reward claim mismatch, generator root/ref root mismatch, cost over/under-reporting, canonical generator encoding gates, Merkle/filter mismatches, duplicate outputs/removals, DB and fork double-spends, unknown fork spends, minting, invalid fees, and aggregate signature failures. Many tests bypass prevalidation only when the body path is the intended target.

Reorg tests are behavior-heavy. They validate short reorgs, reorgs from genesis, long reorgs over difficulty changes, heavier-lower-height branches, flip-flops back to a prior branch, stale fork-height handling, failed rollback behavior, reorg transaction replay, get_tx_peak() updates, and generator refs that point into the new fork. Shared ForkInfo and shared AugmentedBlockchain are reused across fork blocks to mirror full-node batch validation.

Important Sibling Contracts

AugmentedBlockchain is the speculative overlay used during parallel validation. Its tests assert that extra blocks are contiguous, first-block ancestry exists in the underlying chain, fork ancestry is populated for orphan branches, generator refs search overlay before underlying chain, committed extra blocks are removed, MMR state is copied, and read-only snapshots reject mutation while preserving lookup behavior.

find_fork_point.lookup_fork_chain() and find_fork_point_in_chain() are tested with synthetic block graphs because boundary behavior matters at the pre-genesis/root edge, root-shared forks, same-height forks, asymmetric branch lengths, and no-common-ancestor cases. The returned fork-chain map excludes the fork point and uses the genesis challenge for the pre-genesis edge.

get_block_generator() is intentionally small but consensus-sensitive: a block with no generator must have no refs; a generator with no refs must not call lookup; refs are returned in the original ref-list order and missing refs surface as KeyError.

test_build_chains.py protects persistent block fixtures. It verifies cached chains still match BlockTools generation parameters and that additions/removals do not spend nonexistent coins. If generated-chain behavior changes intentionally, the cache regeneration path is part of the change.

test_block_commitments.py covers HF2 commitment activation by lowering fork heights, then validating both local block acceptance and two-node sync/weight-proof behavior. These tests are expensive but cover the production boundary where consensus commitments interact with full-node sync.

test_blockchain_transactions.py uses two_nodes, mempool submission, and block creation to bridge protocol/mempool behavior into block validation. It is useful for transaction conditions whose setup is easier through full-node APIs than through isolated consensus helpers.

Review And Implementation Pitfalls

Do not replace shared fork ForkInfo with per-block fresh instances in reorg tests unless the production flow also changed. Fresh instances can hide missing additions/removals replay across fork blocks.

Do not treat _validate_and_add_block_no_error() as success-on-peak. It accepts ALREADY_HAVE_BLOCK, ADDED_AS_ORPHAN, and NEW_PEAK; use _validate_and_add_block(..., expected_result=...) when peak status matters.

When mutating signed/header-linked fields, update the dependent hash and plot signature or the test may fail earlier than intended. Existing tests often recalculate transactions_info_hash, foliage_transaction_block_hash, and foliage_transaction_block_signature after targeted body mutations.

Hard-fork-gated expectations often vary by ConsensusMode. The suite deliberately limits modes for slow or mode-sensitive cases; changing fixtures or heights can invalidate assumptions about which generated blocks are transaction blocks, overflow blocks, or generator-bearing blocks.

Avoid raw sleeps. Blockchain tests mostly use direct deterministic validation; full-node sync/transaction convergence uses time_out_assert(...).

Verification Guidance

For helper changes touching _validate_and_add_block, AugmentedBlockchain, generator lookup, or fork handling, include at least one focused test from the affected area plus a representative reorg/generator lookup test. For hard-fork commitment or generated-chain changes, include the relevant commitment/build-chain tests and expect longer runtime.

Source Pointers

  • Consensus regression tests: chia/_tests/blockchain/.
  • Shared blockchain test helpers: chia/_tests/blockchain/blockchain_test_utils.py.
  • Chain fixture generation: chia/_tests/blockchain/test_build_chains.py, chia/_tests/util/blockchain.py.
  • Source behavior context: .cursor/context/consensus.md, .cursor/context/full-node.md.

Starter Template

from __future__ import annotations

import pytest
from chia_rs.sized_ints import uint32

from chia._tests.blockchain.blockchain_test_utils import (
    _validate_and_add_block,
    _validate_and_add_block_multi_result,
)
from chia.consensus.augmented_chain import AugmentedBlockchain
from chia.consensus.block_body_validation import ForkInfo
from chia.consensus.blockchain import AddBlockResult, Blockchain
from chia.consensus.pot_iterations import is_overflow_block
from chia.simulator.block_tools import BlockTools


@pytest.mark.anyio
async def test_example(empty_blockchain: Blockchain, bt: BlockTools) -> None:
    blocks = bt.get_consecutive_blocks(5)
    for block in blocks:
        await _validate_and_add_block(empty_blockchain, block)

    fork_blocks = bt.get_consecutive_blocks(
        3, block_list_input=blocks[:3], seed=b"fork"
    )
    # Add fork blocks and assert reorg results...

For reorg tests, reuse a single AugmentedBlockchain and shared ForkInfo across fork blocks to mirror batch validation. Expect ALREADY_HAVE_BLOCK for shared prefix blocks, ADDED_AS_ORPHAN before the fork wins, and NEW_PEAK once the heavier fork overtakes. Use is_overflow_block(constants, block.reward_chain_block.signage_point_index) for overflow assertions.