Перейти к содержанию

Узлы сети и история

Связка с общей моделью: концептуальная модель COOPOS, сетевые слои и интерфейсы. Программная реализация узла — nodeos (обзор).

Все транзакции, которые отправляются в блокчейн — принимаются нодами. На полных PEER-нодах хранится полная копия цепочки блоков; она передаётся другим нодам по внутренним протоколам с регулярностью дважды в секунду (2 блока в секунду). Light-ноды намеренно не держат архив всей цепи: они стартуют со снимка и синхронизируют только новые блоки (см. раздел LIGHT-нода ниже).

Нода - экземпляр серверного программного обеспечения блокчейна

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

История транзакций образует публичную последовательность вызова действий всех смарт-контрактов от момента запуска платформы. На полных нодах она идентична; у light-нод локально доступны только фрагмент цепи после снимка и текущее согласованное состояние для работы приложений.

Однако, то, как ноды работают с этой историей, зависит от их назначения. На прикладном уровне обычно выделяют HISTORY-ноды (в конфигурации COOPOS это часто отдельный профиль state-ноды с state_history_plugin), DELEGATE-ноды, SEED-ноды и API-ноды. Отдельно в эксплуатации кооперативов повсеместно используются light-ноды: они поднимаются со снимка состояния, не хранят полную историю с генезиса, но мгновенно готовы к работе и обычно включают локальный API и P2P для синхронизации новых блоков между контурами кооперативов. Примеры config.ini для state- и light-профилей см. в разделе Конфигурация.

Все эти ноды по своей сути являются PEER-нодами, т.е. нодами, которые равны друг другу.

PEER-нода - это любая нода блокчейна

Все PEER-ноды функционально одинаковы. Они позволяют принимать и передавать новые блоки истории от подключенных пиров, и делают автоматически. Все представленные ниже ноды - это PEER-ноды в своей основе. Мы же будем рассматривать только практически-полезные ноды на прикладном уровне.

flowchart TD
    subgraph Layer0["Ноды истории"]
        History1["HISTORY-1"]
        History2["HISTORY-2"]
        History3["HISTORY-..."]
    end

    subgraph Layer1["Делегатские ноды"]
        Delegate1["DELEGATE-1"]
        Delegate2["DELEGATE-..."]
        Delegate3["DELEGATE-21"]
    end

    subgraph Layer2["SEED-ноды"]
        Seed1["SEED-1"]
        Seed2["SEED-2"]
        Seed3["SEED-..."]
    end

    subgraph Layer3["API-ноды"]
        API1["API-1"]
        API2["API-2"]
        API2["API-..."]
    end

    ExternalApps["Приложения провайдеров"]

    Layer0 --> Layer1
    Layer0 --> Layer2
    Layer1 --> Layer3
    Layer2 --> Layer3
    Layer3 --> ExternalApps

HISTORY-нода

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

Чтобы их использовать активно, каждый желающий может запустить HISTORY-ноду, включив дополнительный плагин, который сделает исторические данные доступными по протоколу State History (SHiP) поверх WebSocket (см. State History (SHiP)). Для работы с этим потоком из приложений в экосистеме COOPOS есть подписка на поток данных (клиент SHiP) на TypeScript; классические пайплайны также выгружают данные в MongoDB или PostgreSQL. State-ноду при желании совмещают с API-нодой на одном хосте или выносят отдельно — см. state-нода.

flowchart TD
    subgraph Layer0["HISTORY-нода"]
        A1["Хранение полной истории блоков"]
        A2["Предоставление API"]
        A3["Поддержка Websocket соединений"]
    end

    subgraph Layer1["Методы API"]
        B["Извлечение блоков"]
        C["Действия и каскадные вызовы"]
        D["Срез состояния таблиц"]
    end

    subgraph Layer2["Приложения"]
        E["Обозреватели"]
        F["Инструменты анализа"]
        G["Фабрики документов"]
    end

    Layer0 --> Layer1
    Layer1 --> Layer2

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

