@@ -145,6 +145,7 @@ impl<H: IsHeader + Clone + Send> ChainFollower<H> {
145145 } )
146146 }
147147
148+ #[ allow( clippy:: panic) ]
148149 pub fn next_op ( & mut self , store : Arc < dyn ReadOnlyChainStore < H > > ) -> Option < ClientOp < H > > {
149150 // is this initial rollback?
150151 if let Some ( ref init_tip) = self . initial {
@@ -167,12 +168,10 @@ impl<H: IsHeader + Clone + Send> ChainFollower<H> {
167168 trace ! ( forwarded = %child. point( ) , anchor = ?self . anchor, "forwarding from store at origin" ) ;
168169 return Some ( ClientOp :: Forward ( child) ) ;
169170 }
170- None => {
171- // FIXME: this seems possible in some circumstances given how our DB is structured
172- // but this should never happen in practice. Perhaps turn into a proper `panic!`?
173- warn ! ( intersection = ?self . intersection, child = %point, anchor = ?self . anchor, "child not found in store" ) ;
174- return None ;
175- }
171+ None => panic ! (
172+ "Store invariant violated:\n next_best_chain returned {} but header not in store (intersection: {:?}, anchor: {:?})" ,
173+ point, self . intersection, self . anchor
174+ ) ,
176175 }
177176 }
178177 None => {
@@ -182,7 +181,12 @@ impl<H: IsHeader + Clone + Send> ChainFollower<H> {
182181 }
183182 }
184183
185- self . ops . pop_front ( )
184+ if let Some ( op) = self . ops . pop_front ( ) {
185+ self . intersection = op. tip ( ) ;
186+ Some ( op)
187+ } else {
188+ None
189+ }
186190 }
187191
188192 pub fn add_op ( & mut self , op : ClientOp < H > ) {
@@ -248,11 +252,11 @@ pub(crate) mod tests {
248252 fn find_headers_starting_at_tip ( ) {
249253 let store = mk_in_memory_store ( CHAIN_47 ) ;
250254
251- let tip = store. get_point ( TIP_47 ) ;
255+ let tip_point = store. get_point ( TIP_47 ) ;
252256 let points = [ store. get_point ( TIP_47 ) ] ;
253- let start = Tip ( tip . clone ( ) , store. get_height ( TIP_47 ) ) ;
257+ let start = Tip ( tip_point . clone ( ) , store. get_height ( TIP_47 ) ) ;
254258
255- let mut chain_follower = ChainFollower :: new ( store. clone ( ) , & tip , & points) . unwrap ( ) ;
259+ let mut chain_follower = ChainFollower :: new ( store. clone ( ) , & tip_point , & points) . unwrap ( ) ;
256260
257261 assert_eq ! (
258262 chain_follower. next_op( store. clone( ) ) ,
@@ -343,6 +347,7 @@ pub(crate) mod tests {
343347 }
344348
345349 #[ test]
350+ #[ should_panic( expected = "Store invariant violated" ) ]
346351 fn next_op_returns_none_given_it_fails_to_load_child_header ( ) {
347352 let store = mk_in_memory_store ( CHAIN_47 ) ;
348353 let unstored_header = run ( any_header_with_parent ( Hash :: from (
@@ -364,7 +369,6 @@ pub(crate) mod tests {
364369 let mut chain_follower = ChainFollower :: new ( store. clone ( ) , & tip, & points) . unwrap ( ) ;
365370
366371 let _ = chain_follower. next_op ( store. clone ( ) ) ; // initial rollback
367- assert_eq ! ( chain_follower. next_op( store. clone( ) ) , None ) ;
368372 }
369373
370374 // HELPERS
0 commit comments