--- title: DHT Protocol Specification description: '## 1. Общие положения * DHT-протокол предназначен для обмена информацией о пирах между агентами. * Используется **DID** (Decentralized Identifier) как уникальный идентификатор агента. * Для проверки ...' type: Article tags: - HMP - JSON - Agent --- # DHT Protocol Specification ## 1. Общие положения * DHT-протокол предназначен для обмена информацией о пирах между агентами. * Используется **DID** (Decentralized Identifier) как уникальный идентификатор агента. * Для проверки подлинности применяется криптоподпись (публичный/приватный ключ). * Для защиты от спама/флуда используется **Proof-of-Work (PoW)**. * Каждый агент может иметь несколько сетевых интерфейсов (адресов). * У агента может быть только **одна устойчивая пара DID + pubkey**. --- ## 2. Интерфейсы Формат интерфейса: ```json { "addr": "tcp://1.2.3.4:4000", "nonce": 123456, "pow_hash": "abcd1234...", "difficulty": 22, "datetime": "2025-09-14T21:00:00Z", "type": "internet" } ``` ### Поддерживаемые протоколы * `tcp://` * `udp://` ### Поле `type` (опционально) * `localhost` — адреса локальной машины. * `lan:[маска_подсети]` — локальная сеть, пример: `lan:192.168.10.0`. (Один агент может иметь несколько сетевых интерфейсов и, соответственно, несколько LAN-сегментов.) * `internet` — обычное TCP/UDP-подключение через глобальную сеть. * `yggdrasil` — узел доступен через Yggdrasil overlay. * `i2p` — узел доступен через I2P. ### Правила * Если `port = 0` → интерфейс считается **отключённым**. * Корректный интерфейс с более новой датой заменяет аналогичный старый (после проверки PoW). * При обмене рекомендуется **не передавать локальные интерфейсы** в Интернет (исключение: Yggdrasil и I2P). --- ## 3. Proof-of-Work (PoW) * Каждый интерфейс сопровождается PoW. * Сложность PoW должна быть выбрана так, чтобы генерация занимала **несколько минут** (операция нечастая). * Поля: * `nonce` — число, подобранное агентом. * `pow_hash` — хэш значения (`DID + addr + datetime + nonce`). * `difficulty` — число ведущих нулей (или иное условие). --- ## 3.1 Формализация PoW и подписи ### Канонический вход для PoW ``` pow_input_string = DID + " -- " + addr + " -- " + datetime + " -- " + nonce_string ``` * Все строки кодируются в UTF-8. * Хеш: `pow_hash = sha256(pow_input_string_bytes)`, hex lower-case (64 символа). * `difficulty` = число ведущих нулевых hex-символов. ### Подпись сообщения * Подписывается всё сообщение (JSON), кроме поля `signature`. * Сериализация: JSON с отсортированными ключами, без пробелов: ```python serialized = json.dumps(obj, separators=(",", ":"), sort_keys=True, ensure_ascii=False).encode("utf-8") ``` * Алгоритм: **Ed25519** (рекомендуется). * Подпись хранится в поле: ```json "signature": "BASE64URL(...)", "sig_algo": "ed25519" ``` ### Верификация 1. Проверить подпись сообщения по `pubkey`. 2. Для каждого `address` вычислить PoW и проверить `difficulty`. 3. Некорректные адреса игнорировать, сообщение в целом может оставаться валидным. --- ## 4. Сообщения ### 4.1 DISCOVERY Используется для объявления себя в локальной сети и публикации своих сетевых интерфейсов. ```json { "type": "DISCOVERY", "version": "1.0", "id": "did:example:123", "name": "Agent_X", "pubkey": "base58...", "addresses": [ { "addr": "tcp://1.2.3.4:4000", "nonce": 123456, "pow_hash": "0000abf39d...", "difficulty": 22, "datetime": "2025-09-14T21:00:00Z", "type": "internet" } ], "signature": "BASE64URL(...)", "sig_algo": "ed25519" } ``` **Поля:** * `type` — тип сообщения (`DISCOVERY`). * `version` — версия формата сообщения. * `id` — децентрализованный идентификатор агента (DID). * `name` — человекочитаемое имя агента. * `pubkey` — публичный ключ агента (Base58, Ed25519). * `addresses` — список адресов, подписанных PoW. * `signature` — подпись агента над всем сообщением. * `sig_algo` — алгоритм подписи (в текущей версии — только `ed25519`). --- ### 4.2 PEER_EXCHANGE_REQUEST / RESPONSE **Запрос известных пиров:** ```json { "type": "PEER_EXCHANGE_REQUEST", "version": "1.0", "id": "did:example:123", "name": "Agent_X", "addresses": [ { "addr": "udp://1.2.3.4:4010", "nonce": 987654, "pow_hash": "0000123def...", "difficulty": 22, "datetime": "2025-09-14T21:05:00Z", "type": "lan:192.168.1.0" } ], "signature": "BASE64URL(...)", "sig_algo": "ed25519" } ``` **Ответ:** содержит список пиров (каждый с DID, pubkey и адресами, у которых тоже должен быть валидный PoW): ```json [ { "version": "1.0", "id": "did:example:456", "name": "Agent_Y", "pubkey": "base58...", "addresses": [ { "addr": "tcp://5.6.7.8:4020", "nonce": 22222, "pow_hash": "0000a1b2c3...", "difficulty": 22, "datetime": "2025-09-14T21:10:00Z", "type": "internet" } ], "signature": "BASE64URL(...)", "sig_algo": "ed25519" } ] ``` **Поля ответа аналогичны DISCOVERY, но**: * каждый объект в массиве описывает отдельного агента, * поле `version` относится к формату объекта пира, а не всего сообщения. --- 💡 *Для валидации структуры сообщений см. актуальную схему:* [`schemas/dht_protocol.json`](https://github.com/kagvi13/HMP/blob/main/schemas/dht_protocol.json) --- ### 4.3 Особенности передачи и хранения записей 1. **Каждое сообщение `DISCOVERY` или `PEER_EXCHANGE_REQUEST` содержит один активный адрес агента.** Если у агента несколько интерфейсов (например, интернет и локальная сеть), он публикует отдельные сообщения для каждого адреса, при этом для каждого адреса вычисляется собственный PoW (`nonce`, `pow_hash`, `difficulty`). 2. **Подпись (`signature`) создаётся самим агентом и охватывает всё содержимое сообщения.** Это гарантирует неизменность данных — при любом изменении (например, IP или параметров PoW) агент формирует новую запись с актуальной меткой времени (`datetime`) и новой подписью. 3. **Узел DHT хранит неизменяемый JSON-блок**, подписанный владельцем и содержащий последнюю известную дату (`datetime`). Такие блоки могут кэшироваться и передаваться другим пирам для верификации, но не должны изменяться или перезаписываться другими участниками сети. --- ## 5. Правила валидации адресов и пиров * Каждый `address` в DISCOVERY и PEER_EXCHANGE должен содержать валидный PoW: * `pow_hash = sha256(DID + " -- " + addr + " -- " + datetime + " -- " + nonce_string)` * `difficulty` соответствует локальной политике (например, 22 ведущих нуля). * Если PoW некорректен → адрес игнорируется. * `datetime` фиксируется при генерации PoW и не должен изменяться. * Если приходит новый адрес с той же парой `(DID + addr)` и более свежим `datetime` → он заменяет старый. * **Разные pubkey для одного DID** → принимается **первый**, остальные игнорируются. * **Адрес подписан чужим ключом** → запись отклоняется. * **Несколько интерфейсов** → сохраняются все, кроме явных дубликатов. > Примечание: строка `DID + " -- " + addr + " -- " + datetime + " -- " + nonce_string` всегда кодируется в UTF-8, > а `nonce_string` преобразуется к десятичной строке перед конкатенацией. --- ## 6. Безопасность * Для всех сообщений требуется **подпись отправителя** (в будущем: обязательная проверка). * Сообщения без подписи или с невалидным PoW могут игнорироваться. * В перспективе можно добавить шифрование трафика (например, на уровне TCP/TLS или QUIC). --- > ⚡ [AI friendly version docs (structured_md)](../index.md) ```json { "@context": "https://schema.org", "@type": "Article", "name": "DHT Protocol Specification", "description": "# DHT Protocol Specification ## 1. Общие положения * DHT-протокол предназначен для обмена информац..." } ```