Skip to content

Commit e527992

Browse files
authored
feat!: refactor NoteGetterOptions::select API (#8504)
1 parent d5ad11d commit e527992

File tree

15 files changed

+85
-88
lines changed

15 files changed

+85
-88
lines changed

docs/docs/migration_notes.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,25 @@ keywords: [sandbox, aztec, notes, migration, updating, upgrading]
66

77
Aztec is in full-speed development. Literally every version breaks compatibility with the previous ones. This page attempts to target errors and difficulties you might encounter when upgrading, and how to resolve them.
88

9+
## TBD
10+
11+
### [Aztec.nr] Rework `NoteGetterOptions::select`
12+
13+
The `select` function in both `NoteGetterOptions` and `NoteViewerOptions` no longer takes an `Option` of a comparator, but instead requires an explicit comparator to be passed. Additionally, the order of the parameters has been changed so that they are `(lhs, operator, rhs)`. These two changes should make invocations of the function easier to read:
14+
15+
```diff
16+
- options.select(ValueNote::properties().value, amount, Option::none())
17+
+ options.select(ValueNote::properties().value, Comparator.EQ, amount)
18+
```
19+
920
## 0.53.0
21+
1022
### [Aztec.nr] Remove `OwnedNote` and create `UintNote`
23+
1124
`OwnedNote` allowed having a U128 `value` in the custom note while `ValueNote` restricted to just a Field.
1225

1326
We have removed `OwnedNote` but are introducing a more genric `UintNote` within aztec.nr
27+
1428
```
1529
#[aztec(note)]
1630
struct UintNote {
@@ -24,9 +38,11 @@ struct UintNote {
2438
```
2539

2640
### [TXE] logging
41+
2742
You can now use `debug_log()` within your contract to print logs when using the TXE
2843

2944
Remember to set the following environment variables to activate debug logging:
45+
3046
```bash
3147
export DEBUG="aztec:*"
3248
export LOG_LEVEL="debug"
@@ -36,7 +52,7 @@ export LOG_LEVEL="debug"
3652

3753
`is_valid_impl` method in account contract asserted if signature was true. Instead now we will return the verification to give flexibility to developers to handle it as they please.
3854

39-
```diff
55+
````diff
4056
- let verification = std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message);
4157
- assert(verification == true);
4258
- true
@@ -57,7 +73,7 @@ Public keys (ivpk, ovpk, npk, tpk) should no longer be fetched using the old `ge
5773
+let owner_keys = get_current_public_keys(&mut context, owner);
5874
+let owner_ivpk_m = owner_keys.ivpk_m;
5975
+let owner_ovpk_m = owner_keys.ovpk_m;
60-
```
76+
````
6177

6278
If using more than one key per account, this will result in very large circuit gate count reductions.
6379

