use crate::diff::StateSnapshot;
pub const MAX_RECEIPT_FIELDS: usize = 64;
#[inline]
fn fast_fingerprint(data: &[u8]) -> [u8; 8] {
let len = data.len() as u32;
let mut lo = 0x243f_6a88_u32 ^ len;
let mut hi = 0x85a3_08d3_u32 ^ len.rotate_left(16);
let mut i = 0usize;
while i + 8 <= data.len() {
let a = u32::from_le_bytes([data[i], data[i + 1], data[i + 2], data[i + 3]]);
let b = u32::from_le_bytes([data[i + 4], data[i + 5], data[i + 6], data[i + 7]]);
lo = (lo.rotate_left(5) ^ a).wrapping_add(0x9e37_79b9);
hi = (hi.rotate_left(7) ^ b).wrapping_add(0x7f4a_7c15);
i += 8;
}
if i < data.len() {
let mut tail = [0u8; 8];
let mut tail_i = 0usize;
while i < data.len() {
tail[tail_i] = data[i];
tail_i += 1;
i += 1;
}
let a = u32::from_le_bytes([tail[0], tail[1], tail[2], tail[3]]);
let b = u32::from_le_bytes([tail[4], tail[5], tail[6], tail[7]]);
lo = lo.rotate_left(5) ^ a;
hi = hi.rotate_left(7) ^ b;
}
let mixed_lo = lo ^ hi.rotate_left(13);
let mixed_hi = hi ^ lo.rotate_left(11) ^ len;
let mut out = [0u8; 8];
out[0..4].copy_from_slice(&mixed_lo.to_le_bytes());
out[4..8].copy_from_slice(&mixed_hi.to_le_bytes());
if out == [0u8; 8] {
out[0] = 1;
}
out
}
pub struct StateReceipt<const SNAP_SIZE: usize> {
pub layout_id: [u8; 8],
snapshot: StateSnapshot<SNAP_SIZE>,
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,
committed: 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,
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FailureStage {
None = 0,
Validation = 1,
Handler = 2,
Invariant = 3,
Post = 4,
Teardown = 5,
}
impl FailureStage {
#[inline(always)]
pub fn from_tag(tag: u8) -> Self {
match tag {
1 => Self::Validation,
2 => Self::Handler,
3 => Self::Invariant,
4 => Self::Post,
5 => Self::Teardown,
_ => Self::None,
}
}
#[inline(always)]
pub fn name(self) -> &'static str {
match self {
Self::None => "none",
Self::Validation => "validation",
Self::Handler => "handler",
Self::Invariant => "invariant",
Self::Post => "post",
Self::Teardown => "teardown",
}
}
}
pub const FAILED_INVARIANT_NONE: u8 = 0xFF;
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Phase {
Update = 0,
Init = 1,
Close = 2,
Migrate = 3,
ReadOnly = 4,
}
impl Phase {
#[inline(always)]
pub fn from_tag(tag: u8) -> Self {
match tag {
1 => Self::Init,
2 => Self::Close,
3 => Self::Migrate,
4 => Self::ReadOnly,
_ => Self::Update,
}
}
#[inline(always)]
pub fn name(self) -> &'static str {
match self {
Self::Update => "Update",
Self::Init => "Init",
Self::Close => "Close",
Self::Migrate => "Migrate",
Self::ReadOnly => "ReadOnly",
}
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CompatImpact {
None = 0,
Append = 1,
Migration = 2,
Breaking = 3,
}
impl CompatImpact {
#[inline(always)]
pub fn from_tag(tag: u8) -> Self {
match tag {
1 => Self::Append,
2 => Self::Migration,
3 => Self::Breaking,
_ => Self::None,
}
}
#[inline(always)]
pub fn name(self) -> &'static str {
match self {
Self::None => "none",
Self::Append => "append",
Self::Migration => "migration",
Self::Breaking => "breaking",
}
}
}
impl<const SNAP_SIZE: usize> StateReceipt<SNAP_SIZE> {
#[inline]
pub fn begin(layout_id: &[u8; 8], data: &[u8]) -> Self {
Self {
layout_id: *layout_id,
snapshot: StateSnapshot::capture(data),
changed_fields: 0,
changed_bytes: 0,
changed_regions: 0,
was_resized: false,
old_size: data.len(),
new_size: data.len(),
invariants_passed: false,
invariants_checked: 0,
cpi_invoked: false,
committed: false,
had_failure: false,
failed_error_code: 0,
failed_invariant_idx: FAILED_INVARIANT_NONE,
failure_stage: FailureStage::None as u8,
before_fingerprint: fast_fingerprint(data),
after_fingerprint: [0; 8],
segment_changed_mask: 0,
policy_flags: 0,
journal_appends: 0,
cpi_count: 0,
phase: Phase::Update as u8,
validation_bundle_id: 0,
compat_impact: CompatImpact::None as u8,
migration_flags: 0,
}
}
#[inline]
pub fn commit(&mut self, current_data: &[u8]) {
let diff = self.snapshot.diff(current_data);
self.changed_bytes = diff.changed_byte_count();
self.was_resized = diff.was_resized();
self.new_size = current_data.len();
let regions = diff.changed_regions::<16>();
self.changed_regions = regions.len();
self.after_fingerprint = fast_fingerprint(current_data);
self.committed = true;
}
#[inline]
pub fn commit_with_fields(&mut self, current_data: &[u8], fields: &[(&str, usize, usize)]) {
self.commit(current_data);
self.changed_fields =
crate::diff::field_diff_mask(self.snapshot.data(), current_data, fields);
}
#[inline]
pub fn commit_with_segments(&mut self, current_data: &[u8], segments: &[(usize, usize)]) {
self.commit(current_data);
let snap_data = self.snapshot.data();
let mut mask: u16 = 0;
let compare_len = if snap_data.len() < current_data.len() {
snap_data.len()
} else {
current_data.len()
};
for (i, &(offset, size)) in segments.iter().enumerate() {
if i >= 16 {
break;
}
let end = offset + size;
if end <= compare_len {
if snap_data[offset..end] != current_data[offset..end] {
mask |= 1 << i;
}
} else if offset < compare_len {
mask |= 1 << i;
} else if self.was_resized {
mask |= 1 << i;
}
}
self.segment_changed_mask = mask;
}
#[inline(always)]
pub fn set_invariants(&mut self, passed: bool, checked: u16) {
self.invariants_passed = passed;
self.invariants_checked = checked;
}
#[inline(always)]
pub fn set_invariants_passed(&mut self, passed: bool) {
self.invariants_passed = passed;
}
#[inline(always)]
pub fn set_cpi_invoked(&mut self, invoked: bool) {
self.cpi_invoked = invoked;
}
#[inline(always)]
pub fn set_cpi_count(&mut self, count: u8) {
self.cpi_count = count;
self.cpi_invoked = count > 0;
}
#[inline(always)]
pub fn set_policy_flags(&mut self, flags: u32) {
self.policy_flags = flags;
}
#[inline(always)]
pub fn set_journal_appends(&mut self, count: u16) {
self.journal_appends = count;
}
#[inline(always)]
pub fn set_phase(&mut self, phase: Phase) {
self.phase = phase as u8;
}
#[inline(always)]
pub fn set_validation_bundle_id(&mut self, id: u16) {
self.validation_bundle_id = id;
}
#[inline(always)]
pub fn set_compat_impact(&mut self, impact: CompatImpact) {
self.compat_impact = impact as u8;
}
#[inline(always)]
pub fn set_migration_flags(&mut self, flags: u8) {
self.migration_flags = flags;
}
#[inline]
pub fn set_failure(&mut self, code: u32, invariant_idx: u8, stage: FailureStage) {
self.had_failure = true;
self.failed_error_code = code;
self.failed_invariant_idx = invariant_idx;
self.failure_stage = stage as u8;
self.invariants_passed = false;
}
#[inline]
pub fn set_invariant_failure(&mut self, code: u32, invariant_idx: u8) {
self.set_failure(code, invariant_idx, FailureStage::Invariant);
}
#[inline(always)]
pub fn is_committed(&self) -> bool {
self.committed
}
#[inline(always)]
pub fn has_changes(&self) -> bool {
self.changed_bytes > 0 || self.was_resized
}
#[inline(always)]
pub fn fingerprint_changed(&self) -> bool {
self.before_fingerprint != self.after_fingerprint
}
#[inline]
pub fn to_bytes(&self) -> [u8; RECEIPT_SIZE] {
let mut out = [0u8; RECEIPT_SIZE];
out[0..8].copy_from_slice(&self.layout_id);
out[8..16].copy_from_slice(&self.changed_fields.to_le_bytes());
out[16..20].copy_from_slice(&(self.changed_bytes as u32).to_le_bytes());
out[20..22].copy_from_slice(&(self.changed_regions as u16).to_le_bytes());
out[22..26].copy_from_slice(&(self.old_size as u32).to_le_bytes());
out[26..30].copy_from_slice(&(self.new_size as u32).to_le_bytes());
out[30..32].copy_from_slice(&self.invariants_checked.to_le_bytes());
let mut flags: u8 = 0;
if self.was_resized {
flags |= 1 << 0;
}
if self.invariants_passed {
flags |= 1 << 1;
}
if self.cpi_invoked {
flags |= 1 << 2;
}
if self.committed {
flags |= 1 << 3;
}
if self.had_failure {
flags |= 1 << 4;
}
out[32] = flags;
out[33..41].copy_from_slice(&self.before_fingerprint);
out[41..49].copy_from_slice(&self.after_fingerprint);
out[49..51].copy_from_slice(&self.segment_changed_mask.to_le_bytes());
out[51..55].copy_from_slice(&self.policy_flags.to_le_bytes());
out[55..57].copy_from_slice(&self.journal_appends.to_le_bytes());
out[57] = self.cpi_count;
out[58] = self.phase;
out[59..61].copy_from_slice(&self.validation_bundle_id.to_le_bytes());
out[61] = self.compat_impact;
out[62] = self.migration_flags;
out[63] = self.failed_invariant_idx;
out[64..68].copy_from_slice(&self.failed_error_code.to_le_bytes());
out[68] = self.failure_stage;
out
}
}
pub const RECEIPT_SIZE: usize = 72;
pub const RECEIPT_SIZE_LEGACY: usize = 64;
pub struct DecodedReceipt {
pub layout_id: [u8; 8],
pub changed_fields: u64,
pub changed_bytes: u32,
pub changed_regions: u16,
pub old_size: u32,
pub new_size: u32,
pub invariants_checked: u16,
pub was_resized: bool,
pub invariants_passed: bool,
pub cpi_invoked: bool,
pub committed: bool,
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,
pub had_failure: bool,
pub failed_error_code: u32,
pub failed_invariant_idx: u8,
pub failure_stage: u8,
}
impl DecodedReceipt {
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
if bytes.len() < RECEIPT_SIZE_LEGACY {
return None;
}
let mut layout_id = [0u8; 8];
layout_id.copy_from_slice(&bytes[0..8]);
let changed_fields = u64::from_le_bytes([
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
]);
let changed_bytes = u32::from_le_bytes([bytes[16], bytes[17], bytes[18], bytes[19]]);
let changed_regions = u16::from_le_bytes([bytes[20], bytes[21]]);
let old_size = u32::from_le_bytes([bytes[22], bytes[23], bytes[24], bytes[25]]);
let new_size = u32::from_le_bytes([bytes[26], bytes[27], bytes[28], bytes[29]]);
let invariants_checked = u16::from_le_bytes([bytes[30], bytes[31]]);
let flags = bytes[32];
let was_resized = flags & (1 << 0) != 0;
let invariants_passed = flags & (1 << 1) != 0;
let cpi_invoked = flags & (1 << 2) != 0;
let committed = flags & (1 << 3) != 0;
let had_failure = flags & (1 << 4) != 0;
let mut before_fingerprint = [0u8; 8];
before_fingerprint.copy_from_slice(&bytes[33..41]);
let mut after_fingerprint = [0u8; 8];
after_fingerprint.copy_from_slice(&bytes[41..49]);
let segment_changed_mask = u16::from_le_bytes([bytes[49], bytes[50]]);
let policy_flags = u32::from_le_bytes([bytes[51], bytes[52], bytes[53], bytes[54]]);
let journal_appends = u16::from_le_bytes([bytes[55], bytes[56]]);
let cpi_count = bytes[57];
let phase = bytes[58];
let validation_bundle_id = u16::from_le_bytes([bytes[59], bytes[60]]);
let compat_impact = bytes[61];
let migration_flags = bytes[62];
let (failed_invariant_idx, failed_error_code, failure_stage) =
if bytes.len() >= RECEIPT_SIZE {
let idx = bytes[63];
let code = u32::from_le_bytes([bytes[64], bytes[65], bytes[66], bytes[67]]);
let stage = bytes[68];
(idx, code, stage)
} else {
(FAILED_INVARIANT_NONE, 0u32, FailureStage::None as u8)
};
Some(Self {
layout_id,
changed_fields,
changed_bytes,
changed_regions,
old_size,
new_size,
invariants_checked,
was_resized,
invariants_passed,
cpi_invoked,
committed,
before_fingerprint,
after_fingerprint,
segment_changed_mask,
policy_flags,
journal_appends,
cpi_count,
phase,
validation_bundle_id,
compat_impact,
migration_flags,
had_failure,
failed_error_code,
failed_invariant_idx,
failure_stage,
})
}
#[inline(always)]
pub fn failure_stage_enum(&self) -> FailureStage {
FailureStage::from_tag(self.failure_stage)
}
#[inline(always)]
pub fn has_changes(&self) -> bool {
self.changed_bytes > 0 || self.was_resized
}
#[inline(always)]
pub fn fingerprint_changed(&self) -> bool {
self.before_fingerprint != self.after_fingerprint
}
#[inline(always)]
pub fn phase_enum(&self) -> Phase {
Phase::from_tag(self.phase)
}
#[inline(always)]
pub fn compat_impact_enum(&self) -> CompatImpact {
CompatImpact::from_tag(self.compat_impact)
}
pub fn explain(&self) -> ReceiptExplain {
let phase = self.phase_enum();
let compat = self.compat_impact_enum();
let mutation_desc = if !self.has_changes() {
"No mutations detected"
} else if self.was_resized {
"Account was resized"
} else {
"Account data modified in-place"
};
let integrity_desc = if self.had_failure {
match self.failure_stage_enum() {
FailureStage::Invariant => "INVARIANT FAILED. execution aborted",
FailureStage::Validation => "Account validation failed. execution aborted",
FailureStage::Handler => "Handler aborted before invariant evaluation",
FailureStage::Post => "Failure during receipt commit path",
FailureStage::Teardown => "Failure during close/teardown",
FailureStage::None => "FAILURE flagged without stage (malformed receipt)",
}
} else if !self.committed {
"Receipt was NOT committed (incomplete)"
} else if self.invariants_passed && self.invariants_checked > 0 {
"All invariants passed"
} else if self.invariants_checked > 0 {
"INVARIANT VIOLATION detected"
} else {
"No invariants checked"
};
let cpi_desc = if self.cpi_invoked {
"CPI was invoked during execution"
} else {
"No CPI calls"
};
ReceiptExplain {
phase_name: phase.name(),
compat_label: compat.name(),
policy_name: "unknown",
mutation_summary: mutation_desc,
integrity_summary: integrity_desc,
cpi_summary: cpi_desc,
changed_field_count: self.changed_fields.count_ones() as u16,
segment_count: self.segment_changed_mask.count_ones() as u8,
fingerprint_changed: self.fingerprint_changed(),
segment_role_names: [""; 8],
segment_role_count: 0,
}
}
}
pub struct ReceiptExplain {
pub phase_name: &'static str,
pub compat_label: &'static str,
pub policy_name: &'static str,
pub mutation_summary: &'static str,
pub integrity_summary: &'static str,
pub cpi_summary: &'static str,
pub changed_field_count: u16,
pub segment_count: u8,
pub fingerprint_changed: bool,
pub segment_role_names: [&'static str; 8],
pub segment_role_count: u8,
}
impl ReceiptExplain {
#[inline]
pub const fn with_policy_name(mut self, name: &'static str) -> Self {
self.policy_name = name;
self
}
#[inline]
pub const fn with_segment_role(mut self, idx: u8, name: &'static str) -> Self {
if (idx as usize) < 8 {
self.segment_role_names[idx as usize] = name;
if idx >= self.segment_role_count {
self.segment_role_count = idx + 1;
}
}
self
}
#[inline]
pub const fn summary(&self) -> &'static str {
if !crate::const_str_eq(self.phase_name, "Update")
&& !crate::const_str_eq(self.phase_name, "Init")
&& !crate::const_str_eq(self.phase_name, "Close")
&& !crate::const_str_eq(self.phase_name, "Migrate")
{
return "Read-only operation, no state changes";
}
if crate::const_str_eq(self.phase_name, "Init") {
return "Account initialized";
}
if crate::const_str_eq(self.phase_name, "Close") {
return "Account closed";
}
if crate::const_str_eq(self.phase_name, "Migrate") {
if self.fingerprint_changed {
return "Migration applied, layout fingerprint updated";
}
return "Migration applied";
}
if !self.fingerprint_changed && self.changed_field_count == 0 {
return "Update executed with no observable state changes";
}
if self.fingerprint_changed && self.changed_field_count > 0 && self.segment_count > 1 {
return "State mutated across multiple segments with fingerprint change";
}
if self.fingerprint_changed && self.changed_field_count > 0 {
return "State mutated with fingerprint change";
}
if self.fingerprint_changed {
return "Fingerprint changed without field-level mutations";
}
if self.changed_field_count > 0 && self.segment_count > 1 {
return "State mutated across multiple segments";
}
if self.changed_field_count > 0 {
return "State mutated";
}
"Update completed"
}
}
pub struct ReceiptNarrative {
pub fragments: [&'static str; 8],
pub count: u8,
pub risk_level: NarrativeRisk,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum NarrativeRisk {
None = 0,
Low = 1,
Medium = 2,
High = 3,
Critical = 4,
}
impl NarrativeRisk {
pub const fn name(self) -> &'static str {
match self {
Self::None => "none",
Self::Low => "low",
Self::Medium => "medium",
Self::High => "high",
Self::Critical => "critical",
}
}
}
impl core::fmt::Display for NarrativeRisk {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(self.name())
}
}
impl ReceiptNarrative {
pub fn from_explain(explain: &ReceiptExplain) -> Self {
let mut frags: [&'static str; 8] = [""; 8];
let mut n = 0u8;
let mut risk = NarrativeRisk::None;
let phase_frag = match explain.phase_name {
"Init" => "Account was initialized.",
"Close" => "Account was closed.",
"Migrate" => "Migration was applied to the account.",
"ReadOnly" => "Read-only operation executed.",
_ => "State mutation executed.",
};
if n < 8 {
frags[n as usize] = phase_frag;
n += 1;
}
if explain.changed_field_count > 0 {
risk = NarrativeRisk::Low;
if explain.segment_count > 1 {
if n < 8 {
frags[n as usize] = "Changes span multiple segments.";
n += 1;
}
}
}
if explain.fingerprint_changed {
if n < 8 {
frags[n as usize] = "Layout fingerprint changed.";
n += 1;
}
if risk as u8 == NarrativeRisk::Low as u8 {
risk = NarrativeRisk::Medium;
}
}
match explain.compat_label {
"Append" => {
if n < 8 {
frags[n as usize] = "Append-safe extension applied.";
n += 1;
}
}
"Migration" => {
if n < 8 {
frags[n as usize] = "Migration-level change detected.";
n += 1;
}
risk = NarrativeRisk::High;
}
"Breaking" => {
if n < 8 {
frags[n as usize] = "Breaking compatibility change.";
n += 1;
}
risk = NarrativeRisk::High;
}
_ => {}
}
if !crate::const_str_eq(explain.cpi_summary, "No CPI calls") {
if n < 8 {
frags[n as usize] = "Cross-program invocation occurred.";
n += 1;
}
}
if crate::const_str_eq(explain.integrity_summary, "INVARIANT VIOLATION detected") {
if n < 8 {
frags[n as usize] = "INVARIANT VIOLATION: post-mutation checks failed.";
n += 1;
}
risk = NarrativeRisk::Critical;
}
if crate::const_str_eq(
explain.integrity_summary,
"Receipt was NOT committed (incomplete)",
) {
if n < 8 {
frags[n as usize] = "Receipt was not committed. Mutation may be incomplete.";
n += 1;
}
risk = NarrativeRisk::Critical;
}
if explain.segment_role_count > 0 {
let mut i = 0u8;
while i < explain.segment_role_count && i < 8 {
let role = explain.segment_role_names[i as usize];
if crate::const_str_eq(role, "audit") || crate::const_str_eq(role, "Audit") {
if n < 8 {
frags[n as usize] = "Audit segment was touched.";
n += 1;
}
}
i += 1;
}
}
if crate::const_str_eq(explain.phase_name, "Migrate") {
if (risk as u8) < NarrativeRisk::High as u8 {
risk = NarrativeRisk::High;
}
}
Self {
fragments: frags,
count: n,
risk_level: risk,
}
}
}
impl core::fmt::Display for ReceiptNarrative {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut i = 0u8;
while i < self.count {
if i > 0 {
write!(f, " ")?;
}
write!(f, "{}", self.fragments[i as usize])?;
i += 1;
}
write!(f, " [risk: {}]", self.risk_level.name())
}
}