@@ -5,6 +5,7 @@ use blockifier::execution::contract_class::{ClassInfo, ContractClass, ContractCl
5
5
use cairo_lang_starknet_classes:: casm_contract_class:: {
6
6
CasmContractClass , CasmContractEntryPoints ,
7
7
} ;
8
+ use cairo_lang_starknet_classes:: contract_class:: ContractClass as CairoLangContractClass ;
8
9
use starknet_api:: core:: CompiledClassHash ;
9
10
use starknet_api:: rpc_transaction:: RPCDeclareTransaction ;
10
11
use starknet_sierra_compile:: compile:: compile_sierra_to_casm;
@@ -19,6 +20,7 @@ use crate::utils::is_subsequence;
19
20
#[ path = "compilation_test.rs" ]
20
21
mod compilation_test;
21
22
23
+ // TODO(Arni): Pass the compiler with dependancy injection.
22
24
#[ derive( Clone ) ]
23
25
pub struct GatewayCompiler {
24
26
#[ allow( dead_code) ]
@@ -29,64 +31,56 @@ impl GatewayCompiler {
29
31
/// Formats the contract class for compilation, compiles it, and returns the compiled contract
30
32
/// class wrapped in a [`ClassInfo`].
31
33
/// Assumes the contract class is of a Sierra program which is compiled to Casm.
32
- pub fn compile_contract_class (
34
+ pub fn process_declare_tx (
33
35
& self ,
34
36
declare_tx : & RPCDeclareTransaction ,
35
37
) -> GatewayResult < ClassInfo > {
36
38
let RPCDeclareTransaction :: V3 ( tx) = declare_tx;
37
- let starknet_api_contract_class = & tx. contract_class ;
38
- let cairo_lang_contract_class =
39
- into_contract_class_for_compilation ( starknet_api_contract_class) ;
39
+ let rpc_contract_class = & tx. contract_class ;
40
+ let cairo_lang_contract_class = into_contract_class_for_compilation ( rpc_contract_class) ;
40
41
41
- // Compile Sierra to Casm.
42
+ let casm_contract_class = self . compile ( cairo_lang_contract_class) ?;
43
+
44
+ validate_compiled_class_hash ( & casm_contract_class, & tx. compiled_class_hash ) ?;
45
+ validate_casm_class ( & casm_contract_class) ?;
46
+
47
+ Ok ( ClassInfo :: new (
48
+ & ContractClass :: V1 ( ContractClassV1 :: try_from ( casm_contract_class) ?) ,
49
+ rpc_contract_class. sierra_program . len ( ) ,
50
+ rpc_contract_class. abi . len ( ) ,
51
+ ) ?)
52
+ }
53
+
54
+ // TODO(Arni): Pass the compilation args from the config.
55
+ fn compile (
56
+ & self ,
57
+ cairo_lang_contract_class : CairoLangContractClass ,
58
+ ) -> Result < CasmContractClass , GatewayError > {
42
59
let catch_unwind_result =
43
60
panic:: catch_unwind ( || compile_sierra_to_casm ( cairo_lang_contract_class) ) ;
44
- let casm_contract_class = match catch_unwind_result {
45
- Ok ( compilation_result) => compilation_result?,
46
- Err ( _) => {
47
- // TODO(Arni): Log the panic.
48
- return Err ( GatewayError :: CompilationError ( CompilationUtilError :: CompilationPanic ) ) ;
49
- }
50
- } ;
51
- self . validate_casm_class ( & casm_contract_class) ?;
61
+ let casm_contract_class =
62
+ catch_unwind_result. map_err ( |_| CompilationUtilError :: CompilationPanic ) ??;
52
63
53
- let hash_result = CompiledClassHash ( casm_contract_class. compiled_class_hash ( ) ) ;
54
- if hash_result != tx. compiled_class_hash {
55
- return Err ( GatewayError :: CompiledClassHashMismatch {
56
- supplied : tx. compiled_class_hash ,
57
- hash_result,
58
- } ) ;
59
- }
60
-
61
- // Convert Casm contract class to Starknet contract class directly.
62
- let blockifier_contract_class =
63
- ContractClass :: V1 ( ContractClassV1 :: try_from ( casm_contract_class) ?) ;
64
- let class_info = ClassInfo :: new (
65
- & blockifier_contract_class,
66
- starknet_api_contract_class. sierra_program . len ( ) ,
67
- starknet_api_contract_class. abi . len ( ) ,
68
- ) ?;
69
- Ok ( class_info)
64
+ Ok ( casm_contract_class)
70
65
}
66
+ }
71
67
72
- // TODO(Arni): Add test.
73
- fn validate_casm_class ( & self , contract_class : & CasmContractClass ) -> Result < ( ) , GatewayError > {
74
- let CasmContractEntryPoints { external, l1_handler, constructor } =
75
- & contract_class. entry_points_by_type ;
76
- let entry_points_iterator =
77
- external. iter ( ) . chain ( l1_handler. iter ( ) ) . chain ( constructor. iter ( ) ) ;
68
+ // TODO(Arni): Add test.
69
+ fn validate_casm_class ( contract_class : & CasmContractClass ) -> Result < ( ) , GatewayError > {
70
+ let CasmContractEntryPoints { external, l1_handler, constructor } =
71
+ & contract_class. entry_points_by_type ;
72
+ let entry_points_iterator = external. iter ( ) . chain ( l1_handler. iter ( ) ) . chain ( constructor. iter ( ) ) ;
78
73
79
- for entry_point in entry_points_iterator {
80
- let builtins = & entry_point. builtins ;
81
- if !is_subsequence ( builtins, supported_builtins ( ) ) {
82
- return Err ( GatewayError :: UnsupportedBuiltins {
83
- builtins : builtins. clone ( ) ,
84
- supported_builtins : supported_builtins ( ) . to_vec ( ) ,
85
- } ) ;
86
- }
74
+ for entry_point in entry_points_iterator {
75
+ let builtins = & entry_point. builtins ;
76
+ if !is_subsequence ( builtins, supported_builtins ( ) ) {
77
+ return Err ( GatewayError :: UnsupportedBuiltins {
78
+ builtins : builtins. clone ( ) ,
79
+ supported_builtins : supported_builtins ( ) . to_vec ( ) ,
80
+ } ) ;
87
81
}
88
- Ok ( ( ) )
89
82
}
83
+ Ok ( ( ) )
90
84
}
91
85
92
86
// TODO(Arni): Add to a config.
@@ -101,3 +95,19 @@ fn supported_builtins() -> &'static Vec<String> {
101
95
SUPPORTED_BUILTIN_NAMES . iter ( ) . map ( |builtin| builtin. to_string ( ) ) . collect :: < Vec < String > > ( )
102
96
} )
103
97
}
98
+
99
+ /// Validates that the compiled class hash of the compiled contract class matches the supplied
100
+ /// compiled class hash.
101
+ fn validate_compiled_class_hash (
102
+ casm_contract_class : & CasmContractClass ,
103
+ supplied_compiled_class_hash : & CompiledClassHash ,
104
+ ) -> Result < ( ) , GatewayError > {
105
+ let compiled_class_hash = CompiledClassHash ( casm_contract_class. compiled_class_hash ( ) ) ;
106
+ if compiled_class_hash != * supplied_compiled_class_hash {
107
+ return Err ( GatewayError :: CompiledClassHashMismatch {
108
+ supplied : * supplied_compiled_class_hash,
109
+ hash_result : compiled_class_hash,
110
+ } ) ;
111
+ }
112
+ Ok ( ( ) )
113
+ }
0 commit comments