HISTORY-нода позволяет извлекать не только данные о действиях, которые вызывались пользователями, но и о каскадных действиях, которые вызывались автоматически смарт-контрактами в других смарт-контрактах согласно заложенной в них бизнес-логике кооперации.

Например, все действия с цифровыми кошельками пользователей - автомарны, и вызываются только каскадными действиями других смарт-контрактов. Таким образом, HISTORY-нода позволит при необходимости извлечь все действия, которые влияли на кошелёк пользователя. Также, HISTORY-нода позволяет не только извлекать действия, но и все изменения в таблицах контрактов.

Используя HISTORY-ноду можно получить "срез" состояния блокчейна в любой момент времени. Выяснить, какие действие исполнялись тогда, и какое состояние таблиц блокчейна было. Всё это позволяет делать HISTORY-нода, и по сути, они являются основанием для подробных обозревателей истории транзакций блокчейна.

DELEGATE-нода

Все принятые нодами транзакции образуют неизменяемую цепочку истории событий и приходят процесс утверждения каждым делегатом. Для того, чтобы новая транзакция была принята, необходимо, чтобы по-крайней мере 2/3 нод делегатов были согласны с тем, что транзакция удовлетворяет всем математическим правилам валидации, включая проверки на аудентификацию, целостность и доступность. Процесс достижения консенсуса подробнее описан в другом разделе.

Делегаты - это участники, которые предоставляют вычислительные ресурсы своих серверов для работы платформы.

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

Состав производителей и вознаграждение на текущий момент, а также планируемый переход к другой модели формирования набора производителей, изложены в Делегаты и консенсус. Ресурсы узла: Ресурсы сети, регистрация и контракты; экономика токена и эмиссия: Контракты.

flowchart TB
    subgraph Layer0["DELEGATE-нода"]
        A1["Производство блоков"]
        A2["Достижение консенсуса"]
        A3["Предоставление вычислительных ресурсов"]
        A4["Получение вознаграждений"]
    end

Запуск делегатской ноды осуществляется путём добавления плагина и ключа производителя в конфигурацию ноды при её синхронизации. Условия допуска к производству блоков задаются политикой сети и системными контрактами: сейчас это может включать программы оператора и голосование за производителей; планируемый переход к dPoA описан в Делегаты и консенсус — с оговоркой, что процедуры присвоения статуса производителя ещё уточняются.

Здесь же следует сказать, что ключевым для делегата является его скорость и надежность в производстве транзакций. Это значит, что никаких других операций на той же ноде совершать нежелательно. Поэтому ноды делегатов рекомендуется отделять от всех других нод в производственных средах. Более того, существует программная возможность соединения нод делегатов исключительно с доверенными SEED-нодами, что позволяет делегатам построить внутреннюю, изолированную топологию для надежной обработки транзакций.

API-нода

API-нода - программный интерфейс для связи с приложениями провайдеров

Все ноды обладают API - например, у HISTORY - это API для извлечения истории, а у делегата - это API делегата. Однако, для регулярной работы с платформой необходим доступ к методам, которые позволяют отправлять транзакции, получать информацию из таблиц распределенной базы данных, и другую, прочую информацию о состоянии блокчейна.

Для этого нужны API-ноды. Они конфигурируются таким образом, что предоставляют публичные конечные точки доступа для взаимодействия с внешним программным обеспечением. Они предоставляют RPC-интерфейсы, позволяющие отправлять POST и GET запросы для отправки транзакций и извлечения данных.

flowchart TD
    subgraph Layer0["API-нода"]
        A1["Публичная точка доступа"]
        A2["Первичная валидация транзакций"]
        A3["Вещание транзакций в сеть"]
        A4["Извлечение данных из базы"]
    end

    subgraph Layer1["Функции взаимодействия"]
        B1["Отправка транзакций"]
        B2["Получение данных из таблиц"]
        B3["Получение информации о состоянии блокчейна"]
    end

    subgraph Layer2["Внешние приложения"]
        C1["Приложения провайдеров"]
    end

    Layer0 --> Layer1
    Layer1 --> Layer2

