Counter ASIC 3.0 gates (hash): the v4 unit test follows the amendment (the base program is its own stream over class v3's load slots and era draw; every load site obeys the source rule)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-josh 2026-10-07 11:07:43 +01:00
parent d8859522d0
commit 4aa0c665e8

View file

@ -1739,8 +1739,9 @@ mod tests {
} }
/// Counter ASIC 3.0 (6 October 2026): class v4 is class v3 with the latency-shadow block `sh256x27`, drawn after /// Counter ASIC 3.0 (6 October 2026): class v4 is class v3 with the latency-shadow block `sh256x27`, drawn after
/// the base program, so a v4 program's base instructions, attempt and era draw are the v3 program's of the same /// the base program; since the AP-F8-1 amendment (7 October 2026) its base program draws a load's source only
/// seed and era, draw for draw; its generator is 4, its id `program_id(4, seed, attempt)`, its era recorded; /// from registers whose last writer keeps entropy, so it is its own stream over class v3's load slots and era
/// draw; its generator is 4, its id `program_id(4, seed, attempt)` with the sub-version suffix, its era recorded;
/// v2 and v3 are untouched. /// v2 and v3 are untouched.
#[test] #[test]
fn program_class_v4_is_class_v3_with_the_shadow_block() { fn program_class_v4_is_class_v3_with_the_shadow_block() {
@ -1757,9 +1758,24 @@ mod tests {
assert_eq!(v4.generator, GENERATOR_VERSION_V4); assert_eq!(v4.generator, GENERATOR_VERSION_V4);
assert_eq!(v4.program_class(), ProgramClass::V4); assert_eq!(v4.program_class(), ProgramClass::V4);
assert_eq!(v4.era_bytes.as_deref(), Some(&era[..])); assert_eq!(v4.era_bytes.as_deref(), Some(&era[..]));
assert_eq!(v4.instrs, v3.instrs, "the base program is class v3's, draw for draw"); // The AP-F8-1 amendment (7 October 2026): class v4's chain draw takes a load's source only from registers
assert_eq!(v4.attempt, v3.attempt); // whose last writer injects or rotates, so its base program is its own stream (the 6 October stream, equal
// to class v3's draw for draw, is sub-version 0 and never stamped); the load slots, the op draws and the era
// draw are still class v3's, and every load site obeys the rule
assert_eq!(v4.seed, v3.seed); assert_eq!(v4.seed, v3.seed);
assert_eq!(
v4.instrs.iter().map(|i| i.op.is_load()).collect::<Vec<_>>(),
v3.instrs.iter().map(|i| i.op.is_load()).collect::<Vec<_>>(),
"the load slots are class v3's"
);
let mut kept = [false; 8];
for (k, i) in v4.instrs.iter().enumerate() {
if i.op.is_load() {
assert!(kept[i.src as usize], "load #{k} reads r{} whose last writer does not keep entropy", i.src);
}
kept[i.dst as usize] = i.op.injects() || matches!(i.op, Op::Rotl | Op::Rotr);
}
assert_ne!(v4.instrs, v3.instrs, "the amended v4 base program is not class v3's (a lossy-sourced load was redrawn)");
assert!(v3.shadow.is_empty() && !v3.has_shadow()); assert!(v3.shadow.is_empty() && !v3.has_shadow());
assert_eq!(v4.shadow.len(), 256); assert_eq!(v4.shadow.len(), 256);
assert_eq!(v4.shadow_reps(), 27); assert_eq!(v4.shadow_reps(), 27);