@@ -207,11 +207,11 @@ fn make_ast(
207207
208208/// STatic execution cost for functions within Environment
209209/// returns the top level cost for specific functions
210- /// {function_name: cost }
210+ /// {some-function-name: (CostAnalysisNode, Some({some-function-name: (1,1)})) }
211211pub fn static_cost (
212212 env : & mut Environment ,
213213 contract_identifier : & QualifiedContractIdentifier ,
214- ) -> Result < HashMap < String , StaticCost > , String > {
214+ ) -> Result < HashMap < String , ( CostAnalysisNode , Option < TraitCount > ) > , String > {
215215 let contract_source = env
216216 . global_context
217217 . database
@@ -234,19 +234,15 @@ pub fn static_cost(
234234 let epoch = env. global_context . epoch_id ;
235235 let ast = make_ast ( & contract_source, epoch, clarity_version) ?;
236236
237- let costs = static_cost_from_ast ( & ast, clarity_version) ?;
238- Ok ( costs
239- . into_iter ( )
240- . map ( |( name, ( cost, _trait_count) ) | ( name, cost) )
241- . collect ( ) )
237+ static_cost_tree_from_ast ( & ast, clarity_version)
242238}
243239
244240/// same idea as `static_cost` but returns the root of the cost analysis tree for each function
245241/// Useful if you need to analyze specific nodes in the cost tree
246242pub fn static_cost_tree (
247243 env : & mut Environment ,
248244 contract_identifier : & QualifiedContractIdentifier ,
249- ) -> Result < HashMap < String , CostAnalysisNode > , String > {
245+ ) -> Result < HashMap < String , ( CostAnalysisNode , Option < TraitCount > ) > , String > {
250246 let contract_source = env
251247 . global_context
252248 . database
@@ -276,16 +272,23 @@ pub fn static_cost_from_ast(
276272 contract_ast : & crate :: vm:: ast:: ContractAST ,
277273 clarity_version : & ClarityVersion ,
278274) -> Result < HashMap < String , ( StaticCost , Option < TraitCount > ) > , String > {
279- let cost_trees = static_cost_tree_from_ast ( contract_ast, clarity_version) ?;
275+ let cost_trees_with_traits = static_cost_tree_from_ast ( contract_ast, clarity_version) ?;
280276
281- let trait_count = get_trait_count ( & cost_trees) ;
282- let costs: HashMap < String , StaticCost > = cost_trees
277+ // Extract trait_count from the first entry (all entries have the same trait_count)
278+ let trait_count = cost_trees_with_traits
279+ . values ( )
280+ . next ( )
281+ . and_then ( |( _, trait_count) | trait_count. clone ( ) ) ;
282+
283+ // Convert CostAnalysisNode to StaticCost
284+ let costs: HashMap < String , StaticCost > = cost_trees_with_traits
283285 . into_iter ( )
284- . map ( |( name, cost_analysis_node) | {
286+ . map ( |( name, ( cost_analysis_node, _ ) ) | {
285287 let summing_cost = calculate_total_cost_with_branching ( & cost_analysis_node) ;
286288 ( name, summing_cost. into ( ) )
287289 } )
288290 . collect ( ) ;
291+
289292 Ok ( costs
290293 . into_iter ( )
291294 . map ( |( name, cost) | ( name, ( cost, trait_count. clone ( ) ) ) )
@@ -295,26 +298,39 @@ pub fn static_cost_from_ast(
295298pub ( crate ) fn static_cost_tree_from_ast (
296299 ast : & crate :: vm:: ast:: ContractAST ,
297300 clarity_version : & ClarityVersion ,
298- ) -> Result < HashMap < String , CostAnalysisNode > , String > {
301+ ) -> Result < HashMap < String , ( CostAnalysisNode , Option < TraitCount > ) > , String > {
299302 let exprs = & ast. expressions ;
300303 let user_args = UserArgumentsContext :: new ( ) ;
301304 let costs_map: HashMap < String , Option < StaticCost > > = HashMap :: new ( ) ;
302305 let mut costs: HashMap < String , Option < CostAnalysisNode > > = HashMap :: new ( ) ;
306+ // first pass extracts the function names
303307 for expr in exprs {
304308 if let Some ( function_name) = extract_function_name ( expr) {
305309 costs. insert ( function_name, None ) ;
306310 }
307311 }
312+ // second pass computes the cost
308313 for expr in exprs {
309314 if let Some ( function_name) = extract_function_name ( expr) {
310315 let ( _, cost_analysis_tree) =
311316 build_cost_analysis_tree ( expr, & user_args, & costs_map, clarity_version) ?;
312317 costs. insert ( function_name, Some ( cost_analysis_tree) ) ;
313318 }
314319 }
315- Ok ( costs
320+
321+ // Build the final map with cost analysis nodes
322+ let cost_trees: HashMap < String , CostAnalysisNode > = costs
316323 . into_iter ( )
317324 . filter_map ( |( name, cost) | cost. map ( |c| ( name, c) ) )
325+ . collect ( ) ;
326+
327+ // Compute trait_count while creating the root CostAnalysisNode
328+ let trait_count = get_trait_count ( & cost_trees) ;
329+
330+ // Return each node with its trait_count
331+ Ok ( cost_trees
332+ . into_iter ( )
333+ . map ( |( name, node) | ( name, ( node, trait_count. clone ( ) ) ) )
318334 . collect ( ) )
319335}
320336
0 commit comments