pub struct StateReceipt<const SNAP_SIZE: usize> {Show 24 fields
pub layout_id: [u8; 8],
pub changed_fields: u64,
pub changed_bytes: usize,
pub changed_regions: usize,
pub was_resized: bool,
pub old_size: usize,
pub new_size: usize,
pub invariants_passed: bool,
pub invariants_checked: u16,
pub cpi_invoked: bool,
pub had_failure: bool,
pub failed_error_code: u32,
pub failed_invariant_idx: u8,
pub failure_stage: u8,
pub before_fingerprint: [u8; 8],
pub after_fingerprint: [u8; 8],
pub segment_changed_mask: u16,
pub policy_flags: u32,
pub journal_appends: u16,
pub cpi_count: u8,
pub phase: u8,
pub validation_bundle_id: u16,
pub compat_impact: u8,
pub migration_flags: u8,
/* private fields */
}Expand description
A structured record of a state mutation.
SNAP_SIZE is the maximum snapshot size (stack-allocated).
Fields§
§layout_id: [u8; 8]Layout ID of the account being mutated.
changed_fields: u64Field-level change bitmask (bit N = field N changed).
changed_bytes: usizeNumber of bytes that changed.
changed_regions: usizeNumber of changed regions (contiguous runs).
was_resized: boolWhether the account was resized.
old_size: usizeOld account data length.
new_size: usizeNew account data length.
invariants_passed: boolWhether all invariants passed after mutation.
invariants_checked: u16Number of invariants checked.
cpi_invoked: boolWhether CPI was invoked during the instruction.
had_failure: boolWhether execution hit a failure path.
When true, failed_error_code, failed_invariant_idx, and
failure_stage identify the failing check. This closes the
provable-safety chain: a receipt that escapes the program
carries enough information for the off-chain SDK to render
“Invariant balance_nonzero failed” instead of an opaque hex code.
failed_error_code: u32User error code that aborted execution (e.g. VaultError::InsufficientBalance as u32).
0 when had_failure is false.
failed_invariant_idx: u8Index into the program’s INVARIANT_TABLE for the failing invariant.
0xFF means “no invariant was the cause”. the failure happened
outside an invariant check (e.g. a constraint guard).
failure_stage: u8Stage at which the failure occurred. See FailureStage.
before_fingerprint: [u8; 8]FNV-1a fingerprint of the data before mutation.
after_fingerprint: [u8; 8]FNV-1a fingerprint of the data after mutation (set on commit).
segment_changed_mask: u16Bitmask of which segments were touched (bit N = segment N changed).
policy_flags: u32CapabilitySet bits describing what this instruction does.
journal_appends: u16Number of journal entries appended during this instruction.
cpi_count: u8Number of CPI calls made during this instruction.
phase: u8Instruction phase tag (see Phase).
validation_bundle_id: u16Validation bundle identifier (program-defined).
compat_impact: u8Compatibility impact of this mutation (see CompatImpact).
migration_flags: u8Migration flags (bit 0 = triggered, bit 1 = realloc, bit 2 = schema bump).
Implementations§
Source§impl<const SNAP_SIZE: usize> StateReceipt<SNAP_SIZE>
impl<const SNAP_SIZE: usize> StateReceipt<SNAP_SIZE>
Sourcepub fn begin(layout_id: &[u8; 8], data: &[u8]) -> Self
pub fn begin(layout_id: &[u8; 8], data: &[u8]) -> Self
Begin recording a state receipt.
Captures a before-snapshot and fingerprint of the account data.
Sourcepub fn commit(&mut self, current_data: &[u8])
pub fn commit(&mut self, current_data: &[u8])
Commit the receipt by providing post-mutation data.
Computes the diff and after-fingerprint.
Sourcepub fn commit_with_fields(
&mut self,
current_data: &[u8],
fields: &[(&str, usize, usize)],
)
pub fn commit_with_fields( &mut self, current_data: &[u8], fields: &[(&str, usize, usize)], )
Commit with field-level tracking.
fields is (name, offset, size) per layout field.
Sets the changed_fields bitmask based on which fields actually changed.
Sourcepub fn commit_with_segments(
&mut self,
current_data: &[u8],
segments: &[(usize, usize)],
)
pub fn commit_with_segments( &mut self, current_data: &[u8], segments: &[(usize, usize)], )
Commit with segment-level tracking.
segments is (offset, size) per segment in the account.
Sets segment_changed_mask based on which segments have byte changes.
Sourcepub fn set_invariants(&mut self, passed: bool, checked: u16)
pub fn set_invariants(&mut self, passed: bool, checked: u16)
Set invariant results.
Sourcepub fn set_invariants_passed(&mut self, passed: bool)
pub fn set_invariants_passed(&mut self, passed: bool)
Set invariant pass status (convenience).
Sourcepub fn set_cpi_invoked(&mut self, invoked: bool)
pub fn set_cpi_invoked(&mut self, invoked: bool)
Mark that CPI was invoked during this instruction.
Sourcepub fn set_cpi_count(&mut self, count: u8)
pub fn set_cpi_count(&mut self, count: u8)
Set the number of CPI calls made. Also sets cpi_invoked if count > 0.
Sourcepub fn set_policy_flags(&mut self, flags: u32)
pub fn set_policy_flags(&mut self, flags: u32)
Set the policy/capability flags for this instruction.
Pass CapabilitySet::bits() to record which capabilities were active.
Sourcepub fn set_journal_appends(&mut self, count: u16)
pub fn set_journal_appends(&mut self, count: u16)
Set the number of journal entries appended during this instruction.
Sourcepub fn set_validation_bundle_id(&mut self, id: u16)
pub fn set_validation_bundle_id(&mut self, id: u16)
Set the validation bundle identifier.
Sourcepub fn set_compat_impact(&mut self, impact: CompatImpact)
pub fn set_compat_impact(&mut self, impact: CompatImpact)
Set the compatibility impact level.
Sourcepub fn set_migration_flags(&mut self, flags: u8)
pub fn set_migration_flags(&mut self, flags: u8)
Set migration flags (bit 0 = triggered, bit 1 = realloc, bit 2 = schema bump).
Sourcepub fn set_failure(&mut self, code: u32, invariant_idx: u8, stage: FailureStage)
pub fn set_failure(&mut self, code: u32, invariant_idx: u8, stage: FailureStage)
Record a failing error code, its associated invariant index (if any), and the stage at which the failure occurred.
This is the hook that closes the invariant-error chain: when an
instruction aborts, the program writes the actual user error
code (from the #[hopper::error]-derived enum) and the invariant
index (from INVARIANT_TABLE) into the receipt before emitting
it. The off-chain SDK can then map the code back to a variant name
and the idx to an invariant label without ever guessing.
Pass FAILED_INVARIANT_NONE for invariant_idx when the failure
did not come from an invariant check (for example a constraint
guard or an account validation failure).
Sourcepub fn set_invariant_failure(&mut self, code: u32, invariant_idx: u8)
pub fn set_invariant_failure(&mut self, code: u32, invariant_idx: u8)
Convenience: record a failure caused by a specific invariant index.
Sourcepub fn is_committed(&self) -> bool
pub fn is_committed(&self) -> bool
Whether the receipt has been committed.
Sourcepub fn has_changes(&self) -> bool
pub fn has_changes(&self) -> bool
Whether any data actually changed.
Sourcepub fn fingerprint_changed(&self) -> bool
pub fn fingerprint_changed(&self) -> bool
Whether the before and after fingerprints differ.
Sourcepub fn to_bytes(&self) -> [u8; 72]
pub fn to_bytes(&self) -> [u8; 72]
Serialize the receipt summary into a fixed-size byte array.
Wire format (72 bytes, 8-byte aligned):
[layout_id: 8 bytes] // 0.. 8
[changed_fields: 8 bytes (u64 LE)] // 8..16
[changed_bytes: 4 bytes (u32 LE)] // 16..20
[changed_regions: 2 bytes (u16 LE)] // 20..22
[old_size: 4 bytes (u32 LE)] // 22..26
[new_size: 4 bytes (u32 LE)] // 26..30
[invariants_checked: 2 bytes (u16 LE)]// 30..32
[flags: 1 byte] // 32
bit 0: was_resized
bit 1: invariants_passed
bit 2: cpi_invoked
bit 3: committed
bit 4: had_failure
[before_fingerprint: 8 bytes] // 33..41
[after_fingerprint: 8 bytes] // 41..49
[segment_changed_mask: 2 bytes (u16)] // 49..51
[policy_flags: 4 bytes (u32 LE)] // 51..55
[journal_appends: 2 bytes (u16 LE)] // 55..57
[cpi_count: 1 byte] // 57
[phase: 1 byte] // 58
[validation_bundle_id: 2 bytes (u16)] // 59..61
[compat_impact: 1 byte] // 61
[migration_flags: 1 byte] // 62
[failed_invariant_idx: 1 byte] // 63 (0xFF = none)
[failed_error_code: 4 bytes (u32 LE)] // 64..68 (0 = none)
[failure_stage: 1 byte] // 68 (see FailureStage)
[_reserved: 3 bytes] // 69..72 (future)Pre-0.2 decoders that stopped at byte 64 still read correctly: the first 64 bytes carry exactly the same fields they always did, plus one new flag bit and one new idx byte that old parsers can safely ignore.