Skip to content

Commit b938c7e

Browse files
phatedsirasistantTomAFrenchvezenovm
authored
chore!: Update to ACVM 0.12.0 (#1339)
* chore!: Update to ACVM 0.12.0 * feat: adapted to heterogeneous bb calls * chore: update cargo tomls * test: re enabled sort test * fix: improve variable resolution * feat: use dummy constructor for bb call * updates for latest * feat!: Move WitnessMap type into ACVM to avoid leaking BTreeMap type * feat(nargo): Consume CommonReferenceString functions & manage caching (#1348) * switch to published acvm and backend * fix compilation issue * chore: Remove usage of `acvm::default_is_opcode_supported` (#1366) Co-authored-by: Blaine Bublitz <blaine.bublitz@gmail.com> Co-authored-by: Tom French <tom@tomfren.ch> * add issue numbers to TODOs * chore: deduplicate driver setup logic * chore: clippy --------- Co-authored-by: sirasistant <sirasistant@gmail.com> Co-authored-by: Tom French <tom@tomfren.ch> Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Maxim Vezenov <mvezenov@gmail.com>
1 parent a21b251 commit b938c7e

31 files changed

+666
-393
lines changed

Cargo.lock

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

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ edition = "2021"
2424
rust-version = "1.66"
2525

2626
[workspace.dependencies]
27-
acvm = "0.11.0"
27+
acvm = "0.12.0"
2828
arena = { path = "crates/arena" }
2929
fm = { path = "crates/fm" }
3030
iter-extended = { path = "crates/iter-extended" }

crates/nargo/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ rustc_version = "0.4.0"
1414
acvm.workspace = true
1515
noirc_abi.workspace = true
1616
noirc_driver.workspace = true
17-
iter-extended.workspace = true
1817
toml.workspace = true
1918
serde.workspace = true
2019
thiserror.workspace = true

crates/nargo/src/ops/codegen_verifier.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use acvm::SmartContract;
22

33
pub fn codegen_verifier<B: SmartContract>(
44
backend: &B,
5+
common_reference_string: &[u8],
56
verification_key: &[u8],
67
) -> Result<String, B::Error> {
7-
backend.eth_contract_from_vk(verification_key)
8+
backend.eth_contract_from_vk(common_reference_string, verification_key)
89
}

crates/nargo/src/ops/execute.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use acvm::{acir::circuit::Circuit, pwg::block::Blocks};
2-
use acvm::{PartialWitnessGenerator, PartialWitnessGeneratorStatus};
3-
use noirc_abi::WitnessMap;
1+
use acvm::pwg::{solve, PartialWitnessGeneratorStatus};
2+
use acvm::PartialWitnessGenerator;
3+
use acvm::{acir::circuit::Circuit, acir::native_types::WitnessMap, pwg::block::Blocks};
44

55
use crate::NargoError;
66

@@ -10,7 +10,7 @@ pub fn execute_circuit(
1010
mut initial_witness: WitnessMap,
1111
) -> Result<WitnessMap, NargoError> {
1212
let mut blocks = Blocks::default();
13-
let solver_status = backend.solve(&mut initial_witness, &mut blocks, circuit.opcodes)?;
13+
let solver_status = solve(backend, &mut initial_witness, &mut blocks, circuit.opcodes)?;
1414
if matches!(solver_status, PartialWitnessGeneratorStatus::RequiresOracleData { .. }) {
1515
todo!("Add oracle support to nargo execute")
1616
}

crates/nargo/src/ops/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pub use self::codegen_verifier::codegen_verifier;
22
pub use self::execute::execute_circuit;
3-
pub use self::preprocess::{preprocess_contract, preprocess_program};
3+
pub use self::preprocess::{preprocess_contract_function, preprocess_program};
44
pub use self::prove::prove_execution;
55
pub use self::verify::verify_proof;
66

crates/nargo/src/ops/preprocess.rs

+22-30
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
use acvm::ProofSystemCompiler;
2-
use iter_extended::try_vecmap;
3-
use noirc_driver::{CompiledContract, CompiledProgram};
2+
use noirc_driver::{CompiledProgram, ContractFunction};
43

5-
use crate::artifacts::{
6-
contract::{PreprocessedContract, PreprocessedContractFunction},
7-
program::PreprocessedProgram,
8-
};
4+
use crate::artifacts::{contract::PreprocessedContractFunction, program::PreprocessedProgram};
95

10-
// TODO: pull this from backend.
6+
// TODO(#1388): pull this from backend.
117
const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg";
128

139
pub fn preprocess_program<B: ProofSystemCompiler>(
1410
backend: &B,
11+
common_reference_string: &[u8],
1512
compiled_program: CompiledProgram,
1613
) -> Result<PreprocessedProgram, B::Error> {
1714
// TODO: currently `compiled_program`'s bytecode is already optimized for the backend.
1815
// In future we'll need to apply those optimizations here.
1916
let optimized_bytecode = compiled_program.circuit;
20-
let (proving_key, verification_key) = backend.preprocess(&optimized_bytecode)?;
17+
let (proving_key, verification_key) =
18+
backend.preprocess(common_reference_string, &optimized_bytecode)?;
2119

2220
Ok(PreprocessedProgram {
2321
backend: String::from(BACKEND_IDENTIFIER),
@@ -28,30 +26,24 @@ pub fn preprocess_program<B: ProofSystemCompiler>(
2826
})
2927
}
3028

31-
pub fn preprocess_contract<B: ProofSystemCompiler>(
29+
pub fn preprocess_contract_function<B: ProofSystemCompiler>(
3230
backend: &B,
33-
compiled_contract: CompiledContract,
34-
) -> Result<PreprocessedContract, B::Error> {
35-
let preprocessed_contract_functions = try_vecmap(compiled_contract.functions, |func| {
36-
// TODO: currently `func`'s bytecode is already optimized for the backend.
37-
// In future we'll need to apply those optimizations here.
38-
let optimized_bytecode = func.bytecode;
39-
let (proving_key, verification_key) = backend.preprocess(&optimized_bytecode)?;
40-
41-
Ok(PreprocessedContractFunction {
42-
name: func.name,
43-
function_type: func.function_type,
44-
abi: func.abi,
31+
common_reference_string: &[u8],
32+
func: ContractFunction,
33+
) -> Result<PreprocessedContractFunction, B::Error> {
34+
// TODO: currently `func`'s bytecode is already optimized for the backend.
35+
// In future we'll need to apply those optimizations here.
36+
let optimized_bytecode = func.bytecode;
37+
let (proving_key, verification_key) =
38+
backend.preprocess(common_reference_string, &optimized_bytecode)?;
4539

46-
bytecode: optimized_bytecode,
47-
proving_key,
48-
verification_key,
49-
})
50-
})?;
40+
Ok(PreprocessedContractFunction {
41+
name: func.name,
42+
function_type: func.function_type,
43+
abi: func.abi,
5144

52-
Ok(PreprocessedContract {
53-
name: compiled_contract.name,
54-
backend: String::from(BACKEND_IDENTIFIER),
55-
functions: preprocessed_contract_functions,
45+
bytecode: optimized_bytecode,
46+
proving_key,
47+
verification_key,
5648
})
5749
}

crates/nargo/src/ops/prove.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
use acvm::acir::circuit::Circuit;
1+
use acvm::acir::{circuit::Circuit, native_types::WitnessMap};
22
use acvm::ProofSystemCompiler;
3-
use noirc_abi::WitnessMap;
43

54
pub fn prove_execution<B: ProofSystemCompiler>(
65
backend: &B,
6+
common_reference_string: &[u8],
77
circuit: &Circuit,
88
solved_witness: WitnessMap,
99
proving_key: &[u8],
1010
) -> Result<Vec<u8>, B::Error> {
11-
backend.prove_with_pk(circuit, solved_witness, proving_key)
11+
backend.prove_with_pk(common_reference_string, circuit, solved_witness, proving_key)
1212
}

crates/nargo/src/ops/verify.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use acvm::acir::circuit::Circuit;
1+
use acvm::acir::{circuit::Circuit, native_types::WitnessMap};
22
use acvm::ProofSystemCompiler;
3-
use noirc_abi::WitnessMap;
43

54
pub fn verify_proof<B: ProofSystemCompiler>(
65
backend: &B,
6+
common_reference_string: &[u8],
77
circuit: &Circuit,
88
proof: &[u8],
99
public_inputs: WitnessMap,
1010
verification_key: &[u8],
1111
) -> Result<bool, B::Error> {
12-
backend.verify_with_vk(proof, public_inputs, circuit, verification_key)
12+
backend.verify_with_vk(common_reference_string, proof, public_inputs, circuit, verification_key)
1313
}

crates/nargo_cli/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ hex = "0.4.2"
3535
serde_json = "1.0"
3636
termcolor = "1.1.2"
3737
color-eyre = "0.6.2"
38+
tokio = "1.0"
3839

3940
# Backends
40-
acvm-backend-barretenberg = { version = "0.1.2", default-features = false }
41+
acvm-backend-barretenberg = { version = "0.2.0", default-features = false }
4142

4243
[dev-dependencies]
4344
tempdir = "0.3.7"

crates/nargo_cli/src/cli/check_cmd.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use crate::{errors::CliError, resolver::Resolver};
1+
use crate::errors::CliError;
22
use acvm::Backend;
33
use clap::Args;
44
use iter_extended::btree_map;
55
use noirc_abi::{AbiParameter, AbiType, MAIN_RETURN_NAME};
66
use noirc_driver::CompileOptions;
77
use std::path::{Path, PathBuf};
88

9-
use super::fs::write_to_file;
109
use super::NargoConfig;
10+
use super::{compile_cmd::setup_driver, fs::write_to_file};
1111
use crate::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE};
1212

1313
/// Checks the constraint system for errors
@@ -29,15 +29,10 @@ pub(crate) fn run<B: Backend>(
2929

3030
fn check_from_path<B: Backend, P: AsRef<Path>>(
3131
backend: &B,
32-
p: P,
32+
program_dir: P,
3333
compile_options: &CompileOptions,
3434
) -> Result<(), CliError<B>> {
35-
let mut driver = Resolver::resolve_root_manifest(
36-
p.as_ref(),
37-
backend.np_language(),
38-
#[allow(deprecated)]
39-
Box::new(acvm::default_is_opcode_supported(backend.np_language())),
40-
)?;
35+
let mut driver = setup_driver(backend, program_dir.as_ref())?;
4136

4237
driver.check_crate(compile_options).map_err(|_| CliError::CompilationError)?;
4338

@@ -47,7 +42,7 @@ fn check_from_path<B: Backend, P: AsRef<Path>>(
4742
// For now it is hard-coded to be toml.
4843
//
4944
// Check for input.toml and verifier.toml
50-
let path_to_root = PathBuf::from(p.as_ref());
45+
let path_to_root = PathBuf::from(program_dir.as_ref());
5146
let path_to_prover_input = path_to_root.join(format!("{PROVER_INPUT_FILE}.toml"));
5247
let path_to_verifier_input = path_to_root.join(format!("{VERIFIER_INPUT_FILE}.toml"));
5348

crates/nargo_cli/src/cli/codegen_verifier_cmd.rs

+34-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
use super::fs::{create_named_dir, program::read_program_from_file, write_to_file};
1+
use super::fs::{
2+
common_reference_string::{
3+
read_cached_common_reference_string, update_common_reference_string,
4+
write_cached_common_reference_string,
5+
},
6+
create_named_dir,
7+
program::read_program_from_file,
8+
write_to_file,
9+
};
210
use super::NargoConfig;
311
use crate::{
412
cli::compile_cmd::compile_circuit, constants::CONTRACT_DIR, constants::TARGET_DIR,
@@ -29,18 +37,36 @@ pub(crate) fn run<B: Backend>(
2937
.circuit_name
3038
.map(|circuit_name| config.program_dir.join(TARGET_DIR).join(circuit_name));
3139

32-
let preprocessed_program = match circuit_build_path {
33-
Some(circuit_build_path) => read_program_from_file(circuit_build_path)?,
40+
let common_reference_string = read_cached_common_reference_string();
41+
42+
let (common_reference_string, preprocessed_program) = match circuit_build_path {
43+
Some(circuit_build_path) => {
44+
let program = read_program_from_file(circuit_build_path)?;
45+
let common_reference_string = update_common_reference_string(
46+
backend,
47+
&common_reference_string,
48+
&program.bytecode,
49+
)
50+
.map_err(CliError::CommonReferenceStringError)?;
51+
(common_reference_string, program)
52+
}
3453
None => {
35-
let compiled_program =
54+
let program =
3655
compile_circuit(backend, config.program_dir.as_ref(), &args.compile_options)?;
37-
preprocess_program(backend, compiled_program)
38-
.map_err(CliError::ProofSystemCompilerError)?
56+
let common_reference_string =
57+
update_common_reference_string(backend, &common_reference_string, &program.circuit)
58+
.map_err(CliError::CommonReferenceStringError)?;
59+
let program = preprocess_program(backend, &common_reference_string, program)
60+
.map_err(CliError::ProofSystemCompilerError)?;
61+
(common_reference_string, program)
3962
}
4063
};
4164

42-
let smart_contract_string = codegen_verifier(backend, &preprocessed_program.verification_key)
43-
.map_err(CliError::SmartContractError)?;
65+
let smart_contract_string =
66+
codegen_verifier(backend, &common_reference_string, &preprocessed_program.verification_key)
67+
.map_err(CliError::SmartContractError)?;
68+
69+
write_cached_common_reference_string(&common_reference_string);
4470

4571
let contract_dir = config.program_dir.join(CONTRACT_DIR);
4672
create_named_dir(&contract_dir, "contract");

crates/nargo_cli/src/cli/compile_cmd.rs

+52-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
use acvm::Backend;
22
use iter_extended::try_vecmap;
3+
use nargo::artifacts::contract::PreprocessedContract;
34
use noirc_driver::{CompileOptions, CompiledProgram, Driver};
45
use std::path::Path;
56

67
use clap::Args;
78

8-
use nargo::ops::{preprocess_contract, preprocess_program};
9+
use nargo::ops::{preprocess_contract_function, preprocess_program};
910

1011
use crate::resolver::DependencyResolutionError;
1112
use crate::{constants::TARGET_DIR, errors::CliError, resolver::Resolver};
1213

13-
use super::fs::program::{save_contract_to_file, save_program_to_file};
14+
use super::fs::{
15+
common_reference_string::{
16+
read_cached_common_reference_string, update_common_reference_string,
17+
write_cached_common_reference_string,
18+
},
19+
program::{save_contract_to_file, save_program_to_file},
20+
};
1421
use super::NargoConfig;
1522

23+
// TODO(#1388): pull this from backend.
24+
const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg";
25+
1626
/// Compile the program and its secret execution trace into ACIR format
1727
#[derive(Debug, Clone, Args)]
1828
pub(crate) struct CompileCommand {
@@ -34,16 +44,40 @@ pub(crate) fn run<B: Backend>(
3444
) -> Result<(), CliError<B>> {
3545
let circuit_dir = config.program_dir.join(TARGET_DIR);
3646

47+
let mut common_reference_string = read_cached_common_reference_string();
48+
3749
// If contracts is set we're compiling every function in a 'contract' rather than just 'main'.
3850
if args.contracts {
3951
let mut driver = setup_driver(backend, &config.program_dir)?;
4052
let compiled_contracts = driver
4153
.compile_contracts(&args.compile_options)
4254
.map_err(|_| CliError::CompilationError)?;
43-
let preprocessed_contracts = try_vecmap(compiled_contracts, |contract| {
44-
preprocess_contract(backend, contract).map_err(CliError::ProofSystemCompilerError)
45-
})?;
46-
for contract in preprocessed_contracts {
55+
56+
// TODO(#1389): I wonder if it is incorrect for nargo-core to know anything about contracts.
57+
// As can be seen here, It seems like a leaky abstraction where ContractFunctions (essentially CompiledPrograms)
58+
// are compiled via nargo-core and then the PreprocessedContract is constructed here.
59+
// This is due to EACH function needing it's own CRS, PKey, and VKey from the backend.
60+
let preprocessed_contracts: Result<Vec<PreprocessedContract>, CliError<B>> =
61+
try_vecmap(compiled_contracts, |contract| {
62+
let preprocessed_contract_functions = try_vecmap(contract.functions, |func| {
63+
common_reference_string = update_common_reference_string(
64+
backend,
65+
&common_reference_string,
66+
&func.bytecode,
67+
)
68+
.map_err(CliError::CommonReferenceStringError)?;
69+
70+
preprocess_contract_function(backend, &common_reference_string, func)
71+
.map_err(CliError::ProofSystemCompilerError)
72+
})?;
73+
74+
Ok(PreprocessedContract {
75+
name: contract.name,
76+
backend: String::from(BACKEND_IDENTIFIER),
77+
functions: preprocessed_contract_functions,
78+
})
79+
});
80+
for contract in preprocessed_contracts? {
4781
save_contract_to_file(
4882
&contract,
4983
&format!("{}-{}", &args.circuit_name, contract.name),
@@ -52,22 +86,29 @@ pub(crate) fn run<B: Backend>(
5286
}
5387
} else {
5488
let program = compile_circuit(backend, &config.program_dir, &args.compile_options)?;
55-
let preprocessed_program =
56-
preprocess_program(backend, program).map_err(CliError::ProofSystemCompilerError)?;
89+
common_reference_string =
90+
update_common_reference_string(backend, &common_reference_string, &program.circuit)
91+
.map_err(CliError::CommonReferenceStringError)?;
92+
93+
let preprocessed_program = preprocess_program(backend, &common_reference_string, program)
94+
.map_err(CliError::ProofSystemCompilerError)?;
5795
save_program_to_file(&preprocessed_program, &args.circuit_name, circuit_dir);
5896
}
97+
98+
write_cached_common_reference_string(&common_reference_string);
99+
59100
Ok(())
60101
}
61102

62-
fn setup_driver<B: Backend>(
103+
pub(super) fn setup_driver<B: Backend>(
63104
backend: &B,
64105
program_dir: &Path,
65106
) -> Result<Driver, DependencyResolutionError> {
66107
Resolver::resolve_root_manifest(
67108
program_dir,
68109
backend.np_language(),
69-
#[allow(deprecated)]
70-
Box::new(acvm::default_is_opcode_supported(backend.np_language())),
110+
// TODO(#1102): Remove need for driver to be aware of backend.
111+
Box::new(|op| B::default().supports_opcode(op)),
71112
)
72113
}
73114

0 commit comments

Comments
 (0)