mirror of
https://github.com/logos-messaging/logos-delivery.git
synced 2026-07-22 12:39:30 +00:00
ensureFreshMerkleProofPath returns the fetched path instead of leaving callers to re-read merkleProofCache. generateProof uses the returned value, so an invalidate landing during the refresh's updateMemberCache suspension can no longer empty the cache under an in-flight proof-gen and trip its empty-cache guard. The cache field is now only a hint for the next call. invalidateMerkleProofCache also bumps merkleProofCacheGeneration. The refresh stamps the generation before each fetchMerkleProofElements and only caches a result whose generation is unchanged, otherwise it fetches again, bounded by MerkleProofRefetchMaxAttempts. A rejection-driven invalidate is therefore never absorbed by a fetch that predates it, so the path a caller receives always postdates the invalidate. refreshRoots awaits rootsRefreshInFlightFut via join() at both await sites, giving the roots refresh the same cancellation shield the proof path refetch already had: a cancelled validateRoot caller no longer cancels the refresh its coalesced peers are waiting on. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>