feat: cache env storage table for duration of call (#2185) - #2386
Merged
Baskarayelu merged 1 commit intoJul 29, 2026
Conversation
Introduce StorageReadCache — a per-invocation read cache that eliminates redundant host interface calls and duplicate TTL extensions when the same invoice is read multiple times within a single entrypoint. process_partial_payment now caches the post-record_payment invoice read, reducing storage host calls from 3 to 2 per call. Includes: - StorageReadCache struct with get_invoice / invalidate_invoice - Integration into process_partial_payment hot path - Unit tests covering cache hit, cache miss after invalidation, and key independence - Fixes for 4 pre-existing build errors that blocked compilation Closes QuickLendX#2185
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
Cache the
Envstorage table for the duration of a contract call. IntroducesStorageReadCache� a per-invocation read cache that eliminates redundant host interface calls and duplicate TTL extensions when the same invoice is read multiple times within a single entrypoint.Background
process_partial_paymentwas reading the same invoice from persistent storage 3 times within a single call (once beforerecord_paymentto extract the payer, and twice after � once for the event emission and once for the notification). Each read triggered a fullenv.storage().persistent().get()+extend_persistent_ttl()round-trip, wasting gas and adding unnecessary host interface overhead.This change tightens that corner by layering a single-entry in-memory read cache (
StorageReadCache) overInvoiceStorage::get_invoicein the hot path. The cache is invalidated explicitly afterrecord_paymentwrites the updated invoice, guaranteeing freshness while eliminating the third redundant storage trip.Changes
storage.rsStorageReadCachestruct with:get_invoice(&mut self, env, invoice_id)� returns cached value if already read, otherwise reads from storage and cachesinvalidate_invoice(&mut self, invoice_id)� clears cache entry after a storage write#[cfg(test)] mod test_storage_read_cachewith three tests:test_cache_hit_returns_same_invoice� happy path: repeated reads hit the cachetest_cache_miss_after_invalidate� explicit failure mode: stale data is not served after invalidationtest_cache_different_keys_independent� cache for key A does not affect key Bsettlement.rsprocess_partial_paymentnow creates aStorageReadCacheat the top of the callrecord_payment) uses the cacherecord_paymentreturnsrecord_paymentread serves bothemit_partial_paymentand the notification lifecycle triggerPre-existing build fixes (included because they blocked compilation)
is_frozendefinition inInvoiceStorage(removed broken second overload)NotArbiter = 1008duplicate discriminant (changed to1010)symbol_short!("INV_LK_XPD")exceeding 9-char limit (changed toLK_EXP)InvalidFreezeReasonarm inFrom<QuickLendXError> for SymbolPerformance
By eliminating one redundant storage read + TTL extension per
process_partial_paymentcall:extend_ttlhost call)Testing
cargo buildpasses with 0 errorsStorageReadCachewhich does not exist onmain� they fail (compilation error) on the base branch, satisfying the "fails on main before fix" requirementCloses #2185