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

fix: handle struct with nested arrays in oracle return values #5244

Merged
merged 3 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
9 changes: 7 additions & 2 deletions acvm-repo/brillig_vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@
self.set_program_counter(*location)
}
Opcode::Const { destination, value, bit_size } => {
// Consts are not checked in runtime to fit in the bit size, since they can safely be checked statically.

Check warning on line 339 in acvm-repo/brillig_vm/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (Consts)
self.memory.write(*destination, MemoryValue::new_from_field(*value, *bit_size));
self.increment_program_counter()
}
Expand Down Expand Up @@ -500,9 +500,14 @@
match output {
ForeignCallParam::Array(values) => {
if values.len() != *size {
return Err("Foreign call result array doesn't match expected size".to_string());
// foreign call returning flattened values into a nested type, so the sizes do not match
let destination = self.memory.read_ref(*pointer_index);
let return_type = value_type;
let mut flatten_values_idx = 0; //index of values read from flatten_values
self.write_slice_of_values_to_memory(destination, &output.fields(), &mut flatten_values_idx, return_type)?;
} else {
self.write_values_to_memory_slice(*pointer_index, values, value_types)?;
}
self.write_values_to_memory_slice(*pointer_index, values, value_types)?;
}
_ => {
return Err("Function result size does not match brillig bytecode size".to_string());
Expand Down Expand Up @@ -790,7 +795,7 @@
}

#[test]
fn jmpifnot_opcode() {

Check warning on line 798 in acvm-repo/brillig_vm/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (jmpifnot)
let calldata: Vec<FieldElement> = vec![1u128.into(), 2u128.into()];

let calldata_copy = Opcode::CalldataCopy {
Expand Down Expand Up @@ -925,7 +930,7 @@
}

#[test]
fn cmov_opcode() {

Check warning on line 933 in acvm-repo/brillig_vm/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (cmov)
let calldata: Vec<FieldElement> =
vec![(0u128).into(), (1u128).into(), (2u128).into(), (3u128).into()];

Expand Down
34 changes: 33 additions & 1 deletion test_programs/noir_test_success/regression_4561/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,36 @@ unconstrained fn two_nested_return_unconstrained() -> (Field, TReturn, Field, TR
fn two_nested_return() {
OracleMock::mock("two_nested_return").returns((0, [1, 2, 3, 4, 5, 6], 7, [1, 2, 3, 4, 5, 6]));
assert_eq(two_nested_return_unconstrained(), (0, [[1, 2, 3], [4, 5, 6]], 7, [[1, 2, 3], [4, 5, 6]]));
}
}

#[oracle(foo_return)]
unconstrained fn foo_return() -> (Field, TReturn, TestTypeFoo) {}
unconstrained fn foo_return_unconstrained() -> (Field, TReturn, TestTypeFoo) {
foo_return()
}
struct TestTypeFoo {
a: Field,
b: [[[Field; 3]; 4]; 2],
c: [TReturnElem; 2],
d: TReturnElem,
}
#[test]
fn complexe_struct_return() {
OracleMock::mock("foo_return").returns(
(
0, [1, 2, 3, 4, 5, 6], 7, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [1, 2, 3, 4, 5, 6]
)
);
let foo_x = foo_return_unconstrained();
assert_eq((foo_x.0, foo_x.1), (0, [[1, 2, 3], [4, 5, 6]]));
assert_eq(foo_x.2.a, 7);
assert_eq(
foo_x.2.b, [
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18], [19, 20, 21], [22, 23, 24]]
]
);
let a : TReturnElem= [1, 2, 3];
let b : TReturnElem = [4, 5, 6];
assert_eq(foo_x.2.c, [a, b]);
assert_eq(foo_x.2.d, a);
}
Loading