Implement Priority Aging to Prevent Starvation in OutboundTxQueue
Labels: hard reliability Official Campaign Maybe Rewarded
Component: src/queue/priority.rs
Problem
TxPriority (Low/Normal/Emergency) is assigned once, at push() time, and never changes. In a long-running offline scenario — the exact scenario this protocol targets — a Normal payment queued behind a steady stream of newly-arriving Emergency payments can wait indefinitely. Low-tier payments are worse off still. stellarconduit_core::gossip::queue::MessagePriority::urgency_score already solves an analogous problem for mesh-forwarding order by scoring on TTL and message age — this crate's local queue has no equivalent mechanism.
Requirements
- Add an aging mechanism so a
Normal/Low entry's effective dispatch priority increases the longer it waits, eventually reaching (or exceeding) Emergency's effective priority if it waits long enough. Do not mutate the original TxPriority the caller assigned — track effective priority separately (e.g. compute it at pop()/comparison time from priority + enqueued_at + "now").
- Define and document your aging curve (linear, step-function, logarithmic — your choice, but justify it).
- Preserve existing behavior for freshly-enqueued entries: a brand-new
Low entry must not immediately outrank an old Emergency entry; aging should overtake other tiers only after a meaningful, documented wait threshold.
Ord/PartialOrd on the internal heap entry type currently only account for static priority + FIFO enqueued_at tie-break (see src/queue/priority.rs) — you'll need to change the comparison to account for a time-dependent effective priority, which requires either passing "now" into comparisons (tricky with BinaryHeap, which assumes a total order independent of external state) or re-scoring entries periodically. Pick an approach and justify the tradeoff (e.g. re-score/re-heapify on a timer vs. compute effective priority lazily on peek/pop and accept O(n) scans).
Acceptance Criteria
Required Tests
Notes
Implement Priority Aging to Prevent Starvation in
OutboundTxQueueLabels:
hardreliabilityOfficial CampaignMaybe RewardedComponent:
src/queue/priority.rsProblem
TxPriority(Low/Normal/Emergency) is assigned once, atpush()time, and never changes. In a long-running offline scenario — the exact scenario this protocol targets — aNormalpayment queued behind a steady stream of newly-arrivingEmergencypayments can wait indefinitely.Low-tier payments are worse off still.stellarconduit_core::gossip::queue::MessagePriority::urgency_scorealready solves an analogous problem for mesh-forwarding order by scoring on TTL and message age — this crate's local queue has no equivalent mechanism.Requirements
Normal/Lowentry's effective dispatch priority increases the longer it waits, eventually reaching (or exceeding)Emergency's effective priority if it waits long enough. Do not mutate the originalTxPrioritythe caller assigned — track effective priority separately (e.g. compute it atpop()/comparison time frompriority+enqueued_at+ "now").Lowentry must not immediately outrank an oldEmergencyentry; aging should overtake other tiers only after a meaningful, documented wait threshold.Ord/PartialOrdon the internal heap entry type currently only account for staticpriority+ FIFOenqueued_attie-break (seesrc/queue/priority.rs) — you'll need to change the comparison to account for a time-dependent effective priority, which requires either passing "now" into comparisons (tricky withBinaryHeap, which assumes a total order independent of external state) or re-scoring entries periodically. Pick an approach and justify the tradeoff (e.g. re-score/re-heapify on a timer vs. compute effective priority lazily on peek/pop and acceptO(n)scans).Acceptance Criteria
Normalentry that has waited past the aging threshold pops ahead of a freshly-pushedEmergencyentry.Low/Normalentry does not jump ahead of tiers above it before the threshold.test_higher_priority_pops_first,test_fifo_within_same_priority) still pass unmodified.cargo fmt,cargo clippy -D warnings, andcargo testall pass.Required Tests
test_aged_normal_outranks_fresh_emergencytest_fresh_low_does_not_outrank_anythingtest_aging_curve_is_monotonic— effective priority never decreases as wait time increases.test_existing_fifo_and_priority_tests_still_pass(i.e. don't regress current behavior).Notes
OutboundTxQueueCapacity with Priority-Aware Eviction #5.