Kora — это рабочее пространство Rust из трёх крейтов:
kora-libсодержит основную логику и RPC-сервер,kora-cliсобирает бинарный файлkora, который запускают операторы, аkora-deploy— специализированный инструмент для развёртывания программ, версионируется отдельно. Всё описанное ниже находится вcrates/lib/src, если не указано иное.
Жизненный цикл запроса
На диаграмме ниже показан общий путь транзакции через Kora. Понимание цепочки вызовов важно для настройки ноды Kora и добавления новых функций.
Где находится каждый этап
| Этап на диаграмме | Исходный код | Точка входа |
|---|---|---|
| Шлюз | rpc_server/server.rs | run_rpc_server |
| Диспетчеризация | rpc_server/rpc.rs | KoraRpc |
| Логика отдельных методов | rpc_server/method/ | по одному файлу на каждый метод JSON-RPC |
| Валидация | validator/transaction_validator.rs | TransactionValidator |
| Плагины | plugin/mod.rs | TransactionPluginRunner |
| Подписание | signer/ | реализовано на основе крейта solana-keychain |
Ещё два файла, о которых стоит знать: config.rs определяет всю схему kora.toml, а
state.rs хранит десериализованную конфигурацию в глобальном состоянии процесса.
Изучаем RPC-сервер
rpc.rs — тонкий слой диспетчеризации: один метод на каждую конечную точку JSON-RPC. Это
самый быстрый способ увидеть весь API. Логика каждого метода находится в отдельном файле в
rpc_server/method/. Прочитайте sign_transaction.rs от начала до конца: остальные методы
подписания являются его вариациями.
Изучаем валидатор
transaction_validator.rs и transaction/instruction_util.rs содержат логику
валидации транзакций и инструкций. Кроме того, здесь находятся тесты свойств безопасности
для fee-payer-policy: по одному файлу на каждую программу с ограничением доступа в
validator/transaction_validator/fee_payer_policy_props/.
Полезные соглашения
Валидация по умолчанию. Каждый флаг в разделе [validation.fee_payer_policy]
по умолчанию равен false, а у структур политики есть атрибут #[serde(default)]. Такое
сочетание сделано намеренно: добавление новой инструкции с ограничением доступа не должно ломать
конфигурацию существующего оператора и должно приводить к отказу, а не
к случайному разрешению. Сохраняйте оба условия при добавлении флага.
Всегда валидируйте разрешённую транзакцию, а не исходную. Исходная
VersionedTransaction содержит только статические ключи аккаунтов, поэтому при валидации или
расчёте стоимости транзакции V0 по ней аккаунты из таблиц поиска молча пропускаются,
а комиссия оказывается заниженной. VersionedTransactionResolved::from_transaction заранее разрешает эти
адреса, поэтому все последующие этапы принимают разрешённый тип.
Добавление плагина транзакций
Плагины реализуют трейт TransactionPlugin из plugin/mod.rs. В нём два
метода: validate выполняется для каждой транзакции во время подписания, а
validate_config выполняется один раз при запуске и возвращает оператору ошибки и предупреждения.
PluginExecutionContext сообщает плагину, какой из четырёх методов подписания
его вызвал.
TransactionPluginRunner::from_config выполняет сопоставление по TransactionPluginType,
определённому в config.rs. Новый встроенный плагин — это новый вариант в нём плюс новая
ветка match в раннере. Сейчас поставляются два плагина: gas_swap и
deploy_authority.
Тестирование
Kora хранит конфигурацию в глобальном состоянии процесса, поэтому в tests/ объявлена одна
цель [[test]] на каждую фазу, и каждая цель запускает собственный встроенный surfnet и
ноду Kora, инициализируемые с нуля. Одна конфигурация на бинарный файл: новой фазе нужна новая
цель, а не новый модуль в существующей.
cargo test -p tests --test <target>
Всё остальное настраивается через justfile. Читайте его, а не
восстанавливайте команды вручную.
Is this page helpful?