@@ -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
@@ -393,6 +396,9 @@ impl BlockTree {
393396
394397 pub ( crate ) fn block_hash_at_height ( & self , height : impl Into < Height > ) -> Option < BlockHash > {
395398 let height = height. into ( ) ;
399+ if self . active_tip . height . eq ( & height) {
400+ return Some ( self . active_tip . hash ) ;
401+ }
396402 self . canonical_hashes . get ( & height) . copied ( )
397403 }
398404
@@ -410,6 +416,14 @@ impl BlockTree {
410416 self . active_tip . height . to_u32 ( )
411417 }
412418
419+ pub ( crate ) fn contains ( & self , hash : BlockHash ) -> bool {
420+ self . headers . contains_key ( & hash) || self . active_tip . hash . eq ( & hash)
421+ }
422+
423+ pub ( crate ) fn tip_hash ( & self ) -> BlockHash {
424+ self . active_tip . hash
425+ }
426+
413427 pub ( crate ) fn filter_hash ( & self , block_hash : BlockHash ) -> Option < FilterHash > {
414428 self . headers . get ( & block_hash) ?. filter_hash
415429 }
@@ -420,6 +434,26 @@ impl BlockTree {
420434 self . headers . get ( hash) ?. filter_hash
421435 }
422436
437+ pub ( crate ) fn locators ( & self ) -> Vec < BlockHash > {
438+ let mut locators = Vec :: new ( ) ;
439+ locators. push ( self . active_tip . hash ) ;
440+ for locator in LOCATOR_INDEX {
441+ let height = self . active_tip . height . checked_sub ( * locator) ;
442+ match height {
443+ Some ( height) => match self . block_hash_at_height ( height) {
444+ Some ( hash) => locators. push ( hash) ,
445+ None => return locators. into_iter ( ) . rev ( ) . collect ( ) ,
446+ } ,
447+ None => return locators. into_iter ( ) . rev ( ) . collect ( ) ,
448+ }
449+ }
450+ locators. into_iter ( ) . rev ( ) . collect ( )
451+ }
452+
453+ pub ( crate ) fn internally_cached_headers ( & self ) -> usize {
454+ self . headers . len ( )
455+ }
456+
423457 pub ( crate ) fn iter ( & self ) -> BlockTreeIterator {
424458 BlockTreeIterator {
425459 block_tree : self ,
0 commit comments