docs/docs/reference/developer_references/smart_contract_reference/storage/private_state.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ An example of such options is using the [filter_notes_min_sum (GitHub link)](htt
228228

229229
This function has the same behavior as `pop_notes` above but it does not delete the notes.
230230

231-
232231
### `remove`
233232

234233
Will remove a note from the `PrivateSet` if it previously has been read from storage, e.g. you have fetched it through a `get_notes` call. This is useful when you want to remove a note that you have previously read from storage and do not have to read it again.
@@ -255,7 +254,7 @@ You can view the implementation [here (GitHub link)](https://github.com/AztecPro
255254

256255
### `selects: BoundedVec<Option<Select>, N>`
257256

258-
`selects` is a collection of filtering criteria, specified by `Select { property_selector: PropertySelector, value: Field, comparator: u3 }` structs. It instructs the data oracle to find notes whose serialized field (as specified by the PropertySelector) matches the provided `value`, according to the `comparator`. The PropertySelector is in turn specified as having an `index` (nth position of the selected field in the serialized note), an `offset` (byte offset inside the selected serialized field) and `length` (bytes to read of the field from the offset)
257+
`selects` is a collection of filtering criteria, specified by `Select { property_selector: PropertySelector, comparator: u8, value: Field }` structs. It instructs the data oracle to find notes whose serialized field (as specified by the `PropertySelector`) matches the provided `value`, according to the `comparator`. The PropertySelector is in turn specified as having an `index` (nth position of the selected field in the serialized note), an `offset` (byte offset inside the selected serialized field) and `length` (bytes to read of the field from the offset). These values are not expected to be manually computed, but instead specified by passing functions autogenerated from the note definition.
259258

260259
### `sorts: BoundedVec<Option<Sort>, N>`
261260

@@ -329,17 +328,17 @@ This method sets the status of notes to retrieve (active or nullified).
329328

330329
#### Example 1
331330

332-
The following code snippet creates an instance of `NoteGetterOptions`, which has been configured to find the cards that belong to `account_address`. The returned cards are sorted by their points in descending order, and the first `offset` cards with the highest points are skipped.
331+
The following code snippet creates an instance of `NoteGetterOptions`, which has been configured to find the cards that belong to an account with nullifying key hash equal to `account_npk_m_hash`. The returned cards are sorted by their points in descending order, and the first `offset` cards with the highest points are skipped.
333332

334333
#include_code state_vars-NoteGetterOptionsSelectSortOffset /noir-projects/noir-contracts/contracts/docs_example_contract/src/options.nr rust
335334

336-
The first value of `.select` and `.sort` is the index of a field in a note type. For the note type `CardNote` that has the following fields:
335+
The first value of `.select` and `.sort` indicates the property of the note we're looking for. For this we use helper functions that are autogenerated from the note definition. `CardNote` that has the following fields:
337336

338337
#include_code state_vars-CardNote /noir-projects/noir-contracts/contracts/docs_example_contract/src/types/card_note.nr rust
339338

340-
The indices are: 0 for `points`, 1 for `randomness`, and 2 for `npk_m_hash`.
339+
`CardNote::properties()` will return a struct with the values to pass for each field, which are related to their indices inside the `CardNote` struct, internal offset and length.
341340

342-
In the example, `.select(2, account_address, Option::none())` matches the 2nd field of `CardNote`, which is `npk_m_hash`, and returns the cards whose `npk_m_hash` field equals `account_npk_m_hash`, equality is the comparator used because because including no comparator (the third argument) defaults to using the equality comparator. The current possible values of Comparator are specified in the Note Getter Options implementation linked above.
341+
In the example, `.select(CardNote::properties().npk_m_hash, Comparator.EQ, account_npk_m_hash)` matches notes which have the `npk_m_hash` field set to `account_npk_m_hash`. In this case we're using the equality comparator, but other operations exist in the `Comparator` utility struct.
343342

344343
`.sort(0, SortOrder.DESC)` sorts the 0th field of `CardNote`, which is `points`, in descending order.
345344

noir-projects/aztec-nr/aztec/src/note/note_getter/test.nr

+2-2
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ fn rejects_mismatched_selector() {
196196
let mut options = NoteGetterOptions::new();
197197
options = options.select(
198198
PropertySelector { index: 0, offset: 0, length: 32 },
199-
value + 1,
200-
Option::some(Comparator.EQ)
199+
Comparator.EQ,
200+
value + 1
201201
);
202202

203203
let _ = constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);

noir-projects/aztec-nr/aztec/src/note/note_getter_options.nr

+8-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use std::option::Option;
22
use dep::protocol_types::{constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL, traits::ToField};
33
use crate::note::note_interface::NoteInterface;
4-
use crate::utils::comparison::Comparator;
54

65
struct PropertySelector {
76
index: u8,
@@ -11,13 +10,15 @@ struct PropertySelector {
1110

1211
struct Select {
1312
property_selector: PropertySelector,
14-
value: Field,
1513
comparator: u8,
14+
value: Field,
1615
}
1716

1817
impl Select {
19-
pub fn new(property_selector: PropertySelector, value: Field, comparator: u8) -> Self {
20-
Select { property_selector, value, comparator }
18+
// The selected property will be the left hand side and value the right hand side of the operation, so e.g. the
19+
// object created by new(property, Comparator.GT, value) represents 'property > value'.
20+
pub fn new(property_selector: PropertySelector, comparator: u8, value: Field) -> Self {
21+
Select { property_selector, comparator, value }
2122
}
2223
}
2324

@@ -90,18 +91,10 @@ impl<Note, let N: u32, let M: u32, PREPROCESSOR_ARGS, FILTER_ARGS> NoteGetterOpt
9091
pub fn select<T>(
9192
&mut self,
9293
property_selector: PropertySelector,
93-
value: T,
94-
comparator: Option<u8>
94+
comparator: u8,
95+
value: T
9596
) -> Self where T: ToField {
96-
self.selects.push(
97-
Option::some(
98-
Select::new(
99-
property_selector,
100-
value.to_field(),
101-
comparator.unwrap_or(Comparator.EQ)
102-
)
103-
)
104-
);
97+
self.selects.push(Option::some(Select::new(property_selector, comparator, value.to_field())));
10598
*self
10699
}
107100

noir-projects/aztec-nr/aztec/src/note/note_viewer_options.nr

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::option::Option;
2-
use crate::note::note_getter_options::{PropertySelector, Select, Sort, Comparator, NoteStatus};
2+
use crate::note::note_getter_options::{PropertySelector, Select, Sort, NoteStatus};
33
use dep::protocol_types::traits::ToField;
44
use crate::note::note_interface::NoteInterface;
55
use crate::note::constants::MAX_NOTES_PER_PAGE;
@@ -32,18 +32,10 @@ impl<Note, let N: u32, let M: u32> NoteViewerOptions<Note, N, M> {
3232
pub fn select<T>(
3333
&mut self,
3434
property_selector: PropertySelector,
35-
value: T,
36-
comparator: Option<u8>
35+
comparator: u8,
36+
value: T
3737
) -> Self where T: ToField {
38-
self.selects.push(
39-
Option::some(
40-
Select::new(
41-
property_selector,
42-
value.to_field(),
43-
comparator.unwrap_or(Comparator.EQ)
44-
)
45-
)
46-
);
38+
self.selects.push(Option::some(Select::new(property_selector, comparator, value.to_field())));
4739
*self
4840
}
4941

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ contract Child {
66
context::gas::GasOpts, protocol_types::{abis::call_context::CallContext},
77
note::{note_getter_options::NoteGetterOptions, note_header::NoteHeader},
88
encrypted_logs::encrypted_note_emission::encode_and_encrypt_note_with_keys,
9-
keys::getters::get_current_public_keys
9+
keys::getters::get_current_public_keys, utils::comparison::Comparator
1010
};
1111
use dep::value_note::value_note::ValueNote;
1212

@@ -21,7 +21,7 @@ contract Child {
2121
fn value(input: Field) -> Field {
2222
input + context.chain_id() + context.version()
2323
}
24-
// Returns a sum of the input and the chain id and version of the contract in private circuit public input's return_values.
24+
// Returns a sum of the input and the chain id and version of the contract in private circuit public input's return_values.
2525
// Can only be called from this contract.
2626
#[aztec(private)]
2727
#[aztec(internal)]
@@ -62,7 +62,7 @@ contract Child {
6262
#[aztec(private)]
6363
fn private_get_value(amount: Field, owner: AztecAddress) -> Field {
6464
let mut options = NoteGetterOptions::new();
65-
options = options.select(ValueNote::properties().value, amount, Option::none()).set_limit(1);
65+
options = options.select(ValueNote::properties().value, Comparator.EQ, amount).set_limit(1);
6666
let notes = storage.a_map_with_private_values.at(owner).get_notes(options);
6767
notes.get(0).value
6868
}
@@ -78,7 +78,7 @@ contract Child {
7878
}
7979

8080
// Increments `current_value` by `new_value`. Can only be called from this contract.
81-
#[aztec(public)]
81+
#[aztec(public)]
8282
#[aztec(internal)]
8383
fn pub_inc_value_internal(new_value: Field) -> Field {
8484
let old_value = storage.current_value.read();

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

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ contract DelegatedOn {
66
};
77
use dep::aztec::{
88
encrypted_logs::encrypted_note_emission::encode_and_encrypt_note,
9-
keys::getters::get_current_public_keys
9+
keys::getters::get_current_public_keys, utils::comparison::Comparator
1010
};
1111
use dep::value_note::value_note::ValueNote;
1212

@@ -34,7 +34,7 @@ contract DelegatedOn {
3434
#[aztec(private)]
3535
fn get_private_value(amount: Field, owner: AztecAddress) -> pub Field {
3636
let mut options = NoteGetterOptions::new();
37-
options = options.select(ValueNote::properties().value, amount, Option::none()).set_limit(1);
37+
options = options.select(ValueNote::properties().value, Comparator.EQ, amount).set_limit(1);
3838
let notes = storage.a_map_with_private_values.at(owner).get_notes(options);
3939
notes.get(0).value
4040
}
@@ -43,4 +43,3 @@ contract DelegatedOn {
4343
storage.current_value.read()
4444
}
4545
}
46-

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ contract Delegator {
33
use dep::aztec::prelude::{AztecAddress, FunctionSelector, NoteHeader, NoteGetterOptions, PublicMutable, PrivateSet, Deserialize, Map};
44
use dep::value_note::value_note::ValueNote;
55
use dep::delegated_on::DelegatedOn;
6+
use dep::aztec::utils::comparison::Comparator;
67

78
#[aztec(storage)]
89
struct Storage {
@@ -33,7 +34,7 @@ contract Delegator {
3334
#[aztec(private)]
3435
fn get_private_value(amount: Field, owner: AztecAddress) -> pub Field {
3536
let mut options = NoteGetterOptions::new();
36-
options = options.select(ValueNote::properties().value, amount, Option::none()).set_limit(1);
37+
options = options.select(ValueNote::properties().value, Comparator.EQ, amount).set_limit(1);
3738
let notes = storage.a_map_with_private_values.at(owner).get_notes(options);
3839
notes.get_unchecked(0).value
3940
}

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

+9-16
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod types;
66
// (tests ordering in the circuit)
77

88
// you have a card (PrivateMutable). Anyone can create a bigger card. Whoever is bigger will be the leader.
9-
// it also has dummy methods and other examples used for documentation e.g.
9+
// it also has dummy methods and other examples used for documentation e.g.
1010
// how to create custom notes, a custom struct for public state, a custom note that may be unencrypted
1111
// also has `options.nr` which shows various ways of using `NoteGetterOptions` to query notes
1212
// it also shows what our macros do behind the scenes!
@@ -19,7 +19,6 @@ contract DocsExample {
1919
PrivateSet, SharedImmutable, Deserialize
2020
};
2121
use dep::aztec::encrypted_logs::encrypted_note_emission::{encode_and_encrypt_note, encode_and_encrypt_note_with_keys};
22-
use dep::aztec::note::note_getter_options::Comparator;
2322
use dep::aztec::keys::getters::get_current_public_keys;
2423
// how to import methods from other files/folders within your workspace
2524
use crate::types::{card_note::{CardNote, CARD_NOTE_LEN}, leader::Leader};
@@ -33,7 +32,7 @@ contract DocsExample {
3332
// docs:start:storage-private-mutable-declaration
3433
legendary_card: PrivateMutable<CardNote>,
3534
// docs:end:storage-private-mutable-declaration
36-
// just used for docs example to show how to create a private mutable map.
35+
// just used for docs example to show how to create a private mutable map.
3736
profiles: Map<AztecAddress, PrivateMutable<CardNote>>,
3837
// docs:start:storage-set-declaration
3938
set: PrivateSet<CardNote>,
@@ -112,7 +111,7 @@ contract DocsExample {
112111
fn get_shared_immutable_constrained_private_indirect() -> pub Leader {
113112
// This is a private function that calls another private function
114113
// and returns the response.
115-
// Used to test that we can retrieve values through calls and
114+
// Used to test that we can retrieve values through calls and
116115
// correctly return them in the simulation
117116
let mut leader = DocsExample::at(context.this_address()).get_shared_immutable_constrained_private().view(&mut context);
118117
leader.points += 1;
@@ -123,7 +122,7 @@ contract DocsExample {
123122
fn get_shared_immutable_constrained_public_indirect() -> pub Leader {
124123
// This is a public function that calls another public function
125124
// and returns the response.
126-
// Used to test that we can retrieve values through calls and
125+
// Used to test that we can retrieve values through calls and
127126
// correctly return them in the simulation
128127
let mut leader = DocsExample::at(context.this_address()).get_shared_immutable_constrained_public().view(&mut context);
129128
leader.points += 1;
@@ -213,15 +212,9 @@ contract DocsExample {
213212
}
214213

215214
// docs:start:state_vars-NoteGetterOptionsComparatorExampleNoir
216-
unconstrained fn read_note(amount: Field, comparator: u8) -> pub BoundedVec<CardNote, 10> {
215+
unconstrained fn read_note(comparator: u8, amount: Field) -> pub BoundedVec<CardNote, 10> {
217216
let mut options = NoteViewerOptions::new();
218-
storage.set.view_notes(
219-
options.select(
220-
CardNote::properties().points,
221-
amount,
222-
Option::some(comparator)
223-
)
224-
)
217+
storage.set.view_notes(options.select(CardNote::properties().points, comparator, amount))
225218
}
226219
// docs:end:state_vars-NoteGetterOptionsComparatorExampleNoir
227220

@@ -327,13 +320,13 @@ contract DocsExample {
327320

328321
// Our original inputs!
329322
a: Field,
330-
b: Field // The actual return type of our circuit is the PrivateCircuitPublicInputs struct, this will be the
331-
// input to our kernel!
323+
b: Field // The actual return type of our circuit is the PrivateCircuitPublicInputs struct, this will be the
324+
// input to our kernel!
332325
// docs:start:context-example-return
333326
) -> pub PrivateCircuitPublicInputs {
334327
// docs:end:context-example-return
335328
// ************************************************************
336-
// The hasher is a structure used to generate a hash of the circuits inputs.
329+
// The hasher is a structure used to generate a hash of the circuits inputs.
337330
// docs:start:context-example-hasher
338331
let mut args_hasher = dep::aztec::hash::ArgsHasher::new();
339332
args_hasher.add(a);

noir-projects/noir-contracts/contracts/docs_example_contract/src/options.nr

+11-7
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@ use crate::types::card_note::{CardNote, CARD_NOTE_LEN, CARD_NOTE_BYTES_LEN};
22
use dep::aztec::prelude::{AztecAddress, NoteGetterOptions};
33

44
use dep::aztec::protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL;
5-
use dep::aztec::note::note_getter_options::{Sort, SortOrder};
5+
use dep::aztec::{note::note_getter_options::{Sort, SortOrder}, utils::comparison::Comparator};
66

77
// Shows how to use NoteGetterOptions and query for notes.
88

99
// docs:start:state_vars-NoteGetterOptionsSelectSortOffset
10-
pub fn create_points_card_getter_options(
11-
points: Field,
10+
pub fn create_npk_card_getter_options(
11+
account_npk_m_hash: Field,
1212
offset: u32
1313
) -> NoteGetterOptions<CardNote, CARD_NOTE_LEN, CARD_NOTE_BYTES_LEN, Field, Field> {
1414
let mut options = NoteGetterOptions::new();
15-
options.select(CardNote::properties().points, points, Option::none()).sort(CardNote::properties().points, SortOrder.DESC).set_offset(offset)
15+
options.select(
16+
CardNote::properties().npk_m_hash,
17+
Comparator.EQ,
18+
account_npk_m_hash
19+
).sort(CardNote::properties().points, SortOrder.DESC).set_offset(offset)
1620
}
1721
// docs:end:state_vars-NoteGetterOptionsSelectSortOffset
1822

@@ -23,10 +27,10 @@ pub fn create_exact_card_getter_options(
2327
account_npk_m_hash: Field
2428
) -> NoteGetterOptions<CardNote, CARD_NOTE_LEN, CARD_NOTE_BYTES_LEN, Field, Field> {
2529
let mut options = NoteGetterOptions::new();
26-
options.select(CardNote::properties().points, points as Field, Option::none()).select(CardNote::properties().randomness, secret, Option::none()).select(
30+
options.select(CardNote::properties().points, Comparator.EQ, points as Field).select(CardNote::properties().randomness, Comparator.EQ, secret).select(
2731
CardNote::properties().npk_m_hash,
28-
account_npk_m_hash,
29-
Option::none()
32+
Comparator.EQ,
33+
account_npk_m_hash
3034
)
3135
}
3236
// docs:end:state_vars-NoteGetterOptionsMultiSelects

0 commit comments

Comments
 (0)