Skip to content

Toccata Cleanup - Part 2 - #1083

Open
biryukovmaxim wants to merge 1 commit into
toccata-cleanup/1-transition-machineryfrom
toccata-cleanup/2-consensus-leaves
Open

Toccata Cleanup - Part 2#1083
biryukovmaxim wants to merge 1 commit into
toccata-cleanup/1-transition-machineryfrom
toccata-cleanup/2-consensus-leaves

Conversation

@biryukovmaxim

@biryukovmaxim biryukovmaxim commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Stack

  1. Toccata Cleanup - Part 1 #1082 Part 1 - transition-only machinery (base: master)
  2. Toccata Cleanup - Part 2 #1083 Part 2 - consensus activation checks
  3. Toccata Cleanup - Part 3 #1084 Part 3 - txscript covenants flag
  4. Toccata Cleanup - Part 4 #1086 Part 4 - mining and mempool policy

Each PR targets the branch below it, so its diff contains only its own layer. Review bottom to top.


Second of a stacked series removing dead Toccata activation handling. Stacked on #1082; review that one first, this PR's diff is only the changes on top of it.

Toccata activated on mainnet at DAA 474_165_565 and testnet at 467_579_632. With a 30 hour pruning duration and a 432,000 block finality depth, pruning_point.daa_score - finality_depth > toccata_activation holds on every live network. That is what makes the pre-Toccata branches below unreachable, including the ones that operate inside the [pruning_point - finality_depth, pruning_point] window. Part 1 activated Toccata on devnet, so all networks are now post-activation.

This part collapses every activation check inside the consensus crates to its post-Toccata branch, and drops each toccata_activation field once its last reader is gone. Params::toccata_activation deliberately stays; it is still read outside consensus and is removed at the top of the stack.

Collapsed checks

  • Transaction validator: the contextual check_transaction_version and check_transaction_signature_scripts_in_header_context are deleted, and the isolation-stage checks become the single enforcement point. This is what the deleted TODO(post-toccata) asked for, and it restores the arrangement described by validate_tx_in_isolation's own doc comment: checks live in header context only while they are activation dependent. check_covenant_info and the script engine's covenant flag become unconditional.
  • Coinbase: the coinbase transaction is always built at TX_VERSION_TOCCATA.
  • Header processor: check_header_version_in_context is deleted and the context-free check_header_version is restored in pre-GHOSTDAG validation. Historical headers are unaffected: pruning-proof headers are inserted directly by apply_proof without passing isolation validation, and ordinary IBD headers start at the current post-activation pruning point.
  • Virtual processor: accepted_id_digests is always the single-element seq_commit form, chain qualification is unconditional, the seq commit accessor is always present, and the inactivity shortcut no longer folds to ZERO_HASH for pre-Toccata ancestors. calc_accepted_id_merkle_root is deleted once both callers are gone.
  • Pruning: SMT store pruning is unconditional, and the pruning-proof chain segment is always built on both the syncer and syncee sides, without the inner breaks that stopped below the activation.
  • Body processor and get_seq_commit_lane_proof lose their remaining gates.

ForkedParam call sites move from .get(daa_score) to .after() rather than to plain constants. The field types stay as they are and collapse to plain values at the top of the stack, so this PR contains no parameter-shape changes.

Genesis accepted-id digests

compute_genesis_accepted_id_digests branched on the genesis DAA score. Mainnet and testnet genesis predate the activation, so the pre-Toccata branch was the live one for them, but it is collapsed here along with the rest.

A node with an existing database does not process genesis at all. A node starting from an empty database does compute this value, but discards it while syncing, because the headers proof builds a staging consensus that skips genesis and seeds virtual state at the current pruning point. Any network defined from now on is post-activation at genesis. The reasoning is recorded in a doc comment on the function.

This is also what allows Params::toccata_activation to be deleted entirely later in the series, rather than kept for a computation that permanently depends on the activation score.

Removed plumbing

toccata_activation is dropped from TransactionValidator, CoinbaseManager, PruningProofManager, VirtualStateProcessor and SeqCommitAccessor, together with their constructor arguments and services.rs call sites. UtxoProcessingContext::accepted_tx_ids and accepted_tx_versions are removed as well: the collapse left them written on every accepted transaction and read nowhere.

Test data

What changes in test data, how and why. Exactly one fixture changes, goref_custom_pruning_depth/blocks.json.gz, regenerated by rerunning simpa/generate-json-tests-data.sh rather than edited by hand. Its OverrideParams header line is identical to the previous one except toccata_activation: 1000 -> 0; pruning_depth: 450, finality_depth: 200 and every other param are unchanged, so the fixture still exercises the custom pruning depth it exists for. goref_custom_pruning_depth_test is not touched and still passes.

simpa's --test-pruning profile pinned toccata_activation at DAA 1000, so goref_custom_pruning_depth was a DAG spanning the activation with mixed header versions. Now that the header version check is unconditional, such a DAG is not valid input, so the toggle is removed and the fixture regenerated; it pins toccata_activation: 0 and is uniformly version 2. The file is a gzipped block dump, so it is meant to be reproduced with simpa/generate-json-tests-data.sh rather than read as a diff.

Integration tests covering the pre-activation to post-activation transition are deleted, since the transition no longer exists in the code. The durable invariants they shared coverage with (covenants, push limits, native payloads, KIP-10, header and transaction version enforcement) remain covered. One assertion in header_in_isolation_validation_test moves from BLOCK_VERSION to TOCCATA_BLOCK_VERSION, following the version check into isolation.

Not in scope

Params::toccata_activation, the ForkedParam getters, BLOCK_VERSION := 2 and TOCCATA_BLOCK_VERSION are handled at the top of the stack. The txscript EngineFlags covenant flag, the MiningManager/Mempool plumbing and protocol/flows follow in later parts. Pre-Toccata storage decoders (utxo/pre_toccata.rs, the EOF tolerant UtxoEntry deserializer, db_compat.rs) are permanent DB compatibility and are never removed, as are the TX_VERSION_TOCCATA keyed transaction rules.

A TODO is left on VirtualState::accepted_id_digests: it now always holds exactly one hash, and could become a dedicated type that serializes as a one-element vector, keeping the stored bytes identical while making the invariant explicit.

* Collapse consensus activation checks to their post-Toccata branch
* Move transaction version and signature script checks back to isolation
* Restore the context-free header version check
* Drop the activation field from the transaction, coinbase, pruning proof,
  virtual and seq commit services
* Stop generating DAGs that span the activation in simpa test pruning
@biryukovmaxim
biryukovmaxim force-pushed the toccata-cleanup/2-consensus-leaves branch from b5b1b00 to e851107 Compare July 27, 2026 16:07
@biryukovmaxim
biryukovmaxim marked this pull request as ready for review July 28, 2026 09:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant