Skip to content

Commit

Permalink
feat: Sync from aztec-packages (#4764)
Browse files Browse the repository at this point in the history
Automated pull of Noir development from
[aztec-packages](https://github.com/AztecProtocol/aztec-packages).
BEGIN_COMMIT_OVERRIDE
feat: Sync from noir
(AztecProtocol/aztec-packages#5619)
feat: add return values to aztec fns
(AztecProtocol/aztec-packages#5389)
feat!: storage_layout and `#[aztec(storage)]`
(AztecProtocol/aztec-packages#5387)
feat(acir)!: Add predicate to call opcode
(AztecProtocol/aztec-packages#5616)
feat: Sync from noir
(AztecProtocol/aztec-packages#5572)
feat!: contract_abi-exports
(AztecProtocol/aztec-packages#5386)
feat(avm): integrate AVM with initializers
(AztecProtocol/aztec-packages#5469)
feat: Restore hashing args via slice for performance
(AztecProtocol/aztec-packages#5539)
END_COMMIT_OVERRIDE

---------

Co-authored-by: sirasistant <sirasistant@gmail.com>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
Co-authored-by: vezenovm <mvezenov@gmail.com>
Co-authored-by: TomAFrench <tom@tomfren.ch>
  • Loading branch information
5 people committed Apr 11, 2024
1 parent f831b0b commit 2bd006a
Show file tree
Hide file tree
Showing 51 changed files with 1,272 additions and 549 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bb719200034e3bc6db09fb56538dadca4203abf4
ff28080bcfb946177010960722925973ee19646b
30 changes: 15 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions acvm-repo/acir/codegen/acir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,6 +1074,7 @@ namespace Program {
uint32_t id;
std::vector<Program::Witness> inputs;
std::vector<Program::Witness> outputs;
std::optional<Program::Expression> predicate;

friend bool operator==(const Call&, const Call&);
std::vector<uint8_t> bincodeSerialize() const;
Expand Down Expand Up @@ -6173,6 +6174,7 @@ namespace Program {
if (!(lhs.id == rhs.id)) { return false; }
if (!(lhs.inputs == rhs.inputs)) { return false; }
if (!(lhs.outputs == rhs.outputs)) { return false; }
if (!(lhs.predicate == rhs.predicate)) { return false; }
return true;
}

Expand All @@ -6199,6 +6201,7 @@ void serde::Serializable<Program::Opcode::Call>::serialize(const Program::Opcode
serde::Serializable<decltype(obj.id)>::serialize(obj.id, serializer);
serde::Serializable<decltype(obj.inputs)>::serialize(obj.inputs, serializer);
serde::Serializable<decltype(obj.outputs)>::serialize(obj.outputs, serializer);
serde::Serializable<decltype(obj.predicate)>::serialize(obj.predicate, serializer);
}

template <>
Expand All @@ -6208,6 +6211,7 @@ Program::Opcode::Call serde::Deserializable<Program::Opcode::Call>::deserialize(
obj.id = serde::Deserializable<decltype(obj.id)>::deserialize(deserializer);
obj.inputs = serde::Deserializable<decltype(obj.inputs)>::deserialize(deserializer);
obj.outputs = serde::Deserializable<decltype(obj.outputs)>::deserialize(deserializer);
obj.predicate = serde::Deserializable<decltype(obj.predicate)>::deserialize(deserializer);
return obj;
}

Expand Down
7 changes: 6 additions & 1 deletion acvm-repo/acir/src/circuit/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ pub enum Opcode {
inputs: Vec<Witness>,
/// Outputs of the function call
outputs: Vec<Witness>,
/// Predicate of the circuit execution - indicates if it should be skipped
predicate: Option<Expression>,
},
}

Expand Down Expand Up @@ -97,8 +99,11 @@ impl std::fmt::Display for Opcode {
write!(f, "INIT ")?;
write!(f, "(id: {}, len: {}) ", block_id.0, init.len())
}
Opcode::Call { id, inputs, outputs } => {
Opcode::Call { id, inputs, outputs, predicate } => {
write!(f, "CALL func {}: ", id)?;
if let Some(pred) = predicate {
writeln!(f, "PREDICATE = {pred}")?;
}
write!(f, "inputs: {:?}, ", inputs)?;
write!(f, "outputs: {:?}", outputs)
}
Expand Down
40 changes: 26 additions & 14 deletions acvm-repo/acir/tests/test_program_serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,18 @@ fn nested_acir_call_circuit() {
// assert(x == y);
// x
// }
let nested_call =
Opcode::Call { id: 1, inputs: vec![Witness(0), Witness(1)], outputs: vec![Witness(2)] };
let nested_call_two =
Opcode::Call { id: 1, inputs: vec![Witness(0), Witness(1)], outputs: vec![Witness(3)] };
let nested_call = Opcode::Call {
id: 1,
inputs: vec![Witness(0), Witness(1)],
outputs: vec![Witness(2)],
predicate: None,
};
let nested_call_two = Opcode::Call {
id: 1,
inputs: vec![Witness(0), Witness(1)],
outputs: vec![Witness(3)],
predicate: None,
};

let assert_nested_call_results = Opcode::AssertZero(Expression {
mul_terms: Vec::new(),
Expand All @@ -410,8 +418,12 @@ fn nested_acir_call_circuit() {
],
q_c: FieldElement::one() + FieldElement::one(),
});
let call =
Opcode::Call { id: 2, inputs: vec![Witness(2), Witness(1)], outputs: vec![Witness(3)] };
let call = Opcode::Call {
id: 2,
inputs: vec![Witness(2), Witness(1)],
outputs: vec![Witness(3)],
predicate: None,
};

let nested_call = Circuit {
current_witness_index: 3,
Expand Down Expand Up @@ -444,14 +456,14 @@ fn nested_acir_call_circuit() {

let expected_serialization: Vec<u8> = vec![
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 97, 10, 195, 32, 12, 133, 163, 66, 207, 147,
24, 109, 227, 191, 93, 101, 50, 123, 255, 35, 172, 99, 25, 83, 17, 250, 99, 14, 250, 224,
97, 144, 16, 146, 143, 231, 224, 45, 167, 126, 105, 57, 108, 14, 91, 248, 202, 168, 65,
255, 207, 122, 28, 180, 250, 244, 221, 244, 197, 223, 68, 182, 154, 197, 184, 134, 80, 54,
95, 136, 233, 142, 62, 101, 137, 24, 98, 94, 133, 132, 162, 196, 135, 23, 230, 34, 65, 182,
148, 211, 134, 137, 2, 23, 218, 99, 226, 93, 135, 185, 121, 123, 33, 84, 12, 234, 218, 192,
64, 174, 3, 248, 47, 88, 48, 17, 150, 157, 183, 151, 95, 244, 86, 91, 221, 61, 10, 81, 31,
178, 190, 110, 194, 102, 96, 76, 251, 202, 80, 13, 204, 77, 224, 25, 176, 70, 79, 197, 128,
18, 64, 3, 4, 0, 0,
24, 173, 241, 223, 174, 50, 153, 189, 255, 17, 214, 177, 148, 89, 17, 250, 99, 14, 246,
224, 97, 144, 16, 146, 143, 231, 224, 45, 167, 126, 105, 217, 109, 118, 91, 248, 200, 168,
225, 248, 191, 106, 114, 208, 233, 104, 188, 233, 139, 223, 137, 108, 51, 139, 113, 13,
161, 38, 95, 137, 233, 142, 62, 23, 137, 24, 98, 89, 133, 132, 162, 196, 135, 23, 230, 42,
65, 82, 46, 57, 97, 166, 192, 149, 182, 152, 121, 211, 97, 110, 222, 94, 8, 13, 132, 182,
54, 48, 144, 235, 8, 254, 10, 22, 76, 132, 101, 231, 237, 229, 23, 189, 213, 54, 119, 15,
83, 212, 199, 172, 175, 79, 113, 51, 48, 198, 253, 207, 84, 13, 204, 141, 224, 21, 176,
147, 158, 66, 231, 43, 145, 6, 4, 0, 0,
];
assert_eq!(bytes, expected_serialization);
}
15 changes: 7 additions & 8 deletions acvm-repo/acvm/src/pwg/memory_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use acir::{
FieldElement,
};

use super::{arithmetic::ExpressionSolver, get_value, insert_value, witness_to_value};
use super::{
arithmetic::ExpressionSolver, get_value, insert_value, is_predicate_false, witness_to_value,
};
use super::{ErrorLocation, OpcodeResolutionError};

type MemoryIndex = u32;
Expand Down Expand Up @@ -80,11 +82,8 @@ impl MemoryOpSolver {
// `operation == 0` implies a read operation. (`operation == 1` implies write operation).
let is_read_operation = operation.is_zero();

// If the predicate is `None`, then we simply return the value 1
let pred_value = match predicate {
Some(pred) => get_value(pred, initial_witness),
None => Ok(FieldElement::one()),
}?;
// Fetch whether or not the predicate is false (e.g. equal to zero)
let skip_operation = is_predicate_false(initial_witness, predicate)?;

if is_read_operation {
// `value_read = arr[memory_index]`
Expand All @@ -97,7 +96,7 @@ impl MemoryOpSolver {

// A zero predicate indicates that we should skip the read operation
// and zero out the operation's output.
let value_in_array = if pred_value.is_zero() {
let value_in_array = if skip_operation {
FieldElement::zero()
} else {
self.read_memory_index(memory_index)?
Expand All @@ -111,7 +110,7 @@ impl MemoryOpSolver {
let value_write = value;

// A zero predicate indicates that we should skip the write operation.
if pred_value.is_zero() {
if skip_operation {
// We only want to write to already initialized memory.
// Do nothing if the predicate is zero.
Ok(())
Expand Down
28 changes: 26 additions & 2 deletions acvm-repo/acvm/src/pwg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> {
};

let witness = &mut self.witness_map;
if BrilligSolver::<B>::should_skip(witness, brillig)? {
if is_predicate_false(witness, &brillig.predicate)? {
return BrilligSolver::<B>::zero_out_brillig_outputs(witness, brillig).map(|_| None);
}

Expand Down Expand Up @@ -448,7 +448,9 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> {
}

pub fn solve_call_opcode(&mut self) -> Result<Option<AcirCallWaitInfo>, OpcodeResolutionError> {
let Opcode::Call { id, inputs, outputs } = &self.opcodes[self.instruction_pointer] else {
let Opcode::Call { id, inputs, outputs, predicate } =
&self.opcodes[self.instruction_pointer]
else {
unreachable!("Not executing a Call opcode");
};
if *id == 0 {
Expand All @@ -459,6 +461,14 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> {
});
}

if is_predicate_false(&self.witness_map, predicate)? {
// Zero out the outputs if we have a false predicate
for output in outputs {
insert_value(output, FieldElement::zero(), &mut self.witness_map)?;
}
return Ok(None);
}

if self.acir_call_counter >= self.acir_call_results.len() {
let mut initial_witness = WitnessMap::default();
for (i, input_witness) in inputs.iter().enumerate() {
Expand Down Expand Up @@ -556,6 +566,20 @@ fn any_witness_from_expression(expr: &Expression) -> Option<Witness> {
}
}

/// Returns `true` if the predicate is zero
/// A predicate is used to indicate whether we should skip a certain operation.
/// If we have a zero predicate it means the operation should be skipped.
pub(crate) fn is_predicate_false(
witness: &WitnessMap,
predicate: &Option<Expression>,
) -> Result<bool, OpcodeResolutionError> {
match predicate {
Some(pred) => get_value(pred, witness).map(|pred_value| pred_value.is_zero()),
// If the predicate is `None`, then we treat it as an unconditional `true`
None => Ok(false),
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct AcirCallWaitInfo {
/// Index in the list of ACIR function's that should be called
Expand Down
7 changes: 7 additions & 0 deletions acvm-repo/acvm_js/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ function run_or_fail {
exit $status
fi
}
function run_if_available {
if command -v "$1" >/dev/null 2>&1; then
"$@"
else
echo "$1 is not installed. Please install it to use this feature." >&2
fi
}

require_command jq
require_command cargo
Expand Down
14 changes: 7 additions & 7 deletions acvm-repo/acvm_js/test/shared/nested_acir_call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { WitnessMap, StackItem, WitnessStack } from '@noir-lang/acvm_js';

// See `nested_acir_call_circuit` integration test in `acir/tests/test_program_serialization.rs`.
export const bytecode = Uint8Array.from([
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 97, 10, 195, 32, 12, 133, 163, 66, 207, 147, 24, 109, 227, 191, 93, 101,
50, 123, 255, 35, 172, 99, 25, 83, 17, 250, 99, 14, 250, 224, 97, 144, 16, 146, 143, 231, 224, 45, 167, 126, 105, 57,
108, 14, 91, 248, 202, 168, 65, 255, 207, 122, 28, 180, 250, 244, 221, 244, 197, 223, 68, 182, 154, 197, 184, 134, 80,
54, 95, 136, 233, 142, 62, 101, 137, 24, 98, 94, 133, 132, 162, 196, 135, 23, 230, 34, 65, 182, 148, 211, 134, 137, 2,
23, 218, 99, 226, 93, 135, 185, 121, 123, 33, 84, 12, 234, 218, 192, 64, 174, 3, 248, 47, 88, 48, 17, 150, 157, 183,
151, 95, 244, 86, 91, 221, 61, 10, 81, 31, 178, 190, 110, 194, 102, 96, 76, 251, 202, 80, 13, 204, 77, 224, 25, 176,
70, 79, 197, 128, 18, 64, 3, 4, 0, 0,
31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 205, 146, 97, 10, 195, 32, 12, 133, 163, 66, 207, 147, 24, 173, 241, 223, 174, 50,
153, 189, 255, 17, 214, 177, 148, 89, 17, 250, 99, 14, 246, 224, 97, 144, 16, 146, 143, 231, 224, 45, 167, 126, 105,
217, 109, 118, 91, 248, 200, 168, 225, 248, 191, 106, 114, 208, 233, 104, 188, 233, 139, 223, 137, 108, 51, 139, 113,
13, 161, 38, 95, 137, 233, 142, 62, 23, 137, 24, 98, 89, 133, 132, 162, 196, 135, 23, 230, 42, 65, 82, 46, 57, 97,
166, 192, 149, 182, 152, 121, 211, 97, 110, 222, 94, 8, 13, 132, 182, 54, 48, 144, 235, 8, 254, 10, 22, 76, 132, 101,
231, 237, 229, 23, 189, 213, 54, 119, 15, 83, 212, 199, 172, 175, 79, 113, 51, 48, 198, 253, 207, 84, 13, 204, 141,
224, 21, 176, 147, 158, 66, 231, 43, 145, 6, 4, 0, 0,
]);

export const initialWitnessMap: WitnessMap = new Map([
Expand Down
Loading

0 comments on commit 2bd006a

Please sign in to comment.