Skip to content

Commit 8c940bc

Browse files
test(TasmStruct::destructure): Add test cases
Co-authored-by: sword-smith <[email protected]>
1 parent 3af418a commit 8c940bc

File tree

2 files changed

+136
-31
lines changed

2 files changed

+136
-31
lines changed

tasm-lib/src/neptune/neptune_like_types_for_tests.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,43 +49,43 @@ pub(crate) struct CollectTypeScriptsWitnessLookalike {
4949
salted_output_utxos: SaltedUtxosLookalike,
5050
}
5151

52-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
52+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
5353
pub(crate) struct NeptuneCoinsLookalike(u128);
5454

55-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
55+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
5656
pub(crate) struct ChunkLookalike {
5757
pub relative_indices: Vec<u32>,
5858
}
5959

60-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
60+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
6161
pub(crate) struct ChunkDictionaryLookalike {
6262
dictionary: Vec<(u64, (MmrMembershipProof, ChunkLookalike))>,
6363
}
6464

6565
const NUM_TRIALS_LOOKALIKE: usize = 45;
66-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
66+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
6767
pub(crate) struct AbsoluteIndexSetLookalike([u128; NUM_TRIALS_LOOKALIKE]);
6868

69-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
69+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
7070
pub(crate) struct RemovalRecordLookalike {
7171
pub absolute_indices: AbsoluteIndexSetLookalike,
7272
pub target_chunks: ChunkDictionaryLookalike,
7373
}
7474

75-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
75+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
7676
pub(crate) struct AdditionRecordLookalike {
7777
pub canonical_commitment: Digest,
7878
}
7979

80-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
80+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
8181
pub(crate) struct PublicAnnouncementLookalike {
8282
pub message: Vec<BFieldElement>,
8383
}
8484

85-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
85+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
8686
pub(crate) struct TimestampLookalike(pub(crate) BFieldElement);
8787

88-
#[derive(Debug, Clone, TasmObject, BFieldCodec, Arbitrary)]
88+
#[derive(Debug, Clone, Eq, PartialEq, TasmObject, BFieldCodec, Arbitrary)]
8989
pub(crate) struct TransactionKernelLookalike {
9090
pub inputs: Vec<RemovalRecordLookalike>,
9191

@@ -142,27 +142,27 @@ pub(crate) struct RemovalRecordsIntegrityWitnessLookalike {
142142
mast_root: Digest,
143143
}
144144

145-
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
145+
#[derive(Debug, Clone, Eq, PartialEq, BFieldCodec, TasmObject, Arbitrary)]
146146
pub(crate) struct MmrSuccessorProofLookalike {
147147
pub paths: Vec<Digest>,
148148
}
149149

150-
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
150+
#[derive(Debug, Clone, Eq, PartialEq, BFieldCodec, TasmObject, Arbitrary)]
151151
pub(crate) struct UpdateWitnessLookalike {
152-
old_kernel: TransactionKernelLookalike,
153-
new_kernel: TransactionKernelLookalike,
154-
old_kernel_mast_hash: Digest,
155-
new_kernel_mast_hash: Digest,
156-
old_proof: Proof,
157-
new_swbfi_bagged: Digest,
158-
new_aocl: MmrAccumulator,
159-
new_swbfa_hash: Digest,
160-
old_swbfi_bagged: Digest,
161-
old_aocl: MmrAccumulator,
162-
old_swbfa_hash: Digest,
163-
aocl_successor_proof: MmrSuccessorProofLookalike,
164-
outputs_hash: Digest,
165-
public_announcements_hash: Digest,
152+
pub old_kernel: TransactionKernelLookalike,
153+
pub new_kernel: TransactionKernelLookalike,
154+
pub old_kernel_mast_hash: Digest,
155+
pub new_kernel_mast_hash: Digest,
156+
pub old_proof: Proof,
157+
pub new_swbfi_bagged: Digest,
158+
pub new_aocl: MmrAccumulator,
159+
pub new_swbfa_hash: Digest,
160+
pub old_swbfi_bagged: Digest,
161+
pub old_aocl: MmrAccumulator,
162+
pub old_swbfa_hash: Digest,
163+
pub aocl_successor_proof: MmrSuccessorProofLookalike,
164+
pub outputs_hash: Digest,
165+
pub public_announcements_hash: Digest,
166166
}
167167

168168
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]

tasm-lib/src/structure/tasm_object.rs

