11use crate :: {
2- indexer:: {
3- database:: BlocksDatabaseAccess , fork_scratch_pad:: CONFIRMED_SEGMENT_MINIMUM_LENGTH ,
4- ChainSegment , ChainSegmentIncompatibility ,
5- } ,
2+ indexer:: { database:: BlocksDatabaseAccess , ChainSegment , ChainSegmentIncompatibility } ,
63 try_error, try_info,
74 utils:: Context ,
85} ;
@@ -16,6 +13,8 @@ use hiro_system_kit::slog;
1613use std:: collections:: { hash_map:: Entry , BTreeMap , BTreeSet , HashMap , HashSet } ;
1714use std:: sync:: Arc ;
1815
16+ const STACKS_CONFIRMED_SEGMENT_MINIMUM_LENGTH : i32 = 20 ;
17+
1918pub struct StacksBlockPool {
2019 canonical_fork_id : usize ,
2120 highest_competing_fork_height_delta : Option < u16 > ,
@@ -102,6 +101,18 @@ impl StacksBlockPool {
102101 }
103102 }
104103
104+ fn add_fork ( & mut self , fork : ChainSegment ) -> usize {
105+ let number_of_forks = self . forks . len ( ) ;
106+ let mut next_fork_id = 0 ;
107+ for ( index, ( fork_id, _) ) in self . forks . iter ( ) . enumerate ( ) {
108+ if ( index + 1 ) == number_of_forks {
109+ next_fork_id = fork_id + 1 ;
110+ }
111+ }
112+ self . forks . insert ( next_fork_id, fork) ;
113+ next_fork_id
114+ }
115+
105116 pub fn process_block (
106117 & mut self ,
107118 block : StacksBlockData ,
@@ -135,14 +146,7 @@ impl StacksBlockPool {
135146 let ( block_appended, mut new_fork) = fork. try_append_block ( & block, ctx) ;
136147 if block_appended {
137148 if let Some ( new_fork) = new_fork. take ( ) {
138- let number_of_forks = self . forks . len ( ) ;
139- let mut next_fork_id = 0 ;
140- for ( index, ( fork_id, _) ) in self . forks . iter ( ) . enumerate ( ) {
141- if ( index + 1 ) == number_of_forks {
142- next_fork_id = fork_id + 1 ;
143- }
144- }
145- self . forks . insert ( next_fork_id, new_fork) ;
149+ let next_fork_id = self . add_fork ( new_fork) ;
146150 fork_updated = self . forks . get_mut ( & next_fork_id) ;
147151 } else {
148152 fork_updated = Some ( fork) ;
@@ -161,28 +165,49 @@ impl StacksBlockPool {
161165 ) ;
162166 self . block_store
163167 . insert ( block. block_identifier . clone ( ) , block. clone ( ) ) ;
164- fork
165168 }
166169 None => {
167170 // Look for the orphan block in the blocks DB. If it already exists, it means we've received an old block and we
168171 // should just ignore it. This can happen if the Stacks node feeding us blocks is still catching up to our chain
169172 // tip.
170- if let Some ( db_access) = & self . database_access {
173+ let handled = if let Some ( db_access) = & self . database_access {
171174 if let Ok ( true ) = db_access. block_exists ( & block. block_identifier , ctx) {
172175 try_info ! (
173176 ctx,
174177 "Ignoring previously processed block: Stacks {}" ,
175178 block. block_identifier
176179 ) ;
177- return Ok ( None ) ;
180+ true
181+ } else {
182+ // Check the new block's parent, perhaps this is a deep re-orged block segment we need to add to our
183+ // forks.
184+ if let Ok ( true ) =
185+ db_access. block_exists ( & block. parent_block_identifier , ctx)
186+ {
187+ try_info ! (
188+ ctx,
189+ "Appending new deep re-orged fork for block: Stacks {}" ,
190+ block. parent_block_identifier
191+ ) ;
192+ let mut fork = ChainSegment :: new ( ) ;
193+ fork. append_block_identifier ( & block. parent_block_identifier ) ;
194+ self . add_fork ( fork) ;
195+ true
196+ } else {
197+ false
198+ }
178199 }
200+ } else {
201+ false
202+ } ;
203+ if !handled {
204+ try_error ! (
205+ ctx,
206+ "Unable to process orphan block: Stacks {}" ,
207+ block. block_identifier
208+ ) ;
209+ return Err ( "Unable to process orphan Stacks block" . to_string ( ) ) ;
179210 }
180- try_error ! (
181- ctx,
182- "Unable to process orphan block: Stacks {}" ,
183- block. block_identifier
184- ) ;
185- return Err ( "Unable to process orphan Stacks block" . to_string ( ) ) ;
186211 }
187212 } ;
188213
@@ -321,12 +346,12 @@ impl StacksBlockPool {
321346 segment
322347 } ;
323348
324- if canonical_segment. len ( ) < CONFIRMED_SEGMENT_MINIMUM_LENGTH as usize {
349+ if canonical_segment. len ( ) < STACKS_CONFIRMED_SEGMENT_MINIMUM_LENGTH as usize {
325350 ctx. try_log ( |logger| slog:: info!( logger, "No block to confirm" ) ) ;
326351 return ;
327352 }
328353 // Any block beyond 6th ancestor is considered as confirmed and can be pruned
329- let cut_off = & canonical_segment[ ( CONFIRMED_SEGMENT_MINIMUM_LENGTH - 2 ) as usize ] ;
354+ let cut_off = & canonical_segment[ ( STACKS_CONFIRMED_SEGMENT_MINIMUM_LENGTH - 2 ) as usize ] ;
330355
331356 // Prune forks using the confirmed block
332357 let mut blocks_to_prune = vec ! [ ] ;
0 commit comments