Expand description
RAII-leased typed segment guards.
The Hopper Safety Audit called out that SegmentBorrowRegistry was
being used as an instruction-sticky ledger: every segment_ref /
segment_mut call appended an entry, nothing ever released, and the
entries outlived the returned Ref<T> / RefMut<T> for the rest of
the instruction. That model makes legitimate sequential patterns
like
{ let mut b = ctx.segment_mut::<WireU64>(0, BAL)?; *b += amount; }
{ let mut b = ctx.segment_mut::<WireU64>(0, BAL)?; *b += more; }impossible inside one instruction, because the second call would collide with the lingering entry from the first.
SegmentLease, SegRef, and SegRefMut replace that model
with real RAII: the registry entry lives exactly as long as the
returned typed guard, and dropping the guard releases the entry.
Sequential non-overlapping (and sequential same-region-read-then-
write) patterns now behave exactly the way Rust borrowers expect.
§Representation
SegmentLease stores a raw pointer to the registry plus a
PhantomData<&'a mut SegmentBorrowRegistry>. Raw is necessary
because the returned SegRef<T> otherwise exclusively borrows the
whole Context, which would prevent even reading another account
, a regression far worse than the sticky behavior we are fixing.
The PhantomData ties the lease’s lifetime to the registry’s, so
use-after-free is impossible at the type level. Drop performs a
single swap-remove; no allocation, no heap touch.
§Why a wrapper, not a field on Ref/RefMut
The canonical hopper_runtime::Ref / RefMut are kept flat on
Solana ({ptr, state_ptr} = 2 words, see borrow.rs). Adding a
registry pointer to them would re-inflate the flat representation
for every access path, even the whole-account load() path that
doesn’t touch the segment registry. Keeping the lease as a separate
wrapper means load() stays at 2 words and only segment access
pays for the lease (one extra pointer-word on Solana).
Structs§
- SegRef
- Shared typed segment guard: a
Ref<T>paired with aSegmentLeasethat releases the registry entry on drop. - SegRef
Mut - Exclusive typed segment guard.
- Segment
Lease - RAII lease on one registered entry in a
SegmentBorrowRegistry.