@@ -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 ( ) ;
@@ -164,7 +167,7 @@ impl BlockTree {
164167 }
165168 }
166169
167- pub fn from_header ( height : impl Into < Height > , header : Header , network : Network ) -> Self {
170+ pub ( crate ) fn from_header ( height : impl Into < Height > , header : Header , network : Network ) -> Self {
168171 let height = height. into ( ) ;
169172 let hash = header. block_hash ( ) ;
170173 let tip = Tip {
@@ -184,7 +187,7 @@ impl BlockTree {
184187 }
185188 }
186189
187- fn accept_header ( & mut self , new_header : Header ) -> AcceptHeaderChanges {
190+ pub ( crate ) fn accept_header ( & mut self , new_header : Header ) -> AcceptHeaderChanges {
188191 let new_hash = new_header. block_hash ( ) ;
189192 let prev_hash = new_header. prev_blockhash ;
190193
@@ -391,6 +394,9 @@ impl BlockTree {
391394
392395 pub ( crate ) fn block_hash_at_height ( & self , height : impl Into < Height > ) -> Option < BlockHash > {
393396 let height = height. into ( ) ;
397+ if self . active_tip . height . eq ( & height) {
398+ return Some ( self . active_tip . hash ) ;
399+ }
394400 self . canonical_hashes . get ( & height) . copied ( )
395401 }
396402
@@ -408,6 +414,14 @@ impl BlockTree {
408414 self . active_tip . height . to_u32 ( )
409415 }
410416
417+ pub ( crate ) fn contains ( & self , hash : BlockHash ) -> bool {
418+ self . headers . contains_key ( & hash) || self . active_tip . hash . eq ( & hash)
419+ }
420+
421+ pub ( crate ) fn tip_hash ( & self ) -> BlockHash {
422+ self . active_tip . hash
423+ }
424+
411425 pub ( crate ) fn filter_hash ( & self , block_hash : BlockHash ) -> Option < FilterHash > {
412426 self . headers . get ( & block_hash) ?. filter_hash
413427 }
@@ -418,6 +432,26 @@ impl BlockTree {
418432 self . headers . get ( hash) ?. filter_hash
419433 }
420434
435+ pub ( crate ) fn locators ( & self ) -> Vec < BlockHash > {
436+ let mut locators = Vec :: new ( ) ;
437+ locators. push ( self . active_tip . hash ) ;
438+ for locator in LOCATOR_INDEX {
439+ let height = self . active_tip . height . checked_sub ( * locator) ;
440+ match height {
441+ Some ( height) => match self . block_hash_at_height ( height) {
442+ Some ( hash) => locators. push ( hash) ,
443+ None => return locators. into_iter ( ) . rev ( ) . collect ( ) ,
444+ } ,
445+ None => return locators. into_iter ( ) . rev ( ) . collect ( ) ,
446+ }
447+ }
448+ locators. into_iter ( ) . rev ( ) . collect ( )
449+ }
450+
451+ pub ( crate ) fn internally_cached_headers ( & self ) -> usize {
452+ self . headers . len ( )
453+ }
454+
421455 pub ( crate ) fn iter ( & self ) -> BlockTreeIterator {
422456 BlockTreeIterator {
423457 block_tree : self ,
0 commit comments