Skip to content

chore: drop tx replay with backward compatibility - #7496

Open
federico-stacks wants to merge 13 commits into
stacks-network:mainfrom
federico-stacks:chore/drop-tx-replay-s1
Open

chore: drop tx replay with backward compatibility#7496
federico-stacks wants to merge 13 commits into
stacks-network:mainfrom
federico-stacks:chore/drop-tx-replay-s1

Conversation

@federico-stacks

@federico-stacks federico-stacks commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Description

This PR removes the tx-replay feature in a backward compatible way, as a first step. This lets us delete the whole logic and code without bumping the signer protocol version or requiring a coordinated release of the signer binary.

Signers and nodes running older binaries interoperate with this release unchanged: the StateMachineUpdate V1/V2 codec is untouched, so a non-upgraded signer keeps parsing an upgraded signer's StackerDB messages, and vice versa.

What is intentionally kept

4 compatibility hooks are retained on purpose. Each is pinned by a regression test in stacks-signer/src/tests/tx_replay_removal_compat.rs (commit 1).

Hook Protects
StateMachineUpdateContent::V1/V2 keep replay_transactions (always empty) — codec untouched An older signer reading a newer signer's StackerDB message. Dropping the 4-byte empty vector makes its decode hit EOF and discard the whole update.
BlockValidateOk::replay_tx_hash / replay_tx_exhausted, hardcoded None / false An older signer parsing a newer node's /v3/block_proposal response. replay_tx_exhausted is a required serde field with no #[serde(default)], so omitting it breaks parsing of the entire response.
ValidateRejectCode::InvalidTransactionReplay = 7, reserved A newer signer decoding a 7 emitted by an older node.
block_validated_by_replay_txs table, SCHEMA_VERSION still 19 Preservering current schema and avoid db bump.

Toml config changes

  • replay_transactions is removed from miner config.
  • reset_replay_set_after_fork_blocks is removed from signer config.

In case the config were used the binary would fail to start, so these changes are reported in the related changelog .breaking.

Relevant changes

To simplify review, the work is split into meaningful commits:

  1. 37c311d: add regression tests validating backward
    compatibility, chiefly that the signer V1/V2 codec is untouched.
  2. 04c9d4c: remove toml sample config entries
  3. 07683d3: remove integration tests
  4. bc3eb53: remove behaviour on miner side (includes
    the miner.replay_transactions config removal)
  5. 18f871a: remove behaviour on signer side, keeping the
    block_validated_by_replay_txs table and SCHEMA_VERSION at 19.
  6. 548d0dd: remove behaviour on the postblock_proposal
    side, keeping BlockValidateOk::replay_tx_hash / replay_tx_exhausted defaulted to
    None / false, and InvalidTransactionReplay = 7 as a reserved code.
  7. 503c27e: clean behaviour on libsigner side with V1/V2
    backward compatibility (no codec change)
  8. 932423f: remove tx replay references from dead code
    (multiversion.rs, behind the build-signer-v3-3-0-0-5-0 feature gate)

Applicable issues

Additional info (benefits, drawbacks, caveats)

> Open question: miner-side GlobalStateEvaluator to drop, or to keep as an API?

Removing tx-replay behaviour on the miner side, now makes SignerCoordinator:::get_signer_global_state -> StackerDBListnerComms::get_signer_global_state() unused. As a conseguence, the following are still executing but feeding nothing:

  • the work down by update_global_state_evaluator() fired from the message loop on every incoming StateMachineUpdate
  • the global_state_evaluator field, its GlobalStateEvaluator::new construction, and the startup insert_update backfill.

What would be the preferred approach here?

  • Drop it: the miner currently decodes and accumulates every signer state-machine message
    into an evaluator nobody reads
  • "Keep it": as an API, considering it is the only place the node observes signer global state, so a
    future feature or observability work could take advantage of it

Checklist

  • Test coverage for new or modified code paths
  • For new Clarity features or consensus changes, add property tests (see
    docs/property-testing.md)
  • Changelog fragment(s) or "no changelog" label added (see
    changelog.d/README.md). If this PR breaks
    anything for node operators or users, or requires them to manually do
    anything (such as adjust a setting), use the breaking category.
  • Required documentation changes (e.g.,
    rpc/openapi.yaml for RPC endpoints,
    event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the transaction-replay feature across node/miner, signer, and libsigner while intentionally preserving backward-compatibility surfaces (wire codecs, API response fields, and signer DB schema version) so older and newer binaries can interoperate during rollout.

Changes:

  • Removes tx-replay behavior from miner block construction and /v3/block_proposal validation, while keeping compatibility fields (replay_tx_hash, replay_tx_exhausted, reject code 7) for older signers/nodes.
  • Removes tx-replay-related TOML config options and sample config entries, plus deletes tx-replay integration/unit tests that no longer apply.
  • Adds signer regression tests that “pin” the backward-compatibility hooks (wire format, JSON fields, reject code, schema version).

Reviewed changes

Copilot reviewed 38 out of 38 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
stackslib/src/net/api/tests/postblock_proposal.rs Removes tx-replay validation tests and updates proposals to omit replay payloads.
stackslib/src/net/api/postblock_proposal.rs Drops tx-replay request/validation logic while retaining deprecated response fields and reserved reject code.
stackslib/src/config/mod.rs Removes miner replay_transactions config plumbing and associated mainnet guard.
stackslib/src/chainstate/stacks/miner.rs Removes replay-transaction mining path and related fault-injection flags/helpers.
stackslib/src/chainstate/nakamoto/miner.rs Updates block builder metadata creation signature to no longer accept replay txs.
stacks-signer/src/v0/tests.rs Updates signer tests for removal of replay-related config fields.
stacks-signer/src/v0/signer.rs Removes replay-aware proposal validation/submission paths and replay DB writes.
stacks-signer/src/v0/signer_state.rs Removes replay state management (scope/failsafe/fork handling) from signer local state machine.
stacks-signer/src/tests/tx_replay_removal_compat.rs Adds compatibility “tripwire” tests to pin wire/API/schema invariants during phased removal.
stacks-signer/src/tests/signer_state.rs Updates signer state tests to remove replay-set assumptions.
stacks-signer/src/tests/mod.rs Registers new compatibility test module.
stacks-signer/src/signerdb.rs Removes replay-validation accessors while leaving the legacy table creation for schema compatibility.
stacks-signer/src/runloop.rs Removes replay-related config propagation into proposal evaluation config.
stacks-signer/src/config.rs Removes replay-related config fields and parsing/validation paths.
stacks-signer/src/client/stacks_client.rs Removes replay tx payload from /v3/block_proposal submission API.
stacks-signer/src/client/mod.rs Removes replay-related fields from client test config plumbing.
stacks-signer/src/chainstate/v2.rs Removes replay-based exceptions from tenure-extend validation logic.
stacks-signer/src/chainstate/v1.rs Removes replay-set parameterization from proposal checks and extend validation logic.
stacks-signer/src/chainstate/tests/v2.rs Deletes replay-specific test coverage and updates fixtures accordingly.
stacks-signer/src/chainstate/tests/v1.rs Deletes replay-specific test coverage and updates fixtures accordingly.
stacks-signer/src/chainstate/mod.rs Removes replay failsafe parameter from proposal evaluation config.
stacks-signer/changelog.d/drop-tx-replay.changed Notes signer behavior change removing tx-replay logic.
stacks-signer/changelog.d/drop-tx-replay.breaking Notes signer config key removal.
stacks-node/src/tests/signer/v0/tx_replay.rs Removes tx-replay integration test suite.
stacks-node/src/tests/signer/v0/tenure_extend.rs Updates signer test config construction after replay config removal.
stacks-node/src/tests/signer/v0/mod.rs Removes tx-replay module and replay-config usage in signer test harness.
stacks-node/src/tests/signer/multiversion.rs Updates multiversion compatibility shims to hard-disable replay on pinned older signer.
stacks-node/src/tests/signer/mod.rs Removes replay-specific helper methods from signer test harness.
stacks-node/src/tests/nakamoto_integrations.rs Updates integration tests to remove replay payloads and replay-config usage.
stacks-node/src/nakamoto_node/miner.rs Removes miner-side replay-tx selection and replay-based tenure-extend behavior.
sample/conf/signer/mainnet-signer-conf.toml Removes signer replay-related sample config entries.
sample/conf/mainnet-miner-conf.toml Removes miner replay-related sample config entries.
libsigner/src/v0/signer_state.rs Removes replay-set aggregation from global state evaluation; makes state machine hashable for map keys.
libsigner/src/v0/messages.rs Retains legacy replay vector in V1/V2 wire format but always emits it empty in newly produced updates.
libsigner/src/tests/signer_state.rs Removes replay-set-related global state evaluator tests.
contrib/stacks-inspect/src/lib.rs Updates miner helper invocation after replay parameter removal.
changelog.d/drop-tx-replay.changed Notes node/miner behavior change removing tx-replay logic.
changelog.d/drop-tx-replay.breaking Notes miner config key removal.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread stackslib/src/net/api/postblock_proposal.rs Outdated
Comment thread stacks-signer/src/config.rs
@federico-stacks
federico-stacks marked this pull request as ready for review August 10, 2026 14:21
@coveralls

coveralls commented Aug 10, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 31578966868

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage decreased (-0.05%) to 86.556%

Details

  • Coverage decreased (-0.05%) from the base build.
  • Patch coverage: 32 of 32 lines across 8 files are fully covered (100%).
  • 180 coverage regressions across 41 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

180 previously-covered lines in 41 files lost coverage.

Top 10 Files by Coverage Loss Lines Losing Coverage Coverage
stackslib/src/net/p2p.rs 22 74.14%
clarity/src/vm/ast/mod.rs 16 81.48%
stackslib/src/chainstate/nakamoto/mod.rs 13 84.54%
stacks-signer/src/signerdb.rs 9 93.73%
stacks-node/src/nakamoto_node/stackerdb_listener.rs 8 86.94%
stacks-signer/src/v0/signer.rs 8 87.35%
stackslib/src/net/download/epoch2x.rs 7 59.69%
libsigner/src/v0/messages.rs 6 91.22%
stackslib/src/net/stackerdb/config.rs 6 81.45%
stacks-node/src/nakamoto_node/relayer.rs 6 86.84%

Coverage Stats

Coverage Status
Relevant Lines: 232216
Covered Lines: 200998
Line Coverage: 86.56%
Coverage Strength: 18465084.23 hits per line

💛 - Coveralls

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.

3 participants