BlockDAG Kaspa производит блоки со скоростью 10 в секунду. Каждый из этих блоков должен достичь каждой честной ноды в сети — достаточно быстро, чтобы DAG оставался связным, а GHOSTDAG мог правильно упорядочивать события. Но всё это происходит не по мановению волшебной палочки. Под слоем консенсуса лежит стек одноранговой сети, который решает три внешне простых задачи: нахождение других нод, поддержание с ними соединений и передача данных между ними.
Эта статья рассматривает этот сетевой слой — механику, которая поддерживает работу gossip, — и объясняет, почему Kaspa Forge решил построить собственную инфраструктуру нод поверх него.
Загрузка: Первый адрес
Только что запущенная нода Kaspa никого не знает. У неё нет списка пиров, кэша адресов, истории. Чтобы решить эту проблему холодного старта, кодовая база включает набор DNS-сидеров, захардкоженных в сетевых параметрах (domain/dagconfig/params.go).
При запуске нода резолвит эти DNS-имена, которые возвращают IP-адреса, принадлежащие хорошо известным, работающим в данный момент нодам Kaspa. Нода выбирает из этого списка и пытается установить первые TCP-подключения. Как документирует база знаний разработчиков вики Kaspa, это входная точка, через которую должна пройти каждая нода.
DNS-сидер: DNS-сервис, возвращающий IP-адреса известных активных нод блокчейна. Он служит механизмом загрузки для новых нод, у которых нет предварительного списка пиров. В Kaspa адреса сидеров компилируются в программное обеспечение ноды.
Это самый централизованный контактный узел во всём сетевом слое — небольшой набор сидеров, которые должна достичь каждая новая нода. Это прагматический компромисс: без *какой-либо* известной входной точки у ноды нет возможности обнаружить сеть вовсе. После подключения нода быстро переходит к децентрализованному обмену пирами.
Обмен пирами: Увеличение набора адресов
После первого успешного подключения нода запрашивает у своего нового пира больше адресов. По умолчанию пир отвечает 1000 перемешанных адресами из своей локальной базы адресов, которая вмещает до 4096 записей.
Запрашивающая нода сохраняет их и начинает подключаться к ним. Каждый новый пир, с которым она связывается, предоставляет ещё порцию адресов. За несколько минут нода строит собственную базу адресов — постоянно обновляемый, распространяемый через gossip каталог активных участников сети.
Этот механизм означает, что обнаружение адресов пропорционально размеру сети. Чем больше нод, тем быстрее любая отдельная нода заполняет своё хранилище адресов. После начальной DNS-загрузки центральный каталог не требуется.
Управление соединениями: Восемь исходящих пиров и сигнал активности
Нода Kaspa не подключается ко всем. Она стремится поддерживать 8 активных исходящих соединений (infrastructure/network/connmanager/outgoing_connections.go). Она также принимает входящие подключения от других нод, но 8 — это число, которое она активно поддерживает.
Исходящий пир: соединение, которое нода инициирует к другой ноде. Цель в 8 пиров гарантирует, что у ноды есть надёжные каналы для получения новых блоков и транзакций, независимо от того, кто подключается к ней входящим образом.
Чтобы поддерживать эти соединения в рабочем состоянии, ноды обмениваются сообщениями ping-pong каждые 2 минуты (app/protocol/flows/v5/ping/send.go). Пир, не ответивший на запрос, считается мёртвым и отключается. Нода затем просматривает свою базу адресов в поисках замены и переподключается, поддерживая целевое количество.
Восемь пиров может показаться скромным числом — Bitcoin также по умолчанию использует 8 исходящих, но Bitcoin производит один блок каждые 10 минут. Kaspa производит 10 блоков в секунду. Каждое пир-несущее соединение несёт значительно больше данных. Количество соединений — это сознательный баланс между избыточностью и стоимостью пропускной способности для поддержания синхронизации на скорости 10 BPS.
Слой Gossip: Объявление, а затем запрос
Вот основной механизм, который перемещает данные по сети.
Когда нода Kaspa получает новый блок — будь то блок, который она намайнила сама, или получила от пира — она не немедленно отправляет полный блок каждому подключённому пиру. Вместо этого она транслирует только хеш блока (app/protocol/flowcontext/blocks.go). С хешами транзакций поступают так же (app/protocol/flowcontext/transactions.go).
Каждый получающий пир проверяет, есть ли у него уже соответствующий блок или транзакция. Если есть — ничего не происходит, хеш просто подтверждается и игнорируется. Если нет — пир запрашивает полные данные у ноды-объявителя.
Нода A намайнила блок B
→ транслирует хеш(B) пирам [C, D, E, ...]
→ Нода C получает хеш(B), блока у неё нет
→ запрашивает полный блок B у A
→ получив его, транслирует хеш(B) своим пирам [F, G, ...]
→ Нода D уже имеет блок B
→ игнорирует хеш(B)
Этот gossip на основе инвентаря — паттерн, популяризированный Bitcoin и унаследованный Kaspa — обладает важным свойством: полезная нагрузка объявления — это фиксированный 32-байтный хеш независимо от размера блока. Дорогостоящая передача полного блока происходит один раз для каждого пира, которому он нужен, и только по запросу.
При скорости 10 блоков в секунду это имеет огромное значение. Наивная трансляция полных блоков каждому пиру означала бы пропускную способность, пропорциональную пиры × размер_блока × 10. Паттерн «объявление-затем-запрос» снижает базовый трафик gossip до пиры × 32 байта × 10, а полные блоки передаются только там, где есть пробелы.
Транспорт: TCP, а не UDP
Пир-коммуникация Kaspa использует TCP — а именно, gRPC поверх TCP (infrastructure/network/netadapter/server/grpcserver/grpc_server.go). Это сознательный выбор с чётко определёнными компромиссами.
TCP гарантирует упорядоченную, надёжную доставку. Каждое сообщение приходит ровно один раз, в последовательности. UDP, напротив, быстрее, но ненадёжён — пакеты могут прийти не в том порядке или не прийти вовсе. Для блокчейн-сети, где пропущенный хеш блока означает пропущенный блок и потенциальный пробел в DAG-представлении ноды, надёжность TCP перевешивает преимущество UDP в задержке.
Цена реальна: накладные расходы TCP на установление соединения, контроль перегрузки и подтверждения добавляют задержку, которой UDP избегает. В чувствительных к задержке приложениях — прямой трансляции видео, играх — выигрывает UDP. Для слоя gossip блокчейна, где важнее корректность, а не выигрыш в миллисекундах, TCP является более обоснованной основой.
Ретрансляция транзакций: Политика мемпула на границе сети
Транзакции распространяются по тому же механизму gossip — сначала хеш, полные данные по запросу — но мемпул добавляет поверх этого уровень политики.
По умолчанию ноды Kaspa применяют минимальную комиссию в 0.0001 KAS на UTXO в качестве порога ретрансляции. Транзакция с комиссией ниже этого значения отклоняется из мемпула ноды и не пересылается пирам. Это анти-спам мера, а не правило консенсуса. Майнер волен включать транзакции с нулевой комиссией в блок; другие ноды примут этот блок без жалоб.
Различие между политикой ретрансляции и правилом консенсуса важно. Порог комиссии — это социальное соглашение между операторами нод — спам-фильтр на границе сети. Его можно скорректировать обновлением программного обеспечения ноды; для этого не требуется хард-форк.
Транзакции также имеют поведение истечения срока, зависящее от того, как они попали в мемпул:
- Транзакции, ретранслированные через P2P (полученные от пира), истекают через 60 блоков, если не были включены в DAG.
- Транзакции, отправленные через RPC (посланные кошельком, например Desk), никогда не истекают. Они периодически ретранслируются до тех пор, пока нода не перезапустится или транзакция не будет намайнена.
Эта асимметрия означает, что транзакции, отправленные кошельком, сохраняются в мемпуле неопределённо, в то время как ретранслируемые «мусорно собираются». Для продуктов, основанных на ковенантах, где транзакции могут ждать окончания тайм-лока, не истекающий путь RPC гарантирует, что обязательство останется в силе, пока DAG его не примет.
Почему Kaspa Forge запускает свои собственные ноды
Сетевой слой, описанный выше, — это субстрат, от которого зависит каждый сервис Kaspa. Блоки и транзакции приходят через gossip. Они могут приходить в разное время к разным нодам, что означает, что выбранная цепочка — и, следовательно, «каноническое» упорядочение событий — может временно расходиться между нодами. Это нормально для BlockDAG, но имеет последствия для любого сервиса, отслеживающего состояние в цепочке.
Kaspa Forge запускает выделенные ноды Kaspa, потому что нашим индексерам нужно видеть блоки по мере их доставки слоем gossip, в реальном времени, с полным пониманием структуры DAG. Индексирование, осведомлённое о реорганизациях, — перестройка состояния при сдвиге выбранной цепочки, — требует прямого доступа с низкой задержкой к представлению ноды о DAG. Это то, что обеспечивает отслеживание состояния в реальном времени для Kaspa Safe, Escrow, Deposit, Marketplace, Boards и Arena. Наши архитектурные решения задокументированы в архитектуре Kaspa Forge.
Из модели gossip вытекает несколько последствий для дизайна:
Задержка распространения создаёт временные форки. При 10 BPS блок, намайненный в одной части сети, может не дойти до всех нод до того, как другой блок сослаться на те же самые тэйлы. GHOSTDAG справляется с этим изящно — для этого и нужен DAG — но индексеры должны быть готовы к переработке состояния, когда выбранная цепочка реорганизуется. Наши индексеры перестраивают свои проекции из обновлённого DAG-представления ноды каждый раз, когда это происходит, как описано в нашем дизайне индексера, осведомлённого о реорганизациях.
Отправка транзакций использует тот же путь ретрансляции. Когда пользователь подписывает транзакцию в Desk и отправляет её, эта транзакция попадает в локальный мемпул ноды через RPC, а затем распространяется к пирам через gossip. Не истекающее поведение RPC гарантирует, что транзакции на основе ковенантов — снятия из хранилища, расчёты Escrow, претензии по Deposit — остаются в мемпуле до тех пор, пока не будут намайнены, даже если соответствующий тайм-лок ещё не истёк.
Политика комиссий влияет на скорость ретрансляции. Транзакция с комиссией на уровне или выше порога ретрансляции по умолчанию будет переслана честными пирами. Ниже этого порога она может быть молча отброшена. Для ковенант-контрактов Kaspa Forge, которые должны точно рассчитывать комиссии для обеспечения условий расходования в цепочке, понимание политики ретрансляции не является необязательным — это ограничение дизайна. Наши контракты это учитывают, как подробно описано в заметке о защите от атак на комиссионный бюджет.
Компромиссы и честные ограничения
Сетевой слой работает, но у него есть известные компромиссы, которые стоит открыто упомянуть.
Централизация DNS-сидеров. Механизм загрузки зависит от небольшого набора DNS-сидеров, скомпилированных в бинарный файл ноды. Если бы все сидеры одновременно отключились, у новых нод не было бы автоматического способа обнаружить пиров. На практике операторы могут вручную добавлять адреса пиров, а инфраструктура сидеров была надёжной, — но при первом запуске она остаётся единой точкой доверия.
Накладные расходы TCP при высоком BPS. Надёжность TCP сопряжена с накладными расходами на управление соединениями. При 10 блоках в секунду и 8+ пирах постоянный поток хешей блоков, пинг-понгов и запросов данных накапливается. Сегодня это решаемо, но по мере того, как Kaspa будет масштабироваться к более высоким скоростям создания блоков, сетевой слой будет испытывать всё большее давление по пропускной способности и задержке.
Задержка gossip неоднородна. Хеш блока не достигает всех нод одновременно. Чем дальше нода от майнера в графе gossip — измеряется в хопах, а не географически, — тем больше задержка. Разные ноды могут временно иметь разные представления о тэйлах DAG. GHOSTDAG это терпит, но это создаёт события реорганизации, которые должны обрабатывать нижестоящие индексеры.
Отсутствие встроенного оценивания качества пиров. Текущий протокол не ранжирует пиров по задержке, времени безотказной работы или качеству данных. Медленный или ненадёжный пир занимает одно из 8 исходящих слотов так же, как и быстрый. Это область, где будущие улучшения протокола могли бы помочь, но сегодня нода относится ко всем пирам одинаково.
Это не баги — это инженерные компромиссы, сделанные в контексте сети, которая отдаёт приоритет простоте, корректности и способности функционировать на скорости 10 блоков в секунду. Их понимание помогает объяснить, почему Kaspa Forge инвестирует в выделенную инфраструктуру нод, а не полагается на публичные эндпоинты: когда состояние вашего индексера зависит от видения каждого блока в режиме, близком к реальному времени, контроль вашей позиции в графе gossip — не роскошь.
Продолжить изучение
документация продуктов Kaspa Forge
Следующий шаг: открыть некастодиальный Desk
FAQ
Как новая нода Kaspa находит своих первых пиров?
Нода запрашивает набор захардкоженных DNS-сидеров, определённых в сетевых параметрах. Они возвращают IP-адреса известных активных нод, давая новому клиенту первые подключения.
Сколько пиров нода Kaspa поддерживает по умолчанию?
Нода стремится поддерживать 8 активных исходящих подключений. Она также принимает входящие, но 8 — это число, которое она активно поддерживает для надёжного участия в gossip.
Передают ли ноды Kaspa друг другу полные блоки?
Не изначально. Ноды сначала транслируют хеши блоков и хеши транзакций. Пир, у которого нет данных, затем запрашивает полный блок или транзакцию, экономя пропускную способность сети.
Слой P2P Kaspa использует TCP или UDP?
TCP. Kaspa использует gRPC поверх TCP для коммуникации между пирами, отдавая приоритет надёжной упорядоченной доставке, а не преимуществу в задержке, которое мог бы предоставить UDP.
Почему Kaspa Forge запускает свои собственные ноды?
Выделенные ноды обеспечивают доступ к новым блокам с низкой задержкой по мере их распространения, что критически важно для индексеров, осведомлённых о реорганизациях, которые поддерживают Safe watchers, отслеживание состояния Escrow, Boards и Marketplace.
Держите KAS там, где кражу можно отменить
Ковенант-сейф в мейннете Kaspa: ваши ключи, ваши правила, наш инструмент. Ончейн — бесплатно, навсегда.
Создать сейф
