@@ -9,6 +9,8 @@ use bitcoin::{
99
1010use super :: IndexedHeader ;
1111
12+ const LOCATOR_INDEX : & [ u32 ] = & [ 1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 , 1024 ] ;
13+
1214#[ derive( Debug , Clone , Copy , Hash , PartialEq , Eq , PartialOrd , Ord ) ]
1315pub ( crate ) struct Height ( u32 ) ;
1416
@@ -28,7 +30,8 @@ impl Height {
2830 Self ( self . 0 + 1 )
2931 }
3032
31- fn checked_sub ( & self , other : Height ) -> Option < Self > {
33+ fn checked_sub ( & self , other : impl Into < Height > ) -> Option < Self > {
34+ let other = other. into ( ) ;
3235 let height_sub_checked = self . 0 . checked_sub ( other. 0 ) ;
3336 height_sub_checked. map ( Self )
3437 }
@@ -132,7 +135,7 @@ pub struct BlockTree {
132135
133136#[ allow( unused) ]
134137impl BlockTree {
135- pub fn new ( tip : impl Into < Tip > , network : Network ) -> Self {
138+ pub ( crate ) fn new ( tip : impl Into < Tip > , network : Network ) -> Self {
136139 let tip = tip. into ( ) ;
137140 Self {
138141 canonical_hashes : BTreeMap :: new ( ) ,
@@ -143,7 +146,7 @@ impl BlockTree {
143146 }
144147 }
145148
146- pub fn from_genesis ( network : Network ) -> Self {
149+ pub ( crate ) fn from_genesis ( network : Network ) -> Self {
147150 let genesis = genesis_block ( network) ;
148151 let height = Height :: new ( 0 ) ;
149152 let hash = genesis. block_hash ( ) ;
@@ -166,7 +169,7 @@ impl BlockTree {
166169 }
167170 }
168171
169- pub fn from_header ( height : impl Into < Height > , header : Header , network : Network ) -> Self {
172+ pub ( crate ) fn from_header ( height : impl Into < Height > , header : Header , network : Network ) -> Self {
170173 let height = height. into ( ) ;
171174 let hash = header. block_hash ( ) ;
172175 let tip = Tip {
@@ -186,7 +189,7 @@ impl BlockTree {
186189 }
187190 }
188191
189- fn accept_header ( & mut self , new_header : Header ) -> AcceptHeaderChanges {
192+ pub ( crate ) fn accept_header ( & mut self , new_header : Header ) -> AcceptHeaderChanges {
190193 let new_hash = new_header. block_hash ( ) ;
191194 let prev_hash = new_header. prev_blockhash ;
192195
@@ -385,6 +388,9 @@ impl BlockTree {
385388
386389 pub ( crate ) fn block_hash_at_height ( & self , height : impl Into < Height > ) -> Option < BlockHash > {
387390 let height = height. into ( ) ;
391+ if self . active_tip . height . eq ( & height) {
392+ return Some ( self . active_tip . hash ) ;
393+ }
388394 self . canonical_hashes . get ( & height) . copied ( )
389395 }
390396
@@ -402,6 +408,14 @@ impl BlockTree {
402408 self . active_tip . height . to_u32 ( )
403409 }
404410
411+ pub ( crate ) fn contains ( & self , hash : BlockHash ) -> bool {
412+ self . headers . contains_key ( & hash) || self . active_tip . hash . eq ( & hash)
413+ }
414+
415+ pub ( crate ) fn tip_hash ( & self ) -> BlockHash {
416+ self . active_tip . hash
417+ }
418+
405419 pub ( crate ) fn filter_hash ( & self , block_hash : BlockHash ) -> Option < FilterHash > {
406420 self . headers . get ( & block_hash) ?. filter_hash
407421 }
@@ -412,6 +426,26 @@ impl BlockTree {
412426 self . headers . get ( hash) ?. filter_hash
413427 }
414428
429+ pub ( crate ) fn locators ( & self ) -> Vec < BlockHash > {
430+ let mut locators = Vec :: new ( ) ;
431+ locators. push ( self . active_tip . hash ) ;
432+ for locator in LOCATOR_INDEX {
433+ let height = self . active_tip . height . checked_sub ( * locator) ;
434+ match height {
435+ Some ( height) => match self . block_hash_at_height ( height) {
436+ Some ( hash) => locators. push ( hash) ,
437+ None => return locators. into_iter ( ) . rev ( ) . collect ( ) ,
438+ } ,
439+ None => return locators. into_iter ( ) . rev ( ) . collect ( ) ,
440+ }
441+ }
442+ locators. into_iter ( ) . rev ( ) . collect ( )
443+ }
444+
445+ pub ( crate ) fn internally_cached_headers ( & self ) -> usize {
446+ self . headers . len ( )
447+ }
448+
415449 pub ( crate ) fn iter ( & self ) -> BlockTreeIterator {
416450 BlockTreeIterator {
417451 block_tree : self ,
0 commit comments