# MY Network v3.0 - Новый протокол децентрализованной синхронизации ## 🎯 Обзор протокола v3.0 MY Network v3.0 полностью отказывается от кворумной системы в пользу децентрализованной архитектуры, где каждая нода принимает независимые решения о принятии и хранении контента. ## 🔄 Протокол индивидуальной синхронизации ### Принципы новой системы 1. **Автономность решений**: Каждая нода самостоятельно решает принимать контент или нет 2. **Отсутствие консенсуса**: Нет необходимости в голосовании других нод 3. **Гибкая фильтрация**: Настраиваемые правила принятия контента на уровне ноды 4. **Устойчивость к цензуре**: Контент доступен пока есть хотя бы одна нода ### Новый алгоритм синхронизации ```python class DecentralizedSyncProtocol: """Протокол децентрализованной синхронизации v3.0""" def __init__(self, node_config: dict): self.node_id = node_config["node_id"] self.content_filter = IndividualContentFilter(node_config) self.sync_manager = SyncManager() self.active_peers = {} async def handle_content_announcement(self, peer_id: str, announcement: dict) -> bool: """ Обработка анонса нового контента от пира Новая логика v3.0: 1. Каждая нода принимает решение индивидуально 2. Нет консенсуса или голосования 3. Простая заглушка для фильтрации (пока всегда True) """ content_hash = announcement.get("content_hash") content_metadata = announcement.get("metadata", {}) logger.info(f"Received content announcement from {peer_id}: {content_hash}") # Проверка - не дубликат ли это if await self._content_already_exists(content_hash): logger.debug(f"Content {content_hash} already exists locally") return False # Индивидуальное решение о принятии контента should_accept = await self.content_filter.should_accept_content( content_hash, content_metadata, peer_id ) if should_accept: logger.info(f"Accepting content {content_hash} from {peer_id}") # Добавление в очередь синхронизации await self.sync_manager.queue_content_sync( peer_id=peer_id, content_hash=content_hash, metadata=content_metadata ) return True else: logger.info(f"Rejecting content {content_hash} from {peer_id}") return False async def sync_content_from_peer(self, peer_id: str, content_hash: str, metadata: dict) -> bool: """Синхронизация контента с пира (без консенсуса)""" try: # Запрос метаданных контента content_info = await self._request_content_info(peer_id, content_hash) if not content_info: logger.error(f"Failed to get content info for {content_hash}") return False # Проверка возможности получения контента от пира access_granted = await self._request_content_access(peer_id, content_hash) if not access_granted: logger.warning(f"Access denied for content {content_hash} from {peer_id}") return False # Загрузка контента content_data = await self._download_content(peer_id, content_hash) if not content_data: logger.error(f"Failed to download content {content_hash}") return False # Проверка целостности if not await self._verify_content_integrity(content_hash, content_data): logger.error(f"Content integrity check failed: {content_hash}") return False # Сохранение контента локально stored_content = await self._store_content_locally( content_hash, content_data, metadata ) if stored_content: logger.info(f"Successfully synced content {content_hash} from {peer_id}") # Анонс нового контента другим пирам (кроме источника) await self._announce_content_to_peers(stored_content, exclude_peer=peer_id) return True except Exception as e: logger.error(f"Failed to sync content {content_hash} from {peer_id}: {e}") return False class IndividualContentFilter: """Система индивидуальной фильтрации контента""" def __init__(self, node_config: dict): self.node_config = node_config self.whitelist_authors = set(node_config.get("whitelist_authors", [])) self.blacklist_authors = set(node_config.get("blacklist_authors", [])) self.allowed_content_types = set(node_config.get("allowed_content_types", ["*"])) self.max_file_size = node_config.get("max_file_size", 100 * 1024 * 1024) # 100MB async def should_accept_content(self, content_hash: str, metadata: dict, peer_id: str) -> bool: """ Решение о принятии контента (заглушка для будущего расширения) В текущей версии v3.0 всегда возвращает True. В будущем здесь будут фильтры по: - Авторам (whitelist/blacklist) - Типам контента - Размерам файлов - Тегам и категориям - Репутации пира """ # TODO: Добавить реальную логику фильтрации # Пока принимаем весь контент return True # Пример будущей логики фильтрации: """ author_id = metadata.get("author_id") content_type = metadata.get("content_type") file_size = metadata.get("file_size", 0) # Проверка черного списка авторов if author_id in self.blacklist_authors: return False # Проверка белого списка (если не пустой) if self.whitelist_authors and author_id not in self.whitelist_authors: return False # Проверка типа контента if "*" not in self.allowed_content_types: if content_type not in self.allowed_content_types: return False # Проверка размера файла if file_size > self.max_file_size: return False return True """ ``` ## 🔐 Новая система шифрования и безопасности ### Архитектура безопасности v3.0 ```python class ContentSecurityManager: """Управление безопасностью контента в MY Network v3.0""" def __init__(self): self.hash_algorithm = "sha256" self.encryption_algorithm = "AES-256-GCM" async def create_encrypted_content(self, content_data: bytes, content_metadata: dict) -> dict: """ Создание зашифрованного контента с единым хэшем Система v3.0: 1. Симметричное шифрование с уникальным ключом для каждого контента 2. Единый хэш encrypted_content на всех нодах 3. Отдельные preview_id не связанные с основным хэшем """ # Генерация уникального ключа шифрования для этого контента encryption_key = self._generate_content_key() # Шифрование контента encrypted_data = await self._encrypt_content(content_data, encryption_key) # Вычисление единого хэша зашифрованного контента encrypted_content_hash = self._calculate_deterministic_hash(encrypted_data) # Создание отдельного preview_id (не связанного с хэшем) preview_id = str(uuid4()) return { "encrypted_content_hash": encrypted_content_hash, # Одинаковый на всех нодах "encrypted_data": encrypted_data, "encryption_key": encryption_key, # Передается при продаже "preview_id": preview_id, # Для публичного доступа к preview "metadata": content_metadata } def _generate_content_key(self) -> str: """Генерация уникального ключа для контента""" return secrets.token_hex(32) # 256-bit key async def _encrypt_content(self, content_data: bytes, encryption_key: str) -> bytes: """Симметричное шифрование контента""" # Преобразование ключа в байты key_bytes = bytes.fromhex(encryption_key) # Создание шифратора AES-256-GCM cipher = AES.new(key_bytes, AES.MODE_GCM) # Шифрование ciphertext, auth_tag = cipher.encrypt_and_digest(content_data) # Объединение nonce, auth_tag и ciphertext для детерминированного хэша encrypted_data = cipher.nonce + auth_tag + ciphertext return encrypted_data def _calculate_deterministic_hash(self, encrypted_data: bytes) -> str: """ Вычисление детерминированного хэша зашифрованного контента ВАЖНО: Этот хэш будет одинаковым на всех нодах для одного контента, но через него нельзя получить доступ к самому контенту """ return hashlib.sha256(encrypted_data).hexdigest() async def decrypt_content(self, encrypted_data: bytes, encryption_key: str) -> bytes: """Расшифровка контента с помощью ключа""" # Извлечение компонентов nonce = encrypted_data[:16] # AES-GCM nonce: 16 bytes auth_tag = encrypted_data[16:32] # Auth tag: 16 bytes ciphertext = encrypted_data[32:] # Остальное - зашифрованные данные # Создание дешифратора key_bytes = bytes.fromhex(encryption_key) cipher = AES.new(key_bytes, AES.MODE_GCM, nonce=nonce) # Расшифровка с проверкой подлинности decrypted_data = cipher.decrypt_and_verify(ciphertext, auth_tag) return decrypted_data async def create_preview_content(self, original_content: bytes, content_type: str) -> tuple[bytes, str]: """ Создание preview контента (не зашифрованного) Preview: - Не связан с основным хэшем контента - Имеет собственный уникальный ID - Доступен публично без ключей """ # Создание preview в зависимости от типа контента if content_type.startswith("audio/"): # Для аудио - первые 30 секунд preview_content = await self._create_audio_preview(original_content) elif content_type.startswith("video/"): # Для видео - первые 30 секунд + watermark preview_content = await self._create_video_preview(original_content) elif content_type.startswith("image/"): # Для изображений - уменьшенная версия с watermark preview_content = await self._create_image_preview(original_content) else: # Для других типов - описание или thumbnail preview_content = await self._create_generic_preview(original_content) # Уникальный ID для preview (НЕ хэш!) preview_id = str(uuid4()) return preview_content, preview_id class ContentAccessControl: """Система контроля доступа к контенту""" async def can_provide_content(self, requesting_node: str, content_hash: str, access_type: str = "full") -> dict: """ Проверка возможности предоставления контента В v3.0 пока разрешаем всем (заглушка для будущего расширения) """ # TODO: Добавить реальную логику контроля доступа # Пока разрешаем всем return { "access_granted": True, "access_type": access_type, "reason": "Open access policy" } # Пример будущей логики: """ # Проверка репутации ноды node_reputation = await self._get_node_reputation(requesting_node) if node_reputation < 0.5: return {"access_granted": False, "reason": "Low node reputation"} # Проверка коммерческих лицензий content = await StoredContent.get_by_hash(content_hash) if content and content.commercial_license: license_valid = await self._check_commercial_license( requesting_node, content_hash ) if not license_valid: return {"access_granted": False, "reason": "No valid license"} # Проверка региональных ограничений node_region = await self._get_node_region(requesting_node) if node_region in content.restricted_regions: return {"access_granted": False, "reason": "Regional restrictions"} return {"access_granted": True, "access_type": access_type} """ async def get_content_by_preview_id(self, preview_id: str) -> Optional[bytes]: """ Получение preview контента по preview_id Preview доступен всем без ограничений """ # Поиск preview по ID в базе данных preview_content = await PreviewContent.get_by_preview_id(preview_id) if preview_content: return preview_content.data return None async def request_content_key(self, content_hash: str, user_license: dict) -> Optional[str]: """ Запрос ключа расшифровки контента Ключ выдается только при наличии соответствующих прав """ # Проверка лицензии пользователя if await self._validate_user_license(content_hash, user_license): # Получение ключа расшифровки content = await StoredContent.get_by_hash(content_hash) if content: return content.encryption_key return None ``` ## 🌐 Обновленный протокол обмена сообщениями ### Новые типы сообщений v3.0 ```python class P2PMessageTypes: """Типы сообщений протокола MY Network v3.0""" # Базовые сообщения HANDSHAKE = "handshake" HANDSHAKE_RESPONSE = "handshake_response" # Объявления о контенте (без консенсуса) CONTENT_ANNOUNCEMENT = "content_announcement" CONTENT_REQUEST = "content_request" CONTENT_RESPONSE = "content_response" # Синхронизация SYNC_REQUEST = "sync_request" SYNC_RESPONSE = "sync_response" SYNC_DATA = "sync_data" # Доступ к контенту ACCESS_REQUEST = "access_request" ACCESS_RESPONSE = "access_response" # Версионирование VERSION_INFO = "version_info" VERSION_WARNING = "version_warning" class P2PMessageHandler: """Обработчик P2P сообщений протокола v3.0""" async def handle_content_announcement(self, peer_id: str, message: dict): """Обработка анонса контента (без консенсуса)""" content_hash = message.get("content_hash") metadata = message.get("metadata", {}) # Индивидуальное решение о принятии should_accept = await self.sync_protocol.handle_content_announcement( peer_id, message ) # Отправка ответа пиру response = { "type": P2PMessageTypes.CONTENT_RESPONSE, "content_hash": content_hash, "accepted": should_accept, "node_id": self.node_id, "timestamp": datetime.utcnow().isoformat() } await self.send_message_to_peer(peer_id, response) async def handle_sync_request(self, peer_id: str, message: dict): """Обработка запроса синхронизации""" content_hash = message.get("content_hash") # Проверка доступа к контенту access_check = await self.access_control.can_provide_content( peer_id, content_hash ) if access_check["access_granted"]: # Предоставление контента content_data = await self._get_content_data(content_hash) response = { "type": P2PMessageTypes.SYNC_RESPONSE, "content_hash": content_hash, "status": "approved", "data_size": len(content_data) if content_data else 0 } else: # Отказ в доступе response = { "type": P2PMessageTypes.SYNC_RESPONSE, "content_hash": content_hash, "status": "denied", "reason": access_check.get("reason", "Access denied") } await self.send_message_to_peer(peer_id, response) # Если доступ разрешен, отправляем данные if access_check["access_granted"] and content_data: await self._send_content_data(peer_id, content_hash, content_data) ``` ## 📋 Новые API эндпоинты v3.0 ### Обновленные API для децентрализованной архитектуры ```python # Индивидуальная синхронизация (без консенсуса) POST /api/v3/sync/announce # Анонс контента в сеть GET /api/v3/sync/pending # Ожидающие синхронизации POST /api/v3/sync/accept/{hash} # Принять конкретный контент POST /api/v3/sync/reject/{hash} # Отклонить конкретный контент # Управление фильтрами контента GET /api/v3/filters/content # Текущие фильтры PUT /api/v3/filters/content # Обновить фильтры POST /api/v3/filters/test # Тестирование фильтров # Безопасность контента GET /api/v3/content/{hash}/preview/{preview_id} # Получение preview POST /api/v3/content/{hash}/request-key # Запрос ключа расшифровки GET /api/v3/content/{hash}/access-info # Информация о доступе # Статистика децентрализованной сети GET /api/v3/network/nodes # Известные ноды в сети GET /api/v3/network/content/distribution # Распределение контента GET /api/v3/network/sync/stats # Статистика синхронизации ``` ## 🔄 Алгоритм удаления неиспользуемого контента ### Система очистки контента ```python class ContentCleanupManager: """Управление очисткой контента через 7 дней""" def __init__(self): self.retention_days = 7 self.cleanup_interval = 3600 # 1 час async def start_cleanup_scheduler(self): """Запуск планировщика очистки""" while True: try: await self.cleanup_expired_content() await asyncio.sleep(self.cleanup_interval) except Exception as e: logger.error(f"Cleanup scheduler error: {e}") await asyncio.sleep(60) # Retry in 1 minute async def cleanup_expired_content(self): """Очистка просроченного контента""" cutoff_date = datetime.utcnow() - timedelta(days=self.retention_days) # Поиск контента без blockchain регистрации expired_content = await self._find_expired_content(cutoff_date) for content in expired_content: try: # Проверка отсутствия blockchain записи blockchain_exists = await self._check_blockchain_registration(content.hash) if not blockchain_exists: # Удаление файла и записи await self._remove_content(content) logger.info(f"Removed expired content: {content.hash}") else: # Обновление статуса - контент зарегистрирован content.blockchain_registered = True await content.save() except Exception as e: logger.error(f"Failed to cleanup content {content.hash}: {e}") async def _find_expired_content(self, cutoff_date: datetime) -> List[StoredContent]: """Поиск просроченного контента""" return await StoredContent.filter( created_at__lt=cutoff_date, blockchain_registered=False ).all() async def _check_blockchain_registration(self, content_hash: str) -> bool: """Проверка регистрации контента в блокчейне""" # TODO: Реализовать проверку TON блокчейна # Пока возвращаем False для тестирования return False async def _remove_content(self, content: StoredContent): """Удаление контента и связанных файлов""" # Удаление основного файла if os.path.exists(content.file_path): os.remove(content.file_path) # Удаление preview файлов preview_files = await PreviewContent.filter(parent_content_id=content.id).all() for preview in preview_files: if os.path.exists(preview.file_path): os.remove(preview.file_path) await preview.delete() # Удаление записи из базы данных await content.delete() ``` ## 📊 Мониторинг новой системы ### Расширенная система мониторинга ```python class DecentralizedNetworkMonitor: """Мониторинг децентрализованной сети v3.0""" async def get_network_health(self) -> dict: """Здоровье децентрализованной сети""" return { "decentralization_metrics": { "total_known_nodes": await self._count_known_nodes(), "active_connections": len(self.active_peers), "content_distribution": await self._analyze_content_distribution(), "network_redundancy": await self._calculate_network_redundancy() }, "sync_metrics": { "pending_sync_items": self.sync_manager.get_pending_count(), "successful_syncs_24h": await self._get_sync_count(hours=24), "failed_syncs_24h": await self._get_failed_sync_count(hours=24), "avg_sync_time": await self._get_avg_sync_time() }, "content_metrics": { "total_content_items": await self._count_local_content(), "content_accepted_rate": await self._get_acceptance_rate(), "content_cleanup_stats": await self._get_cleanup_stats(), "storage_usage": await self._get_storage_usage() }, "security_metrics": { "access_requests_24h": await self._count_access_requests(hours=24), "denied_access_rate": await self._get_denied_access_rate(), "encryption_status": "AES-256-GCM", "version_compatibility": await self._get_version_compatibility_stats() } } ``` Этот новый протокол обеспечивает полную децентрализацию MY Network при сохранении безопасности и эффективности системы.