@@ -51,7 +51,7 @@ fn propagate_slow_lane_to_dependents(
5151 let mut dependents_by_dependency: HashMap < ChainHash , Vec < ChainHash > > =
5252 HashMap :: new ( ) ;
5353 for chain in chains {
54- for dependency in & chain. inheritance_parents {
54+ for dependency in & chain. split_dependencies {
5555 dependents_by_dependency
5656 . entry ( * dependency)
5757 . or_default ( )
@@ -74,6 +74,64 @@ fn propagate_slow_lane_to_dependents(
7474 }
7575}
7676
77+ fn classify_slow_by_split_dependency_closure (
78+ chains : & [ Chain ] ,
79+ dependent_ops_by_chain : & HashMap < ChainHash , u64 > ,
80+ max_per_chain : u64 ,
81+ ) -> HashSet < ChainHash > {
82+ let chain_ids = chains
83+ . iter ( )
84+ . map ( |chain| chain. hash )
85+ . collect :: < HashSet < _ > > ( ) ;
86+ let mut neighbors: HashMap < ChainHash , HashSet < ChainHash > > =
87+ HashMap :: with_capacity ( chains. len ( ) ) ;
88+ for chain in chains {
89+ neighbors. entry ( chain. hash ) . or_default ( ) ;
90+ for dependency in & chain. split_dependencies {
91+ if !chain_ids. contains ( dependency) {
92+ continue ;
93+ }
94+ neighbors. entry ( chain. hash ) . or_default ( ) . insert ( * dependency) ;
95+ neighbors. entry ( * dependency) . or_default ( ) . insert ( chain. hash ) ;
96+ }
97+ }
98+
99+ let mut visited = HashSet :: with_capacity ( chains. len ( ) ) ;
100+ let mut slow_dep_chain_ids = HashSet :: new ( ) ;
101+ for chain in chains {
102+ if visited. contains ( & chain. hash ) {
103+ continue ;
104+ }
105+ let mut component = Vec :: new ( ) ;
106+ let mut stack = vec ! [ chain. hash] ;
107+ visited. insert ( chain. hash ) ;
108+ while let Some ( current) = stack. pop ( ) {
109+ component. push ( current) ;
110+ if let Some ( next_neighbors) = neighbors. get ( & current) {
111+ for next in next_neighbors {
112+ if visited. insert ( * next) {
113+ stack. push ( * next) ;
114+ }
115+ }
116+ }
117+ }
118+
119+ let component_ops =
120+ component. iter ( ) . fold ( 0_u64 , |sum, dep_chain_id| {
121+ sum. saturating_add (
122+ dependent_ops_by_chain
123+ . get ( dep_chain_id)
124+ . copied ( )
125+ . unwrap_or ( 0 ) ,
126+ )
127+ } ) ;
128+ if component_ops > max_per_chain {
129+ slow_dep_chain_ids. extend ( component) ;
130+ }
131+ }
132+ slow_dep_chain_ids
133+ }
134+
77135pub async fn ingest_block_logs (
78136 chain_id : ChainId ,
79137 db : & mut Database ,
@@ -205,20 +263,17 @@ pub async fn ingest_block_logs(
205263 let mut slow_dep_chain_ids: HashSet < ChainHash > = HashSet :: new ( ) ;
206264 if slow_lane_enabled {
207265 let max_per_chain = u64:: from ( options. dependent_ops_max_per_chain ) ;
208- for chain in & chains {
209- if let Some ( chain_dep_ops) = dependent_ops_by_chain. get ( & chain. hash )
210- {
211- if * chain_dep_ops > max_per_chain {
212- slow_dep_chain_ids. insert ( chain. hash ) ;
213- }
214- }
215- }
266+ slow_dep_chain_ids = classify_slow_by_split_dependency_closure (
267+ & chains,
268+ & dependent_ops_by_chain,
269+ max_per_chain,
270+ ) ;
216271
217272 let parent_dep_chain_ids = chains
218273 . iter ( )
219274 . flat_map ( |chain| {
220275 chain
221- . inheritance_parents
276+ . split_dependencies
222277 . iter ( )
223278 . map ( |dependency| dependency. to_vec ( ) )
224279 } )
@@ -276,7 +331,7 @@ mod tests {
276331 . iter ( )
277332 . map ( |dep| FixedBytes :: < 32 > :: from ( [ * dep; 32 ] ) )
278333 . collect ( ) ,
279- inheritance_parents : dependencies
334+ split_dependencies : dependencies
280335 . iter ( )
281336 . map ( |dep| FixedBytes :: < 32 > :: from ( [ * dep; 32 ] ) )
282337 . collect ( ) ,
@@ -305,4 +360,31 @@ mod tests {
305360 assert ! ( slow_dep_chain_ids. contains( & chains[ 2 ] . hash) ) ;
306361 assert ! ( !slow_dep_chain_ids. contains( & chains[ 3 ] . hash) ) ;
307362 }
363+
364+ #[ test]
365+ fn classifies_slow_by_split_dependency_closure_sum ( ) {
366+ let chains = vec ! [
367+ fixture_chain( 1 , & [ ] ) ,
368+ fixture_chain( 2 , & [ 1 ] ) ,
369+ fixture_chain( 3 , & [ 2 ] ) ,
370+ fixture_chain( 4 , & [ ] ) ,
371+ ] ;
372+ let dependent_ops_by_chain = HashMap :: from ( [
373+ ( chains[ 0 ] . hash , 30_u64 ) ,
374+ ( chains[ 1 ] . hash , 20_u64 ) ,
375+ ( chains[ 2 ] . hash , 20_u64 ) ,
376+ ( chains[ 3 ] . hash , 10_u64 ) ,
377+ ] ) ;
378+
379+ let slow_dep_chain_ids = classify_slow_by_split_dependency_closure (
380+ & chains,
381+ & dependent_ops_by_chain,
382+ 64 ,
383+ ) ;
384+
385+ assert ! ( slow_dep_chain_ids. contains( & chains[ 0 ] . hash) ) ;
386+ assert ! ( slow_dep_chain_ids. contains( & chains[ 1 ] . hash) ) ;
387+ assert ! ( slow_dep_chain_ids. contains( & chains[ 2 ] . hash) ) ;
388+ assert ! ( !slow_dep_chain_ids. contains( & chains[ 3 ] . hash) ) ;
389+ }
308390}
0 commit comments