refactor: split monitor timer into finalize and resubmit#120
Merged
Conversation
0336ff9 to
a15018c
Compare
b427300 to
99c4f76
Compare
a15018c to
e56c658
Compare
99c4f76 to
0b635f9
Compare
e56c658 to
a205385
Compare
0b635f9 to
a7040bf
Compare
a205385 to
57d3713
Compare
a7040bf to
7d47203
Compare
57d3713 to
519bcf0
Compare
lpahlavi
added a commit
that referenced
this pull request
Apr 13, 2026
## Summary - Adds `ExpiredTransaction` event type (CBOR tag `n(10)`) that records when a submitted transaction has an expired blockhash and a null on-chain status — meaning it will never be executed and must be resubmitted - Adds `transactions_to_resubmit: BTreeSet<Signature>` state field, populated by `ExpiredTransaction` events and cleared on resubmission/finalization — survives canister upgrades since it is rebuilt by replaying the event log This PR is the prerequisite for #120, which splits `monitor_submitted_transactions` into two independent timers: `finalize_transactions` emits `ExpiredTransaction` events, and `resubmit_transactions` drains the queue. ## Stack - Followed by: #120 (split monitor timer into finalize and resubmit) - Followed by: #97 (single-round timers with immediate rescheduling) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
9e81446 to
6918ffa
Compare
- Rename `monitor_submitted_transactions` to two separate timers: `finalize_transactions` (2 min) and `resubmit_transactions` (3 min) - `finalize_transactions` checks submitted transactions, marks succeeded/failed ones and expired ones for resubmission - `resubmit_transactions` processes transactions in the resubmit queue - Staggered intervals avoid concurrent timer execution in steady state - Add `FinalizeTransactions` and `ResubmitTransactions` task types, replacing `MonitorSubmittedTransactions` - Update integration tests to use the new timer delays Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
0264072 to
e4a94e8
Compare
THLO
reviewed
Apr 14, 2026
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
THLO
approved these changes
Apr 14, 2026
The expiry check is `slot + MAX_BLOCKHASH_AGE < current_slot` (strict), so the minimal expired slot is `INITIAL_SLOT + MAX_BLOCKHASH_AGE + 1`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…riants Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…behavior The sol-rpc canister rounds the slot from getSlot down to the nearest multiple of 20 before making getBlock requests. Update get_block_request in the mock fixtures to match this behavior, so tests work with any slot value rather than requiring the slot to already be a multiple of 20. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… met The SOL RPC canister rounds getSlot results down to the nearest multiple of 20 before returning the slot to callers. Using INITIAL_SLOT + MAX_BLOCKHASH_AGE + 1 as resubmission_slot gave 350_000_151, which rounds down to 350_000_140 — not enough to trigger the expiry check (350_000_150 < 350_000_140 is false). Adding SOL_RPC_SLOT_ROUNDING + 1 ensures the rounded slot is strictly greater than the expiry threshold. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lpahlavi
added a commit
that referenced
this pull request
Apr 14, 2026
## Summary Refactors all timer-based processing functions to a single-round, immediately-rescheduling pattern: - Each timer invocation processes one round of up to `MAX_CONCURRENT_RPC_CALLS` batches, then immediately reschedules itself with `Duration::ZERO` if work remains - Rescheduling uses a `scopeguard` that fires on drop (including panics); defused when all work fits in the current round - The `more_to_process` flag is computed from a snapshot of the queue **before** processing begins, so items added concurrently during execution don't trigger a spurious reschedule ## Stack - Based on: #120 (split monitor timer) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits the single
monitor_submitted_transactionstimer into two separate timers with different intervals:finalize_transactions: checks all submitted transactions, finalizes succeeded/failed ones, and marks expired transactions (older thanMAX_BLOCKHASH_AGEslots) for resubmissionresubmit_transactions: processes the resubmission queue by fetching a fresh blockhash and resubmitting each expired transactionAdds
FinalizeTransactionsandResubmitTransactionstask types, replacingMonitorSubmittedTransactions.🤖 Generated with Claude Code