Lines changed: 111 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,10 @@ mod tests {
939939
#[cfg(test)]
940940
mod destructure {
941941
use super::*;
942+
use crate::neptune::neptune_like_types_for_tests::MmrSuccessorProofLookalike;
943+
use crate::neptune::neptune_like_types_for_tests::TransactionKernelLookalike;
944+
use crate::neptune::neptune_like_types_for_tests::UpdateWitnessLookalike;
945+
use crate::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator;
942946

943947
#[test]
944948
fn unit_struct() {
@@ -967,6 +971,9 @@ mod tests {
967971
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
968972
struct TupleDynamic(Vec<u32>);
969973

974+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
975+
struct TupleNested(Vec<Vec<u32>>);
976+
970977
#[derive(Debug, Copy, Clone, BFieldCodec, TasmObject, Arbitrary)]
971978
struct NamedStatic {
972979
field: u32,
@@ -977,9 +984,14 @@ mod tests {
977984
field: Vec<u32>,
978985
}
979986

987+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
988+
struct NamedNested {
989+
field: Vec<Vec<u32>>,
990+
}
991+
980992
// This macro is a little bit cursed due to the `$post_process`. Since it is
981993
// very limited in scope, I say it's better than duplicating essentially the
982-
// same code four times. If you want to extend the scope of this macro, please
994+
// same code six times. If you want to extend the scope of this macro, please
983995
// re-design it.
984996
macro_rules! one_field_test_case {
985997
(fn $test_name:ident for $ty:ident: $f_name:tt $($post_process:tt)*) => {
@@ -998,8 +1010,8 @@ mod tests {
9981010
let mut non_determinism = NonDeterminism::default();
9991011
encode_to_memory(&mut non_determinism.ram, ptr, &foo);
10001012

1001-
let output = VM::run(program, PublicInput::default(), non_determinism);
1002-
let [output] = output.unwrap()[..] else {
1013+
let output = VM::run(program, PublicInput::default(), non_determinism)?;
1014+
let [output] = output[..] else {
10031015
return Err(TestCaseError::Fail("unexpected output".into()));
10041016
};
10051017

@@ -1012,8 +1024,10 @@ mod tests {
10121024

10131025
one_field_test_case!( fn tuple_static for TupleStatic: 0 );
10141026
one_field_test_case!( fn tuple_dynamic for TupleDynamic: 0.len() );
1027+
one_field_test_case!( fn tuple_nested for TupleNested: 0.len() );
10151028
one_field_test_case!( fn named_static for NamedStatic: field );
10161029
one_field_test_case!( fn named_dynamic for NamedDynamic: field.len() );
1030+
one_field_test_case!( fn named_nested for NamedNested: field.len() );
10171031
}
10181032

10191033
mod two_fields {
@@ -1031,6 +1045,15 @@ mod tests {
10311045
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
10321046
struct TupleDynDyn(Vec<u32>, Vec<u32>);
10331047

1048+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
1049+
struct TupleStatNest(u32, Vec<Vec<u32>>);
1050+
1051+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
1052+
struct TupleNestStat(Vec<Vec<u32>>, u32);
1053+
1054+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
1055+
struct TupleNestNest(Vec<Vec<u32>>, Vec<Vec<u32>>);
1056+
10341057
#[derive(Debug, Copy, Clone, BFieldCodec, TasmObject, Arbitrary)]
10351058
struct NamedStatStat {
10361059
a: u32,
@@ -1055,9 +1078,27 @@ mod tests {
10551078
b: Vec<u32>,
10561079
}
10571080

1081+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
1082+
struct NamedStatNest {
1083+
a: u32,
1084+
b: Vec<Vec<u32>>,
1085+
}
1086+
1087+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
1088+
struct NamedNestStat {
1089+
a: Vec<Vec<u32>>,
1090+
b: u32,
1091+
}
1092+
1093+
#[derive(Debug, Clone, BFieldCodec, TasmObject, Arbitrary)]
1094+
struct NamedNestNest {
1095+
a: Vec<Vec<u32>>,
1096+
b: Vec<Vec<u32>>,
1097+
}
1098+
10581099
// This macro is a little bit cursed due to the `$post_process`es. Since it is
10591100
// very limited in scope, I say it's better than duplicating essentially the
1060-
// same code eight times. If you want to extend the scope of this macro, please
1101+
// same code 14 times. If you want to extend the scope of this macro, please
10611102
// re-design it.
10621103
macro_rules! two_fields_test_case {
10631104
(fn $test_name:ident for $ty:ident:
@@ -1080,8 +1121,8 @@ mod tests {
10801121
let mut non_determinism = NonDeterminism::default();
10811122
encode_to_memory(&mut non_determinism.ram, ptr, &foo);
10821123

1083-
let output = VM::run(program, PublicInput::default(), non_determinism);
1084-
let [output_0, output_1] = output.unwrap()[..] else {
1124+
let output = VM::run(program, PublicInput::default(), non_determinism)?;
1125+
let [output_0, output_1] = output[..] else {
10851126
return Err(TestCaseError::Fail("unexpected output".into()));
10861127
};
10871128

@@ -1098,10 +1139,16 @@ mod tests {
10981139
two_fields_test_case!( fn tuple_stat_dyn for TupleStatDyn: (0) (1.len()) );
10991140
two_fields_test_case!( fn tuple_dyn_stat for TupleDynStat: (0.len()) (1) );
11001141
two_fields_test_case!( fn tuple_dyn_dyn for TupleDynDyn: (0.len()) (1.len()) );
1142+
two_fields_test_case!( fn tuple_stat_nest for TupleStatNest: (0) (1.len()) );
1143+
two_fields_test_case!( fn tuple_nest_stat for TupleNestStat: (0.len()) (1) );
1144+
two_fields_test_case!( fn tuple_nest_nest for TupleNestNest: (0.len()) (1.len()) );
11011145
two_fields_test_case!( fn named_stat_stat for NamedStatStat: (a) (b) );
11021146
two_fields_test_case!( fn named_stat_dyn for NamedStatDyn: (a) (b.len()) );
11031147
two_fields_test_case!( fn named_dyn_stat for NamedDynStat: (a.len()) (b) );
11041148
two_fields_test_case!( fn named_dyn_dyn for NamedDynDyn: (a.len()) (b.len()) );
1149+
two_fields_test_case!( fn named_stat_nest for NamedStatNest: (a) (b.len()) );
1150+
two_fields_test_case!( fn named_nest_stat for NamedNestStat: (a.len()) (b) );
1151+
two_fields_test_case!( fn named_nest_nest for NamedNestNest: (a.len()) (b.len()) );
11051152
}
11061153

11071154
#[test]
@@ -1165,6 +1212,64 @@ mod tests {
11651212
let foo_again = Foo { a, b, c, d, e };
11661213
assert_eq!(foo, foo_again);
11671214
}
1215+
1216+
#[proptest]
1217+
fn destructure_update_witness(
1218+
#[strategy(arb())] witness: UpdateWitnessLookalike,
1219+
#[strategy(arb())] witness_ptr: BFieldElement,
1220+
) {
1221+
let mut non_determinism = NonDeterminism::default();
1222+
encode_to_memory(&mut non_determinism.ram, witness_ptr, &witness);
1223+
1224+
let program = triton_program! {
1225+
read_io 1
1226+
{&UpdateWitnessLookalike::destructure()}
1227+
write_io 5 write_io 5 write_io 4
1228+
halt
1229+
};
1230+
1231+
let input = PublicInput::new(vec![witness_ptr]);
1232+
let output = VM::run(program, input, non_determinism.clone())?;
1233+
let mut output = output.into_iter();
1234+
let mut next_ptr = || output.next().unwrap();
1235+
let ram = &non_determinism.ram;
1236+
1237+
let old_kernel =
1238+
*TransactionKernelLookalike::decode_from_memory(ram, next_ptr()).unwrap();
1239+
let new_kernel =
1240+
*TransactionKernelLookalike::decode_from_memory(ram, next_ptr()).unwrap();
1241+
let old_kernel_mast_hash = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1242+
let new_kernel_mast_hash = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1243+
let old_proof = *Proof::decode_from_memory(ram, next_ptr()).unwrap();
1244+
let new_swbfi_bagged = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1245+
let new_aocl = *MmrAccumulator::decode_from_memory(ram, next_ptr()).unwrap();
1246+
let new_swbfa_hash = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1247+
let old_swbfi_bagged = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1248+
let old_aocl = *MmrAccumulator::decode_from_memory(ram, next_ptr()).unwrap();
1249+
let old_swbfa_hash = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1250+
let aocl_successor_proof =
1251+
*MmrSuccessorProofLookalike::decode_from_memory(ram, next_ptr()).unwrap();
1252+
let outputs_hash = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1253+
let public_announcements_hash = *Digest::decode_from_memory(ram, next_ptr()).unwrap();
1254+
1255+
let witness_again = UpdateWitnessLookalike {
1256+
old_kernel,
1257+
new_kernel,
1258+
old_kernel_mast_hash,
1259+
new_kernel_mast_hash,
1260+
old_proof,
1261+
new_swbfi_bagged,
1262+
new_aocl,
1263+
new_swbfa_hash,
1264+
old_swbfi_bagged,
1265+
old_aocl,
1266+
old_swbfa_hash,
1267+
aocl_successor_proof,
1268+
outputs_hash,
1269+
public_announcements_hash,
1270+
};
1271+
prop_assert_eq!(witness, witness_again);
1272+
}
11681273
}
11691274

11701275
#[test]

0 commit comments

Comments
 (0)