main.go
Обзор
Файл main.go реализует основной off-chain клиент для игрового нода, который взаимодействует с блокчейнами на базе Ethereum (через несколько RPC), смарт-контрактами игрового менеджера, а также с Relay API для обработки игровых действий и их батчевой обработки. Это ядро системы, обеспечивающее сбор, валидацию, обработку и синхронизацию игровых действий, включая кросс-чейн взаимодействия.
Основная функциональность:
Конфигурирование и инициализация клиентских соединений с Relay API и Ethereum RPC.
Прослушка и фильтрация событий игровых действий из смарт-контрактов.
Валидация и пакетная обработка игровых действий через встроенный
BatchProcessor.Обработка как локальных, так и кросс-чейн игровых действий.
Синхронизация состояния игроков между разными цепочками.
Управление жизненным циклом приложения с корректной остановкой по сигналам ОС.
Структуры и функции
Константы
Определены статусы игровых действий (ActionStatusCreated, ActionStatusProcessed, ActionStatusExpired, ActionStatusNotFound) и типы игровых действий (ActionTypeSpendMana, ActionTypeEarnMana и т.д.), используемые для классификации и фильтрации игровых событий.
config — структура конфигурации
Параметры конфигурации для запуска ноды:
Поле | Тип | Описание |
|---|---|---|
|
| URL Relay API |
|
| Список RPC URL Ethereum цепочек |
|
| Адреса смарт-контрактов GameManager |
|
| Приватный ключ валидатора |
|
| Уровень логирования (debug/info/warn/error) |
GameNode — основная структура ноды
Ключевые поля:
Поле | Тип | Описание |
|---|---|---|
|
| Клиент Relay API |
|
| Клиенты Ethereum для разных chainID |
|
| Смарт-контракты GameManager для каждой цепочки |
|
| Обработка батчей игровых действий |
|
| Игровой движок (валидация, бизнес-логика) |
|
| Последние обработанные номера блоков по цепочкам |
Основные функции и методы
main()
Точка входа приложения. Инициализирует логирование и вызывает run(). В случае ошибки завершает приложение с кодом 1.
run() error
Настраивает параметры командной строки через библиотеку cobra, требует обязательные параметры и запускает парсинг команд.
rootCmd
Команда cobra, которая при запуске:
Устанавливает уровень логирования.
Создаёт контекст с отменой по сигналам ОС.
Инициализирует
GameNodeчерезNewGameNode.Запускает метод
Startноды.
NewGameNode(ctx context.Context, cfg config) (*GameNode, error)
Функция инициализации игровой ноды:
Устанавливает gRPC соединение с Relay API.
Проверяет корректность конфигурации (кол-во RPC и адресов контрактов).
Создаёт подключения к Ethereum через RPC, получает ChainID.
Создаёт объекты смарт-контрактов
GameContracts.Парсит приватный ключ валидатора.
Инициализирует игровой движок и батч-процессор с нужными параметрами.
Возвращает указатель на
GameNode.
(gn *GameNode) Start(ctx context.Context) error
Главный цикл работы ноды:
Запускает батч-процессор.
Запускает горутину мониторинга результатов батчей.
Создаёт несколько таймеров для периодической работы:
Каждую секунду — обработка новых игровых действий.
Каждые 5 секунд — обработка кросс-чейн действий.
Каждые 30 секунд — синхронизация состояний игроков.
Обрабатывает события и ошибки в бесконечном цикле, завершается при отмене контекста.
(gn *GameNode) processNewActions(ctx context.Context) error
Обрабатывает новые игровые действия с каждой цепочки:
Получает последний блок.
Фильтрует события GameActionSubmitted.
Проверяет статус действия, тип и валидирует.
Добавляет валидные действия в батч-процессор.
(gn *GameNode) monitorBatchResults(ctx context.Context)
Горутина, которая слушает канал результатов батчей. Логирует успешные и неуспешные обработки.
(gn *GameNode) getActionTypeName(actionType uint8) string
Возвращает строковое имя действия по коду actionType. Используется для логирования и отладки.
(gn *GameNode) isValidActionType(actionType uint8) bool
Проверяет корректность типа действия.
(gn *GameNode) filterGameActionEvents(ctx, contract, fromBlock, toBlock)
Фильтрует события GameActionSubmitted в заданном диапазоне блоков.
(gn *GameNode) processActionByType(ctx, actionEvent) error
Выполняет обработку действия, делегируя по типу в соответствующие методы:
processSpendManaActionprocessEarnManaActionprocessLevelUpActionprocessCraftItemActionprocessPvPBattleActionprocessMarketplaceTradeAction
Каждый из них проверяет корректность параметров и логирует процесс.
(gn *GameNode) processCrossChainActions(ctx) error
Обрабатывает кросс-чейн события CrossChainGameActionSubmitted аналогично локальным.
(gn *GameNode) processCrossChainAction(ctx, evt, sourceChain) error
Обрабатывает отдельное кросс-чейн действие:
Проверяет поддержку целевой цепочки.
Валидирует действие через игровой движок.
Отправляет на обработку батчем кросс-чейн действий.
(gn *GameNode) synchronizePlayerStates(ctx) error
Периодическая синхронизация состояний игроков между цепочками:
Получает список активных игроков с каждой цепочки.
Для каждой пары цепочек синхронизирует состояние игрока через батч-процессор.
Вспомогательные методы:
getPlayerStateFromChain — получает состояние игрока из конкретной цепочки.
getDefaultPlayerState — возвращает дефолтное состояние игрока.
getActivePlayersFromChain — заглушка для получения активных игроков (пока пустой список).
filterCrossChainActionEvents— фильтрует кросс-чейн события.
signalContext(ctx context.Context) context.Context
Создаёт контекст, который отменяется при получении сигналов SIGTERM и SIGINT.
Взаимодействие с другими модулями
Пакеты
contracts,game, utils — содержат логику работы с контрактами, игровой логикой, утилитами.Внешние зависимости:
github.com/ethereum/go-ethereum— Ethereum клиент, работа с контрактами.github.com/symbioticfi/relay/api/client/v1— Relay API клиент.github.com/spf13/cobra— командная строка.log/slog— логирование.
game.BatchProcessor— ключевой компонент, управляющий пакетной обработкой игровых событий.Игровой движок (
game.GameEngine) отвечает за валидацию бизнес-логики.
Важные детали реализации
Обработка событий разделена по цепочкам с учётом ChainID.
Используется батчевая модель для повышения эффективности обработки действий.
Кросс-чейн действия валидируются и обрабатываются отдельно, но по схожему принципу.
Состояния игроков синхронизируются между цепочками, чтобы поддерживать консистентность.
Используется контекст с отменой для корректного завершения работы по сигналам ОС.
Есть расширенная фильтрация и проверка параметров действий для защиты от некорректных данных.
Пример использования
Запуск ноды с требуемыми параметрами:
game-node \
--relay-api-url "grpc://relay.api:443" \
--evm-rpc-urls "https://rpc1.eth" --evm-rpc-urls "https://rpc2.eth" \
--contract-addresses "0x1234...abcd" --contract-addresses "0x5678...efgh" \
--private-key "abcdef0123456789..." \
--log-level info
Диаграмма структуры
classDiagram
class GameNode {
-relayClient: *v1.SymbioticClient
-evmClients: map[int64]*ethclient.Client
-gameContracts: map[int64]*contracts.GameContracts
-batchProcessor: *game.BatchProcessor
-gameEngine: *game.GameEngine
-lastBlocks: map[int64]uint64
+Start(ctx context.Context) error
+processNewActions(ctx context.Context) error
+processCrossChainActions(ctx context.Context) error
+synchronizePlayerStates(ctx context.Context) error
+processActionByType(ctx context.Context, actionEvent game.GameActionEvent) error
+getActionTypeName(actionType uint8) string
+isValidActionType(actionType uint8) bool
}
class config {
+relayApiURL: string
+evmRpcURLs: []string
+contractAddresses: []string
+privateKey: string
+logLevel: string
}
GameNode "1" --> "1" game.BatchProcessor : batchProcessor
GameNode "1" --> "1" game.GameEngine : gameEngine
GameNode "1" --> "*" ethclient.Client : evmClients
GameNode "1" --> "*" contracts.GameContracts : gameContracts
GameNode "1" --> "1" v1.SymbioticClient : relayClient
main --> GameNode : создает и запускает
main --> config : конфигурирует через флаги
Заключение
main.go — это центральный компонент off-chain клиента игрового нода, который координирует взаимодействие с блокчейном, Relay API и внутренними игровыми структурами для эффективной и корректной обработки игровых действий и их синхронизации между цепочками.
Документированный код обеспечивает надёжный фундамент для масштабируемой и отказоустойчивой архитектуры многосетевой игровой платформы.