Problem
Keeper creates an empty processed-signature cache during startup. Although transaction status lookup can fall back to the ledger, duplicate detection checks only the cache.
A previously executed transaction can therefore be accepted and executed again after restart while its recent blockhash remains valid. This can repeat state transitions that were already committed.
Snapshot-tail replay has the same requirement: signatures restored before the snapshot boundary and transactions re-executed from the ledger tail must both populate the cache with their original terminal statuses.
Reproduction
- Execute and persist a transaction that mutates an account.
- Restart Engine while the transaction's blockhash remains valid.
- Submit the exact signed transaction again.
- Observe that it is accepted and its state transition executes again.
The same behavior can be exercised by restoring an older AccountsDB snapshot and replaying a retained ledger tail before resubmitting a replayed transaction.
Expected
Startup reconstructs the retained processed-signature history at the authoritative AccountsDB slot.
Transactions executed during snapshot-tail replay refresh their terminal statuses in the cache without appending duplicate ledger records or publishing live transaction events.
Resubmitting any restored transaction returns AlreadyProcessed, preserves its original terminal status, and does not execute it again.
Context
Observed on dev at cd02197.
The affected boundary spans Keeper cache initialization, indexed Ledger history reads, and Processor replay. The current dirty changes add clean-restart and snapshot-tail regressions covering status restoration, duplicate rejection, and prevention of repeated execution.
Problem
Keeper creates an empty processed-signature cache during startup. Although transaction status lookup can fall back to the ledger, duplicate detection checks only the cache.
A previously executed transaction can therefore be accepted and executed again after restart while its recent blockhash remains valid. This can repeat state transitions that were already committed.
Snapshot-tail replay has the same requirement: signatures restored before the snapshot boundary and transactions re-executed from the ledger tail must both populate the cache with their original terminal statuses.
Reproduction
The same behavior can be exercised by restoring an older AccountsDB snapshot and replaying a retained ledger tail before resubmitting a replayed transaction.
Expected
Startup reconstructs the retained processed-signature history at the authoritative AccountsDB slot.
Transactions executed during snapshot-tail replay refresh their terminal statuses in the cache without appending duplicate ledger records or publishing live transaction events.
Resubmitting any restored transaction returns
AlreadyProcessed, preserves its original terminal status, and does not execute it again.Context
Observed on
devatcd02197.The affected boundary spans Keeper cache initialization, indexed Ledger history reads, and Processor replay. The current dirty changes add clean-restart and snapshot-tail regressions covering status restoration, duplicate rejection, and prevention of repeated execution.