montana/Русский/Сеть/ПИРИНГОВАЯ_БЕЛАЯ_КНИГА.md

406 lines
11 KiB
Markdown
Raw Normal View History

# Montana Protocol — P2P Network Specification
# Техническая спецификация пиринговой сети
**Version:** 2.0
**Status:** MAINNET
**Date:** 2026-01-23
**Authors:** Alejandro Montana
---
## Abstract
Настоящий документ описывает архитектуру пиринговой сети Montana Protocol. Сеть обеспечивает распространение подписей присутствия, выбор активного мастера и защиту от изоляции узлов.
---
## 1. Архитектура сети
### 1.1 Топология
Montana Protocol использует фиксированную топологию из 5 узлов:
```
┌─────────────┐
│ amsterdam │ ← PRIMARY (позиция 0)
│ 72.56.102.240│
└──────┬──────┘
┌─────────────────┼─────────────────┐
│ │ │
┌────▼────┐ ┌────▼────┐ ┌─────▼────┐
│ moscow │ │ almaty │ │ spb │
│176.124..│ │91.200...│ │188.225...│
└────┬────┘ └────┬────┘ └────┬─────┘
│ │ │
└────────────────┼────────────────┘
┌──────▼──────┐
│ novosibirsk │
│147.45.147...│
└─────────────┘
```
### 1.2 Типы узлов
| Тип | Описание | Реализация |
|-----|----------|------------|
| **Full Node** | Полный узел сети с Telegram polling | junomontanaagibot.py |
| **Health Server** | HTTP endpoint для проверки здоровья | leader_election.py:8889 |
### 1.3 Порты
| Порт | Протокол | Назначение |
|------|----------|------------|
| 22 | SSH | Администрирование |
| 8889 | HTTP | Health check endpoint |
| 443 | HTTPS | Fallback проверка |
---
## 2. Leader Election Protocol
### 2.1 Алгоритм выбора мастера
Детерминированный выбор мастера на основе позиции в цепочке:
```python
# leader_election.py:326-349
BOT_CHAIN = [
("amsterdam", "72.56.102.240"), # позиция 0
("moscow", "176.124.208.93"), # позиция 1
("almaty", "91.200.148.93"), # позиция 2
("spb", "188.225.58.98"), # позиция 3
("novosibirsk", "147.45.147.247"), # позиция 4
]
def am_i_the_master():
for name, ip in BOT_CHAIN:
if name == my_node_name:
return True # Я первый живой — я мастер
if check_node_health(ip):
return False # Узел выше меня жив
return False
```
### 2.2 Health Check Protocol
HTTP запрос к `/health` endpoint:
```python
# leader_election.py:102-134
def check_node_health(ip: str) -> bool:
try:
url = f"http://{ip}:8889/health"
response = requests.get(url, timeout=5)
return response.status_code == 200
except:
return False
```
**Response format:**
```json
{
"status": "healthy",
"node": "moscow",
"uptime": 3600,
"is_master": false
}
```
### 2.3 Failover Timing
| Событие | Время |
|---------|-------|
| Health check interval | 5 секунд |
| Request timeout | 5 секунд |
| Max failover time | < 10 секунд |
| Startup delay | 7-15 секунд (рандом) |
---
## 3. Message Types
### 3.1 Telegram Polling
Только мастер-узел выполняет polling Telegram API:
```python
# junomontanaagibot.py
async def start_polling():
if not am_i_the_master():
return # Standby режим
await application.run_polling(
drop_pending_updates=True,
allowed_updates=Update.ALL_TYPES
)
```
### 3.2 Presence Proof
Подпись присутствия (ML-DSA-65):
```python
# time_bank.py:271-327
message = f"MONTANA_PRESENCE_V1:{timestamp}:{prev_hash}:{pubkey}:{t2_index}"
signature = ML_DSA_65.sign(private_key, message.encode())
proof_hash = SHA256(message || signature)
```
| Поле | Размер | Описание |
|------|--------|----------|
| version | 20 B | "MONTANA_PRESENCE_V1" |
| timestamp | 8 B | Unix timestamp |
| prev_hash | 64 B | SHA256 предыдущего proof |
| pubkey | 1952 B | ML-DSA-65 public key |
| t2_index | 8 B | Номер τ₂ слайса |
| signature | 3309 B | ML-DSA-65 подпись |
---
## 4. Защита от Eclipse
### 4.1 Стратегия
Eclipse-атака — изоляция узла от честной сети. Защита обеспечивается:
1. **Фиксированная топология** — узлы знают друг друга заранее
2. **Множественные проверки** — ping + TCP fallback
3. **Географическое распределение** — 5 регионов
### 4.2 Multi-method Health Check
```python
# leader_election.py:102-134
def check_node_health(ip: str) -> bool:
# 1. HTTP health endpoint
try:
response = requests.get(f"http://{ip}:8889/health", timeout=5)
if response.status_code == 200:
return True
except:
pass
# 2. Fallback: TCP port check (SSH)
try:
sock = socket.create_connection((ip, 22), timeout=5)
sock.close()
return True
except:
pass
# 3. Fallback: TCP port check (HTTPS)
try:
sock = socket.create_connection((ip, 443), timeout=5)
sock.close()
return True
except:
pass
return False
```
---
## 5. Защита от атак
### 5.1 Random Failover
При обнаружении атаки цепочка перемешивается:
```python
# leader_election.py:395-430
def shuffle_chain_on_attack():
if not attack_detector.is_under_attack():
return
shuffled = list(BOT_CHAIN)
random.shuffle(shuffled)
healthy_nodes = [
(name, ip) for name, ip in shuffled
if check_node_health(ip)
]
BOT_CHAIN = healthy_nodes # Новый порядок
```
**Пример:**
```
Нормальный режим:
amsterdam → moscow → almaty → spb → novosibirsk
После атаки:
spb → novosibirsk → almaty → moscow
(amsterdam исключён как атакованный)
```
### 5.2 Attack Detection Metrics
```python
# leader_election.py:190-232
class AttackDetector:
cpu_threshold = 80.0 # %
network_threshold = 100 MB/s # входящий трафик
max_failures = 10 # подряд
response_time_threshold = 5.0 # секунд
```
---
## 6. Синхронизация состояния
### 6.1 Breathing Sync
Git-синхронизация каждые 12 секунд:
```
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Inhale │────▶│ Work │────▶│ Exhale │
│git pull │ │ 12 sec │ │git push │
└─────────┘ └─────────┘ └─────────┘
▲ │
└───────────────────────────────┘
```
**Исходный код:** [breathing_sync.py](../Бот/breathing_sync.py)
### 6.2 Синхронизируемые данные
| Данные | Путь | Формат |
|--------|------|--------|
| База данных | data/montana.db | SQLite |
| События | data/events.jsonl | JSON Lines |
| Конфигурация | *.py | Python |
---
## 7. Сетевые метрики
### 7.1 Health Status
```python
# junomontanaagibot.py:997-1051
def health_check() -> Dict:
return {
"status": "healthy" | "degraded" | "under_attack",
"uptime": int,
"metrics": {
"cpu_percent": float, # скользящее среднее
"memory_percent": float,
"disk_percent": float,
"active_connections": int,
"blocked_ips": int,
"suspicious_ips": int
}
}
```
### 7.2 Пороги статусов
| Статус | Условие |
|--------|---------|
| healthy | cpu < 90% AND mem < 90% AND suspicious < 5 |
| degraded | (cpu > 90% OR mem > 90%) × 3 подряд |
| under_attack | attack_detector.under_attack = True |
---
## 8. Деплой и обновление
### 8.1 Rolling Deploy
```bash
# deploy_nodes.sh
./deploy_nodes.sh # По одному узлу, 20 сек между ними
./deploy_nodes.sh --fast # Все сразу (downtime!)
./deploy_nodes.sh --node X # Только узел X
```
### 8.2 Порядок деплоя
1. Обновить amsterdam (PRIMARY)
2. Ждать 20 секунд (failover time)
3. Обновить moscow
4. Ждать 20 секунд
5. ... остальные узлы
### 8.3 Верификация
```bash
# Проверка хэшей на всех узлах
for ip in 72.56.102.240 176.124.208.93 ...; do
ssh root@$ip "md5sum /root/bot/junomontanaagibot.py"
done
```
**Ожидаемый результат:** все хэши идентичны.
---
## 9. Диагностика
### 9.1 Проверка статуса узла
```bash
ssh root@IP "systemctl status junona"
ssh root@IP "journalctl -u junona -n 50 --no-pager"
ssh root@IP "curl localhost:8889/health"
```
### 9.2 Проверка leader election
```bash
ssh root@IP "journalctl -u junona | grep -i 'master\|standby'"
```
### 9.3 Проверка синхронизации
```bash
for ip in 72.56.102.240 176.124.208.93 91.200.148.93 188.225.58.98 147.45.147.247; do
echo "=== $ip ==="
ssh root@$ip "md5sum /root/bot/junomontanaagibot.py | cut -d' ' -f1"
done
```
---
## 10. Ограничения
| Ограничение | Описание | Mitigation |
|-------------|----------|------------|
| Фиксированная топология | Нельзя добавить узел динамически | Требует деплой |
| Single Telegram Token | Один токен на всю сеть | Leader Election |
| Git-based sync | Не подходит для high-frequency данных | Event Sourcing |
---
## Заключение
P2P сеть Montana Protocol обеспечивает:
1. **Отказоустойчивость** — 5 узлов, автоматический failover
2. **Безопасность** — ML-DSA-65, Random Failover при атаке
3. **Консистентность** — Breathing Sync через Git
4. **Мониторинг** — Health endpoints, AtlantGuard
Сеть функционирует в MAINNET режиме с января 2026.
---
```
Alejandro Montana
Montana Protocol P2P Specification v2.0
2026-01-23
```