Skip to content

Commit 1abffff

Browse files
author
sklppy88
committed
init
1 parent 20d86fd commit 1abffff

File tree

3 files changed

+350
-1
lines changed

3 files changed

+350
-1
lines changed

noir-projects/noir-contracts/contracts/inclusion_proofs_contract/src/main.nr

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// A demonstration of inclusion and non-inclusion proofs.
22
use dep::aztec::macros::aztec;
33

4+
mod test;
5+
46
#[aztec]
57
pub contract InclusionProofs {
68
use dep::aztec::encrypted_logs::log_assembly_strategies::default_aes128::note::encode_and_encrypt_note;
79
use dep::aztec::prelude::{AztecAddress, Map, NoteGetterOptions, PrivateSet, PublicMutable};
810

911
use dep::aztec::{
1012
macros::{functions::{initializer, private, public}, storage::storage},
11-
note::note_getter_options::NoteStatus,
13+
note::{note_getter_options::NoteStatus, note_viewer_options::NoteViewerOptions},
1214
};
1315
// docs:start:value_note_imports
1416
use dep::value_note::value_note::ValueNote;
@@ -40,6 +42,13 @@ pub contract InclusionProofs {
4042
}
4143
// docs:end:create_note
4244

45+
unconstrained fn get_note(owner: AztecAddress) -> ValueNote {
46+
let options = NoteViewerOptions::new().set_limit(1);
47+
let note = storage.private_values.at(owner).view_notes(options).get(0);
48+
49+
note
50+
}
51+
4352
#[private]
4453
fn test_note_inclusion(
4554
owner: AztecAddress,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,338 @@
1+
use crate::InclusionProofs;
2+
use dep::aztec::{
3+
oracle::execution::get_contract_address,
4+
prelude::AztecAddress,
5+
test::helpers::{cheatcodes, test_environment::TestEnvironment},
6+
};
7+
8+
global INITIAL_VALUE: Field = 69;
9+
10+
pub unconstrained fn setup(
11+
initial_value: Field,
12+
) -> (&mut TestEnvironment, AztecAddress, AztecAddress) {
13+
// Setup env, generate keys
14+
let mut env = TestEnvironment::new();
15+
let owner = env.create_account();
16+
env.impersonate(owner);
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);
20+
21+
// Deploy contract and initialize
22+
let initializer = InclusionProofs::interface().constructor(initial_value);
23+
let inclusion_proofs_contract =
24+
env.deploy_self("InclusionProofs").with_public_void_initializer(initializer);
25+
let contract_address = inclusion_proofs_contract.to_address();
26+
env.advance_block_by(1);
27+
(&mut env, contract_address, owner)
28+
}
29+
30+
#[test]
31+
unconstrained fn note_flow() {
32+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
33+
34+
env.impersonate(owner);
35+
36+
let block_number = env.block_number();
37+
38+
let NOTE_VALUE = 69;
39+
InclusionProofs::at(contract_address).create_note(owner, NOTE_VALUE).call(&mut env.private());
40+
41+
env.advance_block_by(2);
42+
43+
let current_contract_address = get_contract_address();
44+
cheatcodes::set_contract_address(contract_address);
45+
46+
let note = InclusionProofs::get_note(owner);
47+
cheatcodes::set_contract_address(current_contract_address);
48+
49+
assert(note.owner.eq(owner));
50+
assert(note.value.eq(NOTE_VALUE));
51+
52+
InclusionProofs::at(contract_address)
53+
.test_note_inclusion(owner, true, block_number, false)
54+
.call(&mut env.private());
55+
InclusionProofs::at(contract_address).test_note_inclusion(owner, false, 0, false).call(
56+
&mut env.private(),
57+
);
58+
59+
InclusionProofs::at(contract_address)
60+
.test_note_not_nullified(owner, true, block_number, false)
61+
.call(&mut env.private());
62+
InclusionProofs::at(contract_address).test_note_not_nullified(owner, false, 0, false).call(
63+
&mut env.private(),
64+
);
65+
66+
InclusionProofs::at(contract_address).test_note_validity(owner, true, block_number, false).call(
67+
&mut env.private(),
68+
);
69+
InclusionProofs::at(contract_address).test_note_validity(owner, false, 0, false).call(
70+
&mut env.private(),
71+
);
72+
}
73+
74+
#[test]
75+
unconstrained fn nullify_note_flow() {
76+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
77+
78+
env.impersonate(owner);
79+
80+
let note_valid_block_number = env.block_number();
81+
82+
InclusionProofs::at(contract_address).create_note(owner, 5).call(&mut env.private());
83+
84+
env.advance_block_by(1);
85+
86+
InclusionProofs::at(contract_address).nullify_note(owner).call(&mut env.private());
87+
88+
env.advance_block_by(1);
89+
90+
InclusionProofs::at(contract_address)
91+
.test_note_inclusion(owner, true, note_valid_block_number, true)
92+
.call(&mut env.private());
93+
94+
InclusionProofs::at(contract_address).test_note_inclusion(owner, false, 0, true).call(
95+
&mut env.private(),
96+
);
97+
98+
InclusionProofs::at(contract_address)
99+
.test_note_not_nullified(owner, true, note_valid_block_number, true)
100+
.call(&mut env.private());
101+
InclusionProofs::at(contract_address)
102+
.test_note_validity(owner, true, note_valid_block_number, true)
103+
.call(&mut env.private());
104+
}
105+
106+
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
107+
unconstrained fn note_not_nullified_after_nullified() {
108+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
109+
110+
env.impersonate(owner);
111+
112+
InclusionProofs::at(contract_address).create_note(owner, 5).call(&mut env.private());
113+
114+
env.advance_block_by(1);
115+
116+
InclusionProofs::at(contract_address).nullify_note(owner).call(&mut env.private());
117+
118+
env.advance_block_by(1);
119+
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+
InclusionProofs::at(contract_address)
123+
.test_note_not_nullified(owner, true, env.block_number() - 1, true)
124+
.call(&mut env.private());
125+
}
126+
127+
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
128+
unconstrained fn note_not_nullified_after_nullified_no_block_number() {
129+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
130+
131+
env.impersonate(owner);
132+
133+
InclusionProofs::at(contract_address).create_note(owner, 5).call(&mut env.private());
134+
135+
env.advance_block_by(1);
136+
137+
InclusionProofs::at(contract_address).nullify_note(owner).call(&mut env.private());
138+
139+
env.advance_block_by(1);
140+
141+
InclusionProofs::at(contract_address).test_note_not_nullified(owner, false, 0, true).call(
142+
&mut env.private(),
143+
);
144+
}
145+
146+
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
147+
unconstrained fn validity_after_nullified() {
148+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
149+
150+
env.impersonate(owner);
151+
152+
InclusionProofs::at(contract_address).create_note(owner, 5).call(&mut env.private());
153+
154+
env.advance_block_by(1);
155+
156+
InclusionProofs::at(contract_address).nullify_note(owner).call(&mut env.private());
157+
158+
env.advance_block_by(1);
159+
160+
InclusionProofs::at(contract_address)
161+
.test_note_validity(owner, true, env.block_number() - 1, true)
162+
.call(&mut env.private());
163+
}
164+
165+
#[test(should_fail_with = "Assertion failed: Proving nullifier non-inclusion failed: low_nullifier.value < nullifier.value check failed")]
166+
unconstrained fn validity_after_nullified_no_block_number() {
167+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
168+
169+
env.impersonate(owner);
170+
171+
InclusionProofs::at(contract_address).create_note(owner, 5).call(&mut env.private());
172+
173+
env.advance_block_by(1);
174+
175+
InclusionProofs::at(contract_address).nullify_note(owner).call(&mut env.private());
176+
177+
env.advance_block_by(1);
178+
179+
InclusionProofs::at(contract_address).test_note_validity(owner, false, 0, true).call(
180+
&mut env.private(),
181+
);
182+
}
183+
184+
#[test(should_fail_with = "not found in NOTE_HASH_TREE")]
185+
unconstrained fn note_inclusion_fail_case() {
186+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
187+
188+
env.impersonate(owner);
189+
let random_owner = AztecAddress::from_field(dep::aztec::oracle::random::random());
190+
191+
let block_number = env.block_number();
192+
193+
env.advance_block_by(1);
194+
195+
InclusionProofs::at(contract_address)
196+
.test_note_inclusion_fail_case(random_owner, true, block_number)
197+
.call(&mut env.private());
198+
}
199+
200+
#[test(should_fail_with = "not found in NOTE_HASH_TREE")]
201+
unconstrained fn note_inclusion_fail_case_no_block_number() {
202+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
203+
204+
env.impersonate(owner);
205+
let random_owner = AztecAddress::from_field(dep::aztec::oracle::random::random());
206+
207+
env.advance_block_by(1);
208+
209+
InclusionProofs::at(contract_address)
210+
.test_note_inclusion_fail_case(random_owner, false, 0)
211+
.call(&mut env.private());
212+
}
213+
214+
#[test]
215+
unconstrained fn nullifier_inclusion() {
216+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
217+
env.impersonate(owner);
218+
219+
// The first nullifier emitted
220+
let nullifier = 6969 + 1;
221+
222+
InclusionProofs::at(contract_address)
223+
.test_nullifier_inclusion(nullifier, true, env.block_number() - 1)
224+
.call(&mut env.private());
225+
226+
InclusionProofs::at(contract_address).test_nullifier_inclusion(nullifier, false, 0).call(
227+
&mut env.private(),
228+
);
229+
}
230+
231+
#[test]
232+
unconstrained fn nullifier_inclusion_public() {
233+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
234+
235+
env.impersonate(owner);
236+
237+
let unsiloed_nullifier = 0xffffff;
238+
InclusionProofs::at(contract_address).push_nullifier_public(unsiloed_nullifier).call(
239+
&mut env.public(),
240+
);
241+
242+
env.advance_block_by(1);
243+
InclusionProofs::at(contract_address)
244+
.test_nullifier_inclusion_from_public(unsiloed_nullifier)
245+
.call(&mut env.public());
246+
}
247+
248+
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
249+
unconstrained fn nullifier_non_existence() {
250+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
251+
252+
let block_number = env.block_number() - 1;
253+
env.impersonate(owner);
254+
let random_nullifier = dep::aztec::oracle::random::random();
255+
256+
InclusionProofs::at(contract_address)
257+
.test_nullifier_inclusion(random_nullifier, true, block_number)
258+
.call(&mut env.private());
259+
}
260+
261+
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
262+
unconstrained fn nullifier_non_existence_no_block_number() {
263+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
264+
265+
env.impersonate(owner);
266+
let random_nullifier = dep::aztec::oracle::random::random();
267+
268+
InclusionProofs::at(contract_address).test_nullifier_inclusion(random_nullifier, false, 0).call(
269+
&mut env.private(),
270+
);
271+
}
272+
273+
#[test]
274+
unconstrained fn historical_reads() {
275+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
276+
277+
env.impersonate(owner);
278+
279+
let block_number = env.block_number() - 1;
280+
281+
InclusionProofs::at(contract_address)
282+
.test_storage_historical_read(INITIAL_VALUE, true, block_number)
283+
.call(&mut env.private());
284+
InclusionProofs::at(contract_address)
285+
.test_storage_historical_read(INITIAL_VALUE, false, 0)
286+
.call(&mut env.private());
287+
288+
// We are using block number 2 because we know the public value has not been set at this point.
289+
InclusionProofs::at(contract_address).test_storage_historical_read(0, true, 2).call(
290+
&mut env.private(),
291+
);
292+
293+
InclusionProofs::at(contract_address)
294+
.test_storage_historical_read_unset_slot(block_number)
295+
.call(&mut env.private());
296+
}
297+
298+
#[test]
299+
unconstrained fn contract_flow() {
300+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
301+
302+
env.impersonate(owner);
303+
304+
let block_number = env.block_number() - 1;
305+
306+
InclusionProofs::at(contract_address)
307+
.test_contract_inclusion(contract_address, block_number, true, true)
308+
.call(&mut env.private());
309+
310+
// We are using block number 2 because we know the contract has not been deployed nor initialized at this point.
311+
InclusionProofs::at(contract_address)
312+
.test_contract_non_inclusion(contract_address, 2, true, true)
313+
.call(&mut env.private());
314+
}
315+
316+
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
317+
unconstrained fn test_contract_not_initialized() {
318+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
319+
320+
env.impersonate(owner);
321+
322+
// We are using block number 2 because we know the contract has not been deployed nor initialized at this point.
323+
InclusionProofs::at(contract_address)
324+
.test_contract_inclusion(contract_address, 2, true, false)
325+
.call(&mut env.private());
326+
}
327+
328+
#[test(should_fail_with = "Nullifier witness not found for nullifier")]
329+
unconstrained fn test_contract_not_deployed() {
330+
let (env, contract_address, owner) = setup(INITIAL_VALUE);
331+
332+
env.impersonate(owner);
333+
334+
// We are using block number 2 because we know the contract has not been deployed nor initialized at this point.
335+
InclusionProofs::at(contract_address)
336+
.test_contract_inclusion(contract_address, 2, false, true)
337+
.call(&mut env.private());
338+
}

yarn-project/txe/src/oracle/txe_oracle.ts

+2
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,8 @@ export class TXE implements TypedOracle {
688688
txEffect.nullifiers.unshift(this.getTxRequestHash());
689689
}
690690

691+
console.log('all nullifiers', txEffect.nullifiers);
692+
691693
txEffect.publicDataWrites = this.publicDataWrites;
692694

693695
const body = new Body([txEffect]);

0 commit comments

Comments
 (0)