API-ноды при получении новой транзакции немедленно производят валидацию её и действий внутри неё. И только в случае если транзакция признана этой нодой достоверной - она отправляется всем другим нодам сети (вещается). Ноды делегатов получают эти транзакции и точно также проверяют их. И только в том случае, если 2/3 из основных делегатов согласятся с тем, что новая транзакция не содержит ошибок - тогда и только тогда она будет включена в цепочку. А до этого времени она считается всеми нодами - обратимой.

Но API-нода не беспокоится об этом. Её задачи - первичная валидация, вещание транзакции в сеть, а также, извлечение информации из собственной базы данных по запросам. База данных API-ноды формируется в процессе синхронизации и обновляется дважды в секунду автоматизированным и заверенным решением делегатов.

На light-нодах тот же Chain API используется для локальной работы приложений кооператива: состояние соответствует цепи с момента снимка и далее по новым блокам, без полного архива прошлого. Профиль см. light-нода.

LIGHT-нода

Light-нода — экземпляр nodeos, запущенный со снимком (snapshot): не воспроизводится вся цепь с первого блока, узел получает готовое состояние и дальше догоняет сеть по P2P. Такой режим даёт быстрый старт и меньшие требования к диску под полный журнал блоков.

В системе кооперативов типовая схема — light-ноды на каждом контуре: внутри контура работает API для сервисов, а P2P связывает узлы между кооперативами (и при необходимости с публичными seed-нодами сети). Глубокая история и индексация при этом опираются на выделенные state-ноды и клиент подписки на поток SHiP, а не на полный локальный лог на каждой light-ноде.

Подробнее: Конфигурация: light-нода.

SEED-нода

Для того, чтобы все ноды сети могли получить информацию о её состоянии - необходимы специальные ноды, которые будут предоставлять эту информацию большими пачками блоков транзакций. Такие ноды называются SEED, или, семя.

SEED-нода - это публичная точка для синхронизации блокчейна

Любой ноде для того, чтобы подключиться к блокчейн-сети, необходимо указать SEED-ноду, с которой будет произведена полная синхронизация цепочки блоков истории транзакций. SEED-ноды предоставляют такую возможность. Их главная задача - подключать другие ноды, делиться актуальной информацией о состоянии блоков, а также, наличии других нод в сети.

flowchart TD
    Z1["Новая нода"]

    subgraph Layer0["SEED-нода"]
        A2["Синхронизация новых нод"]
        A3["Передача списка активных PEER-нод"]
    end

    subgraph Layer2["PEER-ноды"]
        C1["SEED-ноды"]
        C2["DELEGATE-ноды"]
        C3["HISTORY-ноды"]
        C4["API-ноды"]
    end

    Z1 --> Layer0
    Layer0 --> Layer2

Подключившись к любой активной SEED-ноде, нода немедленно начинает синхронизацию, а также, получает с неё список всех активных PEER-нод, с которыми начнётся взаимодействие после завершения синхронизации. Таким образом, SEED-нода -- это точка входа в блокчейн-сеть. Все доступные SEED-нодами публикуются делегатами на своих ресурсах, распределенно.

Синхронизация

Все принятые блокчейном транзакции образуют цепочку истории действий. Полная копия этой цепочки содержится на каждой PEER-ноде и передаётся другим нодам по внутренним сетевым каналам связи платформы при синхронизации.

Синхронизация - процесс скачивания и криптографической проверки истории транзакций блокчейна.

При подключении новой полной PEER-ноды к платформе она скачивает всю историю, криптографически проверяет взаимосвязь между блоками и полностью воссоздаёт состояние своей базы данных таким, какое оно у остальных нод сети. Light-нода вместо этого загружает снимок состояния и затем синхронизирует только новые блоки по P2P — прошлое не восстанавливается локально, зато узел готов к работе сразу после применения снимка и подключения к пирам.

Синхронизация выполняется между всеми PEER-нодами дважды в секунду. Именно такая скорость производства новых блоков истории транзакций на платформе. Блоки могут быть и пустыми, но процесс производства и синхронизации не останавливается ни на секунду.

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