@@ -15,8 +15,9 @@ pub unconstrained fn setup(
15
15
let owner = env .create_account (1 );
16
16
env .impersonate (owner );
17
17
18
- // Advance a block so we know that at block 2 our contract has not been deployed yet.
19
- env .advance_block_by (2 );
18
+ // We advance one block here, because we want to deploy our contract in block 3.
19
+ // This is because we will do tests later that prove the non inclusion of values and of the contract itself at block 2.
20
+ env .advance_block_by (1 );
20
21
21
22
// Deploy contract and initialize
22
23
let initializer = InclusionProofs ::interface ().constructor (initial_value );
@@ -29,64 +30,72 @@ pub unconstrained fn setup(
29
30
30
31
#[test]
31
32
unconstrained fn note_flow () {
33
+ // This test creates a note and checks certain properties about it, namely its inclusion in the trees,
34
+ // the non-inclusion of its nullifier, and its validity (the combination of the previous two)
32
35
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
33
-
34
36
env .impersonate (owner );
35
37
36
- let block_number = env .block_number ();
37
-
38
38
let NOTE_VALUE = 69 ;
39
39
InclusionProofs ::at (contract_address ).create_note (owner , NOTE_VALUE ).call (&mut env .private ());
40
40
41
- env .advance_block_by (2 );
41
+ env .advance_block_by (1 );
42
+
43
+ let note_creation_block_number = env .block_number ();
44
+
45
+ // We advance by another block to make sure that the note creation block number != our current block number
46
+ env .advance_block_by (1 );
42
47
43
48
let current_contract_address = get_contract_address ();
44
49
cheatcodes:: set_contract_address (contract_address );
45
50
51
+ // We fetch the note we created and make sure that it is valid.
46
52
let note = InclusionProofs ::get_note (owner );
47
53
cheatcodes:: set_contract_address (current_contract_address );
48
54
49
55
assert (note .owner .eq (owner ));
50
56
assert (note .value .eq (NOTE_VALUE ));
51
57
58
+ // Each of these tests (note inclusion, note non-nullification, and validity (inclusion & non-nullification)) check the assertion at the block of creation of note, as well as at the "current" block
52
59
InclusionProofs ::at (contract_address )
53
- .test_note_inclusion (owner , true , block_number , false )
60
+ .test_note_inclusion (owner , true , note_creation_block_number , false )
54
61
.call (&mut env .private ());
55
62
InclusionProofs ::at (contract_address ).test_note_inclusion (owner , false , 0 , false ).call (
56
63
&mut env .private (),
57
64
);
58
65
59
66
InclusionProofs ::at (contract_address )
60
- .test_note_not_nullified (owner , true , block_number , false )
67
+ .test_note_not_nullified (owner , true , note_creation_block_number , false )
61
68
.call (&mut env .private ());
62
69
InclusionProofs ::at (contract_address ).test_note_not_nullified (owner , false , 0 , false ).call (
63
70
&mut env .private (),
64
71
);
65
72
66
- InclusionProofs ::at (contract_address ). test_note_validity ( owner , true , block_number , false ). call (
67
- & mut env . private (),
68
- );
73
+ InclusionProofs ::at (contract_address )
74
+ . test_note_validity ( owner , true , note_creation_block_number , false )
75
+ . call (& mut env . private () );
69
76
InclusionProofs ::at (contract_address ).test_note_validity (owner , false , 0 , false ).call (
70
77
&mut env .private (),
71
78
);
72
79
}
73
80
74
81
#[test]
75
82
unconstrained fn nullify_note_flow () {
83
+ // This test creates a note, nullifies it, and checks certain properties about it, namely its inclusion in the trees,
84
+ // the non-inclusion of its nullifier, and its validity (the combination of the previous two). These properties are checked before nullification.
76
85
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
77
-
78
86
env .impersonate (owner );
79
87
80
- let note_valid_block_number = env .block_number ();
81
-
82
88
InclusionProofs ::at (contract_address ).create_note (owner , 5 ).call (&mut env .private ());
83
89
84
90
env .advance_block_by (1 );
85
91
92
+ let note_valid_block_number = env .block_number ();
93
+
86
94
InclusionProofs ::at (contract_address ).nullify_note (owner ).call (&mut env .private ());
87
95
88
96
env .advance_block_by (1 );
89
97
98
+ // We test note inclusion at the note creation block and at current block
90
99
InclusionProofs ::at (contract_address )
91
100
.test_note_inclusion (owner , true , note_valid_block_number , true )
92
101
.call (&mut env .private ());
@@ -95,6 +104,7 @@ unconstrained fn nullify_note_flow() {
95
104
&mut env .private (),
96
105
);
97
106
107
+ // We test note non-nullification and validity at the note creation block
98
108
InclusionProofs ::at (contract_address )
99
109
.test_note_not_nullified (owner , true , note_valid_block_number , true )
100
110
.call (&mut env .private ());
@@ -106,7 +116,6 @@ unconstrained fn nullify_note_flow() {
106
116
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
107
117
unconstrained fn note_not_nullified_after_nullified () {
108
118
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
109
-
110
119
env .impersonate (owner );
111
120
112
121
InclusionProofs ::at (contract_address ).create_note (owner , 5 ).call (&mut env .private ());
@@ -117,17 +126,14 @@ unconstrained fn note_not_nullified_after_nullified() {
117
126
118
127
env .advance_block_by (1 );
119
128
120
- // TODO: env.block_number() should actually return the private context inputs block number, not the block that is currently being built !
121
- // Change env.block_number to subtract one, then just use `env.block_number()`.
122
129
InclusionProofs ::at (contract_address )
123
- .test_note_not_nullified (owner , true , env .block_number () - 1 , true )
130
+ .test_note_not_nullified (owner , true , env .block_number (), true )
124
131
.call (&mut env .private ());
125
132
}
126
133
127
134
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
128
135
unconstrained fn note_not_nullified_after_nullified_no_block_number () {
129
136
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
130
-
131
137
env .impersonate (owner );
132
138
133
139
InclusionProofs ::at (contract_address ).create_note (owner , 5 ).call (&mut env .private ());
@@ -146,7 +152,6 @@ unconstrained fn note_not_nullified_after_nullified_no_block_number() {
146
152
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
147
153
unconstrained fn validity_after_nullified () {
148
154
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
149
-
150
155
env .impersonate (owner );
151
156
152
157
InclusionProofs ::at (contract_address ).create_note (owner , 5 ).call (&mut env .private ());
@@ -158,14 +163,13 @@ unconstrained fn validity_after_nullified() {
158
163
env .advance_block_by (1 );
159
164
160
165
InclusionProofs ::at (contract_address )
161
- .test_note_validity (owner , true , env .block_number () - 1 , true )
166
+ .test_note_validity (owner , true , env .block_number (), true )
162
167
.call (&mut env .private ());
163
168
}
164
169
165
170
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
166
171
unconstrained fn validity_after_nullified_no_block_number () {
167
172
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
168
-
169
173
env .impersonate (owner );
170
174
171
175
InclusionProofs ::at (contract_address ).create_note (owner , 5 ).call (&mut env .private ());
@@ -184,8 +188,8 @@ unconstrained fn validity_after_nullified_no_block_number() {
184
188
#[test(should_fail_with = "not found in NOTE_HASH_TREE")]
185
189
unconstrained fn note_inclusion_fail_case () {
186
190
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
187
-
188
191
env .impersonate (owner );
192
+
189
193
let random_owner = AztecAddress ::from_field (dep::aztec::oracle::random:: random ());
190
194
191
195
let block_number = env .block_number ();
@@ -200,8 +204,8 @@ unconstrained fn note_inclusion_fail_case() {
200
204
#[test(should_fail_with = "not found in NOTE_HASH_TREE")]
201
205
unconstrained fn note_inclusion_fail_case_no_block_number () {
202
206
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
203
-
204
207
env .impersonate (owner );
208
+
205
209
let random_owner = AztecAddress ::from_field (dep::aztec::oracle::random:: random ());
206
210
207
211
env .advance_block_by (1 );
@@ -231,7 +235,6 @@ unconstrained fn nullifier_inclusion() {
231
235
#[test]
232
236
unconstrained fn nullifier_inclusion_public () {
233
237
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
234
-
235
238
env .impersonate (owner );
236
239
237
240
let unsiloed_nullifier = 0xffffff ;
@@ -248,9 +251,10 @@ unconstrained fn nullifier_inclusion_public() {
248
251
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
249
252
unconstrained fn nullifier_non_existence () {
250
253
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
254
+ env .impersonate (owner );
251
255
252
256
let block_number = env .block_number () - 1 ;
253
- env . impersonate ( owner );
257
+
254
258
let random_nullifier = dep::aztec::oracle::random:: random ();
255
259
256
260
InclusionProofs ::at (contract_address )
@@ -261,8 +265,8 @@ unconstrained fn nullifier_non_existence() {
261
265
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
262
266
unconstrained fn nullifier_non_existence_no_block_number () {
263
267
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
264
-
265
268
env .impersonate (owner );
269
+
266
270
let random_nullifier = dep::aztec::oracle::random:: random ();
267
271
268
272
InclusionProofs ::at (contract_address ).test_nullifier_inclusion (random_nullifier , false , 0 ).call (
@@ -273,10 +277,9 @@ unconstrained fn nullifier_non_existence_no_block_number() {
273
277
#[test]
274
278
unconstrained fn historical_reads () {
275
279
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
276
-
277
280
env .impersonate (owner );
278
281
279
- let block_number = env .block_number () - 1 ;
282
+ let block_number = env .block_number ();
280
283
281
284
InclusionProofs ::at (contract_address )
282
285
.test_storage_historical_read (INITIAL_VALUE , true , block_number )
@@ -297,11 +300,11 @@ unconstrained fn historical_reads() {
297
300
298
301
#[test]
299
302
unconstrained fn contract_flow () {
303
+ // This test deploys a contract and tests for its inclusion of deployment and initialization nullifier. It also checks non-inclusion before its deployment.
300
304
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
301
-
302
305
env .impersonate (owner );
303
306
304
- let block_number = env .block_number () - 1 ;
307
+ let block_number : u32 = env .block_number ();
305
308
306
309
InclusionProofs ::at (contract_address )
307
310
.test_contract_inclusion (contract_address , block_number , true , true )
@@ -314,25 +317,50 @@ unconstrained fn contract_flow() {
314
317
}
315
318
316
319
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
317
- unconstrained fn test_contract_not_initialized () {
320
+ unconstrained fn contract_not_initialized () {
318
321
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
319
-
320
322
env .impersonate (owner );
321
323
322
324
// We are using block number 2 because we know the contract has not been deployed nor initialized at this point.
325
+ // We split the deployment check and the initialization check (true, false), because each one checks for the inclusion of the deployment / initialization nullifier specifically;
326
+ // We can't set `true, true` to check for both in one test because the first failing condition won't let us check the other in isolation.
327
+ // The above statements apply to the rest of the contract inclusion tests.
323
328
InclusionProofs ::at (contract_address )
324
329
.test_contract_inclusion (contract_address , 2 , true , false )
325
330
.call (&mut env .private ());
326
331
}
327
332
328
333
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
329
- unconstrained fn test_contract_not_deployed () {
334
+ unconstrained fn contract_not_deployed () {
330
335
let (env , contract_address , owner ) = setup (INITIAL_VALUE );
331
-
332
336
env .impersonate (owner );
333
337
334
- // We are using block number 2 because we know the contract has not been deployed nor initialized at this point .
338
+ // This checks for the inclusion of the initializer nullifier specifically .
335
339
InclusionProofs ::at (contract_address )
336
340
.test_contract_inclusion (contract_address , 2 , false , true )
337
341
.call (&mut env .private ());
338
342
}
343
+
344
+ #[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed")]
345
+ unconstrained fn contract_deployed_non_inclusion () {
346
+ let (env , contract_address , owner ) = setup (INITIAL_VALUE );
347
+ env .impersonate (owner );
348
+
349
+ let block_number : u32 = env .block_number ();
350
+
351
+ InclusionProofs ::at (contract_address )
352
+ .test_contract_non_inclusion (contract_address , block_number , true , false )
353
+ .call (&mut env .private ());
354
+ }
355
+
356
+ #[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed")]
357
+ unconstrained fn contract_initialized_non_inclusion () {
358
+ let (env , contract_address , owner ) = setup (INITIAL_VALUE );
359
+ env .impersonate (owner );
360
+
361
+ let block_number : u32 = env .block_number ();
362
+
363
+ InclusionProofs ::at (contract_address )
364
+ .test_contract_non_inclusion (contract_address , block_number , false , true )
365
+ .call (&mut env .private ());
366
+ }
0 commit comments