Skip to content

Commit 0c6eb40

Browse files
author
AztecBot
committed
feat(avm): plumb execution hints from TS to AVM prover (AztecProtocol/aztec-packages#6806)
1 parent a40a9a5 commit 0c6eb40

File tree

74 files changed

+26210
-684
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+26210
-684
lines changed

.aztec-sync-commit

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1d785fd1087d7387fc29213ca3be50b2fc9c4725
1+
f3234f1bf037b68237bd6a8b2bce8b016bb170d0

Cargo.lock

+3-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

acvm-repo/acir_field/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ repository.workspace = true
1616
hex.workspace = true
1717
num-bigint.workspace = true
1818
serde.workspace = true
19-
num-traits.workspace = true
2019

2120
ark-bn254 = { version = "^0.4.0", default-features = false, features = ["curve"] }
2221
ark-bls12-381 = { version = "^0.4.0", optional = true, default-features = false, features = ["curve"] }

acvm-repo/acir_field/src/lib.rs

-32
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
#![warn(unreachable_pub)]
33
#![warn(clippy::semicolon_if_nothing_returned)]
44
#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))]
5-
6-
use num_bigint::BigUint;
7-
use num_traits::Num;
85
mod generic_ark;
96

107
pub use generic_ark::AcirField;
@@ -15,40 +12,11 @@ pub use generic_ark::FieldElement as GenericFieldElement;
1512
cfg_if::cfg_if! {
1613
if #[cfg(feature = "bls12_381")] {
1714
pub type FieldElement = generic_ark::FieldElement<ark_bls12_381::Fr>;
18-
pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BLS12_381;
1915
} else {
2016
pub type FieldElement = generic_ark::FieldElement<ark_bn254::Fr>;
21-
pub const CHOSEN_FIELD : FieldOptions = FieldOptions::BN254;
2217
}
2318
}
2419

25-
#[derive(Debug, PartialEq, Eq)]
26-
pub enum FieldOptions {
27-
BN254,
28-
BLS12_381,
29-
}
30-
31-
impl FieldOptions {
32-
pub fn to_string(&self) -> &str {
33-
match self {
34-
FieldOptions::BN254 => "bn254",
35-
FieldOptions::BLS12_381 => "bls12_381",
36-
}
37-
}
38-
39-
pub fn is_native_field(str: &str) -> bool {
40-
let big_num = if let Some(hex) = str.strip_prefix("0x") {
41-
BigUint::from_str_radix(hex, 16)
42-
} else {
43-
BigUint::from_str_radix(str, 10)
44-
};
45-
if let Ok(big_num) = big_num {
46-
big_num == FieldElement::modulus()
47-
} else {
48-
CHOSEN_FIELD.to_string() == str
49-
}
50-
}
51-
}
5220
// This is needed because features are additive through the dependency graph; if a dependency turns on the bn254, then it
5321
// will be turned on in all crates that depend on it
5422
#[macro_export]

acvm-repo/acvm_js/build.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function run_if_available {
2525
require_command jq
2626
require_command cargo
2727
require_command wasm-bindgen
28-
# require_command wasm-opt
28+
#require_command wasm-opt
2929

3030
self_path=$(dirname "$(readlink -f "$0")")
3131
pname=$(cargo read-manifest | jq -r '.name')

aztec_macros/src/transforms/functions.rs

+24-10
Original file line numberDiff line numberDiff line change
@@ -216,12 +216,30 @@ pub fn export_fn_abi(
216216
///
217217
/// Inserts the following code at the beginning of an unconstrained function
218218
/// ```noir
219-
/// let storage = Storage::init(Context::none());
219+
/// let context = UnconstrainedContext::new();
220+
/// let storage = Storage::init(context);
220221
/// ```
221222
///
222223
/// This will allow developers to access their contract' storage struct in unconstrained functions
223224
pub fn transform_unconstrained(func: &mut NoirFunction, storage_struct_name: String) {
225+
// let context = UnconstrainedContext::new();
226+
let let_context = assignment(
227+
"context", // Assigned to
228+
call(
229+
variable_path(chained_dep!(
230+
"aztec",
231+
"context",
232+
"unconstrained_context",
233+
"UnconstrainedContext",
234+
"new"
235+
)),
236+
vec![],
237+
),
238+
);
239+
240+
// We inject the statements at the beginning, in reverse order.
224241
func.def.body.statements.insert(0, abstract_storage(storage_struct_name, true));
242+
func.def.body.statements.insert(0, let_context);
225243
}
226244

227245
/// Helper function that returns what the private context would look like in the ast
@@ -597,30 +615,26 @@ fn abstract_return_values(func: &NoirFunction) -> Result<Option<Vec<Statement>>,
597615
/// ```noir
598616
/// #[aztec(private)]
599617
/// fn lol() {
600-
/// let storage = Storage::init(context);
618+
/// let storage = Storage::init(&mut context);
601619
/// }
602620
/// ```
603621
///
604622
/// For public functions:
605623
/// ```noir
606624
/// #[aztec(public)]
607625
/// fn lol() {
608-
/// let storage = Storage::init(context);
626+
/// let storage = Storage::init(&mut context);
609627
/// }
610628
/// ```
611629
///
612630
/// For unconstrained functions:
613631
/// ```noir
614632
/// unconstrained fn lol() {
615-
/// let storage = Storage::init(());
633+
/// let storage = Storage::init(context);
616634
/// }
617635
fn abstract_storage(storage_struct_name: String, unconstrained: bool) -> Statement {
618-
let context_expr = if unconstrained {
619-
// Note that the literal unit type (i.e. '()') is not the same as a tuple with zero elements
620-
expression(ExpressionKind::Literal(Literal::Unit))
621-
} else {
622-
mutable_reference("context")
623-
};
636+
let context_expr =
637+
if unconstrained { variable("context") } else { mutable_reference("context") };
624638

625639
assignment(
626640
"storage", // Assigned to

compiler/noirc_driver/src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ pub struct CompileOptions {
103103
/// Enable the experimental elaborator pass
104104
#[arg(long, hide = true)]
105105
pub use_elaborator: bool,
106+
107+
/// Outputs the paths to any modified artifacts
108+
#[arg(long, hide = true)]
109+
pub show_artifact_paths: bool,
106110
}
107111

108112
fn parse_expression_width(input: &str) -> Result<ExpressionWidth, std::io::Error> {

compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs

+31-44
Original file line numberDiff line numberDiff line change
@@ -1732,29 +1732,44 @@ impl<'a> Context<'a> {
17321732
) -> Result<Vec<SsaReport>, RuntimeError> {
17331733
let (return_values, call_stack) = match terminator {
17341734
TerminatorInstruction::Return { return_values, call_stack } => {
1735-
(return_values, call_stack)
1735+
(return_values, call_stack.clone())
17361736
}
17371737
// TODO(https://github.com/noir-lang/noir/issues/4616): Enable recursion on foldable/non-inlined ACIR functions
17381738
_ => unreachable!("ICE: Program must have a singular return"),
17391739
};
17401740

1741-
// The return value may or may not be an array reference. Calling `flatten_value_list`
1742-
// will expand the array if there is one.
1743-
let return_acir_vars = self.flatten_value_list(return_values, dfg)?;
1744-
let mut warnings = Vec::new();
1745-
for (acir_var, is_databus) in return_acir_vars {
1746-
if self.acir_context.is_constant(&acir_var) {
1747-
warnings.push(SsaReport::Warning(InternalWarning::ReturnConstant {
1748-
call_stack: call_stack.clone(),
1749-
}));
1750-
}
1751-
if !is_databus {
1752-
// We do not return value for the data bus.
1753-
self.acir_context.return_var(acir_var)?;
1754-
} else {
1755-
self.check_array_is_initialized(self.data_bus.return_data.unwrap(), dfg)?;
1741+
let mut has_constant_return = false;
1742+
for value_id in return_values {
1743+
let is_databus = self
1744+
.data_bus
1745+
.return_data
1746+
.map_or(false, |return_databus| dfg[*value_id] == dfg[return_databus]);
1747+
let value = self.convert_value(*value_id, dfg);
1748+
1749+
// `value` may or may not be an array reference. Calling `flatten` will expand the array if there is one.
1750+
let acir_vars = self.acir_context.flatten(value)?;
1751+
for (acir_var, _) in acir_vars {
1752+
has_constant_return |= self.acir_context.is_constant(&acir_var);
1753+
if is_databus {
1754+
// We do not return value for the data bus.
1755+
self.check_array_is_initialized(
1756+
self.data_bus.return_data.expect(
1757+
"`is_databus == true` implies `data_bus.return_data` is `Some`",
1758+
),
1759+
dfg,
1760+
)?;
1761+
} else {
1762+
self.acir_context.return_var(acir_var)?;
1763+
}
17561764
}
17571765
}
1766+
1767+
let warnings = if has_constant_return {
1768+
vec![SsaReport::Warning(InternalWarning::ReturnConstant { call_stack })]
1769+
} else {
1770+
Vec::new()
1771+
};
1772+
17581773
Ok(warnings)
17591774
}
17601775

@@ -2679,34 +2694,6 @@ impl<'a> Context<'a> {
26792694
}
26802695
}
26812696

2682-
/// Maps an ssa value list, for which some values may be references to arrays, by inlining
2683-
/// the `AcirVar`s corresponding to the contents of each array into the list of `AcirVar`s
2684-
/// that correspond to other values.
2685-
fn flatten_value_list(
2686-
&mut self,
2687-
arguments: &[ValueId],
2688-
dfg: &DataFlowGraph,
2689-
) -> Result<Vec<(AcirVar, bool)>, InternalError> {
2690-
let mut acir_vars = Vec::with_capacity(arguments.len());
2691-
for value_id in arguments {
2692-
let is_databus = if let Some(return_databus) = self.data_bus.return_data {
2693-
dfg[*value_id] == dfg[return_databus]
2694-
} else {
2695-
false
2696-
};
2697-
let value = self.convert_value(*value_id, dfg);
2698-
acir_vars.append(
2699-
&mut self
2700-
.acir_context
2701-
.flatten(value)?
2702-
.iter()
2703-
.map(|(var, _)| (*var, is_databus))
2704-
.collect(),
2705-
);
2706-
}
2707-
Ok(acir_vars)
2708-
}
2709-
27102697
/// Convert a Vec<AcirVar> into a Vec<AcirValue> using the given result ids.
27112698
/// If the type of a result id is an array, several acir vars are collected into
27122699
/// a single AcirValue::Array of the same length.

compiler/noirc_frontend/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ smol_str.workspace = true
2121
im.workspace = true
2222
serde_json.workspace = true
2323
serde.workspace = true
24+
num-bigint.workspace = true
25+
num-traits.workspace = true
2426
rustc-hash = "1.1.0"
2527
small-ord-set = "0.1.3"
2628
regex = "1.9.1"
29+
cfg-if = "1.0.0"
2730
tracing.workspace = true
2831
petgraph = "0.6"
2932
lalrpop-util = { version = "0.20.2", features = ["lexer"] }
3033

34+
3135
[dev-dependencies]
3236
base64.workspace = true
3337
strum = "0.24"
@@ -39,3 +43,5 @@ lalrpop = "0.20.2"
3943

4044
[features]
4145
experimental_parser = []
46+
bn254 = []
47+
bls12_381 = []

compiler/noirc_frontend/src/elaborator/expressions.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use crate::{
1515
hir_def::{
1616
expr::{
1717
HirArrayLiteral, HirBinaryOp, HirBlockExpression, HirCallExpression, HirCastExpression,
18-
HirConstructorExpression, HirIdent, HirIfExpression, HirIndexExpression,
19-
HirInfixExpression, HirLambda, HirMemberAccess, HirMethodCallExpression,
20-
HirMethodReference, HirPrefixExpression,
18+
HirConstructorExpression, HirIfExpression, HirIndexExpression, HirInfixExpression,
19+
HirLambda, HirMemberAccess, HirMethodCallExpression, HirMethodReference,
20+
HirPrefixExpression,
2121
},
2222
traits::TraitConstraint,
2323
},
@@ -84,10 +84,10 @@ impl<'context> Elaborator<'context> {
8484
expr_type: inner_expr_type.clone(),
8585
expr_span: span,
8686
});
87+
}
8788

88-
if i + 1 == statements.len() {
89-
block_type = stmt_type;
90-
}
89+
if i + 1 == statements.len() {
90+
block_type = stmt_type;
9191
}
9292
}
9393

0 commit comments

Comments
 (0)