✅ Phase 0: Pre-implementation checklist completed - Environment configurations (dev/staging/production) - Directory structure setup (logs, backups, monitoring) - Virtual environment with dependencies ✅ Master deployment script created - Single command deployment with validation - Progress tracking and rollback capability - Health checks and deployment reporting ✅ Validation script created - Module import validation - Basic functionality testing - Configuration and script verification ✅ Implementation fixes - Fixed dataclass import in consensus keys - Fixed async function syntax in tests - Updated deployment script for virtual environment 🚀 Ready for deployment: ./scripts/deploy-mesh-network.sh dev
147 lines
5.1 KiB
Python
147 lines
5.1 KiB
Python
"""
|
|
Validator Rotation Mechanism
|
|
Handles automatic rotation of validators based on performance and stake
|
|
"""
|
|
|
|
import asyncio
|
|
import time
|
|
from typing import List, Dict, Optional
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
|
|
from .multi_validator_poa import MultiValidatorPoA, Validator, ValidatorRole
|
|
|
|
class RotationStrategy(Enum):
|
|
ROUND_ROBIN = "round_robin"
|
|
STAKE_WEIGHTED = "stake_weighted"
|
|
REPUTATION_BASED = "reputation_based"
|
|
HYBRID = "hybrid"
|
|
|
|
@dataclass
|
|
class RotationConfig:
|
|
strategy: RotationStrategy
|
|
rotation_interval: int # blocks
|
|
min_stake: float
|
|
reputation_threshold: float
|
|
max_validators: int
|
|
|
|
class ValidatorRotation:
|
|
"""Manages validator rotation based on various strategies"""
|
|
|
|
def __init__(self, consensus: MultiValidatorPoA, config: RotationConfig):
|
|
self.consensus = consensus
|
|
self.config = config
|
|
self.last_rotation_height = 0
|
|
|
|
def should_rotate(self, current_height: int) -> bool:
|
|
"""Check if rotation should occur at current height"""
|
|
return (current_height - self.last_rotation_height) >= self.config.rotation_interval
|
|
|
|
def rotate_validators(self, current_height: int) -> bool:
|
|
"""Perform validator rotation based on configured strategy"""
|
|
if not self.should_rotate(current_height):
|
|
return False
|
|
|
|
if self.config.strategy == RotationStrategy.ROUND_ROBIN:
|
|
return self._rotate_round_robin()
|
|
elif self.config.strategy == RotationStrategy.STAKE_WEIGHTED:
|
|
return self._rotate_stake_weighted()
|
|
elif self.config.strategy == RotationStrategy.REPUTATION_BASED:
|
|
return self._rotate_reputation_based()
|
|
elif self.config.strategy == RotationStrategy.HYBRID:
|
|
return self._rotate_hybrid()
|
|
|
|
return False
|
|
|
|
def _rotate_round_robin(self) -> bool:
|
|
"""Round-robin rotation of validator roles"""
|
|
validators = list(self.consensus.validators.values())
|
|
active_validators = [v for v in validators if v.is_active]
|
|
|
|
# Rotate roles among active validators
|
|
for i, validator in enumerate(active_validators):
|
|
if i == 0:
|
|
validator.role = ValidatorRole.PROPOSER
|
|
elif i < 3: # Top 3 become validators
|
|
validator.role = ValidatorRole.VALIDATOR
|
|
else:
|
|
validator.role = ValidatorRole.STANDBY
|
|
|
|
self.last_rotation_height += self.config.rotation_interval
|
|
return True
|
|
|
|
def _rotate_stake_weighted(self) -> bool:
|
|
"""Stake-weighted rotation"""
|
|
validators = sorted(
|
|
[v for v in self.consensus.validators.values() if v.is_active],
|
|
key=lambda v: v.stake,
|
|
reverse=True
|
|
)
|
|
|
|
for i, validator in enumerate(validators[:self.config.max_validators]):
|
|
if i == 0:
|
|
validator.role = ValidatorRole.PROPOSER
|
|
elif i < 4:
|
|
validator.role = ValidatorRole.VALIDATOR
|
|
else:
|
|
validator.role = ValidatorRole.STANDBY
|
|
|
|
self.last_rotation_height += self.config.rotation_interval
|
|
return True
|
|
|
|
def _rotate_reputation_based(self) -> bool:
|
|
"""Reputation-based rotation"""
|
|
validators = sorted(
|
|
[v for v in self.consensus.validators.values() if v.is_active],
|
|
key=lambda v: v.reputation,
|
|
reverse=True
|
|
)
|
|
|
|
# Filter by reputation threshold
|
|
qualified_validators = [
|
|
v for v in validators
|
|
if v.reputation >= self.config.reputation_threshold
|
|
]
|
|
|
|
for i, validator in enumerate(qualified_validators[:self.config.max_validators]):
|
|
if i == 0:
|
|
validator.role = ValidatorRole.PROPOSER
|
|
elif i < 4:
|
|
validator.role = ValidatorRole.VALIDATOR
|
|
else:
|
|
validator.role = ValidatorRole.STANDBY
|
|
|
|
self.last_rotation_height += self.config.rotation_interval
|
|
return True
|
|
|
|
def _rotate_hybrid(self) -> bool:
|
|
"""Hybrid rotation considering both stake and reputation"""
|
|
validators = [v for v in self.consensus.validators.values() if v.is_active]
|
|
|
|
# Calculate hybrid score
|
|
for validator in validators:
|
|
validator.hybrid_score = validator.stake * validator.reputation
|
|
|
|
# Sort by hybrid score
|
|
validators.sort(key=lambda v: v.hybrid_score, reverse=True)
|
|
|
|
for i, validator in enumerate(validators[:self.config.max_validators]):
|
|
if i == 0:
|
|
validator.role = ValidatorRole.PROPOSER
|
|
elif i < 4:
|
|
validator.role = ValidatorRole.VALIDATOR
|
|
else:
|
|
validator.role = ValidatorRole.STANDBY
|
|
|
|
self.last_rotation_height += self.config.rotation_interval
|
|
return True
|
|
|
|
# Default rotation configuration
|
|
DEFAULT_ROTATION_CONFIG = RotationConfig(
|
|
strategy=RotationStrategy.HYBRID,
|
|
rotation_interval=100, # Rotate every 100 blocks
|
|
min_stake=1000.0,
|
|
reputation_threshold=0.7,
|
|
max_validators=10
|
|
)
|