@@ -12,12 +12,34 @@ use katana_primitives::{ContractAddress, Felt};
1212use katana_provider:: ProviderFactory ;
1313use katana_rpc_server:: starknet:: PendingBlockProvider ;
1414use katana_rpc_types:: broadcasted:: BroadcastedTx ;
15+ use katana_rpc_types:: FeeEstimate ;
1516use serde:: Deserialize ;
1617use starknet:: core:: types:: SimulationFlagForEstimateFee ;
18+ use starknet:: providers:: jsonrpc:: JsonRpcResponse ;
19+ use tracing:: { debug, trace} ;
1720
1821use super :: Paymaster ;
1922use crate :: rpc:: types:: OutsideExecution ;
2023
24+ #[ derive( Deserialize ) ]
25+ struct EstimateFeeParams {
26+ #[ serde( alias = "request" ) ]
27+ txs : Vec < BroadcastedTx > ,
28+ #[ serde( alias = "simulationFlags" ) ]
29+ simulation_flags : Vec < SimulationFlagForEstimateFee > ,
30+ #[ serde( alias = "blockId" ) ]
31+ block_id : BlockIdOrTag ,
32+ }
33+
34+ #[ derive( Deserialize ) ]
35+ struct OutsideExecutionParams {
36+ #[ serde( alias = "address" ) ]
37+ controller_address : ContractAddress ,
38+ #[ serde( alias = "outsideExecution" ) ]
39+ outside_execution : OutsideExecution ,
40+ signature : Vec < Felt > ,
41+ }
42+
2143#[ derive( Debug ) ]
2244pub struct PaymasterLayer < Pool : TransactionPool , PP : PendingBlockProvider , PF : ProviderFactory >
2345where
@@ -60,28 +82,21 @@ where
6082impl < S , Pool : TransactionPool + ' static , PP : PendingBlockProvider , PF : ProviderFactory >
6183 PaymasterService < S , Pool , PP , PF >
6284where
63- S : RpcServiceT + Send + Sync + Clone + ' static ,
85+ S : RpcServiceT < MethodResponse = MethodResponse > + Send + Sync + Clone + ' static ,
6486 <PF as ProviderFactory >:: Provider : ProviderRO ,
6587{
66- async fn intercept_estimate_fee ( paymaster : Paymaster < Pool , PP , PF > , request : & mut Request < ' _ > ) {
88+ /// Extract estimate_fee parameters from the request.
89+ fn parse_estimate_fee_params ( request : & Request < ' _ > ) -> Option < EstimateFeeParams > {
6790 let params = request. params ( ) ;
6891
69- let ( txs, simulation_flags, block_id) = if params. is_object ( ) {
70- #[ derive( Deserialize ) ]
71- struct ParamsObject {
72- request : Vec < BroadcastedTx > ,
73- #[ serde( alias = "simulationFlags" ) ]
74- simulation_flags : Vec < SimulationFlagForEstimateFee > ,
75- #[ serde( alias = "blockId" ) ]
76- block_id : BlockIdOrTag ,
92+ if params. is_object ( ) {
93+ match params. parse ( ) {
94+ Ok ( p) => Some ( p) ,
95+ Err ( ..) => {
96+ debug ! ( target: "cartridge" , "Failed to parse estimate fee params." ) ;
97+ None
98+ }
7799 }
78-
79- let parsed: ParamsObject = match params. parse ( ) {
80- Ok ( p) => p,
81- Err ( ..) => return ,
82- } ;
83-
84- ( parsed. request , parsed. simulation_flags , parsed. block_id )
85100 } else {
86101 let mut seq = params. sequence ( ) ;
87102
@@ -90,81 +105,201 @@ where
90105 let block_id_result: Result < BlockIdOrTag , _ > = seq. next ( ) ;
91106
92107 match ( txs_result, simulation_flags_result, block_id_result) {
93- ( Ok ( txs) , Ok ( simulation_flags) , Ok ( block_id) ) => ( txs, simulation_flags, block_id) ,
94- _ => return ,
108+ ( Ok ( txs) , Ok ( simulation_flags) , Ok ( block_id) ) => {
109+ Some ( EstimateFeeParams { txs, simulation_flags, block_id } )
110+ }
111+ _ => {
112+ debug ! ( target: "cartridge" , "Failed to parse estimate fee params." ) ;
113+ None
114+ }
95115 }
96- } ;
97-
98- if let Ok ( Some ( updated_txs) ) = paymaster. handle_estimate_fees ( block_id, txs) . await {
99- let new_params = {
100- let mut params = jsonrpsee:: core:: params:: ArrayParams :: new ( ) ;
101- params. insert ( & updated_txs) . unwrap ( ) ;
102- params. insert ( simulation_flags) . unwrap ( ) ;
103- params. insert ( block_id) . unwrap ( ) ;
104- params
105- } ;
106-
107- let params = new_params. to_rpc_params ( ) . unwrap ( ) ;
108- let params = params. map ( Cow :: Owned ) ;
109- request. params = params;
110116 }
111117 }
112118
113- async fn intercept_add_outside_execution (
114- paymaster : Paymaster < Pool , PP , PF > ,
115- request : & mut Request < ' _ > ,
116- ) {
119+ /// Extract add_outside_execution parameters from the request.
120+ fn parse_add_outside_execution_params ( request : & Request < ' _ > ) -> Option < OutsideExecutionParams > {
117121 let params = request. params ( ) ;
118122
119- let ( controller_address, outside_execution, signature) = if params. is_object ( ) {
120- #[ derive( Deserialize ) ]
121- struct ParamsObject {
122- address : ContractAddress ,
123- #[ serde( alias = "outsideExecution" ) ]
124- outside_execution : OutsideExecution ,
125- signature : Vec < Felt > ,
123+ if params. is_object ( ) {
124+ println ! ( "params is object: {:?}" , params) ;
125+ match params. parse ( ) {
126+ Ok ( p) => Some ( p) ,
127+ Err ( ..) => {
128+ debug ! ( target: "cartridge" , "Failed to parse outside execution params." ) ;
129+ None
130+ }
126131 }
127-
128- let parsed: ParamsObject = match params. parse ( ) {
129- Ok ( p) => p,
130- Err ( ..) => return ,
131- } ;
132-
133- ( parsed. address , parsed. outside_execution , parsed. signature )
134132 } else {
133+ println ! ( "params is sequence: {:?}" , params) ;
135134 let mut seq = params. sequence ( ) ;
136135
137136 let address_result: Result < ContractAddress , _ > = seq. next ( ) ;
138137 let outside_execution_result: Result < OutsideExecution , _ > = seq. next ( ) ;
139138 let signature_result: Result < Vec < Felt > , _ > = seq. next ( ) ;
140139
141140 match ( address_result, outside_execution_result, signature_result) {
142- ( Ok ( address) , Ok ( outside_execution) , Ok ( signature) ) => {
143- ( address, outside_execution, signature)
141+ ( Ok ( controller_address) , Ok ( outside_execution) , Ok ( signature) ) => {
142+ Some ( OutsideExecutionParams {
143+ controller_address,
144+ outside_execution,
145+ signature,
146+ } )
147+ }
148+ _ => {
149+ debug ! ( target: "cartridge" , "Failed to parse outside execution params." ) ;
150+ None
144151 }
145- _ => return ,
146152 }
147- } ;
148-
149- match paymaster
150- . handle_add_outside_execution ( controller_address, outside_execution, signature)
151- . await
152- {
153- Ok ( Some ( ( outside_execution, signature) ) ) => {
154- let new_params = {
155- let mut params = jsonrpsee:: core:: params:: ArrayParams :: new ( ) ;
156- params. insert ( controller_address) . unwrap ( ) ;
157- params. insert ( outside_execution) . unwrap ( ) ;
158- params. insert ( signature) . unwrap ( ) ;
159- params
153+ }
154+ }
155+
156+ /// Build a new estimate fee request with the updated transactions.
157+ fn build_new_estimate_fee_request < ' a > (
158+ request : & Request < ' a > ,
159+ params : & EstimateFeeParams ,
160+ updated_txs : & Vec < BroadcastedTx > ,
161+ ) -> Request < ' a > {
162+ let mut new_request = request. clone ( ) ;
163+
164+ let mut new_params = jsonrpsee:: core:: params:: ArrayParams :: new ( ) ;
165+ new_params. insert ( updated_txs) . unwrap ( ) ;
166+ new_params. insert ( params. simulation_flags . clone ( ) ) . unwrap ( ) ;
167+ new_params. insert ( params. block_id ) . unwrap ( ) ;
168+
169+ let new_params = new_params. to_rpc_params ( ) . unwrap ( ) ;
170+ new_request. params = new_params. map ( Cow :: Owned ) ;
171+ new_request
172+ }
173+
174+ /// <----
175+ fn build_no_fee_response ( request : & Request < ' _ > , count : usize ) -> MethodResponse {
176+ let estimate_fees = vec ! [
177+ FeeEstimate {
178+ l1_gas_consumed: 0 ,
179+ l1_gas_price: 0 ,
180+ l2_gas_consumed: 0 ,
181+ l2_gas_price: 0 ,
182+ l1_data_gas_consumed: 0 ,
183+ l1_data_gas_price: 0 ,
184+ overall_fee: 0
185+ } ;
186+ count
187+ ] ;
188+
189+ MethodResponse :: response (
190+ request. id ( ) . clone ( ) ,
191+ jsonrpsee:: ResponsePayload :: success ( estimate_fees) ,
192+ usize:: MAX ,
193+ )
194+ }
195+ /// ---->
196+
197+ fn intercept_estimate_fee < ' a > (
198+ service : S ,
199+ paymaster : Paymaster < Pool , PP , PF > ,
200+ request : Request < ' a > ,
201+ ) -> impl Future < Output = S :: MethodResponse > + Send + ' a {
202+ async move {
203+ if let Some ( params) = Self :: parse_estimate_fee_params ( & request) {
204+ let updated_txs = paymaster
205+ . handle_estimate_fees ( params. block_id , & params. txs )
206+ . await
207+ . unwrap_or_default ( ) ;
208+
209+ if let Some ( updated_txs) = updated_txs {
210+ let new_request =
211+ Self :: build_new_estimate_fee_request ( & request, & params, & updated_txs) ;
212+
213+ let response = service. call ( new_request) . await ;
214+
215+ // if `handle_estimate_fees` has added some new transactions at the
216+ // beginning of updated_txs, we have to remove
217+ // extras results from estimate_fees to be
218+ // sure to return the same number of result than the number
219+ // of transactions in the request.
220+ let nb_of_txs = params. txs . len ( ) ;
221+ let nb_of_extra_txs = updated_txs. len ( ) - nb_of_txs;
222+
223+ if response. is_success ( ) && nb_of_extra_txs > 0 {
224+ if let Ok ( JsonRpcResponse :: Success { result : mut estimate_fees, .. } ) =
225+ serde_json:: from_str :: < JsonRpcResponse < Vec < FeeEstimate > > > (
226+ response. to_json ( ) . get ( ) ,
227+ )
228+ {
229+ if estimate_fees. len ( ) >= nb_of_extra_txs {
230+ estimate_fees. drain ( 0 ..nb_of_extra_txs) ;
231+ }
232+
233+ trace ! (
234+ target: "cartridge" ,
235+ nb_of_extra_txs = nb_of_extra_txs,
236+ nb_of_estimate_fees = estimate_fees. len( ) ,
237+ "Removing extra transactions from estimate fees response" ,
238+ ) ;
239+
240+ // TODO: restore the real response
241+
242+ return Self :: build_no_fee_response ( & request, nb_of_txs) ;
243+ // return MethodResponse::response(
244+ // request.id().clone(),
245+ // jsonrpsee::ResponsePayload::success(estimate_fees),
246+ // usize::MAX,
247+ // );
248+ }
249+ }
250+
251+ trace ! ( target: "cartridge" , "Estimate fee endpoint original response returned" ) ;
252+ return Self :: build_no_fee_response ( & request, nb_of_txs) ;
253+ // return response;
254+ }
255+ }
256+
257+ trace ! ( target: "cartridge" , "Estimate fee endpoint called with the original transaction" ) ;
258+ service. call ( request) . await
259+ }
260+ }
261+
262+ fn intercept_add_outside_execution < ' a > (
263+ service : S ,
264+ paymaster : Paymaster < Pool , PP , PF > ,
265+ request : Request < ' a > ,
266+ ) -> impl Future < Output = S :: MethodResponse > + Send + ' a {
267+ async move {
268+ if let Some ( OutsideExecutionParams {
269+ controller_address,
270+ outside_execution,
271+ signature,
272+ } ) = Self :: parse_add_outside_execution_params ( & request)
273+ {
274+ let updated_tx = match paymaster
275+ . handle_add_outside_execution ( controller_address, outside_execution, signature)
276+ . await
277+ {
278+ Ok ( Some ( tx) ) => Some ( tx) ,
279+ Ok ( None ) => None ,
280+ Err ( error) => panic ! ( "{error}" ) ,
160281 } ;
161282
162- let params = new_params. to_rpc_params ( ) . unwrap ( ) ;
163- let params = params. map ( Cow :: Owned ) ;
164- request. params = params;
283+ if let Some ( ( outside_execution, signature) ) = updated_tx {
284+ let mut new_request = request. clone ( ) ;
285+ let new_params = {
286+ let mut params = jsonrpsee:: core:: params:: ArrayParams :: new ( ) ;
287+ params. insert ( controller_address) . unwrap ( ) ;
288+ params. insert ( outside_execution) . unwrap ( ) ;
289+ params. insert ( signature) . unwrap ( ) ;
290+ params
291+ } ;
292+
293+ let params = new_params. to_rpc_params ( ) . unwrap ( ) ;
294+ new_request. params = params. map ( Cow :: Owned ) ;
295+
296+ trace ! ( target: "cartridge" , "Call outside_execution endpoint with the updated transaction" ) ;
297+ return service. call ( new_request) . await ;
298+ }
165299 }
166- Ok ( None ) => { }
167- Err ( error) => panic ! ( "{error}" ) ,
300+
301+ trace ! ( target: "cartridge" , "Call outside_execution endpoint with the original transaction" ) ;
302+ service. call ( request) . await
168303 }
169304 }
170305}
@@ -199,19 +334,19 @@ where
199334
200335 fn call < ' a > (
201336 & self ,
202- mut request : Request < ' a > ,
337+ request : Request < ' a > ,
203338 ) -> impl Future < Output = Self :: MethodResponse > + Send + ' a {
204339 let service = self . service . clone ( ) ;
205340 let paymaster = self . paymaster . clone ( ) ;
206341
207342 async move {
208343 if request. method_name ( ) == "starknet_estimateFee" {
209- Self :: intercept_estimate_fee ( paymaster, & mut request) . await ;
344+ Self :: intercept_estimate_fee ( service , paymaster, request) . await
210345 } else if request. method_name ( ) == "cartridge_addExecuteOutsideTransaction" {
211- Self :: intercept_add_outside_execution ( paymaster, & mut request) . await ;
346+ Self :: intercept_add_outside_execution ( service, paymaster, request) . await
347+ } else {
348+ service. call ( request) . await
212349 }
213-
214- service. call ( request) . await
215350 }
216351 }
217352
0 commit comments