1
1
use acvm:: Backend ;
2
2
use iter_extended:: try_vecmap;
3
+ use nargo:: artifacts:: contract:: PreprocessedContract ;
3
4
use noirc_driver:: { CompileOptions , CompiledProgram , Driver } ;
4
5
use std:: path:: Path ;
5
6
6
7
use clap:: Args ;
7
8
8
- use nargo:: ops:: { preprocess_contract , preprocess_program} ;
9
+ use nargo:: ops:: { preprocess_contract_function , preprocess_program} ;
9
10
10
11
use crate :: resolver:: DependencyResolutionError ;
11
12
use crate :: { constants:: TARGET_DIR , errors:: CliError , resolver:: Resolver } ;
12
13
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
+ } ;
14
21
use super :: NargoConfig ;
15
22
23
+ // TODO(#1388): pull this from backend.
24
+ const BACKEND_IDENTIFIER : & str = "acvm-backend-barretenberg" ;
25
+
16
26
/// Compile the program and its secret execution trace into ACIR format
17
27
#[ derive( Debug , Clone , Args ) ]
18
28
pub ( crate ) struct CompileCommand {
@@ -34,16 +44,40 @@ pub(crate) fn run<B: Backend>(
34
44
) -> Result < ( ) , CliError < B > > {
35
45
let circuit_dir = config. program_dir . join ( TARGET_DIR ) ;
36
46
47
+ let mut common_reference_string = read_cached_common_reference_string ( ) ;
48
+
37
49
// If contracts is set we're compiling every function in a 'contract' rather than just 'main'.
38
50
if args. contracts {
39
51
let mut driver = setup_driver ( backend, & config. program_dir ) ?;
40
52
let compiled_contracts = driver
41
53
. compile_contracts ( & args. compile_options )
42
54
. 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? {
47
81
save_contract_to_file (
48
82
& contract,
49
83
& format ! ( "{}-{}" , & args. circuit_name, contract. name) ,
@@ -52,22 +86,29 @@ pub(crate) fn run<B: Backend>(
52
86
}
53
87
} else {
54
88
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 ) ?;
57
95
save_program_to_file ( & preprocessed_program, & args. circuit_name , circuit_dir) ;
58
96
}
97
+
98
+ write_cached_common_reference_string ( & common_reference_string) ;
99
+
59
100
Ok ( ( ) )
60
101
}
61
102
62
- fn setup_driver < B : Backend > (
103
+ pub ( super ) fn setup_driver < B : Backend > (
63
104
backend : & B ,
64
105
program_dir : & Path ,
65
106
) -> Result < Driver , DependencyResolutionError > {
66
107
Resolver :: resolve_root_manifest (
67
108
program_dir,
68
109
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 ) ) ,
71
112
)
72
113
}
73
114
0 commit comments