/** * Network State Management * Manages the P2P network state and phase transitions */ import { Cell, CellType, CellState } from './cell.js'; export var NetworkPhase; (function (NetworkPhase) { NetworkPhase["GENESIS"] = "genesis"; NetworkPhase["GROWTH"] = "growth"; NetworkPhase["MATURATION"] = "maturation"; NetworkPhase["INDEPENDENCE"] = "independence"; })(NetworkPhase || (NetworkPhase = {})); export class Network { cells; currentPhase; currentTick; config; genesisCells; taskQueue; constructor(config) { this.cells = new Map(); this.currentPhase = NetworkPhase.GENESIS; this.currentTick = 0; this.genesisCells = new Set(); this.taskQueue = []; this.config = { genesisNodeCount: config?.genesisNodeCount ?? 100, targetNodeCount: config?.targetNodeCount ?? 120000, nodesPerTick: config?.nodesPerTick ?? 10, taskGenerationRate: config?.taskGenerationRate ?? 5, baseTaskReward: config?.baseTaskReward ?? 1.0, connectionCost: config?.connectionCost ?? 0.5, maxConnectionsPerNode: config?.maxConnectionsPerNode ?? 50, }; } /** * Initialize network with genesis nodes */ initialize() { console.log(`Initializing network with ${this.config.genesisNodeCount} genesis nodes...`); for (let i = 0; i < this.config.genesisNodeCount; i++) { const cell = new Cell(CellType.GENESIS, this.currentTick, { computePower: 0.8 + Math.random() * 0.2, // Genesis nodes are powerful bandwidth: 0.8 + Math.random() * 0.2, reliability: 0.9 + Math.random() * 0.1, storage: 0.8 + Math.random() * 0.2, }); this.cells.set(cell.id, cell); this.genesisCells.add(cell.id); } // Connect genesis nodes to each other (mesh topology) this.connectGenesisNodes(); } /** * Connect all genesis nodes to each other */ connectGenesisNodes() { const genesisArray = Array.from(this.genesisCells); for (let i = 0; i < genesisArray.length; i++) { for (let j = i + 1; j < genesisArray.length; j++) { const cell1 = this.cells.get(genesisArray[i]); const cell2 = this.cells.get(genesisArray[j]); cell1.connectTo(cell2.id); cell2.connectTo(cell1.id); } } } /** * Add new regular nodes to the network */ spawnNodes(count) { for (let i = 0; i < count; i++) { const cell = new Cell(CellType.REGULAR, this.currentTick); this.cells.set(cell.id, cell); // Connect to random existing nodes (preferential attachment) this.connectNewNode(cell); } } /** * Connect a new node to the network */ connectNewNode(newCell) { const connectionCount = Math.min(5 + Math.floor(Math.random() * 5), this.config.maxConnectionsPerNode); const potentialTargets = Array.from(this.cells.values()) .filter(c => c.id !== newCell.id) .filter(c => { // In Phase 2+, genesis nodes don't accept new connections if (this.currentPhase !== NetworkPhase.GENESIS && c.type === CellType.GENESIS) { return false; } return c.state === CellState.ACTIVE && c.connectedCells.size < this.config.maxConnectionsPerNode; }); // Preferential attachment: higher fitness = more likely to connect const selectedTargets = this.selectPreferentialTargets(potentialTargets, connectionCount); for (const target of selectedTargets) { newCell.connectTo(target.id); target.connectTo(newCell.id); // Connection costs energy newCell.spendEnergy(this.config.connectionCost); target.spendEnergy(this.config.connectionCost); } } /** * Select targets using preferential attachment */ selectPreferentialTargets(candidates, count) { if (candidates.length <= count) { return candidates; } const selected = []; const weights = candidates.map(c => c.getFitnessScore() * (1 + c.connectedCells.size)); const totalWeight = weights.reduce((sum, w) => sum + w, 0); for (let i = 0; i < count && candidates.length > 0; i++) { let random = Math.random() * totalWeight; let selectedIndex = 0; for (let j = 0; j < weights.length; j++) { random -= weights[j]; if (random <= 0) { selectedIndex = j; break; } } selected.push(candidates[selectedIndex]); candidates.splice(selectedIndex, 1); weights.splice(selectedIndex, 1); } return selected; } /** * Generate tasks for the network */ generateTasks() { const tasksToGenerate = Math.floor(this.cells.size * this.config.taskGenerationRate * Math.random()); for (let i = 0; i < tasksToGenerate; i++) { // Task complexity between 0.1 and 1.0 this.taskQueue.push(0.1 + Math.random() * 0.9); } } /** * Distribute tasks to capable cells */ distributeTasks() { const activeCells = Array.from(this.cells.values()) .filter(c => c.state === CellState.ACTIVE); while (this.taskQueue.length > 0 && activeCells.length > 0) { const task = this.taskQueue.shift(); // Select cell based on fitness and availability const selectedCell = activeCells[Math.floor(Math.random() * activeCells.length)]; selectedCell.processTask(task, this.config.baseTaskReward); } } /** * Update network phase based on node count */ updatePhase() { const nodeCount = this.cells.size; const oldPhase = this.currentPhase; if (nodeCount >= 100000) { this.currentPhase = NetworkPhase.INDEPENDENCE; } else if (nodeCount >= 50000) { this.currentPhase = NetworkPhase.MATURATION; } else if (nodeCount >= 10000) { this.currentPhase = NetworkPhase.GROWTH; } else { this.currentPhase = NetworkPhase.GENESIS; } if (oldPhase !== this.currentPhase) { console.log(`\nšŸ”„ PHASE TRANSITION: ${oldPhase} → ${this.currentPhase} (${nodeCount} nodes)`); this.onPhaseTransition(); } } /** * Handle phase transition events */ onPhaseTransition() { // Update all cells based on new phase this.cells.forEach(cell => cell.updateState(this.cells.size)); // Phase-specific actions switch (this.currentPhase) { case NetworkPhase.GROWTH: console.log(' → Genesis nodes reducing 10x multiplier...'); break; case NetworkPhase.MATURATION: console.log(' → Genesis nodes entering READ-ONLY mode...'); break; case NetworkPhase.INDEPENDENCE: console.log(' → Genesis nodes RETIRED. Network is independent!'); break; } } /** * Simulate one tick of the network */ tick() { this.currentTick++; // Spawn new nodes (if not at target) if (this.cells.size < this.config.targetNodeCount) { const nodesToSpawn = Math.min(this.config.nodesPerTick, this.config.targetNodeCount - this.cells.size); this.spawnNodes(nodesToSpawn); } // Generate and distribute tasks this.generateTasks(); this.distributeTasks(); // Update all cells this.cells.forEach(cell => { cell.tick(); cell.updateState(this.cells.size); }); // Check for phase transitions this.updatePhase(); } /** * Get network statistics */ getStats() { const cells = Array.from(this.cells.values()); const genesisCells = cells.filter(c => c.type === CellType.GENESIS); const regularCells = cells.filter(c => c.type === CellType.REGULAR); const totalEnergy = cells.reduce((sum, c) => sum + c.energy, 0); const totalEarned = cells.reduce((sum, c) => sum + c.metrics.energyEarned, 0); const totalSpent = cells.reduce((sum, c) => sum + c.metrics.energySpent, 0); const totalTasks = cells.reduce((sum, c) => sum + c.metrics.tasksCompleted, 0); return { tick: this.currentTick, phase: this.currentPhase, nodeCount: this.cells.size, genesisNodes: { count: genesisCells.length, active: genesisCells.filter(c => c.state === CellState.ACTIVE).length, readOnly: genesisCells.filter(c => c.state === CellState.READ_ONLY).length, retired: genesisCells.filter(c => c.state === CellState.RETIRED).length, avgMultiplier: genesisCells.reduce((sum, c) => sum + c.genesisMultiplier, 0) / genesisCells.length, }, regularNodes: { count: regularCells.length, }, economy: { totalEnergy, totalEarned, totalSpent, netEnergy: totalEarned - totalSpent, avgEnergyPerNode: totalEnergy / this.cells.size, }, tasks: { completed: totalTasks, queued: this.taskQueue.length, avgPerNode: totalTasks / this.cells.size, }, network: { avgConnections: cells.reduce((sum, c) => sum + c.connectedCells.size, 0) / this.cells.size, avgSuccessRate: cells.reduce((sum, c) => sum + c.metrics.successRate, 0) / this.cells.size, }, }; } } //# sourceMappingURL=network.js.map