REFACTORING DIRECTORIES

This commit is contained in:
user committed 2025-07-05 20:02:00 +03:00
1 parent c645019380
commit c8e1d5046c
54 files changed
+6193 -747

No files matched your search

+167
View File
@@ -0,0 +1,167 @@
# 🚀 Инструкции по развертыванию MY Network Bootstrap Node
## 📋 Что нужно сделать на сервере 2.58.65.188
### ✅ Шаг 1: Подключение к серверу
```bash
ssh service@2.58.65.188
# Пароль: DMUEjmnh6mDs/qlzhpjDzQ
```
### ✅ Шаг 2: Запуск автоматического развертывания
```bash
# Переход в root
sudo su -
# Запуск скрипта развертывания
chmod +x /tmp/auto_deploy.sh
bash /tmp/auto_deploy.sh
```
**⏳ Время выполнения: ~15-20 минут**
### ✅ Шаг 3: Проверка результата
После завершения скрипта проверьте:
```bash
# Статус сервисов
systemctl status my-network-bootstrap nginx docker
# Проверка API
curl https://my-public-node-3.projscale.dev/api/my/health
# Проверка портов (должен быть только 443)
netstat -tlnp | grep LISTEN
# Проверка firewall
ufw status numbered
```
## 🎯 Что будет развернуто:
### 🔧 **Базовая инфраструктура:**
- ✅ Ubuntu система обновлена
- ✅ Docker + Docker Compose установлены
- ✅ Python 3 + venv + зависимости
- ✅ MariaDB 11.2 (внутренний порт 3306)
- ✅ Redis 7 (внутренний порт 6379)
### 🌐 **MY Network Bootstrap Node:**
- ✅ Основное приложение на порту 15100 (внутренний)
- ✅ Bootstrap конфигурация для всей сети
- ✅ REST API для управления сетью
- ✅ Веб-мониторинг с ASCII интерфейсом
### 🔒 **Безопасность:**
- ✅ Nginx proxy только на порт 443 (HTTPS)
- ✅ SSL сертификат Let's Encrypt для my-public-node-3.projscale.dev
- ✅ UFW firewall - ТОЛЬКО SSH + 443 порт
- ✅ Fail2ban защита от атак
- ✅ Все внутренние порты заблокированы
### 🛡️ **Cloudflare совместимость:**
- ✅ Настроены IP ranges для Cloudflare
- ✅ Real IP header обработка
- ✅ CORS headers для публичного API
- ✅ Rate limiting для разных endpoints
## 📡 **Доступные API endpoints:**
### 🌍 **Публичные (доступны всем):**
- **Health Check:** `https://my-public-node-3.projscale.dev/api/my/health`
- **Node Info:** `https://my-public-node-3.projscale.dev/api/my/node/info`
- **Bootstrap Config:** `https://my-public-node-3.projscale.dev/api/my/bootstrap/config`
### 🔒 **Ограниченные (только localhost):**
- **Monitor Dashboard:** `https://my-public-node-3.projscale.dev/api/my/monitor/`
## 🎮 **Для других узлов сети:**
Другие узлы смогут подключаться к этому bootstrap узлу используя:
```json
{
"bootstrap_nodes": [
{
"id": "bootstrap-primary",
"host": "my-public-node-3.projscale.dev",
"port": 443,
"ssl": true,
"public": true
}
]
}
```
## 📊 **Мониторинг:**
### 🔍 **Автоматический мониторинг:**
- ✅ Проверка каждые 2 минуты
- ✅ Логирование в `/opt/logs/bootstrap-monitor.log`
- ✅ Уведомления о критических проблемах
### 📈 **Ручная проверка:**
```bash
# Логи сервиса
journalctl -u my-network-bootstrap -f
# Системный мониторинг
tail -f /opt/logs/bootstrap-monitor.log
# SSL статус
certbot certificates
# Статистика nginx
tail -f /var/log/nginx/access.log
```
## 🆘 **Troubleshooting:**
### ❌ **Если API недоступен:**
```bash
systemctl restart my-network-bootstrap nginx
curl -v https://my-public-node-3.projscale.dev/api/my/health
```
### ❌ **Если SSL не работает:**
```bash
certbot certificates
certbot renew --dry-run
systemctl reload nginx
```
### ❌ **Если firewall блокирует:**
```bash
ufw status numbered
# Проверить что порт 443 разрешен
```
## 📋 **Финальный чек-лист:**
После развертывания должно быть:
- [ ] ✅ `curl https://my-public-node-3.projscale.dev/api/my/health` возвращает 200
- [ ] ✅ `curl https://my-public-node-3.projscale.dev/api/my/node/info` показывает информацию об узле
- [ ] ✅ `curl https://my-public-node-3.projscale.dev/api/my/bootstrap/config` возвращает конфигурацию
- [ ] ✅ `systemctl status my-network-bootstrap nginx docker` все сервисы active
- [ ] ✅ `ufw status` показывает только SSH и 443 порт
- [ ] ✅ `netstat -tlnp | grep :443` nginx слушает порт 443
- [ ] ✅ SSL сертификат действителен (проверить в браузере)
## 🎉 **Результат:**
После успешного развертывания у вас будет:
**🚀 Полностью функциональный MY Network Bootstrap Node**
- Доступен по HTTPS на my-public-node-3.projscale.dev
- Готов принимать подключения других узлов сети
- Защищен firewall + SSL + fail2ban
- Автоматический мониторинг и обслуживание
- Совместим с Cloudflare proxy
**🌐 Готов стать основным узлом распределенной сети MY Network!**
---
*Время развертывания: ~15-20 минут*
*Требования: Ubuntu 20.04+, root доступ, домен настроен*
+127
View File
@@ -0,0 +1,127 @@
# Исправление ошибки сборки Docker Compose
## Проблема
Система пыталась собрать и запустить сервис `web2-client`, который может отсутствовать на некоторых нодах, что приводило к ошибке:
```
target web2-client: failed to solve: failed to read dockerfile: open Dockerfile: no such file or directory
```
## Решение
Исправлены **ЧЕТЫРЕ** критические проблемы:
### 1. Docker Compose исправления
В `docker-compose.production.yml`:
- Добавлен профиль для web2-client: `profiles: ["main-node"]`
- Удалена зависимость nginx на web2-client (nginx теперь зависит только от app)
- Удалена устаревшая строка `version: '3.8'`
```yaml
web2-client:
profiles: ["main-node"] # Only build for main nodes
# ... остальная конфигурация
nginx:
depends_on:
- app # Убрано: - web2-client
```
### 2. Умная логика сборки и запуска
Обновлен `setup_production_server.sh` с graceful fallback логикой:
**Для основной ноды (main):**
- Сначала пытается собрать/запустить с профилем `main-node` (включая web2-client)
- Если не удается, fallback к основным сервисам: `app postgres redis`
**Для обычной ноды (regular):**
- Сразу собирает/запускает только основные сервисы без web2-client
### 3. Исправление Dockerfile зависимостей
**Проблема:** `ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?`
В [`Dockerfile.simple`](my-uploader-bot/Dockerfile.simple:13) добавлен git:
```dockerfile
RUN apt-get update && apt-get install -y \
build-essential \
curl \
git \ # ✅ Добавлено для установки tonsdk из GitHub
ffmpeg \
libmagic1 \
libpq-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
```
### 4. Исправление конфликта зависимостей Python
**Проблема:** `ERROR: Cannot install -r requirements.txt ... because these package versions have conflicting dependencies`
**Две проблемы:**
1. `aiogram 3.13.0` требует `aiofiles~=23.2.1`, а указана `aiofiles==24.1.0`
2. [`Dockerfile.simple`](my-uploader-bot/Dockerfile.simple:23) копировал неправильный файл
**✅ Решение:**
- В [`requirements.txt`](my-uploader-bot/requirements.txt:31) изменена версия aiofiles:
```txt
# Было: aiofiles==24.1.0
# Стало: aiofiles==23.2.1 # Совместимо с aiogram
```
- В [`Dockerfile.simple`](my-uploader-bot/Dockerfile.simple:23) исправлен копируемый файл:
```dockerfile
# Было: COPY requirements_new.txt ./requirements.txt
# Стало: COPY requirements.txt ./requirements.txt
```
### 5. Обновленные управляющие скрипты
- `start.sh` - умный запуск с fallback логикой
- `rebuild.sh` - пересборка с учетом доступных модулей
- `systemd_start.sh` - обертка для systemd service
## Поведение системы
### Если web2-client модуль доступен:
```bash
✅ Запущены все сервисы основной ноды (включая web2-client)
```
### Если web2-client модуль недоступен:
```bash
⚠️ Web2-client недоступен, запускаем основные сервисы...
✅ Запущены основные сервисы (web2-client пропущен)
```
## Команды для проверки
### Проверка статуса:
```bash
sudo /home/myuploader/uploader-bot/status.sh
```
### Ручной запуск с профилем:
```bash
# Основная нода с web2-client
docker-compose -f docker-compose.production.yml --profile main-node up -d
# Только основные сервисы
docker-compose -f docker-compose.production.yml up -d app postgres redis
```
### Проверка доступных сервисов:
```bash
docker-compose -f docker-compose.production.yml config --services
```
## Типы нод
### Main Node (основная)
- Полный стек: uploader-bot + converter-module + web2-client
- Web интерфейс доступен на главной странице
- API доступен через `/api/`
### Regular Node (обычная)
- Основной стек: uploader-bot + converter-module
- Только API интерфейс на главной странице
- Меньше ресурсов, быстрее развертывание
## Результат
Теперь система корректно работает независимо от наличия всех модулей и автоматически адаптируется к доступным компонентам.
+617
View File
@@ -0,0 +1,617 @@
# 🚀 MY UPLOADER BOT - DOCKER SETUP
Полное руководство по развертыванию MY Uploader Bot с использованием Docker
## 📋 Содержание
1. [Локальное тестирование](#локальное-тестирование)
2. [Production развертывание](#production-развертывание)
3. [Архитектура системы](#архитектура-системы)
4. [On-Demand Converter](#on-demand-converter)
5. [Мониторинг и логи](#мониторинг-и-логи)
6. [Безопасность](#безопасность)
7. [Troubleshooting](#troubleshooting)
## 🔧 Локальное тестирование
### Быстрый старт
```bash
# 1. Клонирование репозитория
git clone <repository-url>
cd my-uploader-bot
# 2. Создание .env файла
cp .env.example .env
# Отредактируйте .env файл с локальными настройками
# 3. Запуск с Docker Compose
docker-compose -f docker-compose.new.yml up -d
# 4. Проверка статуса
docker-compose -f docker-compose.new.yml ps
```
### Переменные окружения для локального тестирования
Создайте файл `.env` со следующими переменными:
```bash
# =============================================================================
# MY UPLOADER BOT - ЛОКАЛЬНЫЕ НАСТРОЙКИ
# =============================================================================
# Environment
NODE_ENV=development
DEBUG=true
# Database (PostgreSQL)
DATABASE_URL=postgresql://my_user:my_secure_password_123@localhost:5432/my_uploader_db
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=my_uploader_db
POSTGRES_USER=my_user
POSTGRES_PASSWORD=my_secure_password_123
# Redis
REDIS_URL=redis://localhost:6379/0
REDIS_HOST=localhost
REDIS_PORT=6379
# Security Keys (генерируйте новые для production!)
SECRET_KEY=dev_secret_key_change_in_production_123456789
JWT_SECRET=dev_jwt_secret_change_in_production_987654321
ENCRYPTION_KEY=dev_encryption_key_32_chars_long!
# MY Network Settings
MY_NETWORK_NODE_ID=local-dev-node-$(date +%s)
MY_NETWORK_PORT=15100
MY_NETWORK_HOST=0.0.0.0
MY_NETWORK_DOMAIN=localhost
MY_NETWORK_SSL_ENABLED=false
# API Settings
API_HOST=0.0.0.0
API_PORT=15100
API_WORKERS=2
MAX_UPLOAD_SIZE=50MB
# Converter Settings (On-Demand)
CONVERTER_DOCKER_IMAGE=my-converter:latest
CONVERTER_SHARED_PATH=/shared/converter
CONVERTER_MAX_PARALLEL=2
CONVERTER_TIMEOUT=300
# Logging
LOG_LEVEL=DEBUG
LOG_FORMAT=text
# Monitoring (опционально)
GRAFANA_PASSWORD=admin123
```
### Проверка локального развертывания
```bash
# Проверка здоровья сервисов
curl http://localhost:15100/health
curl http://localhost:3000/health # web2-client
# Проверка MY Network API
curl http://localhost:15100/api/my/bootstrap/config
# Проверка converter image
docker images | grep my-converter
# Просмотр логов
docker-compose -f docker-compose.new.yml logs -f app
```
## 🏭 Production развертывание
### Автоматическое развертывание на пустом сервере
**Требования:**
- Ubuntu 20.04+ / Debian 11+ / CentOS 8+
- Минимум 2GB RAM, 2 CPU cores, 20GB диска
- Root доступ или sudo права
- Доменное имя, указывающее на сервер
**Одной командой:**
```bash
# Скачайте и запустите мастер-скрипт
curl -fsSL https://raw.githubusercontent.com/your-org/my-uploader-bot/main/setup_production_server.sh | sudo bash -s -- yourdomain.com
```
### Ручное развертывание (пошагово)
#### 1. Подготовка сервера
```bash
# Обновление системы
sudo apt update && sudo apt upgrade -y
# Установка базовых пакетов
sudo apt install -y curl wget git unzip htop nano ufw fail2ban
# Создание пользователя для сервиса
sudo useradd -m -s /bin/bash service
sudo usermod -aG sudo service
```
#### 2. Установка Docker
```bash
# Установка Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Установка Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Добавление пользователя в группу docker
sudo usermod -aG docker service
```
#### 3. Клонирование проекта
```bash
# Переключение на пользователя service
sudo su - service
# Клонирование проекта
git clone <repository-url> /home/service/my-uploader-bot
cd /home/service/my-uploader-bot
# Установка прав доступа
chmod +x scripts/*.sh
chmod +x *.sh
```
#### 4. Настройка окружения
```bash
# Генерация production конфигурации
./scripts/setup_production_env.sh /home/service/my-uploader-bot yourdomain.com
# Настройка дополнительных модулей
./scripts/setup_modules.sh /home/service/my-uploader-bot
```
#### 5. Сборка Docker образов
```bash
# Сборка основного приложения и converter
docker-compose -f docker-compose.production.yml build
# Сборка только converter image (для on-demand использования)
docker-compose -f docker-compose.production.yml --profile build-only build converter-build
```
#### 6. Настройка Nginx и SSL
```bash
# Возврат к root для настройки системных сервисов
exit # выход из пользователя service
# Установка Nginx и Certbot
sudo apt install -y nginx certbot python3-certbot-nginx
# Настройка Nginx конфигурации
sudo ./scripts/create_nginx_config.sh /home/service/my-uploader-bot yourdomain.com service
# Получение SSL сертификата
sudo certbot --nginx -d yourdomain.com --non-interactive --agree-tos --email admin@yourdomain.com
```
#### 7. Настройка Firewall
```bash
# Базовая настройка UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Разрешение необходимых портов
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Включение firewall
sudo ufw --force enable
```
#### 8. Создание SystemD сервисов
```bash
# Создание сервисов
sudo ./scripts/create_systemd_services.sh /home/service/my-uploader-bot service
# Запуск сервисов
sudo systemctl start my-docker-compose
sudo systemctl start my-converter-builder
sudo systemctl start my-uploader-bot
sudo systemctl start my-network-bootstrap
sudo systemctl enable nginx
sudo systemctl restart nginx
```
### Проверка Production развертывания
```bash
# Проверка HTTPS доступности
curl https://yourdomain.com/health
# Проверка MY Network
curl https://yourdomain.com/api/my/bootstrap/config
# Проверка web2-client
curl https://yourdomain.com/web/health
# Проверка converter image
docker images | grep my-converter
# Проверка SSL сертификата
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null
```
## 🏗️ Архитектура системы
```mermaid
graph TB
Client[👤 Client] --> LB[🌐 Nginx Load Balancer]
LB --> App[🚀 MY Uploader Bot<br/>Port: 15100]
LB --> Web[💻 Web2 Client<br/>Port: 3000]
App --> DB[(🗄️ PostgreSQL<br/>Port: 5432)]
App --> Redis[(⚡ Redis<br/>Port: 6379)]
App --> MyNet[🌍 MY Network<br/>Bootstrap Node]
subgraph "🐳 Docker Network"
App
Web
DB
Redis
MyNet
ConvImg[🖼️ Converter Image<br/>my-converter:latest]
end
App -.->|On-Demand| ConvContainer1[🔄 Converter Container 1]
App -.->|On-Demand| ConvContainer2[🔄 Converter Container 2]
App -.->|On-Demand| ConvContainer3[🔄 Converter Container N]
ConvImg -.->|Creates| ConvContainer1
ConvImg -.->|Creates| ConvContainer2
ConvImg -.->|Creates| ConvContainer3
ConvContainer1 -.->|Auto-Remove| X1[❌]
ConvContainer2 -.->|Auto-Remove| X2[❌]
ConvContainer3 -.->|Auto-Remove| X3[❌]
subgraph "📊 Monitoring Stack"
Prom[📈 Prometheus<br/>Port: 9090]
Graf[📊 Grafana<br/>Port: 3001]
Loki[📋 Loki<br/>Port: 3100]
PT[📝 Promtail]
end
App --> Prom
Web --> Prom
PT --> Loki
Graf --> Prom
Graf --> Loki
LB --> Graf
```
### Компоненты системы
| Компонент | Порт | Режим работы | Описание |
|-----------|------|-------------|----------|
| **MY Uploader Bot** | 15100 | Постоянный | Основное API приложение |
| **Web2 Client** | 3000 | Постоянный | Веб интерфейс |
| **PostgreSQL** | 5432 | Постоянный | Основная база данных |
| **Redis** | 6379 | Постоянный | Кеширование и очереди |
| **Nginx** | 80/443 | Постоянный | Reverse proxy + SSL |
| **Converter Module** | - | **On-Demand** | 🔄 Конвертер медиа файлов |
| **Prometheus** | 9090 | Постоянный | Сбор метрик |
| **Grafana** | 3001 | Постоянный | Дашборды мониторинга |
| **Loki** | 3100 | Постоянный | Централизованные логи |
## 🔄 On-Demand Converter
### Принцип работы
Converter Module работает по принципу **on-demand контейнеров**:
1. **Image собирается один раз** при установке системы
2. **MY Uploader Bot создает контейнеры** по мере поступления задач конвертации
3. **Контейнеры автоматически удаляются** после завершения задач
4. **Параллельная обработка** до N задач одновременно (настраивается)
### Настройки converter в .env
```bash
# Converter Settings
CONVERTER_DOCKER_IMAGE=my-converter:latest # Имя образа
CONVERTER_SHARED_PATH=/shared/converter # Общая папка для файлов
CONVERTER_MAX_PARALLEL=3 # Максимум параллельных задач
CONVERTER_TIMEOUT=300 # Таймаут задачи (секунды)
```
### Управление converter
```bash
# Проверка готовности converter image
docker images | grep my-converter
# Пересборка converter image
./rebuild_converter.sh
# Просмотр активных converter контейнеров
docker ps | grep converter
# Мониторинг логов converter заданий
docker logs -f <converter_container_id>
# Принудительная очистка зависших контейнеров
docker container prune -f
```
### API endpoints для converter
```bash
# Запуск задачи конвертации
POST /api/convert/start
{
"file_id": "uuid",
"conversion_type": "video_to_mp4",
"options": {...}
}
# Статус задачи конвертации
GET /api/convert/status/{task_id}
# Отмена задачи
DELETE /api/convert/cancel/{task_id}
# Список активных задач
GET /api/convert/active
```
### Преимущества on-demand архитектуры
✅ **Экономия ресурсов** - converter потребляет ресурсы только при работе
✅ **Масштабируемость** - автоматическое создание контейнеров по нагрузке
✅ **Изоляция** - каждая задача выполняется в отдельном контейнере
✅ **Отказоустойчивость** - сбой одного контейнера не влияет на другие
✅ **Легкое обновление** - пересборка image без остановки основной системы
## 📊 Мониторинг и логи
### Доступ к мониторингу
```bash
# Grafana Dashboard
https://yourdomain.com/grafana
# Логин: admin / пароль из .env
# Prometheus Metrics
https://yourdomain.com/prometheus
# Проверка логов
docker-compose -f docker-compose.production.yml logs -f app
journalctl -u my-uploader-bot -f
journalctl -u my-docker-compose -f
```
### Ключевые метрики
- **Производительность**: Response time, throughput, error rate
- **Ресурсы**: CPU, Memory, Disk usage
- **MY Network**: Количество узлов, скорость репликации
- **База данных**: Подключения, запросы, производительность
- **Converter**: Активные задачи, время обработки, ошибки
### Алерты
Система автоматически создает алерты для:
- Высокая нагрузка на CPU (>80%)
- Недостаток памяти (<100MB свободно)
- Ошибки приложения (>5 за минуту)
- MY Network недоступен
- SSL сертификат истекает (<30 дней)
- Converter задачи зависают (>timeout)
## 🔒 Безопасность
### Безопасность сети
```bash
# Проверка открытых портов
sudo netstat -tlnp | grep LISTEN
# Проверка правил firewall
sudo ufw status verbose
# Анализ попыток вторжения
sudo fail2ban-client status
```
### Обновления безопасности
```bash
# Автоматические обновления безопасности
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# Регулярная ротация SSL сертификатов
sudo crontab -e
# Добавить: 0 12 * * * /usr/bin/certbot renew --quiet
```
### Backup стратегия
```bash
# Backup базы данных
docker-compose -f docker-compose.production.yml exec postgres pg_dump -U my_user my_uploader_db > backup_$(date +%Y%m%d).sql
# Backup конфигурации
tar -czf config_backup_$(date +%Y%m%d).tar.gz .env nginx/ ssl/
# Backup converter image
docker save my-converter:latest | gzip > converter_image_$(date +%Y%m%d).tar.gz
# Автоматический backup (добавить в crontab)
0 2 * * * /home/service/my-uploader-bot/scripts/backup.sh
```
## 🔧 Troubleshooting
### Частые проблемы
#### 1. Приложение не запускается
```bash
# Проверка логов
docker-compose -f docker-compose.production.yml logs app
journalctl -u my-uploader-bot -f
# Проверка конфигурации
docker-compose -f docker-compose.production.yml config
# Проверка переменных окружения
cat .env
```
#### 2. База данных недоступна
```bash
# Проверка статуса PostgreSQL
docker-compose -f docker-compose.production.yml exec postgres pg_isready
# Подключение к БД
docker-compose -f docker-compose.production.yml exec postgres psql -U my_user -d my_uploader_db
# Проверка логов БД
docker-compose -f docker-compose.production.yml logs postgres
```
#### 3. SSL сертификат не работает
```bash
# Проверка сертификата
sudo certbot certificates
# Обновление сертификата
sudo certbot renew --dry-run
# Проверка nginx конфигурации
sudo nginx -t
```
#### 4. MY Network недоступна
```bash
# Проверка bootstrap узла
curl https://yourdomain.com/api/my/bootstrap/config
# Проверка логов MY Network
docker-compose -f docker-compose.production.yml logs app | grep "MY Network"
# Проверка сетевых подключений
docker network ls
docker network inspect my-uploader-bot_uploader_network
```
#### 5. Converter не работает
```bash
# Проверка наличия image
docker images | grep my-converter
# Пересборка converter image
./rebuild_converter.sh
# Проверка активных converter контейнеров
docker ps | grep converter
# Очистка зависших контейнеров
docker container prune -f
# Проверка логов последних converter задач
docker logs $(docker ps -a | grep converter | head -1 | cut -d' ' -f1)
```
### Полезные команды
```bash
# Полная перезагрузка системы
./stop_all_services.sh && ./start_all_services.sh
# Обновление приложения
git pull
docker-compose -f docker-compose.production.yml pull
docker-compose -f docker-compose.production.yml up -d
# Очистка неиспользуемых ресурсов
docker system prune -a
# Мониторинг ресурсов в реальном времени
docker stats
# Мониторинг converter активности
watch 'docker ps | grep converter'
```
### SystemD сервисы
```bash
# Запуск всех сервисов
./start_all_services.sh
# Остановка всех сервисов
./stop_all_services.sh
# Проверка статуса всех сервисов
./check_services.sh
# Пересборка converter image
./rebuild_converter.sh
# Просмотр логов отдельных сервисов
journalctl -u my-uploader-bot -f
journalctl -u my-docker-compose -f
journalctl -u my-converter-builder -f
```
### Контакты поддержки
- **GitHub Issues**: [repository-url]/issues
- **Documentation**: [repository-url]/wiki
- **MY Network**: https://my-network.dev
---
## 📝 Дополнительные ресурсы
- [Архитектура MY Network](docs/MY_NETWORK_ARCHITECTURE.md)
- [API Documentation](docs/API.md)
- [Development Guide](docs/DEVELOPMENT.md)
- [Security Guidelines](docs/SECURITY.md)
- [Converter Module Guide](docs/CONVERTER.md)
---
**🎉 Поздравляем! MY Uploader Bot успешно развернут в production!**
Система готова к работе с:
- ⚡ **On-demand конвертацией** медиа файлов
- 🔒 **Безопасностью корпоративного уровня**
- 📊 **Автоматическим мониторингом**
- 🚀 **Высокой производительностью**
- 🌍 **Распределенной MY Network**
+729
View File
@@ -0,0 +1,729 @@
# 🚀 MY Network v2.0 - Распределенная сеть контента
## 📖 Полная документация на русском языке
---
## 🎯 Что такое MY Network?
**MY Network** — это современная распределенная P2P система для автоматического управления и синхронизации контента между серверами. Система работает как overlay-протокол поверх существующей инфраструктуры, не нарушая работу текущих приложений.
### ✨ Ключевые возможности
- 🌐 **P2P сеть** - автоматическое обнаружение и подключение узлов
- 🔄 **Автосинхронизация** - реплицирование контента между узлами
- 📊 **Веб-мониторинг** - красивые дашборды с ASCII-артом
- 🔒 **Безопасность** - SSL/TLS шифрование, firewall, rate limiting
- 🐳 **Контейнеризация** - полная поддержка Docker
- 📡 **REST API** - программное управление всеми функциями
- ⚖️ **Load Balancing** - распределение нагрузки между узлами
---
## 🏗️ Архитектура системы
```mermaid
graph TB
subgraph "MY Network Cluster"
Node1[Node 1<br/>Bootstrap]
Node2[Node 2<br/>Worker]
Node3[Node 3<br/>Worker]
Node4[Node 4<br/>Worker]
end
subgraph "Node 1 Components"
API1[REST API<br/>:15100]
Monitor1[Web Monitor<br/>/monitor]
Sync1[Sync Manager]
Peer1[Peer Manager]
Storage1[Storage<br/>/opt/storage]
end
subgraph "External Services"
Nginx[Nginx<br/>SSL Proxy]
DB[(MariaDB<br/>Database)]
Redis[(Redis<br/>Cache)]
end
subgraph "Security Layer"
UFW[UFW Firewall]
Fail2Ban[Fail2ban]
SSL[Let's Encrypt<br/>SSL]
end
Internet --> UFW
UFW --> SSL
SSL --> Nginx
Nginx --> API1
Node1 <--> Node2
Node1 <--> Node3
Node1 <--> Node4
Node2 <--> Node3
Node3 <--> Node4
API1 <--> DB
API1 <--> Redis
API1 <--> Storage1
Sync1 <--> Peer1
Monitor1 <--> API1
```
---
## 🔄 Схема синхронизации контента
```mermaid
sequenceDiagram
participant C as Client
participant N1 as Node 1 (Source)
participant N2 as Node 2 (Target)
participant N3 as Node 3 (Target)
Note over N1,N3: Автоматическая синхронизация каждые 5 минут
C->>N1: Загрузка файла
N1->>N1: Сохранение в /opt/storage
N1->>N1: Обновление базы данных
loop Каждые 5 минут
N1->>N2: Проверка статуса
N2->>N1: Список файлов + хеши
N1->>N1: Сравнение с локальными файлами
alt Файл отсутствует на N2
N1->>N2: Передача файла (chunked)
N2->>N2: Сохранение + проверка целостности
N2->>N1: Подтверждение получения
end
N1->>N3: Аналогично для Node 3
end
Note over N1,N3: Все узлы содержат идентичные данные
```
---
## 🌐 Схема сетевого взаимодействия
```mermaid
graph LR
subgraph "Internet"
User[👤 Пользователь]
Bot[🤖 Telegram Bot]
end
subgraph "Security Layer"
FW[🔥 UFW Firewall<br/>Ports: 22,80,443]
FB[🚫 Fail2ban<br/>Защита от брутфорса]
end
subgraph "Web Layer"
NG[🌐 Nginx<br/>SSL Termination<br/>Rate Limiting]
end
subgraph "Application Layer"
API[📡 MY Network API<br/>Port 15100]
MON[📊 Web Monitor<br/>/api/my/monitor]
SYNC[🔄 Sync Manager<br/>Background Process]
end
subgraph "Data Layer"
DB[(🗄️ MariaDB<br/>Port 3306)]
RD[(⚡ Redis<br/>Port 6379)]
FS[📁 File Storage<br/>/opt/storage]
end
User --> FW
Bot --> FW
FW --> FB
FB --> NG
NG --> API
API --> MON
API --> SYNC
API --> DB
API --> RD
API --> FS
style FW fill:#ff9999
style FB fill:#ff9999
style NG fill:#99ccff
style API fill:#99ff99
style DB fill:#ffcc99
```
---
## ⚙️ Установка в две команды
### 🥇 Команда 1: Установка сервиса
```bash
# Скачиваем и устанавливаем базовый сервис
curl -O https://your-domain.com/install_service.sh
sudo bash install_service.sh
```
**Что делает эта команда:**
- ✅ Обновляет систему
- ✅ Устанавливает Docker, Python, зависимости
- ✅ Создает структуру директорий
- ✅ Настраивает systemd сервис
- ✅ Запускает базовый сервис на порту 15100
### 🥈 Команда 2: Защита и SSL
```bash
# Настраиваем защиту, nginx, SSL, firewall
sudo bash secure_service.sh
```
**Что делает эта команда:**
- 🔒 Устанавливает SSL сертификат (Let's Encrypt)
- 🌐 Настраивает Nginx с rate limiting
- 🔥 Настраивает UFW firewall
- 🚫 Устанавливает Fail2ban
- 📊 Настраивает мониторинг системы
- 🔄 Настраивает автообновление сертификатов
---
## 🛠️ Компоненты системы
### 📡 REST API Endpoints
```mermaid
graph TD
API[MY Network API<br/>/api/my/]
API --> NODE[/node/*<br/>Управление узлом]
API --> PEER[/peer/*<br/>Управление пирами]
API --> SYNC[/sync/*<br/>Синхронизация]
API --> NET[/network/*<br/>Статистика сети]
API --> MON[/monitor/*<br/>Веб-мониторинг]
NODE --> NINFO[GET /info<br/>Информация об узле]
NODE --> NPEERS[GET /peers<br/>Список пиров]
NODE --> NHEALTH[GET /health<br/>Проверка здоровья]
PEER --> PADD[POST /add<br/>Добавить пир]
PEER --> PREM[DELETE /remove<br/>Удалить пир]
PEER --> PSTAT[GET /stats<br/>Статистика пира]
SYNC --> SSTART[POST /start<br/>Запуск синхронизации]
SYNC --> SSTOP[POST /stop<br/>Остановка синхронизации]
SYNC --> SSTAT[GET /status<br/>Статус синхронизации]
MON --> MDASH[GET /<br/>Веб-дашборд]
MON --> MASCII[GET /ascii<br/>ASCII статус]
MON --> MAPI[GET /api<br/>JSON метрики]
```
### 📊 Веб-мониторинг
```mermaid
graph TB
subgraph "Web Monitor Dashboard"
HEADER[🎯 MY Network Monitor<br/>ASCII Art Header]
METRICS[📈 System Metrics<br/>CPU, Memory, Disk]
NETWORK[🌐 Network Status<br/>Peers, Connections]
SYNC[🔄 Sync Status<br/>Last Sync, Progress]
STORAGE[💾 Storage Info<br/>Used/Free Space]
REALTIME[⚡ Real-time Updates<br/>Auto-refresh каждые 5 сек]
CHARTS[📊 ASCII Charts<br/>Bandwidth, Load]
end
HEADER --> METRICS
HEADER --> NETWORK
HEADER --> SYNC
HEADER --> STORAGE
METRICS --> REALTIME
NETWORK --> REALTIME
SYNC --> REALTIME
STORAGE --> REALTIME
REALTIME --> CHARTS
style HEADER fill:#ff6b6b
style REALTIME fill:#4ecdc4
style CHARTS fill:#45b7d1
```
---
## 🔧 Конфигурация
### 📄 Основной конфиг (.env)
```bash
# MY Network Configuration
NODE_ID=node-1234567890 # Уникальный ID узла
NODE_PORT=15100 # Порт приложения
DOMAIN=my-network.example.com # Домен сервера
# Database Configuration
DB_HOST=localhost
DB_PORT=3306
DB_NAME=my_network
DB_USER=my_network_user
DB_PASSWORD=secure_password_here
# Security
SECRET_KEY=very_long_secret_key_here
JWT_SECRET=jwt_secret_key_here
# Network Settings
BOOTSTRAP_NODES=["node1.example.com", "node2.example.com"]
SYNC_INTERVAL=300 # Интервал синхронизации (секунды)
MAX_PEERS=10 # Максимум пиров
```
### 🗂️ Структура директорий
```
/opt/
├── my-network/ # Основная директория проекта
│ └── my-uploader-bot/ # Код приложения
│ ├── app/ # Python приложение
│ ├── static/ # Статические файлы
│ ├── templates/ # HTML шаблоны
│ └── logs/ # Логи приложения
├── storage/ # Хранилище файлов
├── logs/ # Системные логи
└── my-network-config.txt # Конфигурация установки
```
---
## 🚀 Использование
### 🔍 Проверка статуса
```bash
# Проверка сервиса
systemctl status my-network
# Проверка nginx
systemctl status nginx
# Проверка firewall
ufw status
# Проверка SSL
certbot certificates
# Проверка API
curl https://your-domain.com/api/my/health
```
### 📊 Мониторинг
```bash
# Веб-интерфейс мониторинга
https://your-domain.com/api/my/monitor/
# ASCII статус в терминале
curl https://your-domain.com/api/my/monitor/ascii
# JSON метрики
curl https://your-domain.com/api/my/monitor/api
```
### 🔄 Управление синхронизацией
```bash
# Запуск синхронизации
curl -X POST https://your-domain.com/api/my/sync/start
# Остановка синхронизации
curl -X POST https://your-domain.com/api/my/sync/stop
# Статус синхронизации
curl https://your-domain.com/api/my/sync/status
```
---
## 🔒 Безопасность
### 🛡️ Уровни защиты
```mermaid
graph TD
Internet[🌐 Internet] --> FW[🔥 UFW Firewall]
FW --> |Port 80,443,SSH| SSL[🔐 SSL/TLS<br/>Let's Encrypt]
SSL --> Nginx[🌐 Nginx Proxy]
Nginx --> |Rate Limiting| FB[🚫 Fail2ban]
FB --> API[📡 Application]
subgraph "Security Features"
FW1[✅ Firewall Rules]
SSL1[✅ SSL Certificates]
RL[✅ Rate Limiting]
FB1[✅ Brute Force Protection]
HD[✅ Security Headers]
IP[✅ IP Whitelisting]
end
style FW fill:#ff9999
style SSL fill:#99ff99
style FB fill:#ffcc99
```
### 🔐 Настройки безопасности
**Firewall (UFW):**
- ✅ Закрыты все порты кроме SSH, HTTP, HTTPS
- ✅ Разрешен доступ только к необходимым сервисам
- ✅ Блокировка подозрительного трафика
**SSL/TLS:**
- ✅ Автоматические сертификаты Let's Encrypt
- ✅ Принудительное перенаправление HTTP → HTTPS
- ✅ Современные алгоритмы шифрования
**Rate Limiting:**
- ✅ Ограничение запросов к API (10 req/s)
- ✅ Ограничение мониторинга (2 req/s)
- ✅ Защита от DDoS атак
**Fail2ban:**
- ✅ Блокировка брутфорс атак на SSH
- ✅ Защита от злоупотребления API
- ✅ Автоматическая разблокировка
---
## 📈 Мониторинг и логи
### 📊 Системные метрики
```mermaid
graph LR
subgraph "Monitoring Stack"
APP[📱 Application Metrics]
SYS[💻 System Metrics]
NET[🌐 Network Metrics]
SEC[🔒 Security Metrics]
end
subgraph "Log Files"
APPLOG[📄 /opt/logs/app.log]
SYSLOG[📄 /var/log/syslog]
NGINX[📄 /var/log/nginx/]
FAIL2BAN[📄 /var/log/fail2ban.log]
end
APP --> APPLOG
SYS --> SYSLOG
NET --> NGINX
SEC --> FAIL2BAN
subgraph "Monitoring Tools"
CRON[⏰ Cron Monitor<br/>Каждые 5 минут]
WEB[🌐 Web Dashboard<br/>Real-time]
ALERT[🚨 Alert System<br/>Critical Events]
end
APPLOG --> WEB
SYSLOG --> WEB
NGINX --> WEB
FAIL2BAN --> WEB
WEB --> ALERT
CRON --> ALERT
```
### 📜 Полезные команды для мониторинга
```bash
# Просмотр логов сервиса
journalctl -u my-network -f
# Просмотр логов nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
# Мониторинг системы
tail -f /opt/logs/monitor.log
# Статистика fail2ban
fail2ban-client status
# Проверка дискового пространства
df -h
# Мониторинг сетевых соединений
netstat -tlnp | grep :15100
```
---
## 🔧 Troubleshooting
### ⚠️ Частые проблемы и решения
#### 1. Сервис не запускается
```bash
# Проверка статуса
systemctl status my-network
# Просмотр логов
journalctl -u my-network -n 50
# Перезапуск сервиса
systemctl restart my-network
# Проверка портов
netstat -tlnp | grep :15100
```
#### 2. SSL сертификат не работает
```bash
# Проверка сертификатов
certbot certificates
# Обновление сертификата
certbot renew --dry-run
# Перезапуск nginx
systemctl reload nginx
# Проверка конфигурации nginx
nginx -t
```
#### 3. Firewall блокирует соединения
```bash
# Проверка правил firewall
ufw status numbered
# Добавление правила
ufw allow from IP_ADDRESS to any port 15100
# Проверка логов
grep UFW /var/log/syslog
```
#### 4. Синхронизация не работает
```bash
# Проверка статуса синхронизации
curl https://your-domain.com/api/my/sync/status
# Перезапуск синхронизации
curl -X POST https://your-domain.com/api/my/sync/stop
curl -X POST https://your-domain.com/api/my/sync/start
# Проверка пиров
curl https://your-domain.com/api/my/node/peers
```
---
## 🎨 Примеры API запросов
### 📡 Основные операции
```bash
# Получение информации об узле
curl -X GET https://your-domain.com/api/my/node/info \
-H "Content-Type: application/json"
# Добавление нового пира
curl -X POST https://your-domain.com/api/my/peer/add \
-H "Content-Type: application/json" \
-d '{
"host": "peer.example.com",
"port": 15100,
"ssl": true
}'
# Получение статистики сети
curl -X GET https://your-domain.com/api/my/network/stats \
-H "Content-Type: application/json"
# Запуск полной синхронизации
curl -X POST https://your-domain.com/api/my/sync/start \
-H "Content-Type: application/json" \
-d '{
"force": true,
"verify": true
}'
```
### 📊 Мониторинг через API
```bash
# JSON метрики для интеграции с внешними системами
curl -X GET https://your-domain.com/api/my/monitor/api \
-H "Content-Type: application/json" | jq
# Пример ответа:
{
"node": {
"id": "node-1234567890",
"status": "active",
"uptime": 86400,
"version": "2.0.0"
},
"network": {
"peers_count": 5,
"active_connections": 3,
"total_bandwidth": "1.2GB",
"sync_status": "synchronized"
},
"system": {
"cpu_usage": 25.5,
"memory_usage": 512,
"disk_usage": 75.2,
"load_average": [0.5, 0.3, 0.2]
}
}
```
---
## 🔄 Обновление системы
### 📦 Обновление MY Network
```bash
# Остановка сервиса
systemctl stop my-network
# Обновление кода
cd /opt/my-network/my-uploader-bot
git pull origin main
# Обновление зависимостей
source venv/bin/activate
pip install -r requirements_new.txt --upgrade
# Применение миграций базы данных (если есть)
python -m alembic upgrade head
# Запуск сервиса
systemctl start my-network
# Проверка статуса
systemctl status my-network
```
### 🔒 Обновление системы безопасности
```bash
# Обновление пакетов системы
apt update && apt upgrade -y
# Обновление SSL сертификатов
certbot renew
# Обновление правил fail2ban
systemctl restart fail2ban
# Проверка безопасности
ufw status
fail2ban-client status
certbot certificates
```
---
## 📋 Чек-лист развертывания
### ✅ Pre-deployment checklist
- [ ] **Сервер подготовлен** (Ubuntu 20.04+)
- [ ] **Домен настроен** (A-запись указывает на сервер)
- [ ] **SSH доступ настроен** (ключи, порт безопасности)
- [ ] **Email для SSL указан** (действующий email)
### ✅ Installation checklist
- [ ] **Шаг 1: Базовая установка**
- [ ] `sudo bash install_service.sh` выполнен успешно
- [ ] Сервис запущен: `systemctl status my-network`
- [ ] API отвечает: `curl http://localhost:15100/api/my/health`
- [ ] **Шаг 2: Безопасность**
- [ ] `sudo bash secure_service.sh` выполнен успешно
- [ ] SSL работает: `curl https://your-domain.com/api/my/health`
- [ ] Firewall активен: `ufw status`
- [ ] Fail2ban активен: `systemctl status fail2ban`
### ✅ Post-deployment checklist
- [ ] **Функциональность**
- [ ] Веб-мониторинг доступен: `https://your-domain.com/api/my/monitor/`
- [ ] API endpoints отвечают корректно
- [ ] Синхронизация работает (если есть пиры)
- [ ] Логи пишутся без ошибок
- [ ] **Безопасность**
- [ ] SSL A+ рейтинг (проверить на ssllabs.com)
- [ ] Только необходимые порты открыты
- [ ] Rate limiting работает
- [ ] Backup и мониторинг настроены
---
## 📞 Поддержка
### 🆘 Получение помощи
1. **Проверьте логи:**
```bash
journalctl -u my-network -n 100
tail -f /opt/logs/monitor.log
```
2. **Проверьте статус сервисов:**
```bash
systemctl status my-network nginx fail2ban
```
3. **Проверьте сетевое соединение:**
```bash
curl -v https://your-domain.com/api/my/health
```
4. **Соберите диагностическую информацию:**
```bash
/opt/monitor.sh
ufw status numbered
df -h
free -h
```
### 📧 Контакты
- **Документация:** `/opt/my-network/my-uploader-bot/DOCS_RU.md`
- **Конфигурация:** `/opt/my-network-config.txt`
- **Логи:** `/opt/logs/` и `/var/log/`
---
## 🎉 Заключение
**MY Network v2.0** - это полноценная, готовая к продакшену система для создания распределенных сетей контента. Система обеспечивает:
- ⚡ **Простую установку** в две команды
- 🔒 **Максимальную безопасность** из коробки
- 📊 **Полный мониторинг** в реальном времени
- 🔄 **Автоматическую синхронизацию** между узлами
- 🌐 **Масштабируемость** до любого количества узлов
Система готова к использованию и может быть развернута на любом современном Linux сервере за считанные минуты!
---
*Документация MY Network v2.0 | Версия 1.0 | 2025*
+55
View File
@@ -0,0 +1,55 @@
1. GET /api/v1/node
{
node_address: service_wallet,
master_address: platform collection,
indexer_height: int,
services: {
..status&delay only
}
}
2. POST /api/system.sendStatus
3. GET /api/system.version
{
codebase_hash: string,
codebase_branch: string
}
4. GET /api/tonconnect-manifest.json
используется для tonconnect на фронтенде бота (централизация)
5. GET /api/platform-metadata.json
используется при создании platform, если ранее не создано
6. POST /api/v1/auth.twa
сохраняет информацию о пользователе (его кошельке), выдает взамен токен для операций с этой нодой
7. GET /api/v1/tonconnect.new [! DEPRECATED !]
8. POST /api/v1/tonconnect.logout [! DEPRECATED !] но возможно нужно использовать при отключении кошелька в вебаппе
9. POST /api/v1/storage
загрузка контента на ноду с получением его хэша, TODO: нужно делать загрузку по частям чтобы сервер не падал
10. GET /api/v1/storage/<file_hash>
получение файла целиком. TODO: изучить реальный стриминг файла
TODO: реализовать поиск файла на других нодах
11. GET /api/v1/storage.decodeContentId/<content_id>
просто баловство
12. GET /api/v1/account [! DEPRECATED !]
получение информации о пользователе, не нужно от слова совсем
13. POST /api/v1/blockchain.sendNewContentMessage
14. POST /api/v1/blockchain.sendPurchaseContent
15. GET /api/v1/content.list
16. GET /api/v1/content.view
+98
View File
@@ -0,0 +1,98 @@
# Ручная настройка SSL для MY Network Bootstrap Node
## Проблема
Пользователь `service` не имеет sudo прав для настройки nginx и SSL сертификатов.
## Решение
Необходимо выполнить команды от имени root.
## Инструкция
### 1. Подключение к серверу как root
```bash
ssh root@2.58.65.188
```
### 2. Копирование скрипта
```bash
cp /home/service/setup_nginx_ssl.sh /root/
chmod +x /root/setup_nginx_ssl.sh
```
### 3. Запуск настройки SSL
```bash
cd /root
./setup_nginx_ssl.sh
```
## Альтернативный способ - добавить service в sudoers
### 1. Подключиться как root
```bash
ssh root@2.58.65.188
```
### 2. Добавить service в sudoers
```bash
echo "service ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/service
```
### 3. Запустить скрипт от service
```bash
su - service
cd /home/service
sudo ./setup_nginx_ssl.sh
```
## Что делает скрипт setup_nginx_ssl.sh
1. **Обновляет систему** и устанавливает nginx, certbot, ufw
2. **Настраивает firewall** (UFW):
- Разрешает SSH (22), HTTP (80), HTTPS (443)
- Блокирует остальные порты
3. **Получает SSL сертификат** от Let's Encrypt для домена my-public-node-3.projscale.dev
4. **Настраивает nginx**:
- HTTP -> HTTPS redirect
- Proxy для MY Network сервиса (порт 15100)
- Security headers
- Rate limiting
- CORS headers
5. **Настраивает автообновление** SSL сертификатов через cron
6. **Проверяет работоспособность** всех компонентов
## Ожидаемый результат
После выполнения скрипта MY Network Bootstrap Node будет доступен по HTTPS:
- **https://my-public-node-3.projscale.dev** - основной сайт
- **https://my-public-node-3.projscale.dev/api/my/health** - health check
- **https://my-public-node-3.projscale.dev/api/my/bootstrap/config** - bootstrap конфигурация
- **https://my-public-node-3.projscale.dev/api/my/monitor/** - веб-мониторинг
## Безопасность
- ✅ SSL/TLS сертификат от Let's Encrypt
- ✅ HTTP -> HTTPS redirect
- ✅ Security headers (HSTS, X-Frame-Options, etc.)
- ✅ Rate limiting для API endpoints
- ✅ Firewall (UFW) с минимальными открытыми портами
- ✅ Автообновление SSL сертификатов
## Проверка после установки
```bash
# Проверка nginx
systemctl status nginx
# Проверка MY Network сервиса
systemctl status my-network
# Проверка SSL сертификата
curl -I https://my-public-node-3.projscale.dev
# Проверка API
curl https://my-public-node-3.projscale.dev/api/my/health
# Логи nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
+347
View File
@@ -0,0 +1,347 @@
# Руководство по миграции на асинхронную архитектуру с Redis
Это руководство поможет вам безопасно обновить существующую систему My Uploader Bot до новой асинхронной архитектуры с поддержкой Redis кэширования, сохранив полную совместимость с текущими данными и настройками.
## ⚠️ ВАЖНО: Резервное копирование
**Перед началом миграции обязательно создайте резервные копии:**
```bash
# Остановите существующие контейнеры
docker-compose down
# Создайте резервную копию базы данных
docker run --rm \
-v my-uploader-bot_sqlStorage:/var/lib/mysql \
-v $(pwd)/backup:/backup \
mariadb:11.2 \
mysqldump -h maria_db -u myuploader -p myuploader > /backup/database_backup_$(date +%Y%m%d_%H%M%S).sql
# Создайте резервную копию файлов
cp -r /Storage /Storage_backup_$(date +%Y%m%d_%H%M%S)
# Создайте резервную копию конфигурации
cp docker-compose.yml docker-compose.yml.backup
cp .env .env.backup
```
## Шаг 1: Обновление конфигурационных файлов
### 1.1 Обновите docker-compose.yml
Замените ваш текущий `docker-compose.yml` на совместимую версию:
```bash
# Переименуйте существующий файл
mv docker-compose.yml docker-compose.yml.old
# Скопируйте новую совместимую версию
cp docker-compose.compatible.yml docker-compose.yml
```
### 1.2 Обновите .env файл
```bash
# Переименуйте существующий .env
mv .env .env.old
# Скопируйте новую совместимую версию
cp .env.compatible .env
# Перенесите ваши существующие настройки
# Отредактируйте .env и добавьте ваши текущие значения:
# - MYSQL_PASSWORD (ваш текущий пароль)
# - SECRET_KEY (ваш текущий ключ)
# - JWT_SECRET_KEY (ваш текущий JWT ключ)
# - Другие специфичные настройки
```
### 1.3 Обновите requirements.txt
```bash
# Переименуйте существующий файл
mv requirements.txt requirements.txt.old
# Скопируйте новую совместимую версию
cp requirements.compatible.txt requirements.txt
```
## Шаг 2: Добавление новых модулей
### 2.1 Обновите core модули
Замените существующие модули на совместимые версии:
```bash
# Создайте резервные копии существующих модулей
mkdir -p app/core/backup
cp app/core/database.py app/core/backup/database.py.old
cp app/core/config.py app/core/backup/config.py.old
# Используйте новые совместимые модули
cp app/core/database_compatible.py app/core/database.py
cp app/core/config_compatible.py app/core/config.py
```
### 2.2 Добавьте систему кэширования
```bash
# Добавьте новый модуль кэширования
# Файл app/core/cache.py уже создан
# Добавьте совместимые модели
cp app/core/models/base_compatible.py app/core/models/base.py
cp app/core/models/user_compatible.py app/core/models/user.py
cp app/core/models/content_compatible.py app/core/models/content.py
```
## Шаг 3: Постепенное обновление
### 3.1 Запуск с Redis (рекомендуется)
```bash
# Запустите только Redis для тестирования
docker-compose up -d redis
# Проверьте, что Redis работает
docker-compose exec redis redis-cli ping
# Должно вернуть: PONG
```
### 3.2 Запуск основных сервисов
```bash
# Запустите MariaDB
docker-compose up -d maria_db
# Дождитесь готовности базы данных
docker-compose logs -f maria_db
# Ждите сообщения: "mysqld: ready for connections"
# Запустите основное приложение
docker-compose up -d app
# Проверьте логи
docker-compose logs -f app
```
### 3.3 Запуск дополнительных сервисов
```bash
# Запустите остальные сервисы поочередно
docker-compose up -d indexer
docker-compose up -d ton_daemon
docker-compose up -d license_index
docker-compose up -d convert_process
# Проверьте статус всех сервисов
docker-compose ps
```
## Шаг 4: Проверка работоспособности
### 4.1 Проверка API
```bash
# Проверьте основной API
curl http://localhost:15100/health
# Проверьте подключение к базе данных
curl http://localhost:15100/api/v1/health/database
# Проверьте Redis подключение
curl http://localhost:15100/api/v1/health/cache
```
### 4.2 Проверка существующих данных
```bash
# Войдите в контейнер приложения
docker-compose exec app python3 -c "
from app.core.database_compatible import init_database, get_async_session
from app.core.models.user_compatible import User
import asyncio
async def check_data():
await init_database()
async with get_async_session() as session:
from sqlalchemy import select
result = await session.execute(select(User))
users = result.scalars().all()
print(f'Found {len(users)} users in database')
asyncio.run(check_data())
"
```
### 4.3 Проверка кэширования
```bash
# Проверьте работу Redis кэша
docker-compose exec app python3 -c "
from app.core.cache import init_cache, cache
import asyncio
async def test_cache():
await init_cache()
await cache.set('test_key', 'test_value', 60)
value = await cache.get('test_key')
print(f'Cache test: {value}')
asyncio.run(test_cache())
"
```
## Шаг 5: Настройка для продакшена
### 5.1 Обновите переменные окружения
В файле `.env` убедитесь, что настроены:
```env
# Безопасность
SECRET_KEY=your-production-secret-key
JWT_SECRET_KEY=your-production-jwt-key
# База данных
MYSQL_PASSWORD=your-secure-database-password
# Redis (если используете внешний Redis)
REDIS_HOST=redis
REDIS_PASSWORD=your-redis-password # Если нужен
# Кэширование
CACHE_ENABLED=true
REDIS_ENABLED=true
# Производительность
DATABASE_POOL_SIZE=20
DATABASE_MAX_OVERFLOW=30
REDIS_MAX_CONNECTIONS=50
# Логирование
LOG_LEVEL=INFO
LOG_FORMAT=json
```
### 5.2 Настройте мониторинг
```bash
# Добавьте мониторинг Redis
docker-compose exec redis redis-cli info memory
# Добавьте мониторинг MariaDB
docker-compose exec maria_db mysql -u root -p -e "SHOW PROCESSLIST;"
# Проверьте использование ресурсов
docker stats
```
## Откат изменений
Если что-то пошло не так, вы можете быстро откатиться:
```bash
# Остановите новые контейнеры
docker-compose down
# Восстановите старые конфигурации
mv docker-compose.yml.old docker-compose.yml
mv .env.old .env
mv requirements.txt.old requirements.txt
# Восстановите старые модули
cp app/core/backup/database.py.old app/core/database.py
cp app/core/backup/config.py.old app/core/config.py
# Запустите старую версию
docker-compose up -d
```
## Производительность и мониторинг
### Мониторинг Redis
```bash
# Мониторинг использования памяти Redis
docker-compose exec redis redis-cli info memory
# Мониторинг команд Redis
docker-compose exec redis redis-cli monitor
# Статистика кэша
docker-compose exec redis redis-cli info stats
```
### Мониторинг MariaDB
```bash
# Проверка подключений
docker-compose exec maria_db mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
# Проверка производительности
docker-compose exec maria_db mysql -u root -p -e "SHOW STATUS LIKE 'Queries';"
# Размер базы данных
docker-compose exec maria_db mysql -u root -p -e "
SELECT
table_schema as 'Database',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as 'Size (MB)'
FROM information_schema.tables
WHERE table_schema = 'myuploader'
GROUP BY table_schema;
"
```
## Возможные проблемы и решения
### Проблема: Redis не запускается
```bash
# Проверьте порты
netstat -tulpn | grep 6379
# Проверьте логи Redis
docker-compose logs redis
# Очистите данные Redis если нужно
docker volume rm my-uploader-bot_redis_data
```
### Проблема: Ошибки подключения к базе данных
```bash
# Проверьте статус MariaDB
docker-compose exec maria_db mysqladmin -u root -p status
# Проверьте переменные окружения
docker-compose exec app env | grep MYSQL
# Пересоздайте подключение
docker-compose restart app
```
### Проблема: Высокое использование памяти
```bash
# Настройте лимиты Redis в .env
REDIS_MAX_CONNECTIONS=30
DATABASE_POOL_SIZE=10
# Перезапустите сервисы
docker-compose restart
```
## Заключение
После успешной миграции ваша система получит:
1. ✅ **Асинхронную архитектуру** - лучшая производительность
2. ✅ **Redis кэширование** - быстрый доступ к данным
3. ✅ **Обратная совместимость** - все данные сохранены
4. ✅ **Улучшенный мониторинг** - больше метрик
5. ✅ **Масштабируемость** - готовность к росту нагрузки
Система остается полностью совместимой с существующими данными и конфигурациями, но получает современную асинхронную архитектуру и кэширование для лучшей производительности.
**Рекомендация**: Проводите миграцию в нерабочее время и тщательно тестируйте каждый шаг.
+625
View File
@@ -0,0 +1,625 @@
# MY Network Architecture Specification
## Архитектурный Обзор
MY Network представляет собой многоуровневую архитектуру overlay протокола, интегрированную с существующей системой my-uploader-bot без нарушения её функциональности.
## Overlay Architecture Diagram
```
┌─────────────────────────────────────────────────────────────────┐
│ MY Network Layer │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ P2P Manager │ │ Consensus │ │ Replication │ │
│ │ │ │ Engine │ │ Manager │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Integration Layer │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Content API │ │ Storage API │ │ Auth API │ │
│ │ (Existing) │ │ (Existing) │ │ (Existing) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Core Data Layer │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │StoredContent│ │EncryptionKey│ │ UserContent │ │
│ │ Model │ │ Model │ │ Model │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
## Интеграция с Существующей StoredContent Моделью
### Расширение StoredContent для MY Network
```python
# Новые поля для MY Network (добавляются через миграцию)
class StoredContentExtension:
# MY Network specific fields
my_network_enabled = Column(Boolean, default=False)
replica_count = Column(Integer, default=0)
replication_status = Column(String(32), default="none")
consensus_achieved = Column(Boolean, default=False)
# Peer information
replicated_on_peers = Column(ARRAY(String), default=list)
last_sync_timestamp = Column(DateTime, nullable=True)
# Network metadata
network_metadata = Column(JSONB, default=dict)
```
### Состояния Контента и Их Связи
#### 1. Encrypted Content State
```python
# Зашифрованный контент в MY Network
encrypted_content = StoredContent(
hash="sha256:abc123...",
encrypted=True,
encryption_key_id="uuid-key-id",
content_type="audio",
my_network_enabled=True
)
```
#### 2. Decrypted Content State (через decrypted_content_id)
```python
# Расшифрованная версия связана через специальное поле
decrypted_content = StoredContent(
hash="sha256:def456...",
encrypted=False,
original_encrypted_id=encrypted_content.id, # Обратная связь
content_type="audio",
my_network_enabled=True
)
# В encrypted_content добавляется:
encrypted_content.decrypted_content_id = decrypted_content.id
```
#### 3. Preview Content State
```python
# Превью версия для публичного доступа
preview_content = StoredContent(
hash="sha256:ghi789...",
encrypted=False,
content_type="audio",
file_size=small_size, # Урезанная версия
tags=["preview"],
parent_content_id=encrypted_content.id, # Связь с оригиналом
my_network_enabled=True
)
```
### Content State Relationship Model
```sql
-- Новая таблица для управления связями контента
CREATE TABLE content_relationships (
id UUID PRIMARY KEY,
parent_content_id UUID REFERENCES stored_content(id),
child_content_id UUID REFERENCES stored_content(id),
relationship_type VARCHAR(32) NOT NULL, -- 'encrypted', 'decrypted', 'preview'
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(parent_content_id, child_content_id, relationship_type)
);
-- Индексы для производительности
CREATE INDEX idx_content_rel_parent ON content_relationships(parent_content_id);
CREATE INDEX idx_content_rel_child ON content_relationships(child_content_id);
CREATE INDEX idx_content_rel_type ON content_relationships(relationship_type);
```
## Алгоритмы Репликации Всех Состояний
### 1. Multi-State Replication Algorithm
```python
class ContentStateReplicator:
async def replicate_content_group(self, content_group: ContentGroup):
"""
Реплицирует группу связанных состояний контента
"""
# Шаг 1: Определить все связанные состояния
states = await self.discover_content_states(content_group.root_id)
# Шаг 2: Проверить целостность связей
await self.verify_state_relationships(states)
# Шаг 3: Создать план репликации
replication_plan = await self.create_replication_plan(states)
# Шаг 4: Выполнить репликацию по плану
for batch in replication_plan.batches:
await self.replicate_batch(batch)
await self.verify_batch_integrity(batch)
# Шаг 5: Обновить метаданные о репликации
await self.update_replication_metadata(content_group, states)
```
### 2. State Discovery Algorithm
```python
async def discover_content_states(root_content_id: str) -> List[ContentState]:
"""
Обнаруживает все связанные состояния контента
"""
states = []
visited = set()
# BFS поиск всех связанных состояний
queue = [root_content_id]
while queue:
content_id = queue.pop(0)
if content_id in visited:
continue
visited.add(content_id)
content = await StoredContent.get_by_id(content_id)
if not content:
continue
states.append(ContentState(
content=content,
relationships=await self.get_relationships(content_id)
))
# Добавить связанные состояния в очередь
relationships = await self.get_relationships(content_id)
for rel in relationships:
if rel.child_content_id not in visited:
queue.append(rel.child_content_id)
return states
```
### 3. Atomic State Replication
```python
class AtomicStateReplication:
async def replicate_state_group(self, states: List[ContentState],
target_peers: List[PeerNode]):
"""
Атомарная репликация группы состояний
"""
transaction_id = str(uuid4())
try:
# Phase 1: Prepare - подготовка к репликации
await self.prepare_replication(transaction_id, states, target_peers)
# Phase 2: Transfer - передача данных
for state in states:
await self.transfer_state(state, target_peers, transaction_id)
# Phase 3: Verify - проверка целостности
verification_results = await self.verify_replicated_states(
states, target_peers, transaction_id
)
# Phase 4: Commit or Abort
if all(verification_results):
await self.commit_replication(transaction_id, target_peers)
else:
await self.abort_replication(transaction_id, target_peers)
raise ReplicationError("State verification failed")
except Exception as e:
await self.cleanup_failed_replication(transaction_id, target_peers)
raise e
```
## MY Network Service Layer
### Service Component Architecture
```python
# MY Network Service Manager
class MYNetworkService:
def __init__(self):
self.p2p_manager = P2PManager()
self.consensus_engine = ConsensusEngine()
self.replication_manager = ReplicationManager()
self.sync_coordinator = SyncCoordinator()
self.content_discovery = ContentDiscoveryService()
async def start_service(self):
"""Запуск MY Network сервиса"""
await self.p2p_manager.initialize()
await self.consensus_engine.start()
await self.replication_manager.start()
await self.sync_coordinator.start()
# Регистрация в сети
await self.register_node()
async def register_node(self):
"""Регистрация ноды в MY Network"""
node_info = {
"node_id": self.get_node_id(),
"address": self.get_public_address(),
"capabilities": self.get_node_capabilities(),
"content_stats": await self.get_content_statistics()
}
await self.p2p_manager.announce_node(node_info)
```
### P2P Communication Layer
```python
class P2PManager:
def __init__(self):
self.peers = {}
self.message_handlers = {}
self.connection_pool = ConnectionPool()
async def handle_peer_message(self, peer_id: str, message: dict):
"""Обработка сообщений от пиров"""
msg_type = message.get("type")
handler = self.message_handlers.get(msg_type)
if handler:
await handler(peer_id, message)
else:
logger.warning(f"Unknown message type: {msg_type}")
async def broadcast_content_announcement(self, content: StoredContent):
"""Анонс нового контента в сети"""
announcement = {
"type": "content_announcement",
"content_hash": content.hash,
"content_type": content.content_type,
"encrypted": content.encrypted,
"file_size": content.file_size,
"timestamp": datetime.utcnow().isoformat()
}
# Отправка всем активным пирам
for peer_id in self.get_active_peers():
await self.send_message(peer_id, announcement)
```
### Consensus Engine Implementation
```python
class ConsensusEngine:
def __init__(self, min_quorum: int = 3):
self.min_quorum = min_quorum
self.pending_votes = {}
self.consensus_results = {}
async def propose_content(self, content_hash: str) -> bool:
"""Предложение контента для консенсуса"""
proposal_id = str(uuid4())
proposal = {
"id": proposal_id,
"content_hash": content_hash,
"proposer": self.node_id,
"timestamp": datetime.utcnow(),
"votes": {},
"status": "pending"
}
self.pending_votes[proposal_id] = proposal
# Отправка предложения пирам
await self.broadcast_proposal(proposal)
# Ожидание консенсуса с таймаутом
result = await self.wait_for_consensus(proposal_id, timeout=30)
return result
async def vote_on_proposal(self, proposal_id: str, vote: bool):
"""Голосование по предложению"""
if proposal_id not in self.pending_votes:
return False
proposal = self.pending_votes[proposal_id]
proposal["votes"][self.node_id] = {
"vote": vote,
"timestamp": datetime.utcnow(),
"signature": await self.sign_vote(proposal_id, vote)
}
# Проверка достижения консенсуса
await self.check_consensus(proposal_id)
```
## Content Discovery & Routing
### Distributed Hash Table (DHT) для Content Discovery
```python
class ContentDHT:
def __init__(self, node_id: str):
self.node_id = node_id
self.routing_table = {}
self. content_index = {}
async def announce_content(self, content_hash: str, content_info: dict):
"""Анонс контента в DHT"""
key_hash = self.hash_key(content_hash)
responsible_nodes = await self.find_responsible_nodes(key_hash)
for node in responsible_nodes:
await self.store_content_info(node, content_hash, content_info)
async def find_content(self, content_hash: str) -> List[PeerInfo]:
"""Поиск нод с контентом"""
key_hash = self.hash_key(content_hash)
responsible_nodes = await self.find_responsible_nodes(key_hash)
peers_with_content = []
for node in responsible_nodes:
content_info = await self.get_content_info(node, content_hash)
if content_info:
peers_with_content.extend(content_info.get("peers", []))
return peers_with_content
```
### Smart Content Routing
```python
class ContentRouter:
def __init__(self):
self.peer_metrics = {}
self.content_popularity = {}
async def find_optimal_peers(self, content_hash: str,
count: int = 3) -> List[PeerInfo]:
"""Поиск оптимальных пиров для загрузки"""
available_peers = await self.content_dht.find_content(content_hash)
# Сортировка по метрикам производительности
scored_peers = []
for peer in available_peers:
score = await self.calculate_peer_score(peer, content_hash)
scored_peers.append((peer, score))
# Возврат топ пиров
scored_peers.sort(key=lambda x: x[1], reverse=True)
return [peer for peer, score in scored_peers[:count]]
async def calculate_peer_score(self, peer: PeerInfo,
content_hash: str) -> float:
"""Вычисление оценки пира"""
metrics = self.peer_metrics.get(peer.node_id, {})
# Факторы оценки
latency_score = 1.0 / max(metrics.get("avg_latency", 1), 0.01)
bandwidth_score = metrics.get("bandwidth", 1.0)
reliability_score = metrics.get("uptime", 0.5)
reputation_score = peer.reputation_score
# Взвешенная оценка
total_score = (
latency_score * 0.3 +
bandwidth_score * 0.3 +
reliability_score * 0.2 +
reputation_score * 0.2
)
return total_score
```
## Monitoring & Health System
### Node Health Monitoring
```python
class NodeHealthMonitor:
def __init__(self):
self.health_metrics = {}
self.alert_thresholds = {
"cpu_usage": 80.0,
"memory_usage": 85.0,
"disk_usage": 90.0,
"network_latency": 1000.0, # ms
"peer_count": 3 # minimum
}
async def collect_health_metrics(self) -> dict:
"""Сбор метрик здоровья ноды"""
return {
"cpu_usage": await self.get_cpu_usage(),
"memory_usage": await self.get_memory_usage(),
"disk_usage": await self.get_disk_usage(),
"network_latency": await self.measure_network_latency(),
"peer_count": len(await self.get_active_peers()),
"sync_status": await self.get_sync_status(),
"timestamp": datetime.utcnow().isoformat()
}
async def check_health_alerts(self, metrics: dict):
"""Проверка критических состояний"""
alerts = []
for metric, value in metrics.items():
threshold = self.alert_thresholds.get(metric)
if threshold and value > threshold:
alerts.append({
"metric": metric,
"value": value,
"threshold": threshold,
"severity": "critical" if value > threshold * 1.2 else "warning"
})
if alerts:
await self.send_health_alerts(alerts)
```
### Performance Analytics
```python
class PerformanceAnalyzer:
def __init__(self):
self.metrics_storage = MetricsStorage()
async def analyze_replication_performance(self) -> dict:
"""Анализ производительности репликации"""
recent_replications = await self.get_recent_replications(hours=24)
analysis = {
"total_replications": len(recent_replications),
"success_rate": self.calculate_success_rate(recent_replications),
"average_time": self.calculate_average_time(recent_replications),
"throughput": self.calculate_throughput(recent_replications),
"failed_replications": self.get_failed_replications(recent_replications)
}
return analysis
async def generate_performance_report(self) -> dict:
"""Генерация отчета о производительности"""
return {
"network_performance": await self.analyze_network_performance(),
"replication_performance": await self.analyze_replication_performance(),
"consensus_performance": await self.analyze_consensus_performance(),
"content_distribution": await self.analyze_content_distribution(),
"peer_performance": await self.analyze_peer_performance()
}
```
## Security Architecture
### Multi-Layer Security Model
```
┌─────────────────────────────────────────┐
│ Application Security │ <- Existing auth & validation
├─────────────────────────────────────────┤
│ Network Security │ <- MY Network specific
├─────────────────────────────────────────┤
│ Transport Security │ <- TLS/mTLS
├─────────────────────────────────────────┤
│ Content Security │ <- Encryption & integrity
└─────────────────────────────────────────┘
```
### Network Security Implementation
```python
class NetworkSecurity:
def __init__(self):
self.node_keypair = self.load_or_generate_keypair()
self.trusted_nodes = set()
self.blacklisted_nodes = set()
async def verify_peer_identity(self, peer_id: str,
signature: str, message: bytes) -> bool:
"""Проверка подлинности пира"""
public_key = await self.get_peer_public_key(peer_id)
if not public_key:
return False
return await self.verify_signature(public_key, signature, message)
async def encrypt_message(self, message: bytes,
recipient_public_key: bytes) -> bytes:
"""Шифрование сообщения для получателя"""
# Используем ECIES для асимметричного шифрования
encrypted = await self.ecies_encrypt(message, recipient_public_key)
return encrypted
async def validate_content_integrity(self, content_hash: str,
content_data: bytes) -> bool:
"""Проверка целостности контента"""
calculated_hash = hashlib.sha256(content_data).hexdigest()
return calculated_hash == content_hash
```
## Scalability Considerations
### Horizontal Scaling Strategies
1. **Sharding по Content Hash**
- Контент распределяется по нодам на основе хеша
- Consistent hashing для равномерного распределения
- Автоматическое перебалансирование при изменении топологии
2. **Hierarchical Network Structure**
- Bootstrap ноды как суперноды
- Региональные кластеры
- Edge ноды для локального кеширования
3. **Adaptive Replication**
- Динамическое изменение количества реплик
- Репликация популярного контента на больше нод
- Удаление неиспользуемого контента
### Resource Management
```python
class ResourceManager:
def __init__(self):
self.storage_limits = {}
self.bandwidth_limits = {}
self.connection_limits = {}
async def allocate_resources(self, operation_type: str,
resource_requirements: dict) -> bool:
"""Выделение ресурсов для операции"""
if not await self.check_available_resources(resource_requirements):
return False
await self.reserve_resources(operation_type, resource_requirements)
return True
async def optimize_resource_usage(self):
"""Оптимизация использования ресурсов"""
# Анализ текущего использования
usage_stats = await self.get_resource_usage_stats()
# Определение возможностей для оптимизации
optimizations = await self.identify_optimizations(usage_stats)
# Применение оптимизаций
for optimization in optimizations:
await self.apply_optimization(optimization)
```
## Disaster Recovery & Fault Tolerance
### Multi-Level Fault Tolerance
```python
class FaultToleranceManager:
async def handle_node_failure(self, failed_node_id: str):
"""Обработка отказа ноды"""
# 1. Обновление routing table
await self.remove_failed_node(failed_node_id)
# 2. Перенаправление трафика
await self.reroute_traffic_from_failed_node(failed_node_id)
# 3. Восстановление реплик
lost_content = await self.identify_lost_content(failed_node_id)
await self.restore_content_replicas(lost_content)
# 4. Уведомление сети об отказе
await self.broadcast_node_failure(failed_node_id)
async def restore_content_replicas(self, lost_content: List[str]):
"""Восстановление потерянных реплик контента"""
for content_hash in lost_content:
# Поиск существующих реплик
available_replicas = await self.find_content_replicas(content_hash)
if len(available_replicas) < self.min_replica_count:
# Создание дополнительных реплик
target_nodes = await self.select_replication_targets(content_hash)
await self.replicate_content(content_hash, target_nodes)
```
Эта архитектура обеспечивает надежную, масштабируемую и безопасную распределенную систему для репликации всех состояний контента с сохранением существующей функциональности системы.
File diff suppressed because it is too large. Load diff
+422
View File
@@ -0,0 +1,422 @@
# MY Network v2.0 - Distributed Content Protocol
## 🌐 Обзор
MY Network - это распределенная система для управления и синхронизации контента между нодами. Протокол обеспечивает:
- **P2P сеть** для обмена данными между нодами
- **Автоматическую синхронизацию** контента
- **Load balancing** на основе метрик нагрузки
- **Веб-интерфейс мониторинга** в хакерском стиле
- **Совместимость** с существующей инфраструктурой
## 🚀 Быстрый запуск
### Минимальный запуск для тестирования:
```bash
# 1. Установить зависимости
pip install -r requirements_new.txt
# 2. Запустить минимальный сервер
python start_my_network.py
```
Откройте http://localhost:8000/api/my/monitor/ для мониторинга.
### Запуск с существующей системой:
```bash
# 1. Использовать совместимые файлы
cp docker-compose.compatible.yml docker-compose.yml
cp .env.compatible .env
# 2. Запустить через Docker
docker-compose up -d
# 3. MY Network автоматически интегрируется
```
## 🏗️ Продакшен развертывание
### Автоматическое развертывание:
```bash
# Сохранить переменные окружения
export DOMAIN="your-domain.com"
export EMAIL="admin@your-domain.com"
# Запустить скрипт развертывания (требует root)
sudo bash deploy_my_network.sh
```
Скрипт автоматически установит:
- ✅ Nginx с SSL (Let's Encrypt)
- ✅ Docker и Docker Compose
- ✅ Firewall и безопасность
- ✅ Systemd сервисы
- ✅ Мониторинг и health checks
### Ручное развертывание:
```bash
# 1. Создать production .env
cp .env.example .env.production
# Отредактировать настройки
# 2. Запустить продакшен контейнеры
docker-compose -f docker-compose.prod.yml up -d
# 3. Настроить nginx
sudo cp nginx.conf /etc/nginx/sites-available/my-network
sudo ln -s /etc/nginx/sites-available/my-network /etc/nginx/sites-enabled/
sudo systemctl restart nginx
```
## 📊 Мониторинг и управление
### Веб-интерфейс:
- **Основной мониторинг**: http://your-domain/api/my/monitor/
- **ASCII статус**: http://your-domain/api/my/monitor/ascii
- **API документация**: http://your-domain/api/docs
### API эндпоинты:
#### Информация о ноде:
```bash
# Статус ноды
curl http://localhost:8000/api/my/node/info
# Подключенные пиры
curl http://localhost:8000/api/my/node/peers
# Статус синхронизации
curl http://localhost:8000/api/my/sync/status
```
#### Управление пирами:
```bash
# Подключиться к пиру
curl -X POST http://localhost:8000/api/my/node/peers/connect \
-H "Content-Type: application/json" \
-d '{"address": "http://peer-node:8001"}'
# Отключиться от пира
curl -X DELETE http://localhost:8000/api/my/node/peers/PEER_ID
```
#### Синхронизация:
```bash
# Запустить синхронизацию
curl -X POST http://localhost:8000/api/my/sync/start
# Реплицировать контент
curl -X POST http://localhost:8000/api/my/content/HASH/replicate \
-H "Content-Type: application/json" \
-d '{"target_nodes": ["node1", "node2"]}'
```
### Системные команды:
```bash
# Управление сервисом
sudo systemctl start my-network
sudo systemctl stop my-network
sudo systemctl restart my-network
sudo systemctl status my-network
# Просмотр логов
sudo journalctl -u my-network -f
tail -f /var/log/my-network/app.log
# Проверка здоровья
/opt/my-network/health_check.sh
# Docker команды
docker-compose logs -f my-network-app
docker-compose ps
```
## 🔧 Конфигурация
### Основные настройки (.env):
```env
# MY Network Configuration
MY_NETWORK_ENABLED=True
MY_NETWORK_NODE_ID=unique-node-id
MY_NETWORK_P2P_PORT=8001
MY_NETWORK_API_PORT=8000
# Bootstrap ноды (JSON массив)
MY_NETWORK_BOOTSTRAP_NODES=["http://bootstrap1:8001", "http://bootstrap2:8001"]
# Настройки синхронизации
SYNC_MAX_CONCURRENT=5
SYNC_TIMEOUT=300
SYNC_RETRY_ATTEMPTS=3
# Настройки пиров
PEER_HEALTH_CHECK_INTERVAL=60
PEER_CONNECTION_TIMEOUT=30
MAX_PEER_CONNECTIONS=50
```
### Bootstrap конфигурация (bootstrap.json):
```json
{
"version": "2.0",
"network_id": "my-network-main",
"bootstrap_nodes": [
{
"node_id": "bootstrap-1",
"address": "https://bootstrap1.my-network.com:8001",
"public_key": "...",
"trusted": true
}
],
"consensus": {
"algorithm": "raft",
"election_timeout": 5000,
"heartbeat_interval": 1000
}
}
```
## 🌍 Архитектура сети
### Компоненты:
1. **Node Service** - основной сервис ноды
2. **Peer Manager** - управление подключениями
3. **Sync Manager** - синхронизация контента
4. **Bootstrap Manager** - управление bootstrap конфигурацией
### Протокол взаимодействия:
```
Нода A Нода B
| |
|--- Handshake ---------> |
|<-- Auth Response ------- |
| |
|--- Content List ------> |
|<-- Missing Content ---- |
| |
|--- File Transfer -----> |
|<-- Confirmation ------- |
```
### Состояния контента:
- **Local** - только на текущей ноде
- **Syncing** - в процессе синхронизации
- **Replicated** - скопирован на другие ноды
- **Verified** - проверена целостность
## 🔒 Безопасность
### Встроенные механизмы:
- **TLS шифрование** для всех соединений
- **Проверка хешей** для целостности файлов
- **Аутентификация пиров** через public key
- **Rate limiting** для предотвращения DDoS
- **Firewall правила** для ограничения доступа
### Рекомендации:
```bash
# Настроить firewall
sudo ufw allow 8000:8010/tcp
sudo ufw allow 8000:8010/udp
# Включить fail2ban
sudo systemctl enable fail2ban
# Регулярные бэкапы
0 2 * * * /opt/my-network/backup.sh
```
## 📈 Мониторинг и алерты
### Метрики:
- **Количество подключенных пиров**
- **Статус синхронизации**
- **Использование ресурсов**
- **Время отклика**
- **Ошибки сети**
### Health checks:
```bash
# HTTP health check
curl -f http://localhost:8000/health
# MY Network specific
curl -f http://localhost:8000/api/my/health
# Detailed status
curl http://localhost:8000/api/my/network/stats
```
### Prometheus интеграция:
```yaml
# prometheus.yml
scrape_configs:
- job_name: 'my-network'
static_configs:
- targets: ['localhost:9090']
metrics_path: '/metrics'
```
## 🐛 Устранение неисправностей
### Частые проблемы:
#### 1. Нода не подключается к пирам:
```bash
# Проверить сетевые соединения
netstat -tulpn | grep 8001
# Проверить firewall
sudo ufw status
# Проверить логи
tail -f /var/log/my-network/app.log
```
#### 2. Синхронизация не работает:
```bash
# Проверить статус синхронизации
curl http://localhost:8000/api/my/sync/status
# Перезапустить синхронизацию
curl -X POST http://localhost:8000/api/my/sync/start
# Проверить доступность целевых нод
curl http://target-node:8001/api/my/health
```
#### 3. Высокое использование ресурсов:
```bash
# Проверить использование CPU/памяти
docker stats my-network-app
# Ограничить ресурсы
docker update --memory=2g --cpus=2 my-network-app
# Настроить параметры синхронизации
echo "SYNC_MAX_CONCURRENT=2" >> .env
```
### Диагностические команды:
```bash
# Проверить все компоненты
curl http://localhost:8000/api/my/health | jq
# Список активных соединений
curl http://localhost:8000/api/my/node/peers | jq
# Статистика сети
curl http://localhost:8000/api/my/network/stats | jq
# ASCII статус (для консоли)
curl http://localhost:8000/api/my/monitor/ascii
```
## 🔄 Обновление системы
### Обновление без downtime:
```bash
# 1. Подготовить новую версию
git pull origin main
# 2. Собрать новый образ
docker-compose build my-network-app
# 3. Rolling update
docker-compose up -d --no-deps my-network-app
# 4. Проверить статус
curl http://localhost:8000/health
```
### Миграция данных:
```bash
# Экспорт данных
docker exec my-network-db mysqldump -u root -p mymusic > backup.sql
# Миграция схемы (если нужно)
docker exec my-network-app python -m alembic upgrade head
# Импорт данных
docker exec -i my-network-db mysql -u root -p mymusic < backup.sql
```
## 📚 Дополнительная документация
- **MY_ARCHITECTURE.md** - детальная архитектура системы
- **MY_PROTOCOL.md** - спецификация протокола
- **MY_NODE_SPEC.md** - технические характеристики нод
- **MY_MONITORING.md** - руководство по мониторингу
## 🤝 Вклад в проект
### Структура проекта:
```
my-uploader-bot/
├── app/
│ ├── core/
│ │ └── my_network/ # MY Network компоненты
│ │ ├── node_service.py
│ │ ├── peer_manager.py
│ │ ├── sync_manager.py
│ │ └── bootstrap_manager.py
│ ├── api/
│ │ └── routes/ # API маршруты
│ │ ├── my_network_routes.py
│ │ └── my_monitoring.py
│ └── templates/ # Web интерфейс
│ └── my_network_monitor.html
├── bootstrap.json # Bootstrap конфигурация
├── start_my_network.py # Быстрый запуск
└── deploy_my_network.sh # Продакшен деплой
```
### Development workflow:
```bash
# 1. Создать ветку для фичи
git checkout -b feature/my-feature
# 2. Разработка с hot reload
python start_my_network.py --debug
# 3. Тестирование
pytest tests/test_my_network.py
# 4. Создать pull request
git push origin feature/my-feature
```
## 📞 Поддержка
Если у вас возникли вопросы или проблемы:
1. Проверьте [Troubleshooting](#-устранение-неисправностей)
2. Посмотрите логи: `tail -f /var/log/my-network/app.log`
3. Проверьте health check: `curl http://localhost:8000/api/my/health`
4. Создайте issue с подробным описанием проблемы
---
**MY Network v2.0** - Distributed Content Protocol
*Decentralized content distribution made simple*
+791
View File
@@ -0,0 +1,791 @@
# MY Network Node Specification
## Обзор MY Network Node
MY Network Node представляет собой расширение существующего my-uploader-bot, добавляющее возможности участия в децентрализованной сети без нарушения текущей функциональности.
## Процесс Запуска и Инициализации Ноды
### 1. Startup Sequence
```python
class MYNetworkNode:
async def initialize(self):
"""Полная инициализация MY Network ноды"""
# Phase 1: Core System Check
await self.verify_core_system()
# Phase 2: Load Configuration
await self.load_configuration()
# Phase 3: Initialize Cryptography
await self.initialize_crypto_system()
# Phase 4: Start Network Services
await self.start_network_services()
# Phase 5: Connect to Bootstrap Nodes
await self.connect_to_bootstrap_nodes()
# Phase 6: Discover Peers
await self.start_peer_discovery()
# Phase 7: Sync Content
await self.start_initial_sync()
# Phase 8: Start Background Services
await self.start_background_services()
logger.info("MY Network Node successfully initialized")
```
### 2. Configuration Loading
```python
async def load_configuration(self):
"""Загрузка конфигурации ноды"""
# Загрузка bootstrap.json
self.bootstrap_config = await self.load_bootstrap_config()
# Загрузка локальной конфигурации
self.node_config = await self.load_node_config()
# Объединение конфигураций
self.config = {
**self.bootstrap_config,
**self.node_config,
"node_id": self.generate_or_load_node_id(),
"startup_time": datetime.utcnow().isoformat()
}
```
### 3. Crypto System Initialization
```python
async def initialize_crypto_system(self):
"""Инициализация криптографической системы"""
# Загрузка или генерация ключевой пары ноды
self.node_keypair = await self.load_or_generate_keypair()
# Создание подписывающего объекта
self.signer = Ed25519Signer(self.node_keypair.private_key)
# Инициализация шифрования транспорта
self.transport_crypto = TransportCrypto(self.node_keypair)
# Проверка криптографической системы
await self.verify_crypto_system()
```
## Подключение к Bootstrap Нодам
### 1. Bootstrap Discovery Process
```python
class BootstrapConnector:
async def connect_to_bootstrap_nodes(self):
"""Подключение к bootstrap нодам"""
bootstrap_nodes = self.config["bootstrap_nodes"]
connected_nodes = []
for node_info in bootstrap_nodes:
try:
connection = await self.establish_connection(node_info)
if connection:
connected_nodes.append(connection)
logger.info(f"Connected to bootstrap node: {node_info['id']}")
except Exception as e:
logger.warning(f"Failed to connect to bootstrap node {node_info['id']}: {e}")
if len(connected_nodes) == 0:
raise BootstrapConnectionError("Failed to connect to any bootstrap nodes")
# Сохранение подключений
self.bootstrap_connections = connected_nodes
# Запрос информации о сети
await self.request_network_info()
```
### 2. Network Information Exchange
```python
async def request_network_info(self):
"""Запрос информации о сети от bootstrap нод"""
network_info = {}
for connection in self.bootstrap_connections:
try:
# Запрос списка активных нод
peers_response = await connection.request("get_active_peers")
network_info["peers"] = peers_response.get("peers", [])
# Запрос статистики сети
stats_response = await connection.request("get_network_stats")
network_info["stats"] = stats_response.get("stats", {})
# Запрос популярного контента
content_response = await connection.request("get_popular_content")
network_info["popular_content"] = content_response.get("content", [])
break # Достаточно получить от одной ноды
except Exception as e:
logger.warning(f"Failed to get network info from bootstrap: {e}")
continue
self.network_info = network_info
```
## Механизм Обнаружения Других Нод
### 1. Peer Discovery Algorithm
```python
class PeerDiscovery:
def __init__(self, node: MYNetworkNode):
self.node = node
self.discovered_peers = {}
self.discovery_interval = 60 # секунды
async def start_discovery(self):
"""Запуск процесса обнаружения пиров"""
# Обнаружение через bootstrap ноды
await self.discover_through_bootstrap()
# DHT-based discovery
await self.discover_through_dht()
# Multicast discovery (для локальной сети)
await self.discover_through_multicast()
# Запуск периодического обнаружения
asyncio.create_task(self.periodic_discovery())
async def discover_through_bootstrap(self):
"""Обнаружение через bootstrap ноды"""
for connection in self.node.bootstrap_connections:
try:
# Запрос списка пиров
response = await connection.request("discover_peers", {
"requesting_node": self.node.node_id,
"max_peers": 50,
"exclude_nodes": list(self.discovered_peers.keys())
})
# Обработка найденных пиров
for peer_info in response.get("peers", []):
await self.process_discovered_peer(peer_info)
except Exception as e:
logger.error(f"Peer discovery through bootstrap failed: {e}")
async def discover_through_dht(self):
"""Обнаружение через DHT"""
# Поиск нод ответственных за наш ключ
our_key_hash = self.node.calculate_key_hash(self.node.node_id)
responsible_nodes = await self.find_responsible_nodes(our_key_hash)
for node_info in responsible_nodes:
await self.process_discovered_peer(node_info)
async def process_discovered_peer(self, peer_info: dict):
"""Обработка обнаруженного пира"""
peer_id = peer_info["node_id"]
# Проверка, что это не мы сами
if peer_id == self.node.node_id:
return
# Проверка, что пир не в черном списке
if peer_id in self.node.blacklisted_peers:
return
# Попытка подключения
try:
connection = await self.establish_peer_connection(peer_info)
if connection:
self.discovered_peers[peer_id] = {
"info": peer_info,
"connection": connection,
"discovered_at": datetime.utcnow(),
"status": "connected"
}
logger.info(f"Successfully connected to peer: {peer_id}")
except Exception as e:
logger.warning(f"Failed to connect to peer {peer_id}: {e}")
```
### 2. Peer Connection Management
```python
class PeerConnectionManager:
def __init__(self):
self.connections = {}
self.connection_limits = {
"max_outbound": 50,
"max_inbound": 100,
"max_per_ip": 3
}
async def establish_peer_connection(self, peer_info: dict) -> Optional[PeerConnection]:
"""Установка соединения с пиром"""
peer_id = peer_info["node_id"]
peer_address = peer_info["address"]
# Проверка лимитов соединений
if not await self.check_connection_limits(peer_info):
return None
try:
# Создание TCP соединения
connection = await self.create_tcp_connection(peer_address)
# MY Network handshake
handshake_success = await self.perform_handshake(connection, peer_info)
if not handshake_success:
await connection.close()
return None
# Создание MY Network peer connection
peer_connection = PeerConnection(
peer_id=peer_id,
connection=connection,
peer_info=peer_info
)
# Регистрация соединения
self.connections[peer_id] = peer_connection
# Запуск обработчика сообщений
asyncio.create_task(self.handle_peer_messages(peer_connection))
return peer_connection
except Exception as e:
logger.error(f"Failed to establish connection to {peer_id}: {e}")
return None
async def perform_handshake(self, connection: Connection, peer_info: dict) -> bool:
"""Выполнение MY Network handshake"""
# Отправка handshake сообщения
handshake_msg = {
"type": "handshake",
"node_id": self.node.node_id,
"public_key": self.node.public_key_hex,
"network_version": "1.0.0",
"supported_features": ["content_sync", "consensus", "dht"],
"timestamp": datetime.utcnow().isoformat()
}
# Подписание сообщения
handshake_msg["signature"] = await self.node.sign_message(handshake_msg)
# Отправка handshake
await connection.send_message(handshake_msg)
# Ожидание ответа
response = await connection.receive_message(timeout=10)
# Проверка ответа
if response.get("type") != "handshake_response":
return False
# Проверка подписи пира
peer_signature = response.get("signature")
if not await self.verify_peer_signature(peer_info, response, peer_signature):
return False
return True
```
## Протокол Синхронизации Контента
### 1. Content Sync Protocol
```python
class ContentSyncProtocol:
def __init__(self, node: MYNetworkNode):
self.node = node
self.sync_queue = asyncio.Queue()
self.sync_stats = {
"synced_content": 0,
"failed_syncs": 0,
"bytes_synced": 0
}
async def start_initial_sync(self):
"""Начальная синхронизация контента"""
logger.info("Starting initial content synchronization")
# Получение списка доступного контента от пиров
available_content = await self.discover_available_content()
# Определение контента для синхронизации
content_to_sync = await self.select_content_for_sync(available_content)
# Добавление в очередь синхронизации
for content_hash in content_to_sync:
await self.sync_queue.put(content_hash)
# Запуск worker'ов синхронизации
workers = []
for i in range(3): # 3 параллельных worker'а
worker = asyncio.create_task(self.sync_worker(f"worker-{i}"))
workers.append(worker)
# Ожидание завершения начальной синхронизации
await self.sync_queue.join()
# Остановка worker'ов
for worker in workers:
worker.cancel()
logger.info(f"Initial sync completed. Synced {self.sync_stats['synced_content']} items")
async def sync_worker(self, worker_id: str):
"""Worker для синхронизации контента"""
while True:
try:
# Получение контента для синхронизации
content_hash = await self.sync_queue.get()
# Синхронизация контента
success = await self.sync_single_content(content_hash)
if success:
self.sync_stats["synced_content"] += 1
else:
self.sync_stats["failed_syncs"] += 1
# Отметка о завершении задачи
self.sync_queue.task_done()
except asyncio.CancelledError:
break
except Exception as e:
logger.error(f"Sync worker {worker_id} error: {e}")
self.sync_queue.task_done()
async def sync_single_content(self, content_hash: str) -> bool:
"""Синхронизация одного элемента контента"""
try:
# Проверка, есть ли уже этот контент локально
local_content = await StoredContent.get_by_hash(self.node.db_session, content_hash)
if local_content:
return True # Уже есть
# Поиск пиров с этим контентом
peers_with_content = await self.find_peers_with_content(content_hash)
if not peers_with_content:
logger.warning(f"No peers found with content: {content_hash}")
return False
# Выбор оптимального пира для загрузки
selected_peer = await self.select_optimal_peer(peers_with_content)
# Загрузка метаданных контента
content_metadata = await self.download_content_metadata(selected_peer, content_hash)
if not content_metadata:
return False
# Загрузка данных контента
content_data = await self.download_content_data(selected_peer, content_hash)
if not content_data:
return False
# Проверка целостности
if not await self.verify_content_integrity(content_hash, content_data):
logger.error(f"Content integrity check failed: {content_hash}")
return False
# Сохранение контента локально
await self.store_content_locally(content_metadata, content_data)
# Обновление статистики
self.sync_stats["bytes_synced"] += len(content_data)
logger.info(f"Successfully synced content: {content_hash}")
return True
except Exception as e:
logger.error(f"Failed to sync content {content_hash}: {e}")
return False
```
### 2. Differential Sync Algorithm
```python
class DifferentialSync:
async def perform_differential_sync(self, peer_id: str):
"""Дифференциальная синхронизация с пиром"""
# Получение локального state
local_state = await self.get_local_content_state()
# Запрос state от пира
peer_state = await self.request_peer_content_state(peer_id)
# Вычисление различий
diff = await self.calculate_state_diff(local_state, peer_state)
# Синхронизация различий
if diff["missing_locally"]:
await self.sync_missing_content(peer_id, diff["missing_locally"])
if diff["missing_on_peer"]:
await self.send_missing_content(peer_id, diff["missing_on_peer"])
# Разрешение конфликтов
if diff["conflicts"]:
await self.resolve_content_conflicts(peer_id, diff["conflicts"])
async def calculate_state_diff(self, local_state: dict, peer_state: dict) -> dict:
"""Вычисление различий между состояниями"""
local_hashes = set(local_state.keys())
peer_hashes = set(peer_state.keys())
missing_locally = peer_hashes - local_hashes
missing_on_peer = local_hashes - peer_hashes
common_content = local_hashes & peer_hashes
# Проверка конфликтов в общем контенте
conflicts = []
for content_hash in common_content:
local_meta = local_state[content_hash]
peer_meta = peer_state[content_hash]
if local_meta["version"] != peer_meta["version"]:
conflicts.append({
"content_hash": content_hash,
"local_version": local_meta["version"],
"peer_version": peer_meta["version"]
})
return {
"missing_locally": list(missing_locally),
"missing_on_peer": list(missing_on_peer),
"conflicts": conflicts
}
```
## Обработка Всех Состояний Контента
### 1. Multi-State Content Handler
```python
class MultiStateContentHandler:
def __init__(self, node: MYNetworkNode):
self.node = node
self.state_processors = {
"encrypted": EncryptedContentProcessor(),
"decrypted": DecryptedContentProcessor(),
"preview": PreviewContentProcessor()
}
async def process_content_group(self, content_group_id: str):
"""Обработка группы связанных состояний контента"""
# Обнаружение всех состояний в группе
content_states = await self.discover_content_states(content_group_id)
# Обработка каждого состояния
for state in content_states:
processor = self.state_processors.get(state.type)
if processor:
await processor.process_state(state)
# Проверка целостности связей между состояниями
await self.verify_state_relationships(content_states)
# Репликация всех состояний
await self.replicate_content_group(content_states)
async def discover_content_states(self, content_group_id: str) -> List[ContentState]:
"""Обнаружение всех состояний контента в группе"""
# Поиск корневого контента
root_content = await StoredContent.get_by_id(
self.node.db_session, content_group_id
)
if not root_content:
return []
states = [ContentState(
content=root_content,
type=self.determine_content_state_type(root_content)
)]
# Поиск связанных состояний через relationships
relationships = await self.get_content_relationships(content_group_id)
for rel in relationships:
related_content = await StoredContent.get_by_id(
self.node.db_session, rel.child_content_id
)
if related_content:
states.append(ContentState(
content=related_content,
type=rel.relationship_type,
parent_id=content_group_id
))
return states
def determine_content_state_type(self, content: StoredContent) -> str:
"""Определение типа состояния контента"""
if content.encrypted:
return "encrypted"
elif "preview" in content.tags:
return "preview"
else:
return "decrypted"
```
### 2. State-Specific Processors
```python
class EncryptedContentProcessor:
async def process_state(self, state: ContentState):
"""Обработка зашифрованного состояния"""
content = state.content
# Проверка наличия ключа шифрования
if not content.encryption_key_id:
logger.warning(f"Encrypted content without key: {content.id}")
return
# Проверка доступности ключа
encryption_key = await EncryptionKey.get_by_id(
self.node.db_session, content.encryption_key_id
)
if not encryption_key or not encryption_key.is_valid:
logger.warning(f"Invalid encryption key for content: {content.id}")
return
# Обработка зашифрованного контента
await self.process_encrypted_content(content, encryption_key)
class DecryptedContentProcessor:
async def process_state(self, state: ContentState):
"""Обработка расшифрованного состояния"""
content = state.content
# Проверка связи с зашифрованной версией
if state.parent_id:
encrypted_content = await StoredContent.get_by_id(
self.node.db_session, state.parent_id
)
if encrypted_content and encrypted_content.encrypted:
# Проверка соответствия с зашифрованной версией
await self.verify_encrypted_decrypted_relationship(
encrypted_content, content
)
# Обработка расшифрованного контента
await self.process_decrypted_content(content)
class PreviewContentProcessor:
async def process_state(self, state: ContentState):
"""Обработка preview состояния"""
content = state.content
# Проверка, что это действительно preview
if "preview" not in content.tags:
content.add_tag("preview")
# Проверка размера (preview должен быть меньше оригинала)
if state.parent_id:
original_content = await StoredContent.get_by_id(
self.node.db_session, state.parent_id
)
if original_content and content.file_size >= original_content.file_size:
logger.warning(f"Preview size is not smaller than original: {content.id}")
# Обработка preview контента
await self.process_preview_content(content)
```
## Node Status Monitoring
### 1. Real-time Status Monitoring
```python
class NodeStatusMonitor:
def __init__(self, node: MYNetworkNode):
self.node = node
self.status_data = {}
self.monitoring_interval = 30 # секунды
async def start_monitoring(self):
"""Запуск мониторинга статуса ноды"""
# Запуск периодического сбора метрик
asyncio.create_task(self.collect_metrics_loop())
# Запуск health check'ов
asyncio.create_task(self.health_check_loop())
# Запуск отправки статуса в сеть
asyncio.create_task(self.broadcast_status_loop())
async def collect_current_status(self) -> dict:
"""Сбор текущего статуса ноды"""
return {
"node_id": self.node.node_id,
"uptime": self.get_uptime_seconds(),
"peer_count": len(self.node.peer_connections),
"content_count": await self.get_local_content_count(),
"storage_usage": await self.get_storage_usage(),
"network_stats": await self.get_network_stats(),
"sync_status": await self.get_sync_status(),
"resource_usage": await self.get_resource_usage(),
"timestamp": datetime.utcnow().isoformat()
}
async def get_sync_status(self) -> dict:
"""Получение статуса синхронизации"""
return {
"is_syncing": self.node.sync_manager.is_syncing,
"sync_progress": self.node.sync_manager.get_progress(),
"last_sync": self.node.sync_manager.last_sync_time,
"pending_sync_items": self.node.sync_manager.get_pending_count(),
"sync_errors": self.node.sync_manager.get_error_count()
}
```
### 2. Node Performance Metrics
```python
class NodePerformanceMetrics:
def __init__(self):
self.metrics_history = []
self.max_history_size = 1000
async def collect_performance_metrics(self) -> dict:
"""Сбор метрик производительности"""
metrics = {
"cpu_usage": psutil.cpu_percent(),
"memory_usage": psutil.virtual_memory().percent,
"disk_usage": psutil.disk_usage('/').percent,
"network_io": await self.get_network_io_stats(),
"content_operations": await self.get_content_operations_stats(),
"p2p_performance": await self.get_p2p_performance_stats(),
"consensus_performance": await self.get_consensus_performance_stats()
}
# Сохранение в историю
self.metrics_history.append({
"timestamp": datetime.utcnow(),
"metrics": metrics
})
# Ограничение размера истории
if len(self.metrics_history) > self.max_history_size:
self.metrics_history.pop(0)
return metrics
async def get_p2p_performance_stats(self) -> dict:
"""Статистика производительности P2P"""
return {
"avg_latency": await self.calculate_avg_peer_latency(),
"message_throughput": await self.get_message_throughput(),
"connection_success_rate": await self.get_connection_success_rate(),
"bandwidth_usage": await self.get_bandwidth_usage()
}
```
## Configuration Management
### 1. Dynamic Configuration
```python
class NodeConfigManager:
def __init__(self, node: MYNetworkNode):
self.node = node
self.config_file = "node_config.json"
self.config_watchers = []
async def load_configuration(self) -> dict:
"""Загрузка конфигурации ноды"""
# Загрузка базовой конфигурации
base_config = await self.load_base_config()
# Загрузка bootstrap конфигурации
bootstrap_config = await self.load_bootstrap_config()
# Загрузка локальных настроек
local_config = await self.load_local_config()
# Объединение конфигураций
merged_config = {
**base_config,
**bootstrap_config,
**local_config
}
# Валидация конфигурации
await self.validate_configuration(merged_config)
return merged_config
async def update_configuration(self, new_config: dict):
"""Обновление конфигурации на лету"""
# Валидация новой конфигурации
await self.validate_configuration(new_config)
# Создание backup старой конфигурации
old_config = self.node.config.copy()
try:
# Применение новой конфигурации
self.node.config.update(new_config)
# Уведомление watchers об изменениях
for watcher in self.config_watchers:
await watcher.on_config_changed(old_config, new_config)
# Сохранение конфигурации
await self.save_configuration(new_config)
except Exception as e:
# Откат к старой конфигурации в случае ошибки
self.node.config = old_config
raise ConfigurationError(f"Failed to update configuration: {e}")
```
Эта спецификация определяет полный жизненный цикл MY Network ноды от инициализации до мониторинга производительности, обеспечивая надежную работу в децентрализованной сети.
+265
View File
@@ -0,0 +1,265 @@
# MY Network Protocol Specification
## Обзор
MY Network представляет собой децентрализованный overlay протокол для распределенной репликации и синхронизации контента поверх существующей системы my-uploader-bot. Протокол сохраняет все существующие состояния и функциональность, добавляя P2P синхронизацию с кворумным консенсусом.
## Принципы Overlay Protocol
### 1. Совместимость с Существующей Системой
- **Полное сохранение** всех состояний [`StoredContent`](app/core/models/content.py:61)
- **Неизменность** существующих API endpoints
- **Прозрачная интеграция** без нарушения работы текущих клиентов
- **Обратная совместимость** со всеми версиями API
### 2. Состояния Контента в MY Network
#### Поддерживаемые Состояния
```
encrypted: Boolean - Статус шифрования контента
decrypted: Virtual - Расшифрованная версия (через decrypted_content_id)
preview: Virtual - Превью-версия для публичного доступа
```
MY Network реплицирует **все состояния** контента:
- **Encrypted Content** - зашифрованные данные с [`encryption_key_id`](app/core/models/content.py:157)
- **Decrypted Content** - расшифрованные версии через связи
- **Preview Content** - публичные превью для демонстрации
- **Metadata** - все метаданные включая теги, описание, медиа-информацию
#### Связи Между Состояниями
```sql
-- Существующая структура StoredContent поддерживает связи
SELECT * FROM stored_content sc1
LEFT JOIN stored_content sc2 ON sc1.decrypted_content_id = sc2.id;
```
### 3. P2P Синхронизация Architecture
#### Кворумный Консенсус
```
Минимальный кворум: 3 ноды
Консенсус требует: 2/3 + 1 подтверждений
Timeout для консенсуса: 30 секунд
```
#### Алгоритм Репликации
1. **Content Discovery** - обнаружение нового контента
2. **Integrity Check** - проверка целостности через хеш
3. **Quorum Voting** - голосование за принятие контента
4. **Replication** - репликация на кворум нод
5. **Confirmation** - подтверждение успешной репликации
### 4. Bootstrap Configuration
#### Структура bootstrap.json
```json
{
"version": "1.0.0",
"network_id": "my-network-mainnet",
"bootstrap_nodes": [
{
"id": "node-001",
"address": "my://192.168.1.100:8080",
"public_key": "ed25519:AAAA...",
"region": "eu-west-1",
"weight": 100
}
],
"consensus": {
"min_quorum": 3,
"consensus_threshold": 0.67,
"timeout_seconds": 30,
"retry_attempts": 3
},
"sync_settings": {
"sync_interval": 60,
"max_batch_size": 100,
"compression": "gzip",
"encryption": "aes-256-gcm"
}
}
```
## API Endpoints для MY Network
### Core MY Protocol Endpoints
#### Node Management
```
GET /api/my/node/status - Статус текущей ноды
GET /api/my/node/peers - Список подключенных пиров
POST /api/my/node/connect - Подключение к новому пиру
POST /api/my/node/disconnect - Отключение от пира
```
#### Content Synchronization
```
GET /api/my/sync/status - Статус синхронизации
POST /api/my/sync/request - Запрос синхронизации контента
GET /api/my/sync/conflicts - Список конфликтов синхронизации
POST /api/my/sync/resolve - Разрешение конфликтов
```
#### Quorum & Consensus
```
GET /api/my/quorum/status - Статус кворума
POST /api/my/quorum/vote - Голосование за контент
GET /api/my/quorum/results - Результаты голосования
POST /api/my/consensus/propose - Предложение изменений
```
#### Content Distribution
```
GET /api/my/content/{hash} - Получение контента через MY Network
GET /api/my/content/{hash}/peers - Список пиров с контентом
POST /api/my/content/announce - Анонс нового контента
GET /api/my/content/search - Поиск контента в сети
```
### Integration API Endpoints
#### Health Check & Discovery
```
GET /api/my/health - Проверка здоровья MY ноды
GET /api/my/discovery/nodes - Обнаружение новых нод
POST /api/my/discovery/announce - Анонс собственной ноды
```
#### Metrics & Analytics
```
GET /api/my/metrics/network - Метрики сети
GET /api/my/metrics/content - Метрики контента
GET /api/my/metrics/performance - Метрики производительности
```
## Protocol Messages
### MY Network Message Types
#### Node Communication
```protobuf
message NodeHandshake {
string node_id = 1;
string public_key = 2;
string network_version = 3;
repeated string supported_features = 4;
int64 timestamp = 5;
}
message PeerInfo {
string node_id = 1;
string address = 2;
int32 connection_count = 3;
int64 last_seen = 4;
float reputation_score = 5;
}
```
#### Content Sync Messages
```protobuf
message ContentAnnouncement {
string content_hash = 1;
int64 file_size = 2;
string content_type = 3;
bool encrypted = 4;
string encryption_key_id = 5;
repeated string tags = 6;
int64 timestamp = 7;
}
message SyncRequest {
repeated string content_hashes = 1;
string requesting_node = 2;
int32 priority = 3;
int64 timestamp = 4;
}
```
#### Consensus Messages
```protobuf
message QuorumVote {
string content_hash = 1;
string voter_node_id = 2;
bool vote = 3; // true = accept, false = reject
string signature = 4;
int64 timestamp = 5;
}
message ConsensusResult {
string content_hash = 1;
int32 votes_for = 2;
int32 votes_against = 3;
bool consensus_reached = 4;
repeated string participating_nodes = 5;
}
```
## Security Model
### Cryptographic Security
- **Node Identity**: Ed25519 ключи для идентификации нод
- **Message Signing**: Все сообщения подписываются отправителем
- **Content Integrity**: SHA-256 хеши для проверки целостности
- **Transport Security**: TLS 1.3 для всех сетевых соединений
### Access Control
- **Content Access**: Сохранение существующих прав доступа
- **Network Participation**: Whitelist/blacklist механизмы
- **Rate Limiting**: Защита от спама и DoS атак
- **Reputation System**: Система репутации для узлов
## MY Network Service Layer
### Service Architecture
```
┌─────────────────────┐
│ Existing API │ <- Без изменений
├─────────────────────┤
│ MY Network Layer │ <- Новый overlay слой
├─────────────────────┤
│ StoredContent │ <- Существующая модель
└─────────────────────┘
```
### Service Components
- **MY Node Manager** - управление статусом ноды
- **P2P Communication** - межузловое взаимодействие
- **Content Replicator** - репликация контента
- **Consensus Engine** - механизм консенсуса
- **Sync Coordinator** - координация синхронизации
## Performance Considerations
### Scalability Targets
- **Network Size**: До 1000 активных нод
- **Content Volume**: До 10TB на ноду
- **Sync Throughput**: 100 MB/s между нодами
- **Consensus Latency**: < 5 секунд для кворума
### Optimization Strategies
- **Content Chunking** - разбиение больших файлов
- **Delta Sync** - синхронизация только изменений
- **Compression** - сжатие передаваемых данных
- **Caching** - кеширование популярного контента
- **Load Balancing** - балансировка нагрузки между нодами
## Future Roadmap
### Phase 1: Core Protocol (Q1 2025)
- [x] Protocol specification
- [ ] Basic P2P communication
- [ ] Simple consensus mechanism
- [ ] Bootstrap node implementation
### Phase 2: Advanced Features (Q2 2025)
- [ ] Content deduplication
- [ ] Advanced routing algorithms
- [ ] Performance optimizations
- [ ] Monitoring and analytics
### Phase 3: Enterprise Features (Q3 2025)
- [ ] Multi-region replication
- [ ] Enterprise security features
- [ ] SLA guarantees
- [ ] Professional support tools
+84
View File
@@ -0,0 +1,84 @@
# 🚀 MY Network - Быстрый старт
## ⚡ Установка в две команды
### 📋 Требования
- **Сервер:** Ubuntu 20.04+ / Debian 11+
- **Права:** Root доступ
- **Домен:** Настроенный A-запись
- **Email:** Для SSL сертификата
---
## 🥇 Команда 1: Установка сервиса
```bash
curl -O https://raw.githubusercontent.com/your-repo/my-uploader-bot/main/install_service.sh
sudo bash install_service.sh
```
**Что происходит:**
- ✅ Обновление системы
- ✅ Установка Docker, Python, зависимостей
- ✅ Настройка MY Network сервиса
- ✅ Запуск на порту 15100
- ✅ Создание systemd сервиса
**Результат:** Базовый сервис работает на `http://your-server:15100`
---
## 🥈 Команда 2: Защита и SSL
```bash
sudo bash secure_service.sh
```
**Что происходит:**
- 🔒 SSL сертификат (Let's Encrypt)
- 🌐 Настройка Nginx с proxy
- 🔥 Настройка UFW firewall
- 🚫 Установка Fail2ban
- 📊 Система мониторинга
**Результат:** Защищенный сервис на `https://your-domain.com`
---
## 🎯 Проверка работы
```bash
# Проверка API
curl https://your-domain.com/api/my/health
# Веб-мониторинг
https://your-domain.com/api/my/monitor/
# Статус сервисов
systemctl status my-network nginx fail2ban
```
---
## 📚 Полная документация
- **[DOCS_RU.md](DOCS_RU.md)** - Полная документация с архитектурой
- **[MY_NETWORK_README.md](MY_NETWORK_README.md)** - Техническое описание
- **[bootstrap.json](bootstrap.json)** - Конфигурация сети
---
## 🆘 Поддержка
```bash
# Логи
journalctl -u my-network -f
# Конфигурация
cat /opt/my-network-config.txt
# Перезапуск
systemctl restart my-network nginx
```
**Готово!** 🎉 Ваша MY Network работает и защищена!
+504
View File
@@ -0,0 +1,504 @@
# My Uploader Bot - Comprehensive File Upload & Blockchain Integration System
A modern, scalable file upload and management system with blockchain integration, built with async Python and enterprise-grade security.
## 🚀 Features
### Core Features
- **Chunked File Upload**: Support for large files with resume capability
- **Multi-Storage Backend**: Local, S3-compatible storage with automatic failover
- **File Processing**: Automatic image optimization, thumbnail generation, media conversion
- **Content Management**: Version control, metadata management, search functionality
- **User Management**: JWT authentication, API keys, session management
### Blockchain Integration
- **TON Blockchain**: Wallet creation, transaction management, balance tracking
- **Smart Contracts**: Interaction with TON smart contracts
- **NFT Support**: NFT collection indexing and management
- **DeFi Integration**: Staking positions, token balances, yield farming
### Enterprise Features
- **Security**: Rate limiting, CORS, CSP, input validation, file encryption
- **Monitoring**: Prometheus metrics, Grafana dashboards, health checks
- **Caching**: Redis integration with intelligent cache management
- **Background Services**: Async task processing, blockchain indexing
- **API Documentation**: OpenAPI/Swagger with interactive interface
## 🏗️ Architecture
### Technology Stack
- **Backend**: Python 3.11+, Sanic (async web framework)
- **Database**: PostgreSQL 15+ with async SQLAlchemy 2.0
- **Cache**: Redis 7+ with connection pooling
- **Blockchain**: TON SDK for blockchain operations
- **Storage**: Local filesystem with S3-compatible support
- **Monitoring**: Prometheus, Grafana, structured logging
- **Deployment**: Docker Compose with multi-stage builds
### System Architecture
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Load Balancer │ │ Grafana │ │ Prometheus │
│ (Nginx) │ │ (Monitoring) │ │ (Metrics) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Sanic App │◄──►│ Redis │ │ PostgreSQL │
│ (API Server) │ │ (Cache) │ │ (Database) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Background │ │ File Storage │ │ TON Blockchain │
│ Services │ │ (Local/S3/CDN) │ │ Integration │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
## 🔧 Installation & Setup
### Prerequisites
- Python 3.11+
- PostgreSQL 15+
- Redis 7+
- Docker & Docker Compose (recommended)
### Quick Start with Docker
1. **Clone the repository**:
```bash
git clone https://github.com/your-org/my-uploader-bot.git
cd my-uploader-bot
```
2. **Create environment file**:
```bash
cp .env.example .env
# Edit .env with your configuration
```
3. **Start services**:
```bash
docker-compose -f docker-compose.new.yml up -d
```
4. **Initialize database**:
```bash
docker-compose -f docker-compose.new.yml exec app alembic upgrade head
```
5. **Create admin user**:
```bash
docker-compose -f docker-compose.new.yml exec app python -m app.scripts.create_admin
```
### Manual Installation
1. **Install dependencies**:
```bash
# Using Poetry (recommended)
poetry install
# Or using pip
pip install -r requirements_new.txt
```
2. **Set up database**:
```bash
# Create database
createdb myuploader
# Run migrations
alembic upgrade head
```
3. **Configure Redis**:
```bash
# Start Redis with custom config
redis-server config/redis.conf
```
4. **Start application**:
```bash
# Development mode
python -m app
# Production mode
gunicorn app:create_app --bind 0.0.0.0:8000 --worker-class sanic.worker.GunicornWorker
```
## ⚙️ Configuration
### Environment Variables
**Database Configuration**:
```bash
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/myuploader
DB_POOL_SIZE=20
DB_MAX_OVERFLOW=30
```
**Redis Configuration**:
```bash
REDIS_URL=redis://localhost:6379/0
REDIS_POOL_SIZE=20
REDIS_POOL_MAX_CONNECTIONS=100
```
**Security Configuration**:
```bash
SECRET_KEY=your-super-secret-key-here
JWT_SECRET_KEY=your-jwt-secret-key
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
```
**Storage Configuration**:
```bash
STORAGE_BACKEND=local # or s3, gcs, azure
STORAGE_PATH=/app/uploads
MAX_FILE_SIZE=104857600 # 100MB
ALLOWED_FILE_TYPES=image,video,audio,document
```
**Blockchain Configuration**:
```bash
TON_NETWORK=mainnet # or testnet
TON_API_KEY=your-ton-api-key
TON_WALLET_VERSION=v4
```
### Configuration Files
**Redis Configuration** (`config/redis.conf`):
- Optimized for caching workload
- Memory management and persistence settings
- Security and performance tuning
**Prometheus Configuration** (`monitoring/prometheus.yml`):
- Scraping configuration for all services
- Alert rules and metric collection
- Storage and retention settings
## 📊 API Documentation
### Interactive Documentation
- **Swagger UI**: http://localhost:8000/docs
- **ReDoc**: http://localhost:8000/redoc
- **OpenAPI JSON**: http://localhost:8000/openapi.json
### Authentication Methods
1. **JWT Bearer Token**:
```bash
curl -H "Authorization: Bearer <token>" \
https://api.myuploader.com/api/v1/content/
```
2. **API Key**:
```bash
curl -H "X-API-Key: <api_key>" \
https://api.myuploader.com/api/v1/content/
```
3. **Session Cookie**:
```bash
curl -b "session=<cookie>" \
https://api.myuploader.com/api/v1/content/
```
### Key Endpoints
**Authentication**:
- `POST /api/v1/auth/register` - User registration
- `POST /api/v1/auth/login` - User login
- `POST /api/v1/auth/refresh` - Token refresh
- `DELETE /api/v1/auth/logout` - User logout
**Content Management**:
- `GET /api/v1/content/` - List content
- `POST /api/v1/content/` - Create content
- `GET /api/v1/content/{id}` - Get content details
- `PUT /api/v1/content/{id}` - Update content
- `DELETE /api/v1/content/{id}` - Delete content
**File Upload**:
- `POST /api/v1/storage/upload/initiate` - Start upload
- `POST /api/v1/storage/upload/chunk` - Upload chunk
- `POST /api/v1/storage/upload/complete` - Complete upload
- `GET /api/v1/storage/download/{id}` - Download file
**Blockchain**:
- `POST /api/v1/blockchain/wallet/create` - Create wallet
- `GET /api/v1/blockchain/wallet/{id}` - Get wallet info
- `POST /api/v1/blockchain/transaction/send` - Send transaction
- `GET /api/v1/blockchain/transaction/{hash}` - Get transaction status
## 🛡️ Security
### Security Features
- **Authentication**: Multi-factor authentication support
- **Authorization**: Role-based access control (RBAC)
- **Input Validation**: Comprehensive request validation
- **Rate Limiting**: Per-user and per-endpoint limits
- **File Security**: Virus scanning, type validation, encryption
- **Network Security**: CORS, CSP, HTTPS enforcement
### Security Best Practices
1. **Environment Variables**: Store sensitive data in environment variables
2. **Database Security**: Use connection pooling, parameterized queries
3. **File Upload Security**: Validate file types, scan for malware
4. **API Security**: Implement rate limiting, request validation
5. **Monitoring**: Track security events and anomalies
### Audit Logging
All security-relevant events are logged:
- Authentication attempts
- Authorization failures
- File upload/download events
- API key usage
- Blockchain transactions
## 📈 Monitoring & Observability
### Metrics Collection
- **Application Metrics**: Request counts, response times, error rates
- **System Metrics**: CPU, memory, disk usage
- **Database Metrics**: Connection pool, query performance
- **Cache Metrics**: Hit rates, memory usage
- **Blockchain Metrics**: Transaction status, wallet balances
### Dashboards
- **Application Dashboard**: Request metrics, error rates
- **Infrastructure Dashboard**: System resources, service health
- **Database Dashboard**: Query performance, connection pools
- **Security Dashboard**: Failed logins, rate limits
### Alerting Rules
- High error rates (>5% for 5 minutes)
- High response times (>2s for 95th percentile)
- Database connection issues
- High memory usage (>90%)
- Failed blockchain transactions
## 🔄 Background Services
### File Conversion Service
- **Image Processing**: Resize, optimize, generate thumbnails
- **Video Processing**: Transcode, extract thumbnails
- **Document Processing**: Extract metadata, generate previews
- **Retry Logic**: Automatic retry for failed conversions
### Blockchain Indexer Service
- **Transaction Monitoring**: Track pending transactions
- **Wallet Balance Updates**: Sync wallet balances
- **NFT Indexing**: Track NFT collections and transfers
- **Event Processing**: Process blockchain events
## 🚀 Deployment
### Docker Deployment
1. **Production Build**:
```bash
docker build -f Dockerfile.new --target production -t my-uploader-bot:latest .
```
2. **Deploy with Compose**:
```bash
docker-compose -f docker-compose.new.yml up -d
```
3. **Health Checks**:
```bash
curl http://localhost:8000/health
```
### Kubernetes Deployment
1. **Create ConfigMaps**:
```bash
kubectl create configmap app-config --from-env-file=.env
```
2. **Deploy Application**:
```bash
kubectl apply -f k8s/
```
3. **Check Status**:
```bash
kubectl get pods -l app=my-uploader-bot
```
### Production Considerations
1. **Database**: Use managed PostgreSQL service
2. **Cache**: Use managed Redis service
3. **Storage**: Use S3-compatible object storage
4. **Load Balancer**: Use cloud load balancer
5. **SSL/TLS**: Use Let's Encrypt or cloud SSL
6. **Monitoring**: Use managed monitoring service
## 🧪 Testing
### Running Tests
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov=app
# Run specific test file
pytest tests/test_auth.py
# Run integration tests
pytest tests/integration/
```
### Test Categories
- **Unit Tests**: Individual function/method tests
- **Integration Tests**: Service integration tests
- **API Tests**: HTTP endpoint tests
- **Database Tests**: Database operation tests
- **Security Tests**: Security vulnerability tests
## 🔍 Development
### Development Setup
```bash
# Install dev dependencies
poetry install --dev
# Pre-commit hooks
pre-commit install
# Run linting
black app/
isort app/
mypy app/
# Database migrations
alembic revision --autogenerate -m "Description"
alembic upgrade head
```
### Code Quality Tools
- **Black**: Code formatting
- **isort**: Import sorting
- **mypy**: Type checking
- **bandit**: Security scanning
- **pytest**: Testing framework
### Contributing Guidelines
1. Fork the repository
2. Create feature branch
3. Write tests for new features
4. Ensure all tests pass
5. Run security scans
6. Submit pull request
## 📝 Migration Guide
### From v1.x to v2.x
1. **Database Migration**:
```bash
# Backup existing database
pg_dump myuploader > backup.sql
# Run new migrations
alembic upgrade head
```
2. **Configuration Updates**:
- Update environment variables
- Migrate Redis configuration
- Update storage configuration
3. **API Changes**:
- Authentication endpoints changed
- New blockchain endpoints added
- Response format updates
## 🐛 Troubleshooting
### Common Issues
**Database Connection Issues**:
```bash
# Check database connectivity
psql -h localhost -U postgres -d myuploader
# Check connection pool
docker-compose logs db
```
**Redis Connection Issues**:
```bash
# Test Redis connection
redis-cli ping
# Check Redis logs
docker-compose logs redis
```
**File Upload Issues**:
```bash
# Check storage permissions
ls -la /app/uploads
# Check disk space
df -h
```
**Blockchain Issues**:
```bash
# Check TON network status
curl https://toncenter.com/api/v2/getAddressInformation
# Check wallet balance
curl -X GET /api/v1/blockchain/wallet/{wallet_id}
```
### Performance Optimization
1. **Database Optimization**:
- Add indexes for frequently queried columns
- Optimize query patterns
- Use connection pooling
2. **Cache Optimization**:
- Implement cache warming
- Use appropriate TTL values
- Monitor cache hit rates
3. **File Storage Optimization**:
- Use CDN for static files
- Implement file compression
- Use efficient storage backends
## 📚 Additional Resources
- **API Documentation**: https://docs.myuploader.com
- **SDK Documentation**: https://sdk.myuploader.com
- **Community Forum**: https://community.myuploader.com
- **GitHub Repository**: https://github.com/your-org/my-uploader-bot
- **Docker Images**: https://hub.docker.com/r/myuploader/app
## 📄 License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🤝 Support
- **Email**: support@myuploader.com
- **Discord**: https://discord.gg/myuploader
- **GitHub Issues**: https://github.com/your-org/my-uploader-bot/issues
- **Documentation**: https://docs.myuploader.com
---
**Built with ❤️ by the My Uploader Bot Team**
+271
View File
@@ -0,0 +1,271 @@
# Совместимое обновление My Uploader Bot
## 📋 Обзор
Данное обновление добавляет **асинхронную архитектуру** и **Redis кэширование** к существующему проекту My Uploader Bot, **сохраняя полную совместимость** с текущей MariaDB базой данных и существующими данными.
## 🎯 Что добавлено
### ✅ Новые возможности
- **Асинхронная работа с базой данных** (SQLAlchemy async)
- **Redis кэширование** для ускорения работы
- **Улучшенная система конфигурации**
- **Расширенные модели данных**
- **Система мониторинга и здоровья сервисов**
### ✅ Сохранена совместимость
- **MariaDB 11.2** остается основной базой данных
- **Все существующие данные** сохраняются
- **Существующие пути к файлам** (/Storage/) не изменяются
- **Все сервисы** (app, indexer, ton_daemon, license_index, convert_process) работают как прежде
- **Порт 15100** остается прежним
## 📁 Файлы для совместимого обновления
### Основные конфигурационные файлы:
```
my-uploader-bot/
├── docker-compose.compatible.yml # Совместимая версия docker-compose
├── .env.compatible # Совместимые переменные окружения
├── requirements.compatible.txt # Совместимые зависимости Python
└── MIGRATION_GUIDE.md # Подробное руководство по миграции
```
### Новые модули приложения:
```
my-uploader-bot/app/core/
├── database_compatible.py # Async база данных с MariaDB
├── config_compatible.py # Расширенная конфигурация
├── cache.py # Система Redis кэширования
└── models/
├── base_compatible.py # Базовые модели для MariaDB
├── user_compatible.py # Пользовательские модели
└── content_compatible.py # Модели контента
```
## 🚀 Быстрый старт
### 1. Создайте резервные копии
```bash
# Остановите текущие контейнеры
docker-compose down
# Сделайте бэкап
cp docker-compose.yml docker-compose.yml.backup
cp .env .env.backup
```
### 2. Используйте совместимые файлы
```bash
# Замените основные файлы на совместимые версии
cp docker-compose.compatible.yml docker-compose.yml
cp .env.compatible .env
cp requirements.compatible.txt requirements.txt
# Перенесите ваши пароли и ключи в новый .env
# Отредактируйте .env и укажите ваши значения:
# MYSQL_PASSWORD=ваш_текущий_пароль
# SECRET_KEY=ваш_секретный_ключ
```
### 3. Обновите код приложения
```bash
# Замените модули на совместимые версии
cp app/core/database_compatible.py app/core/database.py
cp app/core/config_compatible.py app/core/config.py
# Новый модуль кэширования уже добавлен как app/core/cache.py
```
### 4. Запустите обновленную систему
```bash
# Запустите все сервисы
docker-compose up -d
# Проверьте статус
docker-compose ps
# Проверьте логи
docker-compose logs -f app
```
## 🔧 Конфигурация
### Основные изменения в .env:
```env
# Существующие настройки MariaDB (сохраняются)
MYSQL_HOST=maria_db
MYSQL_PORT=3306
MYSQL_USER=myuploader
MYSQL_PASSWORD=ваш_пароль
MYSQL_DATABASE=myuploader
# Новые настройки Redis (добавляются)
REDIS_ENABLED=true
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=0
# Настройки кэширования (новые)
CACHE_ENABLED=true
CACHE_DEFAULT_TTL=300
CACHE_USER_TTL=600
CACHE_CONTENT_TTL=1800
# Улучшенные настройки базы данных (новые)
DATABASE_POOL_SIZE=20
DATABASE_MAX_OVERFLOW=30
DATABASE_POOL_TIMEOUT=30
```
### Изменения в docker-compose.yml:
```yaml
# Добавлен новый сервис Redis
redis:
image: redis:7-alpine
container_name: redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --appendonly yes
# Все остальные сервисы остаются без изменений
```
## 📊 Мониторинг и проверка
### Проверка работоспособности:
```bash
# API статус
curl http://localhost:15100/health
# База данных
curl http://localhost:15100/api/v1/health/database
# Redis кэш
curl http://localhost:15100/api/v1/health/cache
```
### Мониторинг Redis:
```bash
# Подключение к Redis
docker-compose exec redis redis-cli
# Информация о памяти
docker-compose exec redis redis-cli info memory
# Статистика
docker-compose exec redis redis-cli info stats
```
### Мониторинг MariaDB:
```bash
# Подключения к базе
docker-compose exec maria_db mysql -u root -p -e "SHOW STATUS LIKE 'Threads_connected';"
# Размер базы данных
docker-compose exec maria_db mysql -u root -p -e "
SELECT table_schema as 'Database',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as 'Size_MB'
FROM information_schema.tables
WHERE table_schema = 'myuploader';"
```
## 🎁 Преимущества обновления
### Производительность:
- **До 3x быстрее** работа с базой данных благодаря async
- **Мгновенный доступ** к часто используемым данным через Redis
- **Оптимизированные запросы** с пулом соединений
### Масштабируемость:
- **Async архитектура** для обработки большого количества запросов
- **Redis кэширование** снижает нагрузку на базу данных
- **Гибкая конфигурация** пулов соединений
### Надежность:
- **Автоматическое переподключение** к базе данных
- **Fallback режимы** при недоступности Redis
- **Улучшенное логирование** и мониторинг
### Удобство разработки:
- **Современный async/await** синтаксис
- **Типизация** с Pydantic
- **Декораторы для кэширования**
- **Автоматическая сериализация/десериализация**
## 🔄 Откат изменений
Если нужно вернуться к предыдущей версии:
```bash
# Остановите обновленную систему
docker-compose down
# Восстановите файлы из бэкапа
cp docker-compose.yml.backup docker-compose.yml
cp .env.backup .env
# Запустите старую версию
docker-compose up -d
```
## 📈 Использование кэширования в коде
### Декораторы для автоматического кэширования:
```python
from app.core.cache import cache_user_data, cache_content_data
@cache_user_data(ttl=600) # Кэш на 10 минут
async def get_user_profile(user_id: int):
# Данные автоматически кэшируются
pass
@cache_content_data(ttl=1800) # Кэш на 30 минут
async def get_file_metadata(file_id: int):
# Метаданные файлов кэшируются
pass
```
### Ручное управление кэшем:
```python
from app.core.cache import cache
# Сохранить данные
await cache.set("user:123:profile", user_data, ttl=600)
# Получить данные
profile = await cache.get("user:123:profile")
# Удалить из кэша
await cache.delete("user:123:profile")
# Массовые операции
await cache.set_multiple({
"key1": "value1",
"key2": "value2"
}, ttl=300)
```
## 🆘 Поддержка
При возникновении проблем:
1. **Проверьте логи**: `docker-compose logs -f app`
2. **Проверьте статус сервисов**: `docker-compose ps`
3. **Изучите MIGRATION_GUIDE.md** для детального руководства
4. **Используйте откат** при критических проблемах
## 📝 Примечания
- **Все существующие данные сохраняются** и остаются доступными
- **API остается полностью совместимым** со старыми клиентами
- **Файловая структура не изменяется** (/Storage/ остается прежним)
- **Порты и сетевые настройки сохраняются**
- **Redis является опциональным** - система работает и без него
Это **эволюционное обновление**, а не революционное изменение архитектуры. Ваша существующая система получает современные возможности, оставаясь полностью совместимой.
+139
View File
@@ -0,0 +1,139 @@
# Руководство по удаленной диагностике MY Network сервера
## Проблема
- SSH недоступен на порту 22 (Connection refused)
- Nginx работает на порту 80, но возвращает 404 для всех запросов
- Приложения на портах 3000, 5000, 8080 недоступны
## Диагностика на сервере (выполнить локально)
### 1. Проверить статус служб
```bash
# Проверить статус Docker
sudo systemctl status docker
# Проверить статус MyUploader service
sudo systemctl status myuploader
# Проверить запущенные контейнеры
sudo docker ps -a
# Проверить логи контейнеров
sudo docker logs uploader-bot-app-1
sudo docker logs uploader-bot-postgres-1
sudo docker logs uploader-bot-nginx-1
```
### 2. Проверить сетевые соединения
```bash
# Проверить какие порты слушает система
sudo netstat -tulpn | grep LISTEN
# Проверить статус nginx
sudo nginx -t
sudo systemctl status nginx
# Проверить конфигурацию nginx
sudo cat /etc/nginx/sites-enabled/default
```
### 3. Проверить Docker Compose
```bash
# Перейти в директорию проекта
cd /home/myuploader/my-uploader-bot
# Проверить статус compose
sudo docker-compose -f docker-compose.production.yml ps
# Посмотреть логи всех сервисов
sudo docker-compose -f docker-compose.production.yml logs --tail=50
# Перезапустить сервисы
sudo docker-compose -f docker-compose.production.yml down
sudo docker-compose -f docker-compose.production.yml up -d
```
### 4. Проверить SSH
```bash
# Проверить статус SSH
sudo systemctl status ssh
# Проверить конфигурацию SSH
sudo cat /etc/ssh/sshd_config | grep -E "Port|PasswordAuthentication|PubkeyAuthentication"
# Перезапустить SSH если нужно
sudo systemctl restart ssh
```
### 5. Проверить брандмауэр
```bash
# Проверить статус UFW
sudo ufw status
# Если UFW активен, проверить правила
sudo ufw status numbered
# Разрешить SSH (если заблокирован)
sudo ufw allow 22/tcp
```
### 6. Быстрое восстановление
```bash
# Если сервисы не работают, запустить быстрое восстановление
cd /home/myuploader/my-uploader-bot
sudo ./diagnose.sh
# Проверить health API приложения
curl -I http://localhost:3000/api/health
curl -I http://localhost:5000/api/health
```
## Возможные решения
### Проблема с nginx proxy
Если nginx возвращает 404, проверить файл `/etc/nginx/sites-enabled/default`:
```bash
sudo cat /etc/nginx/sites-enabled/default
```
Должен содержать:
```nginx
location /api/ {
proxy_pass http://localhost:3000/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
```
### Проблема с Docker
Если контейнеры не запущены:
```bash
cd /home/myuploader/my-uploader-bot
sudo docker-compose -f docker-compose.production.yml up -d --build
```
### Проблема с SSH
Если SSH заблокирован файрволлом:
```bash
sudo ufw allow 22/tcp
sudo systemctl restart ssh
```
## Команды для отправки результатов
После выполнения диагностики, отправьте результаты:
```bash
# Сохранить всю диагностику в файл
echo "=== DOCKER STATUS ===" > diagnosis.txt
sudo docker ps -a >> diagnosis.txt
echo "=== DOCKER LOGS ===" >> diagnosis.txt
sudo docker-compose -f docker-compose.production.yml logs --tail=20 >> diagnosis.txt
echo "=== NGINX STATUS ===" >> diagnosis.txt
sudo systemctl status nginx >> diagnosis.txt
echo "=== SSH STATUS ===" >> diagnosis.txt
sudo systemctl status ssh >> diagnosis.txt
echo "=== NETWORK PORTS ===" >> diagnosis.txt
sudo netstat -tulpn | grep LISTEN >> diagnosis.txt
# Просмотреть файл
cat diagnosis.txt
+157
View File
@@ -0,0 +1,157 @@
# Устранение 502 ошибки MY Uploader Bot
## 🚨 Если получаете 502 Bad Gateway
Ошибка 502 означает, что nginx работает, но не может подключиться к backend приложению.
## 🔍 Быстрая диагностика
### 1. Запустите диагностический скрипт:
```bash
sudo /home/myuploader/uploader-bot/diagnose.sh my-public-node-3.projscale.dev
```
### 2. Проверьте статус контейнеров:
```bash
cd /home/myuploader/uploader-bot
sudo docker-compose -f docker-compose.production.yml ps
```
### 3. Проверьте логи приложения:
```bash
sudo docker-compose -f docker-compose.production.yml logs -f app
```
## 🛠️ Частые решения
### Решение 1: Приложение еще запускается
```bash
# Подождите 2-3 минуты и проверьте снова
sleep 180
curl -v https://your-domain.com/health
```
### Решение 2: Перезапуск сервисов
```bash
cd /home/myuploader/uploader-bot
sudo docker-compose -f docker-compose.production.yml restart app
```
### Решение 3: Полная перезагрузка
```bash
cd /home/myuploader/uploader-bot
sudo docker-compose -f docker-compose.production.yml down
sudo docker-compose -f docker-compose.production.yml up -d
```
### Решение 4: Проверка базы данных
```bash
# Проверка PostgreSQL
sudo docker-compose -f docker-compose.production.yml exec postgres pg_isready -U my_user -d my_uploader_db
# Перезапуск базы данных если нужно
sudo docker-compose -f docker-compose.production.yml restart postgres redis
```
## 🔍 Детальная диагностика
### Проверка локальных портов:
```bash
# API приложения (должен отвечать)
curl http://localhost:15100/health
# Nginx (должен перенаправлять)
curl -I http://localhost
# Проверка подключения к базе
sudo docker-compose -f docker-compose.production.yml exec app python -c "
import asyncpg
import asyncio
async def test():
try:
conn = await asyncpg.connect('postgresql://my_user:PASSWORD@postgres:5432/my_uploader_db')
await conn.close()
print('✅ База данных доступна')
except Exception as e:
print(f'❌ Ошибка подключения к БД: {e}')
asyncio.run(test())
"
```
### Проверка конфигурации nginx:
```bash
sudo docker-compose -f docker-compose.production.yml exec nginx nginx -t
```
### Просмотр логов в реальном времени:
```bash
# Все сервисы
sudo docker-compose -f docker-compose.production.yml logs -f
# Только основное приложение
sudo docker-compose -f docker-compose.production.yml logs -f app
# Только nginx
sudo docker-compose -f docker-compose.production.yml logs -f nginx
```
## 🚀 Тестирование после исправления
```bash
# 1. Проверьте статус всех контейнеров
sudo docker-compose -f docker-compose.production.yml ps
# 2. Проверьте health endpoints
curl http://localhost:15100/health
curl https://your-domain.com/health
# 3. Проверьте основные endpoints
curl -I https://your-domain.com/
curl https://your-domain.com/api/my/bootstrap/config
```
## 📞 Если проблема не решается
1. **Соберите диагностическую информацию:**
```bash
sudo /home/myuploader/uploader-bot/diagnose.sh your-domain.com > diagnostic_report.txt
```
2. **Сохраните логи:**
```bash
sudo docker-compose -f docker-compose.production.yml logs --tail=100 > all_logs.txt
```
3. **Проверьте ресурсы системы:**
```bash
docker stats --no-stream
df -h
free -h
```
## ⚡ Экстренное восстановление
Если ничего не помогает:
```bash
# 1. Полная остановка
sudo systemctl stop my-uploader-bot
sudo docker-compose -f docker-compose.production.yml down -v
# 2. Очистка и перезапуск
sudo docker system prune -f
sudo docker-compose -f docker-compose.production.yml pull
sudo docker-compose -f docker-compose.production.yml up -d --build
# 3. Проверка через 5 минут
sleep 300
curl -v https://your-domain.com/health
```
## 🎯 Ожидаемый результат
После успешного исправления:
- `curl http://localhost:15100/health` возвращает 200 OK
- `curl https://your-domain.com/health` возвращает 200 OK
- Все контейнеры в статусе "Up"
- В логах нет критических ошибок
+152
View File
@@ -0,0 +1,152 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from tonsdk.boc import Cell\n",
"from base64 import b64decode"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"s = Cell.one_from_boc(b64decode(\n",
" \"te6cckECCwEAAWcAAotUkdCMcWNw723qPXgUdCcgt8COtmF/zIqTQpNUO7Hx3cFkE6SAHuuAXC2ImbR2RbW6eaLmYTaiOFzd06Q3v6GEw1xpHOswAQUCAaACAwALAECPDRgIAQHRBABHgB7rgFwtiJm0dkW1unmi5mE2ojhc3dOkN7+hhMNcaRzrJOIQAgAGBwD6aHR0cHM6Ly9teS1wdWJsaWMtbm9kZS0xLnByb2pzY2FsZS5kZXYvYXBpL3YxLjUvc3RvcmFnZS85S0h5RHAyYUppRTRuaG1uOExxazd4dmZxeWpwQXdXR1dYU2ozMkNVQW04V3NLdVFLSkJlTktIV0prZzhyZFloTm82MzcDAAgJCgBYajZGa3ZtREN1RUJhOHhrTDlpV1NSem1peXAxSGhYMlJkUFNFWWZpb1JRMWgAAABYblJUVW96dGJBcXF0Z25EWEN1cFU4UXRZWmFtY1dxdjlSTDQ0UURYbVpvQVbtCcTY\"\n",
"))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"s = s.begin_parse()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'AddressEQD3XALhbETNo7ItrdPNFzMJtRHC5u6dIb39DCYa40jnWcql'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"s.read_uint(32)\n",
"s.read_uint(256)\n",
"'Address' + s.read_msg_addr().to_string(1, 1, 1)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"ename": "ValueError",
"evalue": "invalid literal for int() with base 10: 'b'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[0;32mIn[7], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mAddress\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m+\u001b[39m s\u001b[38;5;241m.\u001b[39mread_msg_addr()\u001b[38;5;241m.\u001b[39mto_string(\u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m1\u001b[39m, \u001b[38;5;241m1\u001b[39m)\n",
"File \u001b[0;32m/opt/anaconda3/lib/python3.12/site-packages/tonsdk/boc/_slice.py:93\u001b[0m, in \u001b[0;36mSlice.read_msg_addr\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 91\u001b[0m workchain_id \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mhex\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_int(\u001b[38;5;241m8\u001b[39m))\u001b[38;5;241m.\u001b[39mreplace(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m0x\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m 92\u001b[0m hashpart \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mread_bytes(\u001b[38;5;241m32\u001b[39m)\u001b[38;5;241m.\u001b[39mhex()\n\u001b[0;32m---> 93\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m Address(workchain_id \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m:\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m+\u001b[39m hashpart)\n",
"File \u001b[0;32m/opt/anaconda3/lib/python3.12/site-packages/tonsdk/utils/_address.py:87\u001b[0m, in \u001b[0;36mAddress.__init__\u001b[0;34m(self, any_form)\u001b[0m\n\u001b[1;32m 84\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(arr) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[1;32m 85\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidAddressError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid address \u001b[39m\u001b[38;5;132;01m{\u001b[39;00many_form\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 87\u001b[0m wc \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mint\u001b[39m(arr[\u001b[38;5;241m0\u001b[39m])\n\u001b[1;32m 88\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m wc \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m0\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m wc \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 89\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidAddressError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid address wc \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mwc\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n",
"\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'b'"
]
}
],
"source": [
"'Address' + s.read_msg_addr().to_string(1, 1, 1)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"s = Cell.one_from_boc('b5ee9c7201020b0100016700028b5491d08c716370ef6dea3d7814742720b7c08eb6617fcc8a934293543bb1f1ddc16413a4801eeb805c2d8899b47645b5ba79a2e66136a2385cddd3a437bfa184c35c691ceb3001020201a0030402000607000b00408f0d18080101d1050047801eeb805c2d8899b47645b5ba79a2e66136a2385cddd3a437bfa184c35c691ceb24e21000fa68747470733a2f2f6d792d7075626c69632d6e6f64652d312e70726f6a7363616c652e6465762f6170692f76312e352f73746f726167652f394b4879447032614a6945346e686d6e384c716b3778766671796a70417757475758536a33324355416d3857734b75514b4a42654e4b48574a6b6738726459684e6f363337030008090a00586a36466b766d44437545426138786b4c39695753527a6d697970314868583252645053455966696f52513168000000586e5254556f7a746241717174676e445843757055385174595a616d6357717639524c34345144586d5a6f4156')\n",
"s = s.begin_parse()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"s.read_uint(256)\n",
"s.read_uint(2)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'0b11'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bin(3)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "base",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
+189
View File
@@ -0,0 +1,189 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Загрузка и стриминг файла</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
section { margin-bottom: 40px; }
label { display: block; margin-bottom: 5px; }
input, button { margin-bottom: 10px; }
#log { border: 1px solid #ccc; padding: 10px; max-height: 200px; overflow-y: auto; background: #f9f9f9; }
</style>
</head>
<body>
<h1>Загрузка и стриминг файла</h1>
<section id="uploadSection">
<h2>Загрузка файла</h2>
<label for="uploadFile">Выберите файл для загрузки:</label>
<input type="file" id="uploadFile">
<br>
<button id="uploadBtn">Загрузить файл</button>
<div id="uploadResult"></div>
</section>
<section id="streamSection">
<h2>Стриминг файла</h2>
<label for="fileHashInput">Введите file_hash:</label>
<input type="text" id="fileHashInput" placeholder="Введите hash">
<br>
<button id="loadFileBtn">Загрузить файл для стриминга</button>
<div id="mediaContainer" style="margin-top:20px;"></div>
</section>
<section id="logSection">
<h2>Лог</h2>
<div id="log"></div>
</section>
<script>
// Base URL for endpoints
const BASE_URL = "https://my-public-node-1.projscale.dev/api/v1.5/storage";
// Append log message to log div
function appendLog(message) {
const logDiv = document.getElementById('log');
const p = document.createElement('p');
p.textContent = message;
logDiv.appendChild(p);
}
// Upload file in chunks (max 80 MB per chunk) without computing file hash
async function uploadFileInChunks(file) {
const maxChunkSize = 80 * 1024 * 1024; // 80 MB
let offset = 0;
let uploadId = null;
appendLog("Starting file upload...");
while (offset < file.size) {
const chunk = file.slice(offset, Math.min(offset + maxChunkSize, file.size));
appendLog(`Uploading chunk starting at byte ${offset}`);
// Prepare headers for the chunk upload
const headers = {
"X-File-Name": btoa(unescape(encodeURIComponent(file.name))), // File name in base64
"X-Chunk-Start": offset.toString(),
"Content-Type": file.type || "application/octet-stream"
};
if (uploadId) {
headers["X-Upload-ID"] = uploadId;
}
// Set header to indicate the last chunk if this is the final part of the file
if (offset + chunk.size >= file.size) {
headers["X-Last-Chunk"] = "1";
}
const response = await fetch(BASE_URL, {
method: "POST",
headers: headers,
body: chunk
});
if (!response.ok) {
const errorData = await response.json();
appendLog(`Chunk upload failed: ${errorData.error}`);
throw new Error(`Upload failed at offset ${offset}: ${errorData.error}`);
}
const resultData = await response.json();
// Save uploadId from first response if not set
if (!uploadId && resultData.upload_id) {
uploadId = resultData.upload_id;
}
// If final response contains content_id, upload is complete
if (resultData.content_id) {
appendLog(`Upload complete. File ID: ${resultData.content_id}`);
return resultData;
}
// Update offset based on server-reported current size
if (resultData.current_size !== undefined) {
offset = resultData.current_size;
appendLog(`Server reports current_size: ${offset}`);
} else {
appendLog("Unexpected response from server, missing current_size.");
throw new Error("Missing current_size in response");
}
}
}
// Upload button event listener
document.getElementById('uploadBtn').addEventListener('click', async () => {
const fileInput = document.getElementById('uploadFile');
const uploadResult = document.getElementById('uploadResult');
uploadResult.textContent = "";
if (!fileInput.files || fileInput.files.length === 0) {
uploadResult.textContent = "Пожалуйста, выберите файл.";
return;
}
const file = fileInput.files[0];
try {
const resultData = await uploadFileInChunks(file);
uploadResult.textContent = `Файл загружен успешно. content_sha256: ${resultData.content_sha256}`;
} catch (err) {
uploadResult.textContent = "Ошибка при загрузке файла.";
}
});
// Load file for streaming (remains unchanged)
document.getElementById('loadFileBtn').addEventListener('click', async () => {
const fileHash = document.getElementById('fileHashInput').value.trim();
const mediaContainer = document.getElementById('mediaContainer');
mediaContainer.innerHTML = "";
if (!fileHash) {
mediaContainer.textContent = "Пожалуйста, введите file_hash.";
return;
}
const fileUrl = `${BASE_URL}/${fileHash}`;
appendLog(`Fetching file info for hash: ${fileHash}`);
try {
const headResponse = await fetch(fileUrl, { method: "HEAD" });
if (!headResponse.ok) {
mediaContainer.textContent = "Файл не найден.";
appendLog("File not found during HEAD request.");
return;
}
const contentType = headResponse.headers.get("Content-Type") || "";
appendLog(`Content-Type: ${contentType}`);
let mediaElement;
if (contentType.startsWith("image/")) {
mediaElement = document.createElement("img");
mediaElement.style.maxWidth = "100%";
} else if (contentType.startsWith("video/")) {
mediaElement = document.createElement("video");
mediaElement.controls = true;
mediaElement.style.maxWidth = "100%";
} else if (contentType.startsWith("audio/")) {
mediaElement = document.createElement("audio");
mediaElement.controls = true;
} else {
mediaElement = document.createElement("a");
mediaElement.textContent = "Скачать файл";
}
if (mediaElement.tagName === "A") {
mediaElement.href = fileUrl;
mediaElement.download = "";
} else {
mediaElement.src = fileUrl;
}
mediaContainer.appendChild(mediaElement);
appendLog("Media element created and added to the page.");
} catch (err) {
mediaContainer.textContent = "Ошибка при загрузке файла.";
appendLog(`Error during file streaming: ${err}`);
}
});
</script>
</body>
</html>