Узлы сети и история¶
Связка с общей моделью: концептуальная модель 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-нодами дважды в секунду. Именно такая скорость производства новых блоков истории транзакций на платформе. Блоки могут быть и пустыми, но процесс производства и синхронизации не останавливается ни на секунду.
Синхронизация истории между нодами сопровождается синхронизацией текущего состояния распределенной базы данных, которая хранится одновременно на всех серверах нод в их оперативной памяти.