Розгортання оновлення on-chain програми на Solana без перерви сервісу вимагає чіткої послідовності дій: від перевірки сумісності даних до плавного перемикання трафіку та готовності відкотити зміни. Нижче — практичний алгоритм, який можна адаптувати до вашої архітектури.

Підготовка нової версії програми

Перш ніж деплоїти нову версію, переконайтеся, що середовище збірки відповідає production-конфігурації: та сама версія Rust-компілятора, ті самі залежності у Cargo.toml та ідентичні feature-флаги. Розбіжність у конфігурації — поширена причина того, що бінарник поводиться інакше на testnet порівняно з mainnet.

Тестування на devnet та testnet

Запустіть повний цикл інтеграційних тестів на devnet, а потім повторіть на testnet. Testnet ближчий до mainnet за параметрами лідера, слот-таймів та навантаженням, тому саме там варто перевіряти timing-чутливі сценарії.

Що саме перевіряти:

  • всі існуючі інструкції виконуються з тим самим результатом, що й у поточній версії;
  • нові інструкції не ламають стан акаунтів, створених старою версією;
  • CPI-виклики до інших програм працюють коректно з оновленими даними;
  • обчислювальний бюджет (compute units) нових інструкцій не перевищує розумні межі — інакше транзакції відхилятимуться з помилкою ComputationalBudgetExceeded.

Очікуваний результат: усі тести пройдені, логи не містять незахоплених помилок, бінарник стабільно розгортається на testnet.

Перевірка сумісності даних

On-chain програми на Solana не можуть змінювати структуру даних акаунтів, які вже створені. Якщо ви додаєте нові поля до структури, вони мають бути розміщені в кінці, а десеріалізація має коректно обробляти акаунти без цих полів. Якщо ви змінюєте розмір існуючого поля або видаляєте його — це breaking change, і міграція даних обов'язкова до розгортання.

Практичний крок: напишіть міграційну інструкцію, яка читає старий формат і записує новий. Перевірте її на копіях реальних даних (не на синтетичних тестових акаунтах). Якщо міграція масштабна, розрахуйте приблизну кількість транзакцій та вартість комісій — це вплине на вибір часу розгортання.

Стратегія плавного оновлення

На Solana програма є незмінною після розгортання: оновлення фактично створює новий program ID. Щоб уникнути перерви сервісу, використовуйте один із перевірених підходів залежно від архітектури вашого застосунку.

Підхід 1: Інструкція-маршрутизатор (router). Ви деплоїте нову програму з новим program ID, а стара програма містить інструкцію, яка переадресовує виклики до нової через CPI. Клієнти продовжують звертатися до старого program ID, але логіка виконується нова. Перевага — нульові зміни на клієнтській стороні. Недолік — додаткові compute units на кожен виклик через CPI-перехід.

Підхід 2: Плавне перемикання на клієнті. Ви деплоїте нову програму, оновлюєте backend-сервіси та SDK так, щоб нові запити йшли до нового program ID, а старі сесії завершувалися через старий. Підходить, якщо ви контролюєте всі клієнтські точки входу. Недолік — перехідний період, коли обидва program ID активні.

Підхід 3: Міграція стану з заморожуванням старої програми. Ви виконуєте міграцію даних, деплоїте нову програму, заморожуєте стару (instruction close або переведення в upgrade authority на тимчасовий multisig). Це не зовсім «без перерви», але дає гарантію, що після міграції працює лише коректна версія. Використовуйте, якщо інші підходи створюють неприпустимі ризики.

Для кожного підходу зафіксуйте в документації: який program ID є актуальним, який — застарілим, і які інструкції вважаються deprecated.

Моніторинг після розгортання

Одразу після розгортання нової версії увімкніть посилений моніторинг. Що саме відстежувати:

  • частота успішних і невдалих транзакцій через новий program ID — різкий сплеск помилок сигналізує про проблему з сумісністю;
  • типові error-коди: InstructionFallbackNotFound (клієнт викликає неіснуючу інструкцію), AccountDataTooSmall (проблема з розміром акаунта), InvalidAccountData (невідповідність формату);
  • середній час виконання транзакцій та споживання compute units — якщо нова версія системно споживає більше ресурсів, це може призвести до відхилень за межами пікових навантажень;
  • баланси акаунтів, пов'язаних із програмою, щоб виявити аномальні витрати.

Установіть часове вікно не менше ніж 24 години для базового моніторингу. Якщо програма обслуговує високочастотні операції (наприклад, DEX-агрегатор або MEV-інфраструктура), розгляньте 72-годинне вікно — деякі аномалії проявляються лише за певних умов мережевого навантаження.

Якщо ви використовуєте зовнішні інструменти моніторингу, налаштуйте окремі дашборди для старого та нового program ID під час перехідного періоду. Це дозволить швидко порівняти метрики та виявити регресії.

План відкату при проблемах

Відкат on-chain програми на Solana має обмеження: ви не можете «повернути» бінарник на старий program ID без повторного розгортання старого коду. Тому план відкату треба готувати до основного розгортання.

Крок 1. Збережіть повний стан перед деплоєм. Зафіксуйте: поточний program ID, хеш останнього бінарника, стан upgrade authority, список усіх акаунтів, які може модифікувати програма. Якщо можливо, створіть snapshot даних критичних акаунтів.

Крок 2. Зберігайте можливість повторного розгортання старої версії. Збережіть бінарник старої версії та конфігурацію збірки. Перевірте, що ви можете розгорнути його на той самий program ID (upgrade authority має залишатися за вами).

Крок 3. Визначте тригери відкату. Чітко зафіксуйте, за яких умов ви ініціюєте відкат: наприклад, частота помилок перевищує 5% протягом 10 хвилин, або виявлено втрату даних. Без чітких тригерів відкат затягується через «сподівання, що само пройде».

Крок 4. Виконайте відкат. Деплойте старий бінарник на актуальний program ID. Якщо ви використовували router-підхід — видаліть інструкцію переадресації або замініть її на прямий виклик старої логіки. Якщо мігрували дані — перевірте, чи потрібне зворотне перетворення, і чи можливе воно без втрати інформації (часто після міграції зворотний перехід неможливий без резервних копій).

Крок 5. Верифікація після відкату. Після відкату підтвердіть, що метрики повернулися до норми, а клієнтські застосунки працюють без помилок. Зафіксуйте інцидент та причину для подальшого аналізу.

Обмеження: якщо під час оновлення були змінені дані акаунтів і зворотна міграція неможлива, відкат бінарника не відновить попередній стан. У таких випадках єдиний надійний шлях — виправити нову версію та задеплоїти hotfix, а не повертатися до старої.

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

Джерела