@@ -32,7 +32,7 @@ use tracing::{debug, trace};
3232use crate :: cartridge:: { encode_calls, VrfService } ;
3333use crate :: starknet:: { PendingBlockProvider , StarknetApi } ;
3434
35- #[ derive( Debug , Clone ) ]
35+ #[ derive( Debug ) ]
3636pub struct ControllerDeploymentLayer < Pool , PP , PF >
3737where
3838 Pool : TransactionPool + ' static ,
4848 vrf_service : Option < VrfService > ,
4949}
5050
51- #[ derive( Debug , Clone ) ]
51+ #[ derive( Debug ) ]
5252pub struct ControllerDeploymentService < S , Pool , PP , PF >
5353where
5454 Pool : TransactionPool ,
@@ -83,14 +83,51 @@ where
8383 params : EstimateFeeParams ,
8484 request : Request < ' a > ,
8585 ) -> S :: MethodResponse {
86- let EstimateFeeParams { block_id, simulation_flags, txs } = params;
86+ match self . handle_estimate_fee_inner ( params, request) . await {
87+ Ok ( response) => response,
88+ Err ( err) => MethodResponse :: error ( request. id ( ) . clone ( ) , ErrorObjectOwned :: from ( err) ) ,
89+ }
90+ }
91+
92+ async fn handle_execute_outside < ' a > (
93+ & self ,
94+ params : AddExecuteOutsideParams ,
95+ request : Request < ' a > ,
96+ ) -> S :: MethodResponse {
97+ if let Err ( err) = self . handle_execute_outside_inner ( params) . await {
98+ MethodResponse :: error ( request. id ( ) . clone ( ) , ErrorObjectOwned :: from ( err) )
99+ } else {
100+ self . service . call ( request) . await
101+ }
102+ }
103+
104+ async fn handle_estimate_fee_inner < ' a > (
105+ & self ,
106+ params : EstimateFeeParams ,
107+ request : Request < ' a > ,
108+ ) -> Result < S :: MethodResponse , CartridgeApiError > {
109+ let EstimateFeeParams { block_id, simulation_flags, transactions } = params;
87110
88- let deploy_controller_txs =
89- self . get_deploy_controller_txs ( block_id, & txs) . await . unwrap_or_default ( ) ;
111+ let mut undeployed_addresses: Vec < ContractAddress > = Vec :: new ( ) ;
112+
113+ // iterate thru all txs and deploy any undeployed contract (if they are a Controller)
114+ for tx in transactions {
115+ let address = match tx {
116+ BroadcastedTx :: Invoke ( tx) => tx. sender_address ,
117+ BroadcastedTx :: Declare ( tx) => tx. sender_address ,
118+ _ => continue ,
119+ } ;
120+
121+ undeployed_addresses. push ( address) ;
122+ }
123+
124+ let deployer_nonce = self . starknet . nonce_at ( block_id, self . deployer_address ) . await . unwrap ( ) ;
125+ let deploy_txs =
126+ self . get_controller_deployment_txs ( undeployed_addresses, deployer_nonce) . await . unwrap ( ) ;
90127
91128 // no Controller to deploy, simply forward the request
92- if deploy_controller_txs . is_empty ( ) {
93- return self . service . call ( request) . await ;
129+ if deploy_txs . is_empty ( ) {
130+ return Ok ( self . service . call ( request) . await ) ;
94131 }
95132
96133 let original_txs_count = txs. len ( ) ;
@@ -119,22 +156,10 @@ where
119156 ResponsePayload :: Success ( estimates) => {
120157 assert_eq ! ( estimates. len( ) , new_txs_count) ;
121158 estimates. to_mut ( ) . drain ( 0 ..deploy_controller_txs_count) ;
122- build_no_fee_response ( & request, original_txs_count)
159+ Ok ( build_no_fee_response ( & request, original_txs_count) )
123160 }
124161
125- ResponsePayload :: Error ( ..) => response,
126- }
127- }
128-
129- async fn handle_execute_outside < ' a > (
130- & self ,
131- params : AddExecuteOutsideParams ,
132- request : Request < ' a > ,
133- ) -> S :: MethodResponse {
134- if let Err ( err) = self . handle_execute_outside_inner ( params) . await {
135- MethodResponse :: error ( request. id ( ) . clone ( ) , ErrorObjectOwned :: from ( err) )
136- } else {
137- self . service . call ( request) . await
162+ ResponsePayload :: Error ( ..) => Ok ( response) ,
138163 }
139164 }
140165
@@ -190,49 +215,29 @@ where
190215 Ok ( ( ) )
191216 }
192217
193- async fn get_deploy_controller_txs (
218+ async fn get_controller_deployment_txs (
194219 & self ,
195- block_id : BlockIdOrTag ,
196- transactions : & [ BroadcastedTx ] ,
220+ controller_addreses : Vec < ContractAddress > ,
221+ initial_nonce : Nonce ,
197222 ) -> Result < Vec < BroadcastedTx > , Error > {
198223 let mut deploy_transactions: Vec < BroadcastedTx > = Vec :: new ( ) ;
199- let mut deployed_controllers : HashSet < ContractAddress > = HashSet :: new ( ) ;
224+ let mut processed_addresses : Vec < ContractAddress > = Vec :: new ( ) ;
200225
201- let mut deployer_nonce =
202- self . starknet . nonce_at ( block_id, self . deployer_address ) . await . unwrap ( ) ;
203-
204- // iterate thru all txs and deploy any undeployed contract (if they are a Controller)
205- for tx in transactions {
206- let contract_address = match tx {
207- BroadcastedTx :: Invoke ( tx) => tx. sender_address ,
208- BroadcastedTx :: Declare ( tx) => tx. sender_address ,
209- _ => continue ,
210- } ;
226+ let mut deployer_nonce = initial_nonce;
211227
228+ for address in controller_addreses {
212229 // If the address has already been processed in this txs batch, just skip.
213- if deployed_controllers . contains ( & contract_address ) {
230+ if processed_addresses . contains ( & address ) {
214231 continue ;
215232 }
216233
217- // check if the address has already been deployed.
218- match self . starknet . class_hash_at_address ( block_id, contract_address) . await {
219- // attempt to deploy if the address belongs to a Controller account
220- Err ( StarknetApiError :: ContractNotFound ) => {
221- let result = self
222- . get_controller_deployment_tx ( contract_address, deployer_nonce)
223- . await ?
224- . map ( BroadcastedTx :: Invoke ) ;
225-
226- // none means the address is not a Controller
227- if let Some ( tx) = result {
228- deployed_controllers. insert ( contract_address) ;
229- deploy_transactions. push ( tx) ;
230- deployer_nonce += Nonce :: ONE ;
231- }
232- }
234+ let deploy_tx = self . get_controller_deployment_tx ( address, deployer_nonce) . await ?;
233235
234- Err ( e) => panic ! ( "{}" , e. to_string( ) ) ,
235- Ok ( ..) => continue ,
236+ // None means the address is not a Controller
237+ if let Some ( tx) = deploy_tx {
238+ deployer_nonce += Nonce :: ONE ;
239+ processed_addresses. push ( address) ;
240+ deploy_transactions. push ( BroadcastedTx :: Invoke ( tx) ) ;
236241 }
237242 }
238243
@@ -304,6 +309,8 @@ where
304309 & self ,
305310 request : Request < ' a > ,
306311 ) -> impl Future < Output = Self :: MethodResponse > + Send + ' a {
312+ let this = self . clone ( ) ;
313+
307314 async move {
308315 let method = request. method_name ( ) ;
309316
@@ -344,6 +351,26 @@ where
344351 }
345352}
346353
354+ impl < S , Pool , PP , PF > Clone for ControllerDeploymentService < S , Pool , PP , PF >
355+ where
356+ S : Clone ,
357+ Pool : TransactionPool ,
358+ PP : PendingBlockProvider ,
359+ PF : ProviderFactory ,
360+ {
361+ fn clone ( & self ) -> Self {
362+ Self {
363+ service : self . service . clone ( ) ,
364+ starknet : self . starknet . clone ( ) ,
365+ vrf_service : self . vrf_service . clone ( ) ,
366+ cartridge_api : self . cartridge_api . clone ( ) ,
367+ paymaster_client : self . paymaster_client . clone ( ) ,
368+ deployer_address : self . deployer_address . clone ( ) ,
369+ deployer_private_key : self . deployer_private_key . clone ( ) ,
370+ }
371+ }
372+ }
373+
347374#[ derive( Debug , thiserror:: Error ) ]
348375pub enum Error {
349376 #[ error( "cartridge api error: {0}" ) ]
@@ -382,7 +409,7 @@ struct AddExecuteOutsideParams {
382409#[ derive( Deserialize ) ]
383410struct EstimateFeeParams {
384411 #[ serde( alias = "request" ) ]
385- txs : Vec < BroadcastedTx > ,
412+ transactions : Vec < BroadcastedTx > ,
386413 #[ serde( alias = "simulationFlags" ) ]
387414 simulation_flags : Vec < SimulationFlagForEstimateFee > ,
388415 #[ serde( alias = "blockId" ) ]
@@ -444,7 +471,7 @@ fn parse_estimate_fee_params(request: &Request<'_>) -> Option<EstimateFeeParams>
444471
445472 match ( txs_result, simulation_flags_result, block_id_result) {
446473 ( Ok ( txs) , Ok ( simulation_flags) , Ok ( block_id) ) => {
447- Some ( EstimateFeeParams { txs, simulation_flags, block_id } )
474+ Some ( EstimateFeeParams { transactions : txs, simulation_flags, block_id } )
448475 }
449476 _ => {
450477 debug ! ( target: "cartridge" , "Failed to parse estimate fee params." ) ;
0 commit comments