@@ -39,6 +39,7 @@ use crate::{
3939 ProcessingCounters ,
4040 } ,
4141 processes:: {
42+ difficulty:: calc_work,
4243 ghostdag:: ordering:: SortableBlock ,
4344 window:: { WindowManager , WindowType } ,
4445 } ,
@@ -469,12 +470,31 @@ impl Consensus {
469470 }
470471
471472 fn estimate_network_hashes_per_second_impl ( & self , ghostdag_data : & GhostdagData , window_size : usize ) -> ConsensusResult < u64 > {
472- let window = match self . services . window_manager . block_window ( ghostdag_data, WindowType :: VaryingWindow ( window_size) ) {
473- Ok ( w) => w,
474- Err ( RuleError :: InsufficientDaaWindowSize ( s) ) => return Err ( DifficultyError :: InsufficientWindowData ( s) . into ( ) ) ,
475- Err ( e) => panic ! ( "unexpected error: {e}" ) ,
476- } ;
477- Ok ( self . services . window_manager . estimate_network_hashes_per_second ( window) ?)
473+ let mut count = 0 ;
474+ let mut red_work: BlueWorkType = 0 . into ( ) ;
475+ let mut bottom = ghostdag_data. selected_parent ;
476+ for chain_block in self . services . reachability_service . default_backward_chain_iterator ( ghostdag_data. selected_parent ) {
477+ let gd = self . get_ghostdag_data ( chain_block) . unwrap ( ) ;
478+ for red in & gd. mergeset_reds {
479+ let red_header = self . headers_store . get_header ( * red) . unwrap ( ) ;
480+ red_work = red_work + calc_work ( red_header. bits ) ;
481+ }
482+ count += gd. mergeset_blues . len ( ) + gd. mergeset_reds . len ( ) ;
483+ bottom = chain_block;
484+ if count >= window_size {
485+ break ;
486+ }
487+ }
488+ let sp_header = self . headers_store . get_header ( ghostdag_data. selected_parent ) . unwrap ( ) ;
489+ let bottom_header = self . headers_store . get_header ( bottom) . unwrap ( ) ;
490+ let blue_work = sp_header. blue_work - bottom_header. blue_work ;
491+ let total_work = blue_work + red_work;
492+ let time_diff = ( sp_header. timestamp - bottom_header. timestamp ) / 1000 ; // Time difference in seconds
493+ if time_diff == 0 {
494+ return Err ( ConsensusError :: General ( "time difference is zero, cannot estimate hashes per second" ) ) ;
495+ }
496+ let hashes_per_second = ( total_work / time_diff) . as_u64 ( ) ;
497+ Ok ( hashes_per_second)
478498 }
479499
480500 fn pruning_point_compact_headers ( & self ) -> Vec < ( Hash , CompactHeaderData ) > {
0 commit comments