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

11 KiB
Raw Blame 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 Алгоритм выбора мастера

Детерминированный выбор мастера на основе позиции в цепочке:

# 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:

# 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:

{
    "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:

# 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):

# 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

# 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

При обнаружении атаки цепочка перемешивается:

# 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

# 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

6.2 Синхронизируемые данные

Данные Путь Формат
База данных data/montana.db SQLite
События data/events.jsonl JSON Lines
Конфигурация *.py Python

7. Сетевые метрики

7.1 Health Status

# 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

# 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 Верификация

# Проверка хэшей на всех узлах
for ip in 72.56.102.240 176.124.208.93 ...; do
    ssh root@$ip "md5sum /root/bot/junomontanaagibot.py"
done

Ожидаемый результат: все хэши идентичны.


9. Диагностика

9.1 Проверка статуса узла

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

ssh root@IP "journalctl -u junona | grep -i 'master\|standby'"

9.3 Проверка синхронизации

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