Skip to content

Commit a40a9a5

Browse files
AztecBotTomAFrench
andauthored
feat: Sync from aztec-packages (#5125)
Automated pull of Noir development from [aztec-packages](https://github.com/AztecProtocol/aztec-packages). BEGIN_COMMIT_OVERRIDE feat: remove external blackbox solver from acir simulator (AztecProtocol/aztec-packages#6586) chore: remove aes slice (AztecProtocol/aztec-packages#6550) END_COMMIT_OVERRIDE --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: TomAFrench <tom@tomfren.ch>
1 parent 33c2b6b commit a40a9a5

17 files changed

Lines changed: 221 additions & 196 deletions

File tree

.aztec-sync-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
221e2479622aef8e70120dc0a9f91ffcbc99efba
1+
1d785fd1087d7387fc29213ca3be50b2fc9c4725

acvm-repo/acvm_js/src/execute.rs

Lines changed: 5 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,6 @@ use crate::{
1919
JsExecutionError, JsSolvedAndReturnWitness, JsWitnessMap, JsWitnessStack,
2020
};
2121

22-
#[wasm_bindgen]
23-
pub struct WasmBlackBoxFunctionSolver;
24-
25-
impl WasmBlackBoxFunctionSolver {
26-
async fn initialize() -> WasmBlackBoxFunctionSolver {
27-
WasmBlackBoxFunctionSolver
28-
}
29-
}
30-
31-
#[wasm_bindgen(js_name = "createBlackBoxSolver")]
32-
pub async fn create_black_box_solver() -> WasmBlackBoxFunctionSolver {
33-
WasmBlackBoxFunctionSolver::initialize().await
34-
}
35-
3622
/// Executes an ACIR circuit to generate the solved witness from the initial witness.
3723
///
3824
/// @param {Uint8Array} circuit - A serialized representation of an ACIR circuit
@@ -58,14 +44,12 @@ pub async fn execute_circuit(
5844
/// Executes an ACIR circuit to generate the solved witness from the initial witness.
5945
/// This method also extracts the public return values from the solved witness into its own return witness.
6046
///
61-
/// @param {&WasmBlackBoxFunctionSolver} solver - A black box solver.
6247
/// @param {Uint8Array} circuit - A serialized representation of an ACIR circuit
6348
/// @param {WitnessMap} initial_witness - The initial witness map defining all of the inputs to `circuit`..
6449
/// @param {ForeignCallHandler} foreign_call_handler - A callback to process any foreign calls from the circuit.
6550
/// @returns {SolvedAndReturnWitness} The solved witness calculated by executing the circuit on the provided inputs, as well as the return witness indices as specified by the circuit.
6651
#[wasm_bindgen(js_name = executeCircuitWithReturnWitness, skip_jsdoc)]
6752
pub async fn execute_circuit_with_return_witness(
68-
_solver: &WasmBlackBoxFunctionSolver,
6953
program: Vec<u8>,
7054
initial_witness: JsWitnessMap,
7155
foreign_call_handler: ForeignCallHandler,
@@ -94,28 +78,10 @@ pub async fn execute_circuit_with_return_witness(
9478

9579
/// Executes an ACIR circuit to generate the solved witness from the initial witness.
9680
///
97-
/// @param {&WasmBlackBoxFunctionSolver} solver - A black box solver.
98-
/// @param {Uint8Array} circuit - A serialized representation of an ACIR circuit
99-
/// @param {WitnessMap} initial_witness - The initial witness map defining all of the inputs to `circuit`..
100-
/// @param {ForeignCallHandler} foreign_call_handler - A callback to process any foreign calls from the circuit.
101-
/// @returns {WitnessMap} The solved witness calculated by executing the circuit on the provided inputs.
102-
#[wasm_bindgen(js_name = executeCircuitWithBlackBoxSolver, skip_jsdoc)]
103-
pub async fn execute_circuit_with_black_box_solver(
104-
_solver: &WasmBlackBoxFunctionSolver,
105-
program: Vec<u8>,
106-
initial_witness: JsWitnessMap,
107-
foreign_call_handler: ForeignCallHandler,
108-
) -> Result<JsWitnessMap, Error> {
109-
console_error_panic_hook::set_once();
110-
111-
let mut witness_stack =
112-
execute_program_with_native_type_return(program, initial_witness, &foreign_call_handler)
113-
.await?;
114-
let witness_map =
115-
witness_stack.pop().expect("Should have at least one witness on the stack").witness;
116-
Ok(witness_map.into())
117-
}
118-
81+
/// @param {Uint8Array} program - A serialized representation of an ACIR program
82+
/// @param {WitnessMap} initial_witness - The initial witness map defining all of the inputs to `program`.
83+
/// @param {ForeignCallHandler} foreign_call_handler - A callback to process any foreign calls from the program.
84+
/// @returns {WitnessStack} The solved witness calculated by executing the program on the provided inputs.
11985
#[wasm_bindgen(js_name = executeProgram, skip_jsdoc)]
12086
pub async fn execute_program(
12187
program: Vec<u8>,
@@ -124,21 +90,8 @@ pub async fn execute_program(
12490
) -> Result<JsWitnessStack, Error> {
12591
console_error_panic_hook::set_once();
12692

127-
let solver = WasmBlackBoxFunctionSolver::initialize().await;
128-
129-
execute_program_with_black_box_solver(&solver, program, initial_witness, &foreign_call_handler)
130-
.await
131-
}
132-
133-
#[wasm_bindgen(js_name = executeProgramWithBlackBoxSolver, skip_jsdoc)]
134-
pub async fn execute_program_with_black_box_solver(
135-
_solver: &WasmBlackBoxFunctionSolver,
136-
program: Vec<u8>,
137-
initial_witness: JsWitnessMap,
138-
foreign_call_executor: &ForeignCallHandler,
139-
) -> Result<JsWitnessStack, Error> {
14093
let witness_stack =
141-
execute_program_with_native_type_return(program, initial_witness, foreign_call_executor)
94+
execute_program_with_native_type_return(program, initial_witness, &foreign_call_handler)
14295
.await?;
14396

14497
Ok(witness_stack.into())

acvm-repo/acvm_js/src/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@ pub use build_info::build_info;
2323
pub use compression::{
2424
compress_witness, compress_witness_stack, decompress_witness, decompress_witness_stack,
2525
};
26-
pub use execute::{
27-
create_black_box_solver, execute_circuit, execute_circuit_with_black_box_solver,
28-
execute_circuit_with_return_witness, execute_program, execute_program_with_black_box_solver,
29-
};
26+
pub use execute::{execute_circuit, execute_circuit_with_return_witness, execute_program};
3027
pub use js_execution_error::JsExecutionError;
3128
pub use js_witness_map::JsSolvedAndReturnWitness;
3229
pub use js_witness_map::JsWitnessMap;

acvm-repo/acvm_js/test/browser/execute_circuit.test.ts

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
import { expect } from '@esm-bundle/chai';
2-
import initACVM, {
3-
createBlackBoxSolver,
4-
executeCircuit,
5-
executeCircuitWithBlackBoxSolver,
6-
WasmBlackBoxFunctionSolver,
7-
WitnessMap,
8-
initLogLevel,
9-
ForeignCallHandler,
10-
} from '@noir-lang/acvm_js';
2+
import initACVM, { executeCircuit, WitnessMap, initLogLevel, ForeignCallHandler } from '@noir-lang/acvm_js';
113

124
beforeEach(async () => {
135
await initACVM();
@@ -122,23 +114,3 @@ it('successfully executes a MemoryOp opcode', async () => {
122114

123115
expect(solvedWitness).to.be.deep.eq(expectedWitnessMap);
124116
});
125-
126-
it('successfully executes two circuits with same backend', async function () {
127-
// chose pedersen op here because it is the one with slow initialization
128-
// that led to the decision to pull backend initialization into a separate
129-
// function/wasmbind
130-
const solver: WasmBlackBoxFunctionSolver = await createBlackBoxSolver();
131-
132-
const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/pedersen');
133-
134-
const solvedWitness0: WitnessMap = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => {
135-
throw Error('unexpected oracle');
136-
});
137-
138-
expect(solvedWitness0).to.be.deep.eq(expectedWitnessMap);
139-
140-
const solvedWitness1: WitnessMap = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => {
141-
throw Error('unexpected oracle');
142-
});
143-
expect(solvedWitness1).to.be.deep.eq(expectedWitnessMap);
144-
});

acvm-repo/acvm_js/test/node/execute_circuit.test.ts

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { expect } from 'chai';
22
import {
3-
createBlackBoxSolver,
43
executeCircuit,
5-
executeCircuitWithBlackBoxSolver,
6-
WasmBlackBoxFunctionSolver,
74
WitnessMap,
85
ForeignCallHandler,
96
executeProgram,
@@ -120,40 +117,18 @@ it('successfully executes a MemoryOp opcode', async () => {
120117
expect(solvedWitness).to.be.deep.eq(expectedWitnessMap);
121118
});
122119

123-
it('successfully executes two circuits with same backend', async function () {
124-
this.timeout(10000);
125-
126-
// chose pedersen op here because it is the one with slow initialization
127-
// that led to the decision to pull backend initialization into a separate
128-
// function/wasmbind
129-
const solver: WasmBlackBoxFunctionSolver = await createBlackBoxSolver();
130-
131-
const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/pedersen');
132-
133-
const solvedWitness0 = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => {
134-
throw Error('unexpected oracle');
135-
});
136-
137-
const solvedWitness1 = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => {
138-
throw Error('unexpected oracle');
139-
});
140-
141-
expect(solvedWitness0).to.be.deep.eq(expectedWitnessMap);
142-
expect(solvedWitness1).to.be.deep.eq(expectedWitnessMap);
143-
});
144-
145-
it('successfully executes 500 circuits with same backend', async function () {
120+
it('successfully executes 500 pedersen circuits', async function () {
146121
this.timeout(100000);
147122

148-
// chose pedersen op here because it is the one with slow initialization
149-
// that led to the decision to pull backend initialization into a separate
150-
// function/wasmbind
151-
const solver: WasmBlackBoxFunctionSolver = await createBlackBoxSolver();
123+
// Pedersen opcodes used to have a large upfront cost due to generator calculation
124+
// so we'd need to pass around the blackbox solver in JS to avoid redoing this work.
125+
//
126+
// This test now shows that we don't need to do this anymore without a performance regression.
152127

153128
const { bytecode, initialWitnessMap, expectedWitnessMap } = await import('../shared/pedersen');
154129

155130
for (let i = 0; i < 500; i++) {
156-
const solvedWitness = await executeCircuitWithBlackBoxSolver(solver, bytecode, initialWitnessMap, () => {
131+
const solvedWitness = await executeCircuit(bytecode, initialWitnessMap, () => {
157132
throw Error('unexpected oracle');
158133
});
159134

aztec_macros/src/lib.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ fn transform_module(
134134
for func in module.functions.iter_mut() {
135135
let mut is_private = false;
136136
let mut is_public = false;
137-
let mut is_public_vm = false;
138137
let mut is_initializer = false;
139138
let mut is_internal = false;
140139
let mut insert_init_check = has_initializer;
@@ -152,23 +151,15 @@ fn transform_module(
152151
is_internal = true;
153152
} else if is_custom_attribute(&secondary_attribute, "aztec(public)") {
154153
is_public = true;
155-
} else if is_custom_attribute(&secondary_attribute, "aztec(public-vm)") {
156-
is_public_vm = true;
157154
}
158155
if is_custom_attribute(&secondary_attribute, "aztec(view)") {
159156
is_static = true;
160157
}
161158
}
162159

163160
// Apply transformations to the function based on collected attributes
164-
if is_private || is_public || is_public_vm {
165-
let fn_type = if is_private {
166-
"Private"
167-
} else if is_public_vm {
168-
"Avm"
169-
} else {
170-
"Public"
171-
};
161+
if is_private || is_public {
162+
let fn_type = if is_private { "Private" } else { "Public" };
172163
let stub_src = stub_function(fn_type, func, is_static);
173164
stubs.push((stub_src, Location { file: *file_id, span: func.name_ident().span() }));
174165

aztec_macros/src/transforms/contract_interface.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call
8888
})
8989
.collect::<Vec<_>>()
9090
.join("");
91-
if aztec_visibility != "Avm" {
91+
if aztec_visibility != "Public" {
9292
let args_hash = if !parameters.is_empty() {
9393
format!(
9494
"let mut args_acc: [Field] = &[];
@@ -125,7 +125,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call
125125
);
126126
let fn_body = format!(
127127
"{}
128-
dep::aztec::context::Avm{}{}CallInterface {{
128+
dep::aztec::context::Public{}{}CallInterface {{
129129
target_contract: self.target_contract,
130130
selector: {},
131131
args: args_acc,
@@ -134,7 +134,7 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call
134134
args, is_static, is_void, fn_selector,
135135
);
136136
format!(
137-
"pub fn {}(self, {}) -> dep::aztec::context::Avm{}{}CallInterface{} {{
137+
"pub fn {}(self, {}) -> dep::aztec::context::Public{}{}CallInterface{} {{
138138
{}
139139
}}",
140140
fn_name, fn_parameters, is_static, is_void, return_type_hint, fn_body

aztec_macros/src/transforms/functions.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ pub fn transform_function(
3636
is_internal: bool,
3737
is_static: bool,
3838
) -> Result<(), AztecMacroError> {
39+
assert!(matches!(ty, "Private" | "Public"));
3940
let context_name = format!("{}Context", ty);
4041
let inputs_name = format!("{}ContextInputs", ty);
4142
let return_type_name = format!("{}CircuitPublicInputs", ty);
42-
let is_avm = ty == "Avm";
4343
let is_private = ty == "Private";
4444

4545
// Force a static context if the function is static
4646
if is_static {
47-
let is_static_check = create_static_check(func.name(), is_avm);
47+
let is_static_check = create_static_check(func.name(), is_private);
4848
func.def.body.statements.insert(0, is_static_check);
4949
}
5050

@@ -72,10 +72,10 @@ pub fn transform_function(
7272
}
7373

7474
// Insert the context creation as the first action
75-
let create_context = if !is_avm {
76-
create_context(&context_name, &func.def.parameters)?
75+
let create_context = if is_private {
76+
create_context_private(&context_name, &func.def.parameters)?
7777
} else {
78-
create_context_avm()?
78+
create_context_public()?
7979
};
8080
func.def.body.statements.splice(0..0, (create_context).iter().cloned());
8181

@@ -84,7 +84,7 @@ pub fn transform_function(
8484
func.def.parameters.insert(0, input);
8585

8686
// Abstract return types such that they get added to the kernel's return_values
87-
if !is_avm {
87+
if is_private {
8888
if let Some(return_values_statements) = abstract_return_values(func)? {
8989
// In case we are pushing return values to the context, we remove the statement that originated it
9090
// This avoids running duplicate code, since blocks like if/else can be value returning statements
@@ -101,13 +101,13 @@ pub fn transform_function(
101101
}
102102

103103
// Push the finish method call to the end of the function
104-
if !is_avm {
104+
if is_private {
105105
let finish_def = create_context_finish();
106106
func.def.body.statements.push(finish_def);
107107
}
108108

109109
// The AVM doesn't need a return type yet.
110-
if !is_avm {
110+
if is_private {
111111
let return_type = create_return_type(&return_type_name);
112112
func.def.return_type = return_type;
113113
func.def.return_visibility = Visibility::Public;
@@ -116,7 +116,7 @@ pub fn transform_function(
116116
}
117117

118118
// Public functions should have unconstrained auto-inferred
119-
func.def.is_unconstrained = matches!(ty, "Public" | "Avm");
119+
func.def.is_unconstrained = !is_private;
120120

121121
// Private functions need to be recursive
122122
if is_private {
@@ -285,8 +285,8 @@ fn create_mark_as_initialized(ty: &str) -> Statement {
285285
/// ```noir
286286
/// assert(context.inputs.call_context.is_static_call == true, "Function can only be called statically")
287287
/// ```
288-
fn create_static_check(fname: &str, is_avm: bool) -> Statement {
289-
let is_static_call_expr = if !is_avm {
288+
fn create_static_check(fname: &str, is_private: bool) -> Statement {
289+
let is_static_call_expr = if is_private {
290290
["inputs", "call_context", "is_static_call"]
291291
.iter()
292292
.fold(variable("context"), |acc, member| member_access(acc, member))
@@ -410,7 +410,7 @@ fn serialize_to_hasher(
410410
/// let mut context = PrivateContext::new(inputs, hasher.hash());
411411
/// }
412412
/// ```
413-
fn create_context(ty: &str, params: &[Param]) -> Result<Vec<Statement>, AztecMacroError> {
413+
fn create_context_private(ty: &str, params: &[Param]) -> Result<Vec<Statement>, AztecMacroError> {
414414
let mut injected_statements: Vec<Statement> = vec![];
415415

416416
let hasher_name = "args_hasher";
@@ -471,30 +471,33 @@ fn create_context(ty: &str, params: &[Param]) -> Result<Vec<Statement>, AztecMac
471471
Ok(injected_statements)
472472
}
473473

474-
/// Creates the private context object to be accessed within the function, the parameters need to be extracted to be
475-
/// appended into the args hash object.
474+
/// Creates the public context object to be accessed within the function.
476475
///
477476
/// The replaced code:
478477
/// ```noir
479-
/// #[aztec(public-vm)]
480-
/// fn foo(inputs: AvmContextInputs, ...) -> Field {
481-
/// let mut context = AvmContext::new(inputs);
478+
/// #[aztec(public)]
479+
/// fn foo(inputs: PublicContextInputs, ...) -> Field {
480+
/// let mut context = PublicContext::new(inputs);
482481
/// }
483482
/// ```
484-
fn create_context_avm() -> Result<Vec<Statement>, AztecMacroError> {
483+
fn create_context_public() -> Result<Vec<Statement>, AztecMacroError> {
485484
let mut injected_expressions: Vec<Statement> = vec![];
486485

487486
// Create the inputs to the context
488-
let ty = "AvmContext";
489487
let inputs_expression = variable("inputs");
490-
let path_snippet = ty.to_case(Case::Snake); // e.g. private_context
491488

492489
// let mut context = {ty}::new(inputs, hash);
493490
let let_context = mutable_assignment(
494491
"context", // Assigned to
495492
call(
496-
variable_path(chained_dep!("aztec", "context", &path_snippet, ty, "new")), // Path
497-
vec![inputs_expression], // args
493+
variable_path(chained_dep!(
494+
"aztec",
495+
"context",
496+
"public_context",
497+
"PublicContext",
498+
"new"
499+
)), // Path
500+
vec![inputs_expression], // args
498501
),
499502
);
500503
injected_expressions.push(let_context);

0 commit comments

Comments
 (0)