pub struct Keypath { /* private fields */ }Expand description
Path identifying a storage slot.
A keypath is a sequence of length-framed components absorbed into one of
the VM’s incremental hash streams. Each call to child
appends CXS(byte_len) ‖ CXS(value): the component value CXS-encoded,
prefixed by the CXS-encoded byte length of that encoding. The storage key
is the SHA-256 of the concatenated frames; leaf storage cells derive it
once at construction and hold it as a LeafKey.
The keypath IS its midstate: it holds the VM stream that has absorbed
exactly its frames. child forks the parent’s stream — a
constant-time SHA256Copy, which is what that syscall exists for — and
absorbs only its own frame, so a shared parent prefix is absorbed once
ever; generate_key forks once more and finalizes.
No preimage bytes are kept guest-side.
The self-delimiting CXS(len) prefix makes the preimage
child(v1) ‖ child(v2) ‖ … uniquely decodable: read the length, then read
exactly that many value bytes. This holds for any value encoding —
including fixed opaque [u8; N] keys that do not self-delimit — so
distinct component sequences can never share a preimage.
Like a Hasher, a keypath is meaningful only in the current contract
invocation, so it can’t be stored. Live keypaths, user hashers, and one
transient per key derivation share the VM’s live-stream budget (the
chain’s max_sha256_buffers network config parameter); the VM refuses
streams past it and the refusing
syscall’s error is thrown. A stream absorbs at most
kSHA256BufferMaxSize (4096) preimage bytes, also VM-enforced. A single
component’s encoding is capped at the SDK’s fixed encode-buffer size.
Implementations§
Source§impl Keypath
impl Keypath
Sourcepub fn child<I: WriteXDR + ?Sized>(&self, value: &I) -> Keypath
pub fn child<I: WriteXDR + ?Sized>(&self, value: &I) -> Keypath
Child keyed by an encodable value.
Appends CXS(byte_len) ‖ CXS(value), where CXS(value) is the value’s
CXS encoding and byte_len is its byte length, also CXS-encoded (the
same compact codec, so small lengths cost a single byte). The
self-delimiting length prefix keeps the preimage uniquely decodable for
any value bytes.
A single value’s encoding is capped at the SDK’s fixed encode-buffer
size; oversized values throw LibraryExn::StorageSerialization.
Slot identity is the sequence of child values from the root: there is
no per-component “structural vs. user-key” tag, so two children of the
same node built from the same value address the same slot regardless
of intent. SDK-generated code never mixes schemes under one node (a
struct keys children by field position, a Map by user key, a Vector
by region index then element index one level down), so distinct slots
stay distinct. A hand-written From<Keypath> must uphold the same rule:
give each child of a node a distinct value.
pub fn generate_key(&self) -> StorageKey
Sourcepub fn into_key(self) -> StorageKey
pub fn into_key(self) -> StorageKey
Consume the keypath and return its storage key, finalizing its own stream directly — no transient fork.
Sourcepub fn addresses_same_slot(&self, other: &Keypath) -> bool
pub fn addresses_same_slot(&self, other: &Keypath) -> bool
Whether self and other address the same storage slot.
Slot identity is the keypath preimage; SHA-256 is collision
resistant, so equality of the derived keys decides it. The
exclusive access-mode flag is not part of slot identity.