Skip to main content

Module data

Module data 

Source
Expand description

DataCap — backing (immutable dense page slab) + copy-on-write overlay.

A DataCap is { backing: Arc<PageSlab>, overlay }:

  • PageSlab is the immutable backing: a dense runtime-sized vector of pages (index i is absolute page i), Arc-shared so MGMT_COPY is one refcount bump. It is not a sparse RadixMap of 2 MiB groups and not raw bytes — it is a custom SSZ page-vector whose hash_tree_root merkleizes the page roots at the exact runtime depth ceil_log2(page_count) (page_count = size / PAGE_SIZE). ssz::List<T, N> / Vector fix N at compile time; a cap’s page_count is a runtime value, so PageSlab is a bespoke type reusing [ssz::merkle::merkleize] with limit = page_count.
  • overlay is the copy-on-write working layer: the pages this cap has modified since the backing settled, keyed by absolute page index. A page present in the overlay shadows the backing; a clean cap has an empty overlay and is identical to its backing. During execution the engines write dirty pages straight into the overlay (no separate dirty-page list); at settle DataCap::flush folds the overlay into a fresh PageSlab.

Earlier drafts split this across a separate DataCap (immutable, sparse groups) and DataViewCap (backing-by-hash + overlay). They are now one type: DataViewCap == DataCap.

§The cap root (flat, size-scaled) — defined only on a flushed cap

hash_tree_root is the SSZ 2-field container { size, pages }:

cap_root   = merkleize([ htr(size), pages_root ], 2)            // depth-1 container
pages_root = merkleize([ page(0)..page(page_count) ], page_count) // = PageSlab::hash_tree_root
page_count = size / PAGE_SIZE

The cap root is only defined when the overlay is empty — the backing is the hashable, content-addressed form; the overlay is transient working state. Hashing a cap with a non-empty overlay is a usage error (it panics, like hashing a cap graph that still holds an unresolved Ref): callers flush first. The engines’ read path (page_slot / page_at) and the zero-copy slot return read effective bytes without hashing.

The pages-root tracks the cap’s actual size (depth ceil_log2(page_count)), not a fixed compile-time capacity: ≤ 256 pages (≤ 1 MiB) is shallower than depth 9; a 4 GiB cap is depth 20. size is committed in the cap’s own root (the first container field) because SSZ merkleization is not self-describing.

§Page-alignment invariant

Each present page is a PageSlot::Loaded holding a refcounted PageBytes whose bytes is a PAGE_SIZE-aligned 4 KiB slab (alloc_page_aligned_zeroed) — load-bearing because the x86 recompiler resolves each page’s physical address from its slab pointer and maps it directly into a ring-3 page table. This holds for backing and overlay pages.

Structs§

ArchivedDataCap
An archived DataCap
ArchivedPageSlab
An archived PageSlab
DataCap
Data cap: an Arc-shared immutable PageSlab backing plus a copy-on-write overlay of modified pages. The cap identity (when flushed) is the flat size-scaled { size, pages } merkle (see the module docs).
DataCapResolver
The resolver for an archived DataCap
PageSlab
The dense immutable backing of a DataCap: a custom runtime-sized SSZ vector of pages.
PageSlabResolver
The resolver for an archived PageSlab

Enums§

PageResolution
Resolution of a single page within a DataCap, shared by both engines so they materialize byte-identically.

Constants§

GROUP_PAGES
Pages per 2 MiB group (512 = 2^9). Kept as the natural large-page / 2 MiB-cluster unit (architecture-portable large page; the read-only gas materialization unit), even though storage is no longer group-chunked.
GROUP_SIZE
2 MiB span in bytes (512 * 4096 = 1 << 21).
PAGE_SIZE
Cap-level page size. Mirrors the architecture’s 4 KiB page (must match nub_arch_x86::paging::PAGE_SIZE for direct PT mapping to work).

Functions§

alloc_page_aligned_zeroed
Allocate a zero-filled Vec<u8> of len bytes (rounded up to the next page boundary) with PAGE_SIZE-aligned backing storage. Page alignment is what lets the kernel map the buffer directly into a ring-3 PT.
page_content_hash
Content hash of a single page: the SSZ hash_tree_root of the page as a ByteVector[PAGE_SIZE] (zero-padded), under the cap digest (SHA-256). This is the value a materialized page contributes to the cap merkle and the precomputed PageBytes::hash kept by the substitution invariant.