1414// You should have received a copy of the GNU Affero General Public License
1515// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616
17- use std:: mem;
1817use std:: sync:: Arc ;
1918
2019use ctypes:: BlockNumber ;
@@ -25,7 +24,7 @@ use rlp::RlpStream;
2524
2625use super :: block_info:: BestBlockChanged ;
2726use super :: body_db:: { BodyDB , BodyProvider } ;
28- use super :: extras:: { BlockDetails , EpochTransitions , TransactionAddress , EPOCH_KEY_PREFIX } ;
27+ use super :: extras:: { BlockDetails , EpochTransitions , TransactionAddress } ;
2928use super :: headerchain:: { HeaderChain , HeaderProvider } ;
3029use super :: invoice_db:: { InvoiceDB , InvoiceProvider } ;
3130use super :: route:: { tree_route, ImportRoute } ;
@@ -362,128 +361,6 @@ impl BlockChain {
362361 batch. write ( db:: COL_EXTRA , & epoch_num, & transitions) ;
363362 }
364363 }
365-
366- /// Iterate over all epoch transitions.
367- /// This will only return transitions within the canonical chain.
368- #[ allow( dead_code) ]
369- pub fn epoch_transitions ( & self ) -> EpochTransitionIter {
370- let iter = self . db . iter_from_prefix ( db:: COL_EXTRA , & EPOCH_KEY_PREFIX [ ..] ) ;
371- EpochTransitionIter {
372- chain : self ,
373- prefix_iter : iter,
374- }
375- }
376-
377- /// Get a specific epoch transition by block number and provided block hash.
378- pub fn epoch_transition ( & self , block_num : u64 , block_hash : H256 ) -> Option < EpochTransition > {
379- ctrace ! ( BLOCKCHAIN , "Loading epoch transition at block {}, {}" , block_num, block_hash) ;
380-
381- self . db . read ( db:: COL_EXTRA , & block_num) . and_then ( |transitions : EpochTransitions | {
382- transitions. candidates . into_iter ( ) . find ( |c| c. block_hash == block_hash)
383- } )
384- }
385-
386- /// Get the transition to the epoch the given parent hash is part of
387- /// or transitions to.
388- /// This will give the epoch that any children of this parent belong to.
389- ///
390- /// The block corresponding the the parent hash must be stored already.
391- #[ allow( dead_code) ]
392- pub fn epoch_transition_for ( & self , parent_hash : H256 ) -> Option < EpochTransition > {
393- // slow path: loop back block by block
394- #[ allow( clippy:: identity_conversion) ]
395- // This is a false alarm. https://github.com/rust-lang/rust-clippy/issues/3944
396- for hash in self . ancestry_iter ( parent_hash) ? {
397- let details = self . block_details ( & hash) ?;
398-
399- // look for transition in database.
400- if let Some ( transition) = self . epoch_transition ( details. number , hash) {
401- return Some ( transition)
402- }
403-
404- // canonical hash -> fast breakout:
405- // get the last epoch transition up to this block.
406- //
407- // if `block_hash` is canonical it will only return transitions up to
408- // the parent.
409- if self . block_hash ( details. number ) ? == hash {
410- return self . epoch_transitions ( ) . map ( |( _, t) | t) . take_while ( |t| t. block_number <= details. number ) . last ( )
411- }
412- }
413-
414- // should never happen as the loop will encounter genesis before concluding.
415- None
416- }
417-
418- /// Iterator that lists `first` and then all of `first`'s ancestors, by hash.
419- #[ allow( dead_code) ]
420- pub fn ancestry_iter ( & self , first : H256 ) -> Option < AncestryIter > {
421- if self . is_known ( & first) {
422- Some ( AncestryIter {
423- current : first,
424- chain : self ,
425- } )
426- } else {
427- None
428- }
429- }
430- }
431-
432- /// An iterator which walks the blockchain towards the genesis.
433- #[ derive( Clone ) ]
434- pub struct AncestryIter < ' a > {
435- current : H256 ,
436- chain : & ' a BlockChain ,
437- }
438-
439- impl < ' a > Iterator for AncestryIter < ' a > {
440- type Item = H256 ;
441- fn next ( & mut self ) -> Option < H256 > {
442- if self . current . is_zero ( ) {
443- None
444- } else {
445- self . chain . block_details ( & self . current ) . map ( |details| mem:: replace ( & mut self . current , details. parent ) )
446- }
447- }
448- }
449-
450- type TransitionIterInternal < ' a > = Box < Iterator < Item = ( Box < [ u8 ] > , Box < [ u8 ] > ) > + ' a > ;
451- /// An iterator which walks all epoch transitions.
452- /// Returns epoch transitions.
453- #[ allow( dead_code) ]
454- pub struct EpochTransitionIter < ' a > {
455- chain : & ' a BlockChain ,
456- prefix_iter : TransitionIterInternal < ' a > ,
457- }
458-
459- impl < ' a > Iterator for EpochTransitionIter < ' a > {
460- type Item = ( u64 , EpochTransition ) ;
461-
462- fn next ( & mut self ) -> Option < Self :: Item > {
463- loop {
464- // some epochs never occurred on the main chain.
465- let ( key, val) = self . prefix_iter . next ( ) ?;
466-
467- // iterator may continue beyond values beginning with this
468- // prefix.
469- if !key. starts_with ( & EPOCH_KEY_PREFIX [ ..] ) {
470- return None
471- }
472-
473- let transitions: EpochTransitions = :: rlp:: decode ( & val[ ..] ) ;
474-
475- // if there are multiple candidates, at most one will be on the
476- // canon chain.
477- for transition in transitions. candidates . into_iter ( ) {
478- let is_in_canon_chain =
479- self . chain . block_hash ( transition. block_number ) . map_or ( false , |hash| hash == transition. block_hash ) ;
480-
481- if is_in_canon_chain {
482- return Some ( ( transitions. number , transition) )
483- }
484- }
485- }
486- }
487364}
488365
489366/// Interface for querying blocks by hash and by number.
0 commit comments