perf(adv-swap-queue): bound FailedSwapReasons + drop incoherent per-keeper cache

Reduces GC/write thrash on the adv-swap-queue EndBlock path, on top of the queue index/blob split already in develop.

What this does

  • Bound FailedSwapReasons to the most recent advSwapQueueMaxFailedReasons (10). The slice was otherwise unbounded (one error appended per failed block); for a persistently-failing swap the per-block blob re-write grew ~100–150 B/block (O(N²) over the item's life). FailedSwaps/FailCount()/SuccessCount() are untouched. ⚠️ This changes consensus state: FailedSwapReasons is persisted in the queue-item blob, so capping it alters the stored bytes (and the app-hash). It rides the next release's upgrade height (develop target) and must be treated as a consensus-breaking change.
  • Drop the per-keeper ListActiveValidators memoization. It cached per KVStore instance, but the app builds separate keepers for the fee/ante path and the managers over the same store, so a bond write via one keeper left the other serving a stale bond in the same block — and a Ragnarok-start reward payout that read the stale list saved the old bond back, leaving the bond module short (reproduced: 1000 vs 999.98). A coherent shared cache isn't cheaply keyable here (two NewKVStoreService instances on one store key; the key isn't reachable in NewKVStore), so the cache is removed.

Tests

  • Two-keeper ListActiveValidators coherence + bond-invariant regression test (fails against the removed cache: keeper B served 1000 vs 999.98; passes without it).
  • TestCapFailedSwapReasons (cap trims reasons, preserves FailedSwaps/FailCount, nil-safe).
  • Updated the SetAdvSwapQueueItemState boundary test to expect the mocknet panic on a never-indexed item (per the develop index/blob split).
Edited by Itzamna

Merge request reports

Loading
Loading