From a99910acd15b55df51f0765a22dcf609cdb4d0b7 Mon Sep 17 00:00:00 2001 From: Louis Pahlavi Date: Fri, 10 Apr 2026 17:58:50 +0200 Subject: [PATCH] fix: handle resubmission replay for canisters without ExpiredTransaction Canisters deployed before ExpiredTransaction was introduced (#122) have event logs where ResubmittedTransaction events have no preceding ExpiredTransaction. The updated state machine requires the transaction to be in transactions_to_resubmit before it can be resubmitted, so replaying such logs would panic. The fix is a fallback in process_transaction_resubmitted: if the old signature is in submitted_transactions rather than transactions_to_resubmit, process_transaction_expired is called inline first. This makes every replay of old event logs correct. To be removed after the staging migration is complete. Co-Authored-By: Claude Sonnet 4.6 --- minter/src/state/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/minter/src/state/mod.rs b/minter/src/state/mod.rs index dbf48ccc..481ef164 100644 --- a/minter/src/state/mod.rs +++ b/minter/src/state/mod.rs @@ -598,6 +598,14 @@ impl State { new_signature: &Signature, new_slot: Slot, ) { + // Handle event logs from before ExpiredTransaction was introduced: + // if the old transaction is still in submitted_transactions (no preceding + // ExpiredTransaction event in the log), move it to transactions_to_resubmit first. + if !self.transactions_to_resubmit.contains_key(old_signature) + && self.submitted_transactions.contains_key(old_signature) + { + self.process_transaction_expired(old_signature); + } let old_transaction = self .transactions_to_resubmit .remove(old_signature)