Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Make get notes return all notes at beginning of array #4991 #5321

Merged
merged 46 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
1f033aa
Fix
sklppy88 Mar 19, 2024
42ca60a
fix
sklppy88 Mar 19, 2024
da6378a
fix
sklppy88 Mar 20, 2024
a313ca2
asdf
sklppy88 Mar 20, 2024
b57c607
add test
sklppy88 Mar 20, 2024
fd364f3
add test
sklppy88 Mar 21, 2024
ce18eef
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 21, 2024
7b5929f
fix
sklppy88 Mar 21, 2024
5473fd1
formatting fix
sklppy88 Mar 21, 2024
fdd0219
Add comments
sklppy88 Mar 22, 2024
717eb4a
tweak
sklppy88 Mar 22, 2024
276dc0c
feat: truncate SHA hashes inside circuits (#5160)
MirandaWood Mar 21, 2024
fb897db
feat: simplified bb Honk interface (#5319)
ledwards2225 Mar 21, 2024
8cf742d
feat: ZeroMorph working with IPA and integration with ECCVM (#5246)
maramihali Mar 21, 2024
ece6d82
chore: Remove unused FunctionLeafPreimage struct (#5354)
spalladino Mar 21, 2024
0ef7367
fix: Generate noir interface for constructors (#5352)
spalladino Mar 21, 2024
5d1a478
chore: Name change: gen perm sort to delta range constraint (#5378)
ledwards2225 Mar 21, 2024
424401c
git subrepo push --branch=master barretenberg
AztecBot Mar 22, 2024
4447aa9
chore: replace relative paths to noir-protocol-circuits
AztecBot Mar 22, 2024
08c9358
git_subrepo.sh: Fix parent in .gitrepo file. [skip ci]
AztecBot Mar 22, 2024
86a63f7
git subrepo push --branch=master noir-projects/aztec-nr
AztecBot Mar 22, 2024
565f59b
refactor: make get_notes fail if returning no notes #4988 (#5320)
sklppy88 Mar 22, 2024
784585a
feat(AuthWit): chain_id and version in hash (#5331)
LHerskind Mar 22, 2024
a9d22ff
chore: skip slither in docker (#5384)
LHerskind Mar 22, 2024
9ea8186
feat: Dynamic proving (#5346)
PhilWindle Mar 22, 2024
9bc4249
refactor: messaging naming fixes (#5383)
benesjan Mar 22, 2024
0a3ec3d
fix
sklppy88 Mar 22, 2024
eb0d71c
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 22, 2024
a4c86a0
Update note_getter.nr
sklppy88 Mar 22, 2024
2e8e51b
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 22, 2024
a1d8b9a
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 22, 2024
c7955f2
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 22, 2024
8a2ecdf
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 26, 2024
ed51191
fix
sklppy88 Mar 27, 2024
a8f2634
cleanup
sklppy88 Mar 27, 2024
0c71058
cleanup
sklppy88 Mar 27, 2024
86b573a
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 27, 2024
52ec4f6
addressing comments
sklppy88 Mar 27, 2024
a3a34a3
Update noir-projects/aztec-nr/tests/src/note_getter_test.nr
sklppy88 Mar 27, 2024
1c3fc6e
fmt
sklppy88 Mar 27, 2024
ed9d9fd
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 27, 2024
dae4641
address comments
sklppy88 Mar 28, 2024
0ce7455
fix
sklppy88 Mar 28, 2024
7c8abc8
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 28, 2024
c55a9cd
Merge branch 'master' into ek/refactor/get-notes-returns-non-sparse-a…
sklppy88 Mar 28, 2024
b6b4f96
why
sklppy88 Mar 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions noir-projects/aztec-nr/Nargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ members = [
"field-note",
"slow-updates-tree",
"value-note",
"tests",
]
17 changes: 16 additions & 1 deletion noir-projects/aztec-nr/aztec/src/note/note_getter.nr
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ pub fn get_notes<Note, N, FILTER_ARGS>(
options: NoteGetterOptions<Note, N, FILTER_ARGS>
) -> [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where Note: NoteInterface<N> {
let opt_notes = get_notes_internal(storage_slot, options);

_get_notes_constrain_get_notes_internal(context, storage_slot, opt_notes, options)
}

pub fn _get_notes_constrain_get_notes_internal<Note, N, FILTER_ARGS>(
context: &mut PrivateContext,
storage_slot: Field,
opt_notes: [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL],
options: NoteGetterOptions<Note, N, FILTER_ARGS>
) -> [Option<Note>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] where Note: NoteInterface<N> {
let mut returned_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];

let mut num_notes = 0;
let mut prev_fields = [0; N];
for i in 0..opt_notes.len() {
Expand All @@ -120,6 +132,9 @@ pub fn get_notes<Note, N, FILTER_ARGS>(
// failure if malicious oracle injects 0 nonce here for a "pre-existing" note.
context.push_note_hash_read_request(note_hash_for_read_request);

// The below code is used to collapse a sparse array into one where the values are guaranteed to be at the front of the array
// We write at returned_notes[num_notes] because num_notes is only advanced when we have a value in opt_notes
returned_notes[num_notes] = Option::some(note);
num_notes += 1;
};
}
Expand All @@ -129,7 +144,7 @@ pub fn get_notes<Note, N, FILTER_ARGS>(

assert(num_notes != 0, "Cannot return zero notes");

opt_notes
returned_notes
}

unconstrained fn get_note_internal<Note, N>(storage_slot: Field) -> Note where Note: NoteInterface<N> {
Expand Down
9 changes: 9 additions & 0 deletions noir-projects/aztec-nr/tests/Nargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "tests"
authors = ["aztec-labs"]
compiler_version = ">=0.18.0"
type = "lib"

[dependencies]
aztec = { path = "../aztec" }
protocol_types = { path = "../../noir-protocol-circuits/crates/types" }
2 changes: 2 additions & 0 deletions noir-projects/aztec-nr/tests/src/lib.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod note_getter_test;
mod mock;
3 changes: 3 additions & 0 deletions noir-projects/aztec-nr/tests/src/mock.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod test_note;

use test_note::TestNote;
63 changes: 63 additions & 0 deletions noir-projects/aztec-nr/tests/src/mock/test_note.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use dep::aztec::context::PrivateContext;
use dep::aztec::note::{
note_header::NoteHeader,
note_getter_options::{NoteGetterOptions, Select, Sort, SortOrder, Comparator, NoteStatus, PropertySelector},
note_interface::NoteInterface, note_viewer_options::NoteViewerOptions,
utils::compute_note_hash_for_consumption, note_getter::_get_notes_constrain_get_notes_internal
};
sklppy88 marked this conversation as resolved.
Show resolved Hide resolved

global TEST_NOTE_LENGTH = 1;

struct TestNote {
header: NoteHeader,
value: Field,
}

impl NoteInterface<TEST_NOTE_LENGTH> for TestNote {
fn serialize_content(self) -> [Field; TEST_NOTE_LENGTH] {
[self.value]
}

fn deserialize_content(fields: [Field; TEST_NOTE_LENGTH]) -> Self {
Self {
value: fields[0],
header: NoteHeader::empty(),
}
}

fn compute_note_content_hash(self) -> Field {
0
}

fn get_header(self) -> NoteHeader {
self.header
}

fn set_header(&mut self, header: NoteHeader) -> () {
self.header = header;
}

fn get_note_type_id() -> Field {
0
}

fn compute_nullifier(self, _context: &mut PrivateContext) -> Field {
0
}

fn compute_nullifier_without_context(self) -> Field {
0
}

fn broadcast(self, context: &mut PrivateContext, slot: Field) {
assert(
false, "TestNote does not support broadcast."
);
}
}

impl TestNote {
pub fn new(value: Field) -> Self {
TestNote { value, header: NoteHeader::empty() }
}
}
131 changes: 131 additions & 0 deletions noir-projects/aztec-nr/tests/src/note_getter_test.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
use dep::protocol_types::constants::MAX_NOTE_HASH_READ_REQUESTS_PER_CALL;
use dep::aztec::context::PrivateContext;
use dep::aztec::note::{
note_header::NoteHeader,
note_getter_options::{NoteGetterOptions, Sort, SortOrder, Comparator, PropertySelector},
note_getter::_get_notes_constrain_get_notes_internal
};
use dep::aztec::protocol_types::address::AztecAddress;
use crate::mock::test_note::TestNote;

#[test]
fn sets_note_manually_and_fetches_it() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();
context.inputs.call_context.storage_contract_address = AztecAddress::from_field(69);

let mut test_note = TestNote::new(1337);
test_note.header = NoteHeader::new(AztecAddress::from_field(69), 0, 42);

let mut opt_notes = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[0] = Option::some(test_note);

let storage_slot: Field = 42;

let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
sklppy88 marked this conversation as resolved.
Show resolved Hide resolved
opt_notes[0] = Option::some(test_note);

let mut options = NoteGetterOptions::new();
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);
assert_eq(returned[0].unwrap().value, 1337);
}

#[test(should_fail)]
fn cannot_return_zero_notes() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();
let storage_slot: Field = 0;
let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];

let mut options = NoteGetterOptions::new();
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);
}

#[test(should_fail)]
fn mismatched_address() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();
context.inputs.call_context.storage_contract_address = AztecAddress::from_field(1);

let storage_slot: Field = 0;
let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[0] = Option::some(TestNote::new(1));

let mut options = NoteGetterOptions::new();
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);
}

#[test(should_fail)]
fn mismatched_storage_slot() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();
context.inputs.call_context.storage_contract_address = AztecAddress::from_field(1);

let mut test_note = TestNote::new(1);
test_note.header = NoteHeader::new(AztecAddress::from_field(1), 0, 1);

let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[0] = Option::some(test_note);

let storage_slot: Field = 0;

let mut options = NoteGetterOptions::new();
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);
}

#[test(should_fail)]
fn invalid_selector() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();
context.inputs.call_context.storage_contract_address = AztecAddress::from_field(1);

let mut test_note = TestNote::new(1);
test_note.header = NoteHeader::new(AztecAddress::from_field(1), 0, 0);

let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[0] = Option::some(test_note);

let storage_slot: Field = 0;

let mut options = NoteGetterOptions::new().select(
PropertySelector { index: 0, offset: 0, length: 32 },
10,
Option::some(Comparator.EQ)
);
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);
}

#[test(should_fail)]
fn invalid_note_order() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();

let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[0] = Option::some(TestNote::new(1));
opt_notes[1] = Option::some(TestNote::new(2));

let storage_slot: Field = 0;

let mut options = NoteGetterOptions::new().sort(
PropertySelector { index: 0, offset: 0, length: 32 },
SortOrder.DESC
);
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);
}

#[test]
fn sparse_notes_array() {
let mut context: PrivateContext = dep::std::unsafe::zeroed();

let mut opt_notes: [Option<TestNote>; MAX_NOTE_HASH_READ_REQUESTS_PER_CALL] = [Option::none(); MAX_NOTE_HASH_READ_REQUESTS_PER_CALL];
opt_notes[1] = Option::some(TestNote::new(0));
opt_notes[2] = Option::some(TestNote::new(1));
opt_notes[3] = Option::some(TestNote::new(2));
opt_notes[5] = Option::some(TestNote::new(3));
opt_notes[8] = Option::some(TestNote::new(4));
opt_notes[11] = Option::some(TestNote::new(5));
opt_notes[19] = Option::some(TestNote::new(6));

let storage_slot: Field = 0;

let mut options = NoteGetterOptions::new();
let returned = _get_notes_constrain_get_notes_internal(&mut context, storage_slot, opt_notes, options);

for i in 0..7 {
assert(returned[i].unwrap().value == i as Field);
}
}
Loading