test(dao): live-stake round-trip checks decoded struct, not bytes

The first cut asserted byte-exact CBOR round-trip, but pallas-codec
emits def-arrays (`81`) while chain CBOR uses indef (`9f...ff`).
Both are Plutus-structurally-equal — validator's `==` accepts
either — but Vec<u8> equality doesn't. Switch to assert
`decode(reencode(decode(cbor)))` equals `decode(cbor)` instead.
That's the actual validator-relevant invariant: typed fields
preserved, no silent drift.
This commit is contained in:
Kayos 2026-05-06 08:53:04 -07:00
parent 6a408c319a
commit 7d440288bd

View file

@ -364,17 +364,18 @@ mod tests {
assert!(stake.delegated_to.is_none());
assert!(stake.locked_by.is_empty());
// Round-trip — encoding our decoded stake should give back the
// exact bytes we started with. This is the critical property:
// any drift in field order, integer encoding, or empty-list
// shape would break the validator's bit-exact `==` check on
// mutated stake outputs.
// Round-trip via StakeDatum. Encode our decoded stake, decode
// the result, assert the struct survives unchanged. We CAN'T
// assert byte-exact CBOR because pallas-codec emits def-encoded
// arrays while chain CBOR uses indef (`9f ... ff`) — both are
// Plutus-structurally-equal so the validator's `==` accepts
// either. The meaningful invariant is: round-trip preserves
// every typed field, no silent drift across encode/decode.
let re_encoded = pallas_codec::minicbor::to_vec(&stake.to_plutus_data().unwrap()).unwrap();
assert_eq!(
hex::encode(&re_encoded),
cbor_hex,
"round-trip CBOR diverged"
);
let re_pd: pallas_primitives::PlutusData =
pallas_codec::minicbor::decode(&re_encoded).unwrap();
let round_tripped = StakeDatum::from_plutus_data(&re_pd).expect("re-decode");
assert_eq!(round_tripped, stake, "round-trip lost a field");
}
/// Same shape as `decodes_sulkta_live_kayos_stake` but for Cobb's
@ -396,7 +397,10 @@ mod tests {
assert!(stake.locked_by.is_empty());
let re_encoded = pallas_codec::minicbor::to_vec(&stake.to_plutus_data().unwrap()).unwrap();
assert_eq!(hex::encode(&re_encoded), cbor_hex, "round-trip CBOR diverged");
let re_pd: pallas_primitives::PlutusData =
pallas_codec::minicbor::decode(&re_encoded).unwrap();
let round_tripped = StakeDatum::from_plutus_data(&re_pd).expect("re-decode");
assert_eq!(round_tripped, stake, "round-trip lost a field");
}
#[test]