chore: drop tx replay with backward compatibility - #7496
chore: drop tx replay with backward compatibility#7496federico-stacks wants to merge 13 commits into
Conversation
…ith backward compatibility
There was a problem hiding this comment.
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_proposalvalidation, while keeping compatibility fields (replay_tx_hash,replay_tx_exhausted, reject code7) 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.
Coverage Report for CI Build 31578966868Warning Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes. Coverage decreased (-0.05%) to 86.556%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions180 previously-covered lines in 41 files lost coverage.
Coverage Stats
💛 - Coveralls |
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
StateMachineUpdateV1/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).StateMachineUpdateContent::V1/V2keepreplay_transactions(always empty) — codec untouchedBlockValidateOk::replay_tx_hash/replay_tx_exhausted, hardcodedNone/false/v3/block_proposalresponse.replay_tx_exhaustedis a required serde field with no#[serde(default)], so omitting it breaks parsing of the entire response.ValidateRejectCode::InvalidTransactionReplay = 7, reserved7emitted by an older node.block_validated_by_replay_txstable,SCHEMA_VERSIONstill 19Toml config changes
replay_transactionsis removed fromminerconfig.reset_replay_set_after_fork_blocksis removed fromsignerconfig.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:
compatibility, chiefly that the signer V1/V2 codec is untouched.
tomlsample config entriesintegration testsminerside (includesthe
miner.replay_transactionsconfig removal)signerside, keeping theblock_validated_by_replay_txstable andSCHEMA_VERSIONat19.postblock_proposalside, keeping
BlockValidateOk::replay_tx_hash/replay_tx_exhausteddefaulted toNone/false, andInvalidTransactionReplay = 7as a reserved code.libsignerside with V1/V2backward compatibility (no codec change)
(
multiversion.rs, behind thebuild-signer-v3-3-0-0-5-0feature gate)Applicable issues
Additional info (benefits, drawbacks, caveats)
> Open question: miner-side
GlobalStateEvaluatorto 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:update_global_state_evaluator()fired from the message loop on every incomingStateMachineUpdateglobal_state_evaluatorfield, itsGlobalStateEvaluator::newconstruction, and the startupinsert_updatebackfill.What would be the preferred approach here?
into an evaluator nobody reads
future feature or observability work could take advantage of it
Checklist
docs/property-testing.md)changelog.d/README.md). If this PR breaksanything for node operators or users, or requires them to manually do
anything (such as adjust a setting), use the breaking category.
rpc/openapi.yamlfor RPC endpoints,event-dispatcher.mdfor new events)clarity-benchmarkingrepo