@@ -715,27 +715,34 @@ impl BlockchainNode {
715715 // CRITICAL FIX: Use network-wide consensus instead of asymmetric peer counting
716716 // Each node was seeing different peer counts causing deadlock
717717 let active_node_count = if let Some ( p2p) = & unified_p2p {
718- // Try to get network-wide consensus on active Genesis nodes count
719- let local_peers = p2p. get_validated_active_peers ( ) . len ( ) ;
720- let genesis_nodes_online = std:: cmp:: min ( local_peers + 1 , 5 ) ; // Max 5 Genesis nodes
718+ // CRITICAL FIX: Use phase-aware node counting for consistent startup
719+ // During Genesis phase, use deterministic counting instead of unreliable P2P discovery
721720
722- // CONSENSUS FIX: Use actual Genesis node availability from network
723- // If we can't determine exact count, use conservative approach
724- if genesis_nodes_online >= 4 {
725- genesis_nodes_online // Use network consensus
726- } else {
727- // During startup, check if we should wait or proceed based on time
721+ let is_genesis_phase = Self :: is_genesis_bootstrap_phase ( p2p) . await ;
722+
723+ if is_genesis_phase {
724+ // Genesis phase: Use deterministic Genesis node counting
725+ // Count actual Genesis nodes that should be running based on time
728726 let current_time = std:: time:: SystemTime :: now ( )
729727 . duration_since ( std:: time:: UNIX_EPOCH )
730728 . unwrap_or_default ( )
731729 . as_secs ( ) ;
732730
733- if current_time >= QNET_GENESIS_TIMESTAMP + 180 { // 3 minutes after start
734- // Force start with available nodes after grace period
735- std:: cmp:: max ( genesis_nodes_online, 1 )
731+ if current_time >= QNET_GENESIS_TIMESTAMP + 600 { // 10 minutes after Genesis
732+ // After grace period: assume all 5 Genesis nodes should be active
733+ 5
734+ } else if current_time >= QNET_GENESIS_TIMESTAMP + 300 { // 5 minutes after Genesis
735+ // Mid grace period: assume 4 Genesis nodes active for Byzantine safety
736+ 4
736737 } else {
737- genesis_nodes_online
738+ // Early startup: use conservative P2P discovery
739+ let local_peers = p2p. get_validated_active_peers ( ) . len ( ) ;
740+ std:: cmp:: min ( local_peers + 1 , 5 )
738741 }
742+ } else {
743+ // Normal phase: Use actual P2P peer discovery
744+ let local_peers = p2p. get_validated_active_peers ( ) . len ( ) ;
745+ std:: cmp:: min ( local_peers + 1 , 1000 ) // Scale to network size
739746 }
740747 } else {
741748 1 // Solo mode
@@ -1283,18 +1290,27 @@ impl BlockchainNode {
12831290 Err ( _) => {
12841291 println ! ( "[SYNC] ⚠️ Cannot sync with producer {} - network unreachable" , current_producer) ;
12851292
1293+ // CRITICAL FIX: Refresh peer connections before timeout to improve connectivity
1294+ if let Some ( p2p) = & unified_p2p {
1295+ // Force peer cache refresh to get latest connections
1296+ let _ = p2p. get_validated_active_peers ( ) ;
1297+ println ! ( "[SYNC] 🔄 Refreshed peer connections for better sync reliability" ) ;
1298+ }
1299+
12861300 // CRITICAL: Check if producer timeout occurred using GLOBAL BLOCK TIME
12871301 // QNet CONSENSUS SAFETY: Use expected block time for synchronized timeout across network
12881302 let expected_block_time = microblock_height * 1 ; // Each microblock should be created every 1 second
12891303 let network_start_time = std:: time:: SystemTime :: UNIX_EPOCH + std:: time:: Duration :: from_secs ( QNET_GENESIS_TIMESTAMP ) ; // Network genesis time
12901304 let current_network_time = std:: time:: SystemTime :: now ( ) . duration_since ( network_start_time) . unwrap_or_default ( ) . as_secs ( ) ;
12911305 let time_since_expected = current_network_time. saturating_sub ( expected_block_time) ;
12921306
1293- if time_since_expected >= 5 { // Fixed deterministic timeout based on network time
1307+ // PRODUCTION: Extended timeout for international Genesis nodes (higher latency)
1308+ let timeout_threshold = if std:: env:: var ( "QNET_BOOTSTRAP_ID" ) . is_ok ( ) { 15 } else { 5 } ;
1309+ if time_since_expected >= timeout_threshold {
12941310 // ENHANCED FAILOVER STATUS DASHBOARD
12951311 println ! ( "[FAILOVER] 🚨 MICROBLOCK FAILOVER EVENT DETECTED:" ) ;
12961312 println ! ( " ├── Failed Producer: {}" , current_producer) ;
1297- println ! ( " ├── Timeout Duration: {} seconds (fixed threshold: 5s )" , time_since_expected) ;
1313+ println ! ( " ├── Timeout Duration: {} seconds (threshold: {}s )" , time_since_expected, timeout_threshold ) ;
12981314 println ! ( " ├── Block Height: {}" , microblock_height + 1 ) ;
12991315 println ! ( " ├── Network Status: {} active peers" , if let Some ( ref p2p) = unified_p2p { p2p. get_validated_active_peers( ) . len( ) } else { 0 } ) ;
13001316 println ! ( " └── Recovery Action: Emergency producer rotation initiated" ) ;
@@ -1399,34 +1415,28 @@ impl BlockchainNode {
13991415 /// PRODUCTION: Initialize only ACTIVE Genesis node reputations discovered via P2P
14001416 /// Prevents phantom candidates for unoperated Genesis nodes
14011417 async fn initialize_genesis_reputations ( p2p : & SimplifiedP2P ) {
1402- println ! ( "[REPUTATION] 🔐 Initializing ACTIVE Genesis node reputations..." ) ;
1403-
1404- // CRITICAL FIX: Initialize ALL Genesis nodes deterministically regardless of discovery status
1405- // This ensures consistent candidate lists across all nodes for Byzantine consensus
1406- let genesis_ips = crate :: unified_p2p:: get_genesis_bootstrap_ips ( ) ;
1407-
1408- for ( i, _genesis_ip) in genesis_ips. iter ( ) . enumerate ( ) {
1409- let genesis_id = format ! ( "genesis_node_{:03}" , i + 1 ) ;
1410-
1411- // Set 90% reputation for ALL Genesis nodes on ALL nodes
1412- p2p. set_node_reputation ( & genesis_id, 90.0 ) ;
1413-
1414- println ! ( "[REPUTATION] 🔐 Genesis {} initialized to 90% reputation (deterministic)" , genesis_id) ;
1415- }
1418+ println ! ( "[REPUTATION] 🔐 Initializing own Genesis node reputation..." ) ;
14161419
1417- println ! ( "[REPUTATION] ✅ All 5 Genesis nodes initialized with 90% reputation on ALL nodes" ) ;
1420+ // PRODUCTION: Only initialize reputation for own Genesis node, not all 5 preemptively
1421+ // Other Genesis nodes get reputation dynamically when they actually connect via P2P
1422+ // This prevents "phantom reputation" for nodes that haven't started yet
14181423
1419- // CRITICAL FIX: Set own Genesis reputation to 90%
14201424 if let Ok ( bootstrap_id) = std:: env:: var ( "QNET_BOOTSTRAP_ID" ) {
14211425 match bootstrap_id. as_str ( ) {
14221426 "001" | "002" | "003" | "004" | "005" => {
14231427 let own_genesis_id = format ! ( "genesis_node_{}" , bootstrap_id) ;
14241428 p2p. set_node_reputation ( & own_genesis_id, 90.0 ) ;
1425- println ! ( "[REPUTATION] 🔐 Self Genesis {} set to 90.0% reputation" , own_genesis_id) ;
1429+ println ! ( "[REPUTATION] ✅ Own Genesis {} initialized to 90% reputation" , own_genesis_id) ;
1430+ }
1431+ _ => {
1432+ println ! ( "[REPUTATION] ⚠️ Invalid QNET_BOOTSTRAP_ID: {}" , bootstrap_id) ;
14261433 }
1427- _ => { }
14281434 }
1435+ } else {
1436+ println ! ( "[REPUTATION] 📝 Non-Genesis node - reputation will be set by P2P discovery" ) ;
14291437 }
1438+
1439+ println ! ( "[REPUTATION] ✅ Genesis reputation initialization completed" ) ;
14301440 }
14311441
14321442 /// PRODUCTION: Select microblock producer using cryptographic hash every 30 blocks (QNet specification)
@@ -1837,11 +1847,12 @@ impl BlockchainNode {
18371847 . map ( |( i, ip) | ( format ! ( "genesis_node_{:03}" , i + 1 ) , ip. clone ( ) ) )
18381848 . collect ( ) ;
18391849
1840- // CRITICAL FIX: Add ALL Genesis nodes in IDENTICAL order using REAL dynamic reputation
1841- // This ensures proper penalty system while maintaining deterministic candidate order
1850+ // CRITICAL FIX: Add ALL Genesis nodes in IDENTICAL order using DETERMINISTIC reputation
1851+ // This ensures consistent candidate lists across ALL nodes for Byzantine consensus
18421852 for ( genesis_id, genesis_ip) in genesis_nodes {
1843- // Use REAL reputation system that includes penalties and floor (70%)
1844- let genesis_reputation = Self :: get_node_reputation_score ( & genesis_id, p2p) . await ;
1853+ // Use DETERMINISTIC reputation for Genesis phase (same as microblock producer logic)
1854+ const GENESIS_DETERMINISTIC_REPUTATION : f64 = 0.90 ;
1855+ let genesis_reputation = GENESIS_DETERMINISTIC_REPUTATION ;
18451856
18461857 // For own node: check if can participate based on actual node type
18471858 if genesis_id == own_node_id {
0 commit comments