mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
457 lines
18 KiB
Python
457 lines
18 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Waveprobe Adapter for ENE Distributed Node
|
|
|
|
This adapter extracts signal metrics from the ENE (Endless Node Edges) distributed node system
|
|
and provides waveprobe-compatible interfaces for testing and validation.
|
|
"""
|
|
|
|
import json
|
|
import uuid
|
|
import numpy as np
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
from typing import Dict, Any, List, Optional, Tuple
|
|
|
|
class ENEDistributedNodeAdapter:
|
|
"""Waveprobe adapter for ENE distributed node."""
|
|
|
|
def __init__(self):
|
|
"""Initialize adapter."""
|
|
self.probe_id = f"wave_{uuid.uuid4().hex[:12]}"
|
|
self.timestamp = datetime.now().isoformat()
|
|
|
|
# Gossip message types from ENE
|
|
self.gossip_types = ["discovery", "heartbeat", "credential_sync", "replicate"]
|
|
|
|
def execute_probe(self, probe_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Execute a waveprobe probe on ENE distributed node."""
|
|
# Extract probe parameters
|
|
time_steps = probe_config.get("time_steps", 100)
|
|
dt = probe_config.get("dt", 0.1)
|
|
initial_peers = probe_config.get("initial_peers", 3)
|
|
gossip_interval = probe_config.get("gossip_interval", 1.0)
|
|
failure_rate = probe_config.get("failure_rate", 0.0) # Simulated node failure rate
|
|
consensus_threshold = probe_config.get("consensus_threshold", 0.67)
|
|
|
|
# Simulate ENE distributed node operation
|
|
history = self._simulate_ene_mesh(
|
|
time_steps, dt, initial_peers, gossip_interval, failure_rate, consensus_threshold
|
|
)
|
|
|
|
# Extract metrics
|
|
metrics = self._extract_metrics(history, probe_config)
|
|
|
|
# Validate convergence
|
|
convergence_status = self._validate_convergence(metrics)
|
|
|
|
# Build result
|
|
result = {
|
|
"probe_id": self.probe_id,
|
|
"probe_config": probe_config,
|
|
"execution_timestamp": datetime.now().isoformat(),
|
|
"metrics": metrics,
|
|
"convergence_status": convergence_status,
|
|
"history": history
|
|
}
|
|
|
|
return result
|
|
|
|
def _simulate_ene_mesh(
|
|
self,
|
|
time_steps: int,
|
|
dt: float,
|
|
initial_peers: int,
|
|
gossip_interval: float,
|
|
failure_rate: float,
|
|
consensus_threshold: float
|
|
) -> Dict[str, Any]:
|
|
"""Simulate ENE distributed mesh operation."""
|
|
|
|
# Initialize mesh
|
|
t = 0.0
|
|
nodes = self._initialize_nodes(initial_peers)
|
|
|
|
# Trajectory storage
|
|
time_trajectory = []
|
|
peer_count_trajectory = []
|
|
health_score_trajectory = []
|
|
gossip_rate_trajectory = {msg_type: [] for msg_type in self.gossip_types}
|
|
replication_success_trajectory = []
|
|
consensus_reached_trajectory = []
|
|
latency_trajectory = []
|
|
|
|
for step in range(time_steps):
|
|
# Simulate gossip protocol
|
|
gossip_counts = self._simulate_gossip(nodes, t, gossip_interval)
|
|
|
|
# Simulate node health monitoring
|
|
health_scores = self._monitor_health(nodes, failure_rate)
|
|
|
|
# Simulate replication
|
|
replication_success = self._simulate_replication(nodes, failure_rate)
|
|
|
|
# Simulate consensus
|
|
consensus_reached = self._simulate_consensus(nodes, consensus_threshold)
|
|
|
|
# Simulate latency
|
|
avg_latency = self._compute_latency(nodes)
|
|
|
|
# Store trajectory
|
|
time_trajectory.append(t)
|
|
peer_count_trajectory.append(len(nodes))
|
|
health_score_trajectory.append(np.mean(list(health_scores.values())))
|
|
|
|
for msg_type in self.gossip_types:
|
|
gossip_rate_trajectory[msg_type].append(gossip_counts.get(msg_type, 0))
|
|
|
|
replication_success_trajectory.append(replication_success)
|
|
consensus_reached_trajectory.append(consensus_reached)
|
|
latency_trajectory.append(avg_latency)
|
|
|
|
# Evolve mesh
|
|
nodes = self._evolve_mesh(nodes, dt, failure_rate)
|
|
t += dt
|
|
|
|
return {
|
|
"time": time_trajectory,
|
|
"peer_count": peer_count_trajectory,
|
|
"health_scores": health_score_trajectory,
|
|
"gossip_rates": gossip_rate_trajectory,
|
|
"replication_success": replication_success_trajectory,
|
|
"consensus_reached": consensus_reached_trajectory,
|
|
"latency": latency_trajectory,
|
|
"final_nodes": nodes
|
|
}
|
|
|
|
def _initialize_nodes(self, initial_peers: int) -> Dict[str, Dict[str, Any]]:
|
|
"""Initialize ENE nodes."""
|
|
nodes = {}
|
|
for i in range(initial_peers):
|
|
node_id = f"ene_node_{i}"
|
|
nodes[node_id] = {
|
|
"node_id": node_id,
|
|
"health_score": 1.0,
|
|
"capabilities": ["storage", "compute", "relay"],
|
|
"is_active": True,
|
|
"last_seen": 0.0,
|
|
"replication_version": "2.0.0-Cambrian-Bind"
|
|
}
|
|
return nodes
|
|
|
|
def _simulate_gossip(self, nodes: Dict[str, Dict[str, Any]], t: float, interval: float) -> Dict[str, int]:
|
|
"""Simulate gossip protocol message exchange."""
|
|
gossip_counts = {msg_type: 0 for msg_type in self.gossip_types}
|
|
|
|
if t % interval < 0.1: # Gossip happens at intervals
|
|
active_nodes = [n for n in nodes.values() if n["is_active"]]
|
|
|
|
for node in active_nodes:
|
|
# Discovery messages (new node discovery)
|
|
if np.random.rand() < 0.3:
|
|
gossip_counts["discovery"] += 1
|
|
|
|
# Heartbeat messages (health monitoring)
|
|
gossip_counts["heartbeat"] += 1
|
|
|
|
# Credential sync (credential distribution)
|
|
if np.random.rand() < 0.2:
|
|
gossip_counts["credential_sync"] += 1
|
|
|
|
# Replication (ENE propagation)
|
|
if np.random.rand() < 0.1:
|
|
gossip_counts["replicate"] += 1
|
|
|
|
return gossip_counts
|
|
|
|
def _monitor_health(self, nodes: Dict[str, Dict[str, Any]], failure_rate: float) -> Dict[str, float]:
|
|
"""Monitor node health."""
|
|
health_scores = {}
|
|
|
|
for node_id, node in nodes.items():
|
|
if not node["is_active"]:
|
|
health_scores[node_id] = 0.0
|
|
continue
|
|
|
|
# Health degrades randomly
|
|
degradation = np.random.rand() * 0.05
|
|
new_health = max(0.0, node["health_score"] - degradation)
|
|
|
|
# Random failure
|
|
if np.random.rand() < failure_rate:
|
|
new_health = 0.0
|
|
node["is_active"] = False
|
|
|
|
node["health_score"] = new_health
|
|
health_scores[node_id] = new_health
|
|
|
|
return health_scores
|
|
|
|
def _simulate_replication(self, nodes: Dict[str, Dict[str, Any]], failure_rate: float) -> bool:
|
|
"""Simulate ENE replication."""
|
|
active_nodes = [n for n in nodes.values() if n["is_active"]]
|
|
|
|
if len(active_nodes) < 2:
|
|
return False
|
|
|
|
# Replication succeeds if enough healthy nodes
|
|
healthy_nodes = [n for n in active_nodes if n["health_score"] > 0.5]
|
|
success_rate = len(healthy_nodes) / len(active_nodes)
|
|
|
|
return success_rate > (1.0 - failure_rate)
|
|
|
|
def _simulate_consensus(self, nodes: Dict[str, Dict[str, Any]], threshold: float) -> bool:
|
|
"""Simulate consensus achievement."""
|
|
active_nodes = [n for n in nodes.values() if n["is_active"]]
|
|
|
|
if len(active_nodes) == 0:
|
|
return False
|
|
|
|
# Simulate voting
|
|
votes = sum(1 for n in active_nodes if np.random.rand() < n["health_score"])
|
|
consensus_rate = votes / len(active_nodes)
|
|
|
|
return consensus_rate >= threshold
|
|
|
|
def _compute_latency(self, nodes: Dict[str, Dict[str, Any]]) -> float:
|
|
"""Compute average mesh latency."""
|
|
active_nodes = [n for n in nodes.values() if n["is_active"]]
|
|
|
|
if len(active_nodes) < 2:
|
|
return 0.0
|
|
|
|
# Simulate latency based on health
|
|
latencies = []
|
|
for node in active_nodes:
|
|
base_latency = 100.0 # ms
|
|
health_factor = 1.0 - node["health_score"]
|
|
latency = base_latency * (1 + health_factor * 2)
|
|
latencies.append(latency)
|
|
|
|
return np.mean(latencies)
|
|
|
|
def _evolve_mesh(self, nodes: Dict[str, Dict[str, Any]], dt: float, failure_rate: float) -> Dict[str, Dict[str, Any]]:
|
|
"""Evolve mesh topology."""
|
|
# Auto-recovery for failed nodes
|
|
for node_id, node in nodes.items():
|
|
if not node["is_active"]:
|
|
# Small chance of recovery
|
|
if np.random.rand() < 0.05:
|
|
node["is_active"] = True
|
|
node["health_score"] = 0.5
|
|
|
|
# New node discovery (auto-replication)
|
|
if np.random.rand() < 0.02 and len(nodes) < 10:
|
|
new_node_id = f"ene_node_{len(nodes)}"
|
|
nodes[new_node_id] = {
|
|
"node_id": new_node_id,
|
|
"health_score": 1.0,
|
|
"capabilities": ["storage", "compute", "relay"],
|
|
"is_active": True,
|
|
"last_seen": 0.0,
|
|
"replication_version": "2.0.0-Cambrian-Bind"
|
|
}
|
|
|
|
return nodes
|
|
|
|
def _extract_metrics(self, history: Dict[str, Any], probe_config: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Extract standardized metrics from ENE mesh."""
|
|
peer_count_trajectory = history["peer_count"]
|
|
health_score_trajectory = history["health_scores"]
|
|
gossip_rate_trajectory = history["gossip_rates"]
|
|
replication_success_trajectory = history["replication_success"]
|
|
consensus_reached_trajectory = history["consensus_reached"]
|
|
latency_trajectory = history["latency"]
|
|
|
|
metrics = {
|
|
"final_peer_count": int(peer_count_trajectory[-1]),
|
|
"max_peer_count": int(max(peer_count_trajectory)),
|
|
"min_peer_count": int(min(peer_count_trajectory)),
|
|
"final_health_score": float(health_score_trajectory[-1]),
|
|
"mean_health_score": float(np.mean(health_score_trajectory)),
|
|
"health_convergence_rate": self._compute_convergence_rate(health_score_trajectory),
|
|
"final_gossip_rates": {
|
|
msg_type: float(trajectory[-1])
|
|
for msg_type, trajectory in gossip_rate_trajectory.items()
|
|
},
|
|
"mean_gossip_rates": {
|
|
msg_type: float(np.mean(trajectory))
|
|
for msg_type, trajectory in gossip_rate_trajectory.items()
|
|
},
|
|
"replication_success_rate": float(np.mean(replication_success_trajectory)),
|
|
"consensus_achievement_rate": float(np.mean(consensus_reached_trajectory)),
|
|
"final_latency": float(latency_trajectory[-1]),
|
|
"mean_latency": float(np.mean(latency_trajectory)),
|
|
"latency_convergence": self._compute_convergence_rate(latency_trajectory),
|
|
"initial_peers": probe_config.get("initial_peers", 3),
|
|
"failure_rate": probe_config.get("failure_rate", 0.0),
|
|
"consensus_threshold": probe_config.get("consensus_threshold", 0.67),
|
|
"total_time_steps": len(peer_count_trajectory)
|
|
}
|
|
return metrics
|
|
|
|
def _validate_convergence(self, metrics: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Validate convergence criteria."""
|
|
convergence_status = {
|
|
"health_stable": metrics["health_convergence_rate"] < 0.01,
|
|
"latency_stable": metrics["latency_convergence"] < 0.01,
|
|
"replication_reliable": metrics["replication_success_rate"] > 0.9,
|
|
"consensus_achievable": metrics["consensus_achievement_rate"] > 0.67,
|
|
"mesh_stable": metrics["final_peer_count"] >= metrics["initial_peers"] * 0.8,
|
|
"overall_status": "converged" if (
|
|
metrics["health_convergence_rate"] < 0.01 and
|
|
metrics["replication_success_rate"] > 0.9
|
|
) else "not_converged"
|
|
}
|
|
return convergence_status
|
|
|
|
def _compute_convergence_rate(self, trajectory: List[float]) -> float:
|
|
"""Compute convergence rate from trajectory."""
|
|
if len(trajectory) < 10:
|
|
return 1.0
|
|
|
|
tail_size = max(10, len(trajectory) // 10)
|
|
tail = trajectory[-tail_size:]
|
|
convergence_rate = float(np.std(tail) / (np.mean(np.abs(tail)) + 1e-10))
|
|
return convergence_rate
|
|
|
|
def serialize_results(self, result: Dict[str, Any]) -> str:
|
|
"""Serialize results in waveprobe-compatible JSON format."""
|
|
serialized = json.dumps(result, indent=2, default=str)
|
|
return serialized
|
|
|
|
def store_to_topological(self, result: Dict[str, Any], storage_path: Optional[str] = None) -> str:
|
|
"""Store results in topological storage (placeholder for ENE integration)."""
|
|
storage_path = storage_path or f"data/waveprobes/ene_distributed_node/{self.probe_id}.json"
|
|
|
|
Path(storage_path).parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
serialized = self.serialize_results(result)
|
|
Path(storage_path).write_text(serialized)
|
|
|
|
return storage_path
|
|
|
|
|
|
class ENEDistributedNodeProbeGenerator:
|
|
"""Generate waveprobe test probes for ENE distributed node."""
|
|
|
|
@staticmethod
|
|
def generate_mesh_size_probes() -> List[Dict[str, Any]]:
|
|
"""Generate mesh size sweep probes."""
|
|
probes = []
|
|
|
|
# Sweep initial peer count
|
|
for initial_peers in [3, 5, 10]:
|
|
probes.append({
|
|
"probe_type": "mesh_size_sweep",
|
|
"initial_peers": initial_peers,
|
|
"time_steps": 100,
|
|
"dt": 0.1,
|
|
"gossip_interval": 1.0,
|
|
"failure_rate": 0.0,
|
|
"consensus_threshold": 0.67,
|
|
"description": f"Sweep initial_peers={initial_peers}"
|
|
})
|
|
|
|
return probes
|
|
|
|
@staticmethod
|
|
def generate_failure_tolerance_probes() -> List[Dict[str, Any]]:
|
|
"""Generate failure tolerance probes."""
|
|
probes = []
|
|
|
|
# Sweep failure rate
|
|
for failure_rate in [0.0, 0.05, 0.1, 0.2]:
|
|
probes.append({
|
|
"probe_type": "failure_tolerance",
|
|
"initial_peers": 5,
|
|
"time_steps": 100,
|
|
"dt": 0.1,
|
|
"gossip_interval": 1.0,
|
|
"failure_rate": failure_rate,
|
|
"consensus_threshold": 0.67,
|
|
"description": f"Failure tolerance: failure_rate={failure_rate}"
|
|
})
|
|
|
|
return probes
|
|
|
|
@staticmethod
|
|
def generate_consensus_threshold_probes() -> List[Dict[str, Any]]:
|
|
"""Generate consensus threshold probes."""
|
|
probes = []
|
|
|
|
# Sweep consensus threshold
|
|
for threshold in [0.5, 0.67, 0.8, 0.9]:
|
|
probes.append({
|
|
"probe_type": "consensus_threshold",
|
|
"initial_peers": 5,
|
|
"time_steps": 100,
|
|
"dt": 0.1,
|
|
"gossip_interval": 1.0,
|
|
"failure_rate": 0.0,
|
|
"consensus_threshold": threshold,
|
|
"description": f"Consensus threshold: {threshold}"
|
|
})
|
|
|
|
return probes
|
|
|
|
|
|
def main():
|
|
"""Main entry point for testing the adapter."""
|
|
print("=" * 70)
|
|
print("Waveprobe Adapter for ENE Distributed Node")
|
|
print("=" * 70)
|
|
|
|
# Initialize adapter
|
|
adapter = ENEDistributedNodeAdapter()
|
|
print(f"Adapter initialized: {adapter.probe_id}")
|
|
|
|
# Test with a simple probe
|
|
probe_config = {
|
|
"probe_type": "test",
|
|
"initial_peers": 5,
|
|
"time_steps": 100,
|
|
"dt": 0.1,
|
|
"gossip_interval": 1.0,
|
|
"failure_rate": 0.05,
|
|
"consensus_threshold": 0.67
|
|
}
|
|
|
|
print(f"\nExecuting probe: {probe_config}")
|
|
result = adapter.execute_probe(probe_config)
|
|
|
|
print(f"\nProbe execution completed")
|
|
print(f"Final Peer Count: {result['metrics']['final_peer_count']}")
|
|
print(f"Max Peer Count: {result['metrics']['max_peer_count']}")
|
|
print(f"Final Health Score: {result['metrics']['final_health_score']:.6f}")
|
|
print(f"Replication Success Rate: {result['metrics']['replication_success_rate']:.6f}")
|
|
print(f"Consensus Achievement Rate: {result['metrics']['consensus_achievement_rate']:.6f}")
|
|
print(f"Final Latency: {result['metrics']['final_latency']:.2f} ms")
|
|
print(f"Final Gossip Rates: {result['metrics']['final_gossip_rates']}")
|
|
print(f"Convergence Status: {result['convergence_status']['overall_status']}")
|
|
|
|
# Store results
|
|
storage_path = adapter.store_to_topological(result)
|
|
print(f"\nResults stored to: {storage_path}")
|
|
|
|
# Generate probe types
|
|
print("\n" + "=" * 70)
|
|
print("Probe Generation Test")
|
|
print("=" * 70)
|
|
|
|
generator = ENEDistributedNodeProbeGenerator()
|
|
|
|
mesh_size_probes = generator.generate_mesh_size_probes()
|
|
print(f"Mesh size probes: {len(mesh_size_probes)}")
|
|
|
|
failure_tolerance_probes = generator.generate_failure_tolerance_probes()
|
|
print(f"Failure tolerance probes: {len(failure_tolerance_probes)}")
|
|
|
|
consensus_threshold_probes = generator.generate_consensus_threshold_probes()
|
|
print(f"Consensus threshold probes: {len(consensus_threshold_probes)}")
|
|
|
|
print("\n✅ ENE distributed node waveprobe adapter test completed successfully")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|