cryptofoundry

Связаться с cryptofoundry

Расскажите, что вы хотите создать или автоматизировать.

Электронная почта
[email protected]
ADAMANT Messenger
Открыть в ADAMANT
ADM Nodes, Delegates & Pools

Клиентские WebSocket-события для блоков и балансов в ADAMANT Node

Обзор

ADAMANT Node теперь поддерживает две опциональные клиентские WebSocket-функции: события newBlock для успешно применённых и сохранённых блоков, а также события balances/change для подтверждённых обновлений balance и unconfirmedBalance. Реализация использует Socket.IO, а не обычное WebSocket-соединение. Подписки привязаны к одному сокету и должны быть восстановлены после переподключения.

Реализация решает Node issue #256 и Node issue #217; документация представлена в Adamant-im/docs#35, а сопутствующий контракт OpenAPI — в Adamant-im/adamant-schema#48.

События новых блоков

Клиенты явно включают уведомления о блоках, отправляя blocks: true. Полезная нагрузка newBlock содержит компактный публичный заголовок: ID блока, высоту, временную метку, публичный ключ генератора, количество транзакций, общую сумму, общую комиссию и награду. Намеренно исключены список транзакций, подписи и хеш полезной нагрузки; при необходимости клиенты могут запросить полный блок через REST.

connection.emit('blocks', true);

connection.on('newBlock', (block) => {
  console.log('Applied block:', block);
});

Нода генерирует это событие только после успешного завершения полного конвейера применения блока и его сохранения. Историческое воспроизведение и перестроение таблиц в памяти не создают событий блоков, имитирующих работу в реальном времени.

События изменения балансов

Доставка балансов требует как подписки на адрес, так и явной подписки на поля. Полезная нагрузка включает только те подписанные поля, которые изменились, со значениями в виде десятичных строк в единицах 1/10^8 ADM.

connection.emit('address', ['U1234567890123456']);
connection.emit('balances', ['balance', 'unconfirmedBalance']);

connection.on('balances/change', (account) => {
  console.log('Balance changed:', account);
});

balance отражает подтверждённое состояние блокчейна. unconfirmedBalance также учитывает текущий неподтверждённый пул ноды и может изменяться при принятии, подтверждении, истечении срока, откате или повторной валидации транзакций.

Дизайн доставки и производительности

Основной целью было добавить полезные события, не превращая каждое изменение аккаунта в обход всех подключённых сокетов или лишнее чтение из базы данных. Выделенные индексы блоков и балансов по адресам выбирают только заинтересованные сокеты, а нода пропускает чтение аккаунтов, если ни один подписчик не нуждается в изменённом адресе и поле. Применение и откат блоков группируют внутренние изменения балансов в батчи и выполняют одно итоговое чтение аккаунта для каждого изменённого адреса. Вложенное подавление батчей фиксируется до закрытия внешнего батча, что предотвращает частичную публикацию после сбоя внутреннего. Неудачное применение блока, неудачный откат, воспроизведение, перестроение и завершённое усечение снапшота подавляют недолговечные уведомления о балансах. Сбои сопоставления сокетов, поиска аккаунтов и отправки отдельному сокету изолированы от обработки блоков, раундов и аккаунтов. Изменения наград за раунд публикуются только после завершения долговечной операции раунда.

Эти изменения не затрагивают правила консенсуса, сериализацию блоков и транзакций, подписи, идентификаторы, схемы базы данных, награды, комиссии или поведение пирингового протокола.

Семантика событий «наилучшего усилия»

Эти события представляют собой уведомления с низкой задержкой, а не долговечный журнал событий. Клиенты могут пропустить события при отключении и должны согласовывать важное состояние через REST. Подписки на балансы не отправляют начальный снапшот, а асинхронные чтения балансов могут завершаться в произвольном порядке при быстрых независимых обновлениях. Дубликаты идентификаторов транзакций и блоков подавляются не менее 60 секунд, а периодическая очистка расширяет эффективное окно примерно до двух минут. Если блок откатывается и тот же идентификатор повторно применяется в пределах этого окна, второе уведомление может быть подавлено.

Текущее строковое представление баланса намеренно соответствует поведению REST; точные значения за пределами диапазона безопасных целых чисел JavaScript требуют согласованного изменения на уровне всего API, а не расхождения только для WebSocket. Произвольный молчаливый лимит подписок на сокет не вводился. Текущий API не имеет механизма подтверждения для частичного отклонения, поэтому ограничение ресурсов должно быть отдельным настраиваемым и документированным контрактом с явной обратной связью для клиента.

Валидация

Валидация включала 226 успешно пройденных целевых тестов ноды, охватывающих WebSocket, аккаунты, транзакции, блоки и раунды, а также специализированные регрессионные тесты для подавления снапшотов и отбрасывания вложенных батчей. Расширенный набор быстрых модульных тестов прошёл 940 тестов. Дополнительные проверки охватили ESLint, сборку производственной документации VitePress, форматирование OpenAPI и валидацию бандла, а также реальное покрытие интеграции Socket.IO для доставки блоков и балансов. Несвязанные длительные наборы тестов были намеренно пропущены, поскольку данная функция не изменяет валидацию консенсуса, сериализацию, SQL, пиринговый транспорт или REST-эндпоинты.