Біп, біп, біп. Біп, біп, біп.
Спокій Стівена розривається гострими звуками телефона, які раптово виривають його зі снів. У темряві екран яскраво світиться, сильно вібруючи на його тумбочці. Післяпільно він вимовляє: біп-біп-біп. Він стогне, ще напівсплячий, тріщить очі та витягується за пристроєм. Шибаючи від болю з повідомлення, він відчуває, як його серце опускається - вузол відключився. Без вагань він стрибає з ліжка напіводягнутий, мацаючи руками, щоб розблокувати телефон, коли приходять нові повідомлення. І тоді до нього приходить розуміння - весь кластер відключився.
У цей самий момент, по всьому світі, в різних містах і часових поясах сотні операторів вузлів дивляться на свої телефони з тією ж самою реалізацією: Мить, яку вони бояться, настала - відключення.
Як і всі розподілені системи, Solana працює в умовах реальності, що одна помилка в реалізації або незрозумілий випадок може призвести до відмови на всій мережі. Відключення, хоча й заважають, є необхідною частиною підтримки складної розподіленої інфраструктури — чи то в децентралізованих блокчейнах, централізованих біржах або навіть великих постачальниках хмарних послуг, таких як Amazon або Microsoft.
Питання не в тому, чи відбудуться збої, а в тому, коли і як мережа розвиватиметься, щоб адаптуватися та загартуватися до майбутніх інцидентів. Незважаючи на ретельне імітаційне тестування, стимульовану тестову мережу та активну програму винагороди за виявлення помилок, жодна система, незалежно від того, наскільки добре вона спроектована, не може передбачити всі можливі режими збоїв. Найцінніші уроки випливають з реальних операцій.
За останні п'ять років Solana пережила сім окремих інцидентів збою, п'ять з яких були спричинені помилками клієнтів, а два — нездатністю мережі впоратися з потоками спаму транзакцій. У ранніх версіях Solana не вистачало ключових механізмів управління перевантаженнями, таких як пріоритетні збори та місцеві ринки комісій, які пізніше виявилися важливими для пом'якшення навантаження на мережу. Відсутність таких механізмів призвела до тривалих періодів зниження продуктивності та перевантаження протягом 2022 року, оскільки мережа по суті стимулювала спам.
Історичні випадки збоїв у роботі Solana та зниження продуктивності
Ця стаття докладно проаналізує кожне відключення Solana, вивчаючи кореневі причини, спричинюючі події та прийняті заходи для їх врегулювання. Крім того, ми обговоримо ключові аспекти перезапуску мережі, звітування про помилки та фундаментальні концепції живості та відмов безпеки. Хоча ці розділи найкраще читати по порядку, кожен з них розроблений так, щоб бути самостійним, що дозволяє читачам переходити до тем або випадків відключення, які їх цікавлять найбільше.
Згідно з теоремою CAP, також відомою як Теорема Бревера, розподілена система може досягти лише двох з трьох властивостей:
Для блокчейнів толерантність до розділів має важливе значення — збої в роботі мережі неминучі. Це змушує вибирати між точкою доступу (Availability + Partition Tolerance) і CP (Узгодженість + Толерантність до розділів). Як і більшість ланцюгів PoS, що швидко завершуються, Solana надає пріоритет послідовності, а не доступності, що робить її CP-системою. Він зупиняється під час критичних збоїв, замість того, щоб обслуговувати застарілі дані або дозволяти небезпечні записи. Хоча це означає, що програмне забезпечення вузла може перейти в невідновлюваний стан, вимагаючи ручного втручання, воно гарантує, що кошти користувачів залишаться в безпеці.
Позиція Solana в межах компромісів теореми CAP
Збій життєздатності: виникає, коли блокчейн зупиняється в роботі, перешкоджаючи підтвердженню транзакцій і створенню блоків через простої валідатора, мережеві розділи або зупинки консенсусу. У контексті теореми САП це відповідає втраті доступності.
Збій безпеки: виникає, коли остаточний стан блокчейну змінюється або розгалужується неналежним чином. Це може призвести до суперечливих історій або подвійних витрат, часто спричинених помилками консенсусу або зловмисними атаками. У контексті теореми САР це відповідає втраті узгодженості.
Solana надає пріоритет безпеці, а не життю. Таким чином, мережа зупинятиметься у випадках надзвичайного стресу мережі або збою консенсусу, а не ризикує корупцією держави. Хоча збої є руйнівними та можуть вплинути на програми, користувачів і валідаторів, вони кращі, ніж катастрофічні наслідки непослідовного або пошкодженого реєстру.
Перезапуск мережі Solana передбачає ідентифікацію останнього оптимістично підтвердженого слоту блоку та перезапуск вузлів зі знімка довірчого локального стану цього слоту. Оскільки слот перезапуску не визначається on-chain, оператори валідаторів повинні досягти позачанцевого консенсусу, щоб погодитися щодо безпечної точки відкату. Ця координація відбувається публічно в каналі #mb-validators на Solana Tech Discord, де професійні оператори валідаторів спілкуються в реальному часі. Більшість операторів мають автоматизовані системи сповіщень, які сповіщають їх у момент зупинки виробництва блоків, забезпечуючи швидку реакцію.
Коли досягнуто консенсус щодо правильного слоту перезапуску, оператори використовують інструмент лідера для генерації нового локального знімка, перезавантажують свої валідатори та чекають, доки принаймні 80% загального обсягу вернеться в онлайн. Лише після цього мережа відновлює виробництво блоків та валідацію. Підтвердження того, що принаймні 20% відсутнього обсягу під час перезапуску кластера забезпечує достатню маржу безпеки для залишання в онлайн у випадку розгалуження вузлів або повернення в автономний режим безпосереджньо після перезапуску.
Програми винагороди за виявлення помилок винагороджують дослідників безпеки за виявлення вразливостей програмного забезпечення та повідомлення про них. Це критично важлива лінія оборони, оскільки вона активно стимулює виявлення помилок перед тим, як їх можна використати. Дослідникам безпеки та розробникам, які виявляють потенційні вразливості в клієнті Agave рекомендується, повідомляти про них через належні канали безпеки. Детальні вказівки щодо розкриття інформації можна знайти в репозиторії Agave GitHub.
Нагороди надаються за валідні звіти про критичні вразливості, з виплатами, залежними від серйозності:
Додатково, клієнт FireDancer має окрему програму баг-баунті розміщено через Immunefi, пропонуючи максимальну винагороду в розмірі 500 000 доларів США за критичні знахідки.
Наступні розділи надають детальний, хронологічний аналіз відмов Solana та періодів погіршення продуктивності, починаючи з запуску Mainnet Beta 16 березня 2020 року. Це дослідження підкреслить ключові події, їх кореневі причини та подальші поліпшення мережі, що надасть уявлення про те, як Solana еволюціонувала для підвищення стабільності та стійкості з часом.
Перерва у роботі: Що приблизно шість годин
Проблема кореневого блоку: помилка поширення блоку
Виправлення:
Ця перерва була спричинена раніше відома проблема відновлення блоків та обробки кодуспровоковано невідомою помилкою вТурбіна, механізм поширення блоків SolanaПомилка виникла, коли валідатор передав два різних блоки для одного й того ж слоту та розповсюдив їх на дві окремі розділи (A та B), тоді як третій розділ незалежно виявив неузгодженість.
Оскільки кожна партіція мала лише меншість акцій, жодна не могла досягти супербільшинства узгодження для просування ланцюжка. Основна проблема полягала в тому, як внутрішні структури даних Solana відстежують блоки та їх обчислений стан. Система використовувала номер слоту Перевірки Історії (PoH) (ідентифікатор u64) для посилання на стан та блок у цьому слоті. Як тільки мережа розділилася на партіції, вузли неправильно інтерпретували блоки A та B як ідентичні, що перешкоджало належному відновленню та синхронізації блоків.
Кожен розділ припускав, що інший мав той самий блок, що призвело до фундаментального конфлікту:
Оскільки переходи між станами відрізнялися між розділами, валідатори не могли відновити або узгодити відгалуження, що перешкоджало фінальності.
Виправлення цього питання полягало в тому, щобдозволяти службам відстежувати блоки за хешем замість номера слотуЯкщо будь-яка кількість блоків для того ж слоту створює розділи, їх обробляють не інакше, ніж розділи з блоками, які займають різні слоти. Вузли зможуть відновити всі можливі відгалуження, і консенсус зможе вирішити розділи.
Хоча помилка була початковою причиною відключення, більшість перерви в роботі виникла через очікування повернення достатньої ваги стейку онлайн, оскільки для відновлення виробництва блоків Solana потребує щонайменше 80% участі в стейку.
Час простою: сімнадцять годин
Коренева проблема: переповнення пам'яті, спричинене транзакціями ботів
Виправлення:
14 вересня 2021 року Solana зіткнулася з серйозним мережевим зависанням після запуску Grape Protocol своєї первинної пропозиції DEX (IDO) у мережі на краудфандинговій платформі Raydium AcceleRaytor. Протягом 12 хвилин після IDO мережа була перевантажена безпрецедентним потоком транзакцій, керованих ботами, і припинила виробництво рут-слотів. Ці боти ефективно виконували розподілену атаку типу «відмова в обслуговуванні» (DDoS), виводячи навантаження транзакцій за межі пропускної здатності мережі.
На піку завантаженості:
Слоти Solana в секунду під час відключення Grape IDO 14 вересня 2021 року(Джерело даних: Jump Crypto)
Один із ботів структурував свої транзакції для блокування 18 ключових облікових записів, включаючи глобальну програму токенів SPL та програму Serum DEX, яка тепер не діє. Це заблокувало всі транзакції, що взаємодіють з цими обліковими записами, серйозно знизивши паралельні можливості обробки Solana. Замість виконання транзакцій незалежно, мережа стала ущільненою, обробляючи транзакції послідовно - загострюючи затори.
Виправлення, яке ігнорує блокування запису в програмах, вже було розроблено та заплановано до випуску. Пізніше перезавантаження мережі дозволило це оновлення, назавжди видаливши цей вектор атаки.
Під час події IDO валідатори отримували потік транзакцій, керованих ботами, і, у свою чергу, перенаправляли надлишкові транзакції наступному лідеру, посилюючи перевантаження. Перезавантаження мережі ввело обмеження швидкості на переадресацію транзакцій, щоб запобігти майбутнім штормам транзакцій, які переважають лідерів.
RPC-вузли Solana автоматично повторюють невдалі транзакції, функція, призначена для підвищення надійності. Однак цей механізм повторної спроби погіршує транзакційне затоплення при екстремальному заторі, утримуючи старі транзакції в обігу замість того, щоб дозволити мережі відновитися. У версії 1.8 Solana було введено налаштовану поведінку повторної спроби RPC, що дозволяє додаткам оптимізувати спроби з коротшими термінами закінчення та стратегіями експоненційного збільшення.
В умовах сильних перевантажень лідери Solana не змогли включити транзакції з голосуванням, які мають вирішальне значення для підтримки консенсусу. В результаті, відсутність підтверджених голосів призвела до зупинки консенсусу, що зупинило виробництво нових кореневих блоків. У пізніших версіях клієнта Solana з'явився механізм пріоритезації транзакцій голосування, не дозволяючи їх заглушати звичайними транзакціями в майбутніх подіях.
Під час перезапуску мережі з'явилася друга проблема. Валідатори повідомили про значні коливання активних сум стейкінгу. Ця проблема виникла через помилку, через яку відсоток ставки був неправильно помножений на 100, що перевищило максимально можливе значення. Механізм інфляції створив стільки нових токенів SOL, що переповнив 64-бітне беззнакове ціле число. Ця помилка була швидко виявлена та виправлена перед другим перезапуском.
Час простою: немає
Коренева причина: Зайві дубльовані транзакції
Часткове виправлення:
Між 6 і 12 січня 2022 року мережа Solana mainnet стикнулася зі значними перегрузками, що призвели до погіршення продуктивності та часткових відключень. Розлад викликав боти, які спамять зайвими дубльованими транзакціями, значно зменшуючи мережеву пропускну здатність. Блоки оброблялися довше, ніж очікувалося, що призвело до роздвоєння наступного лідера і подальшого зниження пропускної здатності. На піку шанси успішних транзакцій знизились на 70%. Клієнт важко справлявся зі зростаючою складністю та високими обчислювальними потребами мережі, показуючи обмеження у здатності задовольняти попит.
Додаткова нестабільність виникла з 21 по 23 січня, затори продовжують тривати. 22 січня громадська кінцева точка RPC (https://api.mainnet-beta.solana.com) вийшов з ладу через зловживання, оскільки спамовані пакетні виклики RPC перенасичили систему.
Для вирішення цих питань, У випуску Solana 1.8.12 спеціально спрямоване на вичерпання кешу програм, поки версія 1.8.14 внесла покращення до кешу Sysvar, відкидання SigVerify та дедублювання SigVerify.
Час простою: Вісім годин
Проблема в корені: спам транзакцій від облікових записів ботів
Виправлення:
30 квітня 2022 року Solana пережила небачений вибух запитів на транзакції. Деякі вузли повідомили про досягнення шести мільйонів запитів на секунду, генеруючи понад 100 Гбіт / с трафіку на вузол. Цей вибух був викликаний ботами, які намагалися захистити недавно відтворені NFT через програму Metaplex Candy Machine. Цей механізм відтворення працював на «хто перший прийшов, той і здобув», створюючи сильний економічний стимул затопити мережу транзакціями та перемогти відтворення.
30 квітня / 1 травня 2022 року відключення автомата для цукерок, пакетів на секунду вхід(Джерело даних: Jump Crypto)
При зростанні обсягу транзакцій валідатори вийшли з пам'яті та впали, що в кінцевому підсумку призвело до зупинки консенсусу. Недостатня пропускна здатність голосування завадила завершенню раніше сформованих блоків, запобігаючи прибиранню залишених відгалужень. В результаті валідатори були перевантажені великою кількістю відгалужень, які їм довелося оцінити, перевищуючи їхню ємність навіть після перезавантажень та вимагаючи ручного втручання для відновлення мережі.
Попри те, що цей випадок співпав з інцидентом вересня 2021 року, Solana продемонструвала покращену стійкість. Незважаючи на те, що кількість запитів на транзакції у цей раз збільшилася на 10,000%, мережа залишалася працездатною набагато довше, відображаючи вдосконалення, зроблені спільнотою валідаторів у відповідь на попередні виклики масштабування.
30 квітня / 1 травня 2022 року відключення автомату для цукерок, активні валідатори(Джерело даних: Jump Crypto)
Перезапуск мережі зайняв менше 1,5 години після того, як було узгоджено канонічний знімок. Solana v1.10 включала покращення використання пам'яті, щоб продовжити час, протягом якого вузли можуть витримувати повільну або зупинену згоду.
Однак принципові питання залишалися невирішеними. Лідер, як і раніше, обробляв транзакції, претендуючи на ті самі дані облікового запису, у порядку живої черги без ефективного запобігання спаму, через що користувачі не могли визначити пріоритетність терміновості своїх транзакцій. Для вирішення цієї проблеми в якості практичних рішень були запропоновані три довгострокові механізми.
Впровадження QUIC: Раніше Solana покладалася на протокол мережі UDP (User Datagram Protocol), щоб надсилати транзакції через Gulf Stream від вузлів RPC до поточного лідера. Хоча швидкий і ефективний, UDP є безпідключений, не маючи керування потоком та підтверджень отримання. Відповідно, не існує змістовного способу запобігти або пом'якшити зловживання. Для контролю над мережевим трафіком протокол прийому транзакцій валідатора (тобто етап Fetch TPU) було переімплементовано з QUIC.
QUIC намагається пропонувати найкраще з TCP та UDP. Він сприяє швидкій, асинхронній комунікації, схожій на UDP, але з безпечними сеансами та передовими стратегіями керування потоками TCP. Це дозволяє накладати обмеження на окремі джерела трафіку, щоб мережа могла фокусуватися на обробці справжніх транзакцій. У QUIC також є концепція окремих потоків, тому якщо одна транзакція втрачена, це не блокує решту. QUIC врешті-решт був інтегрований в клієнт Solana Labs з випуском 1.13.4.
Стейк-зважена якість обслуговування (SWQoS): Введено нову систему, яка визначає пріоритетність мережевого трафіку на основі стейку, який утримують валідатори, що гарантує, що ті, у кого вищий стейк, можуть відправляти транзакції більш ефективно. За цим механізмом валідатор з 3% від загального стейку може відправити до 3% від загальної кількості пакетів лідеру. SWQoS діє як захист від Сібіла, ускладнюючи завдання зловмисникам затопити мережу низькоякісними транзакціями. Цей підхід заміняє попередню модель першим прийшов, перший обслужений, яка приймала транзакції бездумно, не враховуючи їх джерело.
Введення пріоритетних комісійних: Після того, як транзакції надходять всередину, вони все одно конкурують за доступ до спільних даних облікового запису. Раніше ця суперечка вирішувалася за принципом "першим прийшов - першим обслужений", не надаючи користувачам можливості сигналізувати про терміновість своїх транзакцій. Оскільки будь-хто може подавати транзакції, зважування стейкінгу не підходить для визначення пріоритетів на цьому етапі. Щоб вирішити цю проблему, в програму Compute Budget була додана нова інструкція, що дозволяє користувачам вказувати додаткову плату, що стягується при виконанні, і включення блоку. Співвідношення комісії до одиниці обчислень визначає пріоритет виконання транзакції, забезпечуючи більш динамічний і ринковий підхід до замовлення транзакцій.
Metaplex швидко ввела жорсткий податок на ботів у розмірі 0,01 SOL на транзакції з монетизації взаємодія з програмою Candy Machine для боротьби зі спамом, керованим ботами. Цей механізм боротьби зі спамом стягує мінімальну плату за запобігання зловмисній діяльності, не караючи законних користувачів, які припустилися випадкових помилок. Податок застосовувався за конкретними сценаріями, зокрема:
Цей економічний стримувальний захід виявився дуже ефективним. Снайпери монет були швидко вичерпані, і спам-активність припинилася. Протягом перших кількох днів боти загалом втратили понад 426 SOL.
Час простою: чотири з половиною години
Коренева проблема: Довговічна помилка, що призводить до невдачі у консенсусі
Виправлення:
Під час робочого часу багам дозволили обробляти певні стійкі транзакції nonce подвійно - один раз як звичайна транзакція, і знову як транзакція nonce, якщо вони використовували останній blockhash замість стійкого nonce в полі recent_blockhash. Це призвело до недетермінованої поведінки серед валідаторів, оскільки деякі вузли відхилили друге виконання, тоді як інші його прийняли. Критично, оскільки більше однієї третини валідаторів прийняли блок, це перешкодило досягненню необхідної двох третин більшості для досягнення консенсусу.
Незважаючи на стандартні транзакції, стійкі транзакції засобами nonce не мають терміну дії та потребують унікального механізму для запобігання подвійному виконанню. Вони обробляються послідовно за допомогою значення nonce, пов'язаного з кожним обліковим записом, яке обертається кожного разу, коли обробляється стійка транзакція засобами nonce. Після обертання така ж транзакція засобами nonce не повинна бути знову дійсною.
Для зменшення проблеми тимчасово було вимкнено постійні транзакції.Пізніше виправлення було реалізовано у Solana 1.10.23, що запобігло повторюванню виконання, відокремивши домени nonce і blockhash. Оновлення гарантувало, що під час просування облікових записів nonce блокхеш хешується фіксованим рядком, що робить блокхеш недійсним як значення nonce. Як наслідок, транзакція, виконана один раз як звичайна транзакція, не може бути повторно виконана як довгострокова транзакція, і навпаки. Крім того, новий тип DurableNonce замінив попередні значення blockhash у стані облікового запису nonce, додавши безпеку типів і запобігаючи подібним проблемам у майбутньому.
Прочитайте наш попередній блоговий матеріал Helius, щоб Дізнайтеся більше про довговічні нонсеси та їх використання.
Час простою: вісім з половиною годин
Проблема корениться: Помилка в правилах вибору гілки призвела до невдачі узгодження
Виправити:
Цей вихід з ладу був спричинений тим, що валідатор помилково виробляв дубльовані блоки на тій самій висоті блоку. Це сталося через те, що одночасно стали активними як основний вузол валідатора, так і його запасний вузол, використовуючи той самий ідентифікатор вузла, але запропонувавши різні блоки. Ця умова існувала принаймні 24 години перед виходом з ладу, під час якої мережа правильно обробляла дубльовані слоти лідера валідатора.
Кластер врешті-решт зупинився, коли мережа зіткнулася з непоправною відгалуженістю через помилку в логіці вибору відгалуження. Ця помилка перешкоджала блок-виробникам будувати на попередньому блоку, що призвело до невдачі в консенсусі.
Форки - це регулярне явище на Solana, і звичайно валідатори вирішують їх, узгоджуючись щодо форка із більшістю голосів (найважчий форк). Коли валідатор вибирає неправильний форк, йому потрібно переключитися на найважчий форк, щоб залишатися синхронізованим з мережею. Однак у цьому випадку валідатори не могли повернутися до найважчого блоку, якщо його слот відповідав їхньому останньому проголосованому слоту. Цей недолік призвів до застрягання валідаторів, що перешкоджало прогресуванню консенсусу і в кінцевому підсумку призвело до припинення роботи мережі.
Вибір форка відключення дублікатів блоку, вересень 2022 р.(Джерело: Лейн, Майкл Габбард)
У наведеному вище прикладі вадливий перевіряючий C виробляє дубльовані блоки для своїх лідерських слотів 5-8. Коли перевіряючий G бере на себе роль наступного лідера, він спостерігає лише один з дублікатів і відповідно розширює свій відгалуження. Проте наступний лідер, перевіряючий D, виявляє обидва дубльовані блоки від перевіряючого C та вирішує відкинути їх, замість цього будуючи своє відгалуження на верхівці слота 4.
По мірі розвитку мережі вілка, побудована валідатором G, здобуває голоси більшості стейкерів, встановлюючи себе як канонічний ланцюг. Визнавши, що його вілка програє, валідатор D намагається перейти на вілку валідатора G. Проте перехід не вдається через помилку в логіці вибору вілки. Ця проблема виникає через те, що спільний предок двох вілок - дубльований блок у слоті 5 - не було оброблено правильно, що заважає валідатору D визнати більшість вілки. В результаті валідатор D залишається у зачіпленому стані на своїй вілці, не здатний повернутися до основного ланцюгу.
Проблема була вирішена після огляду основною командою. Патч було об'єднано в гілку master та відповідно перенесено на всі відгалуження релізів.
Час простою: майже 19 годин
Коренева проблема: Невдача логіки дедуплікації в службах пересилання фрагментів
Виправлення:
Служба спеціальної пересилки фрагментів валідатора вийшла з ладу, передавши надзвичайно великий блок (майже 150 000 фрагментів), кілька порядків величини більший, ніж стандартний блок, під час його лідер-слоту. Це перенавантажило фільтри дедуплікації валідатора, що спричинило постійне перенаправлення даних. Проблема загострилася під час вироблення нових блоків, врешті-решт насичуючи протокол.
Відключення великого блоку, шматки на блок, лютий 2023 (Джерело: Лейн, Майкл Хаббард)
Зростання неприродного мережевого трафіку перевантажило Турбіну, змушуючи передавати блокові дані через значно повільніший запасний протокол відновлення блоку. Хоча Турбіна призначена для витримки великих блоків, вона фільтрує їх, але послуги пересилання фрагментів функціонують вище цієї логіки фільтрації, що знижує її ефективність. Протягом періоду погіршення блокові лідери автоматично переходили в режим лише голосування, це захисний механізм, за допомогою якого лідери виключають економічні транзакції без голосування.
Кореневою причиною проблеми була невдача в логіці дедуплікації в службах пересилання долот, що заважала зайвому пере-передаванню долот. Додатково фільтр дедуплікації в конвеєрі повторного передавання спочатку не був розроблений для запобігання петління в межах дерева Турбін, що загострювало проблему.
Мережа була перезапущена вручну з пониженням до останньої відомої стабільної версії програмного забезпечення валідатора. Щоб пом'якшити ці проблеми, У версіях Solana 1.13.7 і 1.14.17 удосконалено логіку дедуплікації, покращуючи його здатність запобігати перенасиченню фільтрів і забезпечуючи більш надійну продуктивність мережі.
Час простою: майже п'ять годин
Коренева проблема: помилка, що викликає безкінечний цикл перекомпіляції в кеші JIT
Виправлення:
Валідатор Agave компілює всі програми безпосередньо в час виконання (JIT), перед виконанням транзакцій, які посилаються на них. Для оптимізації продуктивності JIT-вихід часто використовуваних програм кешується, що зменшує непотрібні повторні компіляції. В рамках Agave v1.16 існуючий механізм кешування, LoadedPrograms, був замінений новою реалізацією під назвою ExecutorsCache, яка ввела кілька ефективностей.
LoadedPrograms забезпечив глобальний перегляд кешованих програм з урахуванням розгалужень, зменшуючи дублювання облікових даних і дозволяючи потокам виконання транзакцій спільно завантажувати нові програми, запобігаючи конфліктам компіляції. Ключовою особливістю цієї системи було відстеження слота, де програма стає активною (відома як ефективна висота слота), щоб виявляти анулювання кешу, коли оновлюються дані програми в ланцюжку.
Ефективна висота слота більшості програм була отримана з їхнього слота розгортання, який зберігався в їхньому обліковому записі в мережі. Однак програми, розгорнуті за допомогою застарілих завантажувачів, не зберегли цей слот розгортання у своїх облікових записах. LoadedPrograms призначив цим програмам ефективну нульову висоту слота як обхідний шлях.
Виняток виникав, коли була виявлена інструкція розгортання, яка сигналізувала про заміну байт-коду програми. У цьому випадку LoadedPrograms тимчасово вставили запис з правильною ефективною висотою слота. Однак, оскільки в угоді ніколи не згадувався цей запис, вона була дуже вразливою до виселення. При виселенні вихід JIT відкидався, а програма позначалася як розвантажена, але ефективна висота слота зберігалася.
Якщо транзакція пізніше посилалася на цю незавантажену програму, LoadedPrograms перекомпілював її і повторно вставляв запис на ефективній висоті слота. Як правило, це робить програму доступною для виконання на наступній ітерації. Однак, для застарілих програм-завантажувачів, новому виводу JIT було присвоєно нульову висоту слота sentinel, що помістило його позаду попереднього незавантаженого запису. В результаті, LoadedPrograms ніколи не розпізнавав програму як завантажену, запускаючи безперервний цикл перекомпіляції на кожній ітерації.
У версії Agave v1.16 LoadedPrograms не підтримував кооперативну завантаження, що дозволяло упаковувати транзакцію, що спричинила блок. Цей блок потім поширювався по мережі, викликаючи кожному валідатору переосмислити його і потрапити в той же нескінченний цикл повторної компіляції. Оскільки під час збою понад 95% загального стейку кластера використовувало Agave v1.17, більшість валідаторів застрягли на цьому блоку, зупинивши мережу.
Цей баг був виявлений минулого тижня під час розслідування випадку відмови кластера Devnet, і планувалося впровадження патча.@jeff.washington/2024-02-06-solana-mainnet-beta-outage-report-619bd75b3ce0">Вибраним заходом було відкатити зміни до Agave v1.17 та негайно видалити відзнаку функції під час перезавантаження мережі. Це вимкнуло старий завантажувач, що відповідав за викликання помилки, запобігаючи подальших випадків.
Час простою: відсутній
Коренева проблема: неправильне припущення про вирівнювання адреси ELF
Виправлення:
5 серпня,Основні інженери Anza були попереджені про вразливість у клієнті Agave, про що повідомив зовнішній дослідник. Зловмисник міг використати цей недолік для збою валідаторів-лідерів, що призвело до зупинки роботи всієї мережі. У відповідь інженери Anza швидко розробили патч, який потім перевірили кілька сторонніх охоронних фірм.
Програми Solana компілюються за допомогою LLVM в Виконуваний і зв'язуваний формат (ELF). Уразливість виникла через неправильне припущення про вирівнювання адрес у цих згенерованих файлах ELF. Хоча дезінфекція ELF зазвичай примушує до різних перевірок цілісності, вона не перевіряє вирівнювання розділу .text. Ця помилка могла призвести до того, що шкідливий файл ELF визначив неправильно вирівняний розділ .text, що призвело б до переходу віртуальної машини на недійсну адресу. Це призведе до помилки сегментації хоста, що призведе до збою валідатора.
Зловмисник міг би використати цю вразливість, виконавши наступне:
Будь-яке загальнодоступне оновлення патчу негайно зробить вразливість зрозумілою для всіх. Це може дати зловмиснику достатньо часу, щоб реконструювати вразливість і зупинити мережу до того, як достатня кількість стейкінгу буде оновлена. Критична маса валідаторів повинна буде прийняти будь-який патч-реліз якомога швидше, щоб уникнути такого сценарію.
До 7 серпня численні члени Solana Foundation зв'язалася з валідаторами через приватні повідомлення на різних комунікаційних платформах, повідомивши їх про наближений критичний патч та поділившись захешованим повідомленням, яке підтвердило дату та унікальний ідентифікатор події. Кілька відомих членів Anza, Jito та Фонду Solana поділилися цим хешем на X, GitHub та LinkedIn, щоб підтвердити точність повідомлення. Приклад поділених хешів:
Протягом наступного дня члени ядра продовжували звертатися до валідаторів, наголошуючи на важливості терміновості та конфіденційності. У заздалегідь визначений час, 8 серпня, о 14:00 UTC, оператори валідаторів отримали ще одне повідомлення, що містить інструкції щодо завантаження, перевірки та застосування патча. Патч був розміщений у репозиторії Github відомого інженера Anza, а не в основному репозиторії Agave . Інструкції включали перевірку завантажених файлів патчів на відповідність наданих шасумів.
До 20:00 за координованим всесвітнім часом 8 серпня було виправлено супербільшість ставок, що забезпечує безпеку мережі. Після цього вразливість та відповідний патч були публічно оприлюднені, супроводжуються закликом до всіх залишкових валідаторів щодо оновлення.
Тихе розподілання патчу та тендітна координація валідаторів викликали побоювання щодо децентралізації Solana. Незабаром після інциденту виконавчий директор Фонду Solana, Ден Альберт, звернувся до цих критик в інтерв'ю для ЗМІ.
«Я думаю, що важливо не плутати централізацію з можливістю координації. У всьому світі налічується 1500 вузлів, що виробляють блоки, якими керує майже стільки ж людей.... Можливість спілкуватися з ними, або з деякими з них, добровільно, не слід плутати з централізацією».
Корейський тиждень блокчейну (KBW) 2024
Я думаю, що важливо не плутати централізацію з можливістю координації. У всьому світі налічується 1500 вузлів, що виробляють блоки, якими керує майже стільки ж людей.... Можливість спілкуватися з ними, або з деякими з них, добровільно, не слід плутати з централізацією.
На момент написання цієї статті Solana провела більше року без збоїв, досягнувши ключової віхи для видалення тегу «beta» з основної бета-версії. Частота відключень, схоже, зменшується в міру дозрівання мережі, і очікується, що впровадження Firedancer підвищить різноманітність клієнтів, зменшивши ризик невиявлених помилок або крайніх випадків, що спричиняють повне відключення всього кластера. Однак деякі лідери спільноти, зокрема засновник Helius Мерт Мумтаз, прогнозують, що відключення триватимуть. Час покаже.
Велика подяка Зантетсу (Shinobi Systems) та OxIchigo за перегляд попередніх версій цієї роботи.
Поділіться
Біп, біп, біп. Біп, біп, біп.
Спокій Стівена розривається гострими звуками телефона, які раптово виривають його зі снів. У темряві екран яскраво світиться, сильно вібруючи на його тумбочці. Післяпільно він вимовляє: біп-біп-біп. Він стогне, ще напівсплячий, тріщить очі та витягується за пристроєм. Шибаючи від болю з повідомлення, він відчуває, як його серце опускається - вузол відключився. Без вагань він стрибає з ліжка напіводягнутий, мацаючи руками, щоб розблокувати телефон, коли приходять нові повідомлення. І тоді до нього приходить розуміння - весь кластер відключився.
У цей самий момент, по всьому світі, в різних містах і часових поясах сотні операторів вузлів дивляться на свої телефони з тією ж самою реалізацією: Мить, яку вони бояться, настала - відключення.
Як і всі розподілені системи, Solana працює в умовах реальності, що одна помилка в реалізації або незрозумілий випадок може призвести до відмови на всій мережі. Відключення, хоча й заважають, є необхідною частиною підтримки складної розподіленої інфраструктури — чи то в децентралізованих блокчейнах, централізованих біржах або навіть великих постачальниках хмарних послуг, таких як Amazon або Microsoft.
Питання не в тому, чи відбудуться збої, а в тому, коли і як мережа розвиватиметься, щоб адаптуватися та загартуватися до майбутніх інцидентів. Незважаючи на ретельне імітаційне тестування, стимульовану тестову мережу та активну програму винагороди за виявлення помилок, жодна система, незалежно від того, наскільки добре вона спроектована, не може передбачити всі можливі режими збоїв. Найцінніші уроки випливають з реальних операцій.
За останні п'ять років Solana пережила сім окремих інцидентів збою, п'ять з яких були спричинені помилками клієнтів, а два — нездатністю мережі впоратися з потоками спаму транзакцій. У ранніх версіях Solana не вистачало ключових механізмів управління перевантаженнями, таких як пріоритетні збори та місцеві ринки комісій, які пізніше виявилися важливими для пом'якшення навантаження на мережу. Відсутність таких механізмів призвела до тривалих періодів зниження продуктивності та перевантаження протягом 2022 року, оскільки мережа по суті стимулювала спам.
Історичні випадки збоїв у роботі Solana та зниження продуктивності
Ця стаття докладно проаналізує кожне відключення Solana, вивчаючи кореневі причини, спричинюючі події та прийняті заходи для їх врегулювання. Крім того, ми обговоримо ключові аспекти перезапуску мережі, звітування про помилки та фундаментальні концепції живості та відмов безпеки. Хоча ці розділи найкраще читати по порядку, кожен з них розроблений так, щоб бути самостійним, що дозволяє читачам переходити до тем або випадків відключення, які їх цікавлять найбільше.
Згідно з теоремою CAP, також відомою як Теорема Бревера, розподілена система може досягти лише двох з трьох властивостей:
Для блокчейнів толерантність до розділів має важливе значення — збої в роботі мережі неминучі. Це змушує вибирати між точкою доступу (Availability + Partition Tolerance) і CP (Узгодженість + Толерантність до розділів). Як і більшість ланцюгів PoS, що швидко завершуються, Solana надає пріоритет послідовності, а не доступності, що робить її CP-системою. Він зупиняється під час критичних збоїв, замість того, щоб обслуговувати застарілі дані або дозволяти небезпечні записи. Хоча це означає, що програмне забезпечення вузла може перейти в невідновлюваний стан, вимагаючи ручного втручання, воно гарантує, що кошти користувачів залишаться в безпеці.
Позиція Solana в межах компромісів теореми CAP
Збій життєздатності: виникає, коли блокчейн зупиняється в роботі, перешкоджаючи підтвердженню транзакцій і створенню блоків через простої валідатора, мережеві розділи або зупинки консенсусу. У контексті теореми САП це відповідає втраті доступності.
Збій безпеки: виникає, коли остаточний стан блокчейну змінюється або розгалужується неналежним чином. Це може призвести до суперечливих історій або подвійних витрат, часто спричинених помилками консенсусу або зловмисними атаками. У контексті теореми САР це відповідає втраті узгодженості.
Solana надає пріоритет безпеці, а не життю. Таким чином, мережа зупинятиметься у випадках надзвичайного стресу мережі або збою консенсусу, а не ризикує корупцією держави. Хоча збої є руйнівними та можуть вплинути на програми, користувачів і валідаторів, вони кращі, ніж катастрофічні наслідки непослідовного або пошкодженого реєстру.
Перезапуск мережі Solana передбачає ідентифікацію останнього оптимістично підтвердженого слоту блоку та перезапуск вузлів зі знімка довірчого локального стану цього слоту. Оскільки слот перезапуску не визначається on-chain, оператори валідаторів повинні досягти позачанцевого консенсусу, щоб погодитися щодо безпечної точки відкату. Ця координація відбувається публічно в каналі #mb-validators на Solana Tech Discord, де професійні оператори валідаторів спілкуються в реальному часі. Більшість операторів мають автоматизовані системи сповіщень, які сповіщають їх у момент зупинки виробництва блоків, забезпечуючи швидку реакцію.
Коли досягнуто консенсус щодо правильного слоту перезапуску, оператори використовують інструмент лідера для генерації нового локального знімка, перезавантажують свої валідатори та чекають, доки принаймні 80% загального обсягу вернеться в онлайн. Лише після цього мережа відновлює виробництво блоків та валідацію. Підтвердження того, що принаймні 20% відсутнього обсягу під час перезапуску кластера забезпечує достатню маржу безпеки для залишання в онлайн у випадку розгалуження вузлів або повернення в автономний режим безпосереджньо після перезапуску.
Програми винагороди за виявлення помилок винагороджують дослідників безпеки за виявлення вразливостей програмного забезпечення та повідомлення про них. Це критично важлива лінія оборони, оскільки вона активно стимулює виявлення помилок перед тим, як їх можна використати. Дослідникам безпеки та розробникам, які виявляють потенційні вразливості в клієнті Agave рекомендується, повідомляти про них через належні канали безпеки. Детальні вказівки щодо розкриття інформації можна знайти в репозиторії Agave GitHub.
Нагороди надаються за валідні звіти про критичні вразливості, з виплатами, залежними від серйозності:
Додатково, клієнт FireDancer має окрему програму баг-баунті розміщено через Immunefi, пропонуючи максимальну винагороду в розмірі 500 000 доларів США за критичні знахідки.
Наступні розділи надають детальний, хронологічний аналіз відмов Solana та періодів погіршення продуктивності, починаючи з запуску Mainnet Beta 16 березня 2020 року. Це дослідження підкреслить ключові події, їх кореневі причини та подальші поліпшення мережі, що надасть уявлення про те, як Solana еволюціонувала для підвищення стабільності та стійкості з часом.
Перерва у роботі: Що приблизно шість годин
Проблема кореневого блоку: помилка поширення блоку
Виправлення:
Ця перерва була спричинена раніше відома проблема відновлення блоків та обробки кодуспровоковано невідомою помилкою вТурбіна, механізм поширення блоків SolanaПомилка виникла, коли валідатор передав два різних блоки для одного й того ж слоту та розповсюдив їх на дві окремі розділи (A та B), тоді як третій розділ незалежно виявив неузгодженість.
Оскільки кожна партіція мала лише меншість акцій, жодна не могла досягти супербільшинства узгодження для просування ланцюжка. Основна проблема полягала в тому, як внутрішні структури даних Solana відстежують блоки та їх обчислений стан. Система використовувала номер слоту Перевірки Історії (PoH) (ідентифікатор u64) для посилання на стан та блок у цьому слоті. Як тільки мережа розділилася на партіції, вузли неправильно інтерпретували блоки A та B як ідентичні, що перешкоджало належному відновленню та синхронізації блоків.
Кожен розділ припускав, що інший мав той самий блок, що призвело до фундаментального конфлікту:
Оскільки переходи між станами відрізнялися між розділами, валідатори не могли відновити або узгодити відгалуження, що перешкоджало фінальності.
Виправлення цього питання полягало в тому, щобдозволяти службам відстежувати блоки за хешем замість номера слотуЯкщо будь-яка кількість блоків для того ж слоту створює розділи, їх обробляють не інакше, ніж розділи з блоками, які займають різні слоти. Вузли зможуть відновити всі можливі відгалуження, і консенсус зможе вирішити розділи.
Хоча помилка була початковою причиною відключення, більшість перерви в роботі виникла через очікування повернення достатньої ваги стейку онлайн, оскільки для відновлення виробництва блоків Solana потребує щонайменше 80% участі в стейку.
Час простою: сімнадцять годин
Коренева проблема: переповнення пам'яті, спричинене транзакціями ботів
Виправлення:
14 вересня 2021 року Solana зіткнулася з серйозним мережевим зависанням після запуску Grape Protocol своєї первинної пропозиції DEX (IDO) у мережі на краудфандинговій платформі Raydium AcceleRaytor. Протягом 12 хвилин після IDO мережа була перевантажена безпрецедентним потоком транзакцій, керованих ботами, і припинила виробництво рут-слотів. Ці боти ефективно виконували розподілену атаку типу «відмова в обслуговуванні» (DDoS), виводячи навантаження транзакцій за межі пропускної здатності мережі.
На піку завантаженості:
Слоти Solana в секунду під час відключення Grape IDO 14 вересня 2021 року(Джерело даних: Jump Crypto)
Один із ботів структурував свої транзакції для блокування 18 ключових облікових записів, включаючи глобальну програму токенів SPL та програму Serum DEX, яка тепер не діє. Це заблокувало всі транзакції, що взаємодіють з цими обліковими записами, серйозно знизивши паралельні можливості обробки Solana. Замість виконання транзакцій незалежно, мережа стала ущільненою, обробляючи транзакції послідовно - загострюючи затори.
Виправлення, яке ігнорує блокування запису в програмах, вже було розроблено та заплановано до випуску. Пізніше перезавантаження мережі дозволило це оновлення, назавжди видаливши цей вектор атаки.
Під час події IDO валідатори отримували потік транзакцій, керованих ботами, і, у свою чергу, перенаправляли надлишкові транзакції наступному лідеру, посилюючи перевантаження. Перезавантаження мережі ввело обмеження швидкості на переадресацію транзакцій, щоб запобігти майбутнім штормам транзакцій, які переважають лідерів.
RPC-вузли Solana автоматично повторюють невдалі транзакції, функція, призначена для підвищення надійності. Однак цей механізм повторної спроби погіршує транзакційне затоплення при екстремальному заторі, утримуючи старі транзакції в обігу замість того, щоб дозволити мережі відновитися. У версії 1.8 Solana було введено налаштовану поведінку повторної спроби RPC, що дозволяє додаткам оптимізувати спроби з коротшими термінами закінчення та стратегіями експоненційного збільшення.
В умовах сильних перевантажень лідери Solana не змогли включити транзакції з голосуванням, які мають вирішальне значення для підтримки консенсусу. В результаті, відсутність підтверджених голосів призвела до зупинки консенсусу, що зупинило виробництво нових кореневих блоків. У пізніших версіях клієнта Solana з'явився механізм пріоритезації транзакцій голосування, не дозволяючи їх заглушати звичайними транзакціями в майбутніх подіях.
Під час перезапуску мережі з'явилася друга проблема. Валідатори повідомили про значні коливання активних сум стейкінгу. Ця проблема виникла через помилку, через яку відсоток ставки був неправильно помножений на 100, що перевищило максимально можливе значення. Механізм інфляції створив стільки нових токенів SOL, що переповнив 64-бітне беззнакове ціле число. Ця помилка була швидко виявлена та виправлена перед другим перезапуском.
Час простою: немає
Коренева причина: Зайві дубльовані транзакції
Часткове виправлення:
Між 6 і 12 січня 2022 року мережа Solana mainnet стикнулася зі значними перегрузками, що призвели до погіршення продуктивності та часткових відключень. Розлад викликав боти, які спамять зайвими дубльованими транзакціями, значно зменшуючи мережеву пропускну здатність. Блоки оброблялися довше, ніж очікувалося, що призвело до роздвоєння наступного лідера і подальшого зниження пропускної здатності. На піку шанси успішних транзакцій знизились на 70%. Клієнт важко справлявся зі зростаючою складністю та високими обчислювальними потребами мережі, показуючи обмеження у здатності задовольняти попит.
Додаткова нестабільність виникла з 21 по 23 січня, затори продовжують тривати. 22 січня громадська кінцева точка RPC (https://api.mainnet-beta.solana.com) вийшов з ладу через зловживання, оскільки спамовані пакетні виклики RPC перенасичили систему.
Для вирішення цих питань, У випуску Solana 1.8.12 спеціально спрямоване на вичерпання кешу програм, поки версія 1.8.14 внесла покращення до кешу Sysvar, відкидання SigVerify та дедублювання SigVerify.
Час простою: Вісім годин
Проблема в корені: спам транзакцій від облікових записів ботів
Виправлення:
30 квітня 2022 року Solana пережила небачений вибух запитів на транзакції. Деякі вузли повідомили про досягнення шести мільйонів запитів на секунду, генеруючи понад 100 Гбіт / с трафіку на вузол. Цей вибух був викликаний ботами, які намагалися захистити недавно відтворені NFT через програму Metaplex Candy Machine. Цей механізм відтворення працював на «хто перший прийшов, той і здобув», створюючи сильний економічний стимул затопити мережу транзакціями та перемогти відтворення.
30 квітня / 1 травня 2022 року відключення автомата для цукерок, пакетів на секунду вхід(Джерело даних: Jump Crypto)
При зростанні обсягу транзакцій валідатори вийшли з пам'яті та впали, що в кінцевому підсумку призвело до зупинки консенсусу. Недостатня пропускна здатність голосування завадила завершенню раніше сформованих блоків, запобігаючи прибиранню залишених відгалужень. В результаті валідатори були перевантажені великою кількістю відгалужень, які їм довелося оцінити, перевищуючи їхню ємність навіть після перезавантажень та вимагаючи ручного втручання для відновлення мережі.
Попри те, що цей випадок співпав з інцидентом вересня 2021 року, Solana продемонструвала покращену стійкість. Незважаючи на те, що кількість запитів на транзакції у цей раз збільшилася на 10,000%, мережа залишалася працездатною набагато довше, відображаючи вдосконалення, зроблені спільнотою валідаторів у відповідь на попередні виклики масштабування.
30 квітня / 1 травня 2022 року відключення автомату для цукерок, активні валідатори(Джерело даних: Jump Crypto)
Перезапуск мережі зайняв менше 1,5 години після того, як було узгоджено канонічний знімок. Solana v1.10 включала покращення використання пам'яті, щоб продовжити час, протягом якого вузли можуть витримувати повільну або зупинену згоду.
Однак принципові питання залишалися невирішеними. Лідер, як і раніше, обробляв транзакції, претендуючи на ті самі дані облікового запису, у порядку живої черги без ефективного запобігання спаму, через що користувачі не могли визначити пріоритетність терміновості своїх транзакцій. Для вирішення цієї проблеми в якості практичних рішень були запропоновані три довгострокові механізми.
Впровадження QUIC: Раніше Solana покладалася на протокол мережі UDP (User Datagram Protocol), щоб надсилати транзакції через Gulf Stream від вузлів RPC до поточного лідера. Хоча швидкий і ефективний, UDP є безпідключений, не маючи керування потоком та підтверджень отримання. Відповідно, не існує змістовного способу запобігти або пом'якшити зловживання. Для контролю над мережевим трафіком протокол прийому транзакцій валідатора (тобто етап Fetch TPU) було переімплементовано з QUIC.
QUIC намагається пропонувати найкраще з TCP та UDP. Він сприяє швидкій, асинхронній комунікації, схожій на UDP, але з безпечними сеансами та передовими стратегіями керування потоками TCP. Це дозволяє накладати обмеження на окремі джерела трафіку, щоб мережа могла фокусуватися на обробці справжніх транзакцій. У QUIC також є концепція окремих потоків, тому якщо одна транзакція втрачена, це не блокує решту. QUIC врешті-решт був інтегрований в клієнт Solana Labs з випуском 1.13.4.
Стейк-зважена якість обслуговування (SWQoS): Введено нову систему, яка визначає пріоритетність мережевого трафіку на основі стейку, який утримують валідатори, що гарантує, що ті, у кого вищий стейк, можуть відправляти транзакції більш ефективно. За цим механізмом валідатор з 3% від загального стейку може відправити до 3% від загальної кількості пакетів лідеру. SWQoS діє як захист від Сібіла, ускладнюючи завдання зловмисникам затопити мережу низькоякісними транзакціями. Цей підхід заміняє попередню модель першим прийшов, перший обслужений, яка приймала транзакції бездумно, не враховуючи їх джерело.
Введення пріоритетних комісійних: Після того, як транзакції надходять всередину, вони все одно конкурують за доступ до спільних даних облікового запису. Раніше ця суперечка вирішувалася за принципом "першим прийшов - першим обслужений", не надаючи користувачам можливості сигналізувати про терміновість своїх транзакцій. Оскільки будь-хто може подавати транзакції, зважування стейкінгу не підходить для визначення пріоритетів на цьому етапі. Щоб вирішити цю проблему, в програму Compute Budget була додана нова інструкція, що дозволяє користувачам вказувати додаткову плату, що стягується при виконанні, і включення блоку. Співвідношення комісії до одиниці обчислень визначає пріоритет виконання транзакції, забезпечуючи більш динамічний і ринковий підхід до замовлення транзакцій.
Metaplex швидко ввела жорсткий податок на ботів у розмірі 0,01 SOL на транзакції з монетизації взаємодія з програмою Candy Machine для боротьби зі спамом, керованим ботами. Цей механізм боротьби зі спамом стягує мінімальну плату за запобігання зловмисній діяльності, не караючи законних користувачів, які припустилися випадкових помилок. Податок застосовувався за конкретними сценаріями, зокрема:
Цей економічний стримувальний захід виявився дуже ефективним. Снайпери монет були швидко вичерпані, і спам-активність припинилася. Протягом перших кількох днів боти загалом втратили понад 426 SOL.
Час простою: чотири з половиною години
Коренева проблема: Довговічна помилка, що призводить до невдачі у консенсусі
Виправлення:
Під час робочого часу багам дозволили обробляти певні стійкі транзакції nonce подвійно - один раз як звичайна транзакція, і знову як транзакція nonce, якщо вони використовували останній blockhash замість стійкого nonce в полі recent_blockhash. Це призвело до недетермінованої поведінки серед валідаторів, оскільки деякі вузли відхилили друге виконання, тоді як інші його прийняли. Критично, оскільки більше однієї третини валідаторів прийняли блок, це перешкодило досягненню необхідної двох третин більшості для досягнення консенсусу.
Незважаючи на стандартні транзакції, стійкі транзакції засобами nonce не мають терміну дії та потребують унікального механізму для запобігання подвійному виконанню. Вони обробляються послідовно за допомогою значення nonce, пов'язаного з кожним обліковим записом, яке обертається кожного разу, коли обробляється стійка транзакція засобами nonce. Після обертання така ж транзакція засобами nonce не повинна бути знову дійсною.
Для зменшення проблеми тимчасово було вимкнено постійні транзакції.Пізніше виправлення було реалізовано у Solana 1.10.23, що запобігло повторюванню виконання, відокремивши домени nonce і blockhash. Оновлення гарантувало, що під час просування облікових записів nonce блокхеш хешується фіксованим рядком, що робить блокхеш недійсним як значення nonce. Як наслідок, транзакція, виконана один раз як звичайна транзакція, не може бути повторно виконана як довгострокова транзакція, і навпаки. Крім того, новий тип DurableNonce замінив попередні значення blockhash у стані облікового запису nonce, додавши безпеку типів і запобігаючи подібним проблемам у майбутньому.
Прочитайте наш попередній блоговий матеріал Helius, щоб Дізнайтеся більше про довговічні нонсеси та їх використання.
Час простою: вісім з половиною годин
Проблема корениться: Помилка в правилах вибору гілки призвела до невдачі узгодження
Виправити:
Цей вихід з ладу був спричинений тим, що валідатор помилково виробляв дубльовані блоки на тій самій висоті блоку. Це сталося через те, що одночасно стали активними як основний вузол валідатора, так і його запасний вузол, використовуючи той самий ідентифікатор вузла, але запропонувавши різні блоки. Ця умова існувала принаймні 24 години перед виходом з ладу, під час якої мережа правильно обробляла дубльовані слоти лідера валідатора.
Кластер врешті-решт зупинився, коли мережа зіткнулася з непоправною відгалуженістю через помилку в логіці вибору відгалуження. Ця помилка перешкоджала блок-виробникам будувати на попередньому блоку, що призвело до невдачі в консенсусі.
Форки - це регулярне явище на Solana, і звичайно валідатори вирішують їх, узгоджуючись щодо форка із більшістю голосів (найважчий форк). Коли валідатор вибирає неправильний форк, йому потрібно переключитися на найважчий форк, щоб залишатися синхронізованим з мережею. Однак у цьому випадку валідатори не могли повернутися до найважчого блоку, якщо його слот відповідав їхньому останньому проголосованому слоту. Цей недолік призвів до застрягання валідаторів, що перешкоджало прогресуванню консенсусу і в кінцевому підсумку призвело до припинення роботи мережі.
Вибір форка відключення дублікатів блоку, вересень 2022 р.(Джерело: Лейн, Майкл Габбард)
У наведеному вище прикладі вадливий перевіряючий C виробляє дубльовані блоки для своїх лідерських слотів 5-8. Коли перевіряючий G бере на себе роль наступного лідера, він спостерігає лише один з дублікатів і відповідно розширює свій відгалуження. Проте наступний лідер, перевіряючий D, виявляє обидва дубльовані блоки від перевіряючого C та вирішує відкинути їх, замість цього будуючи своє відгалуження на верхівці слота 4.
По мірі розвитку мережі вілка, побудована валідатором G, здобуває голоси більшості стейкерів, встановлюючи себе як канонічний ланцюг. Визнавши, що його вілка програє, валідатор D намагається перейти на вілку валідатора G. Проте перехід не вдається через помилку в логіці вибору вілки. Ця проблема виникає через те, що спільний предок двох вілок - дубльований блок у слоті 5 - не було оброблено правильно, що заважає валідатору D визнати більшість вілки. В результаті валідатор D залишається у зачіпленому стані на своїй вілці, не здатний повернутися до основного ланцюгу.
Проблема була вирішена після огляду основною командою. Патч було об'єднано в гілку master та відповідно перенесено на всі відгалуження релізів.
Час простою: майже 19 годин
Коренева проблема: Невдача логіки дедуплікації в службах пересилання фрагментів
Виправлення:
Служба спеціальної пересилки фрагментів валідатора вийшла з ладу, передавши надзвичайно великий блок (майже 150 000 фрагментів), кілька порядків величини більший, ніж стандартний блок, під час його лідер-слоту. Це перенавантажило фільтри дедуплікації валідатора, що спричинило постійне перенаправлення даних. Проблема загострилася під час вироблення нових блоків, врешті-решт насичуючи протокол.
Відключення великого блоку, шматки на блок, лютий 2023 (Джерело: Лейн, Майкл Хаббард)
Зростання неприродного мережевого трафіку перевантажило Турбіну, змушуючи передавати блокові дані через значно повільніший запасний протокол відновлення блоку. Хоча Турбіна призначена для витримки великих блоків, вона фільтрує їх, але послуги пересилання фрагментів функціонують вище цієї логіки фільтрації, що знижує її ефективність. Протягом періоду погіршення блокові лідери автоматично переходили в режим лише голосування, це захисний механізм, за допомогою якого лідери виключають економічні транзакції без голосування.
Кореневою причиною проблеми була невдача в логіці дедуплікації в службах пересилання долот, що заважала зайвому пере-передаванню долот. Додатково фільтр дедуплікації в конвеєрі повторного передавання спочатку не був розроблений для запобігання петління в межах дерева Турбін, що загострювало проблему.
Мережа була перезапущена вручну з пониженням до останньої відомої стабільної версії програмного забезпечення валідатора. Щоб пом'якшити ці проблеми, У версіях Solana 1.13.7 і 1.14.17 удосконалено логіку дедуплікації, покращуючи його здатність запобігати перенасиченню фільтрів і забезпечуючи більш надійну продуктивність мережі.
Час простою: майже п'ять годин
Коренева проблема: помилка, що викликає безкінечний цикл перекомпіляції в кеші JIT
Виправлення:
Валідатор Agave компілює всі програми безпосередньо в час виконання (JIT), перед виконанням транзакцій, які посилаються на них. Для оптимізації продуктивності JIT-вихід часто використовуваних програм кешується, що зменшує непотрібні повторні компіляції. В рамках Agave v1.16 існуючий механізм кешування, LoadedPrograms, був замінений новою реалізацією під назвою ExecutorsCache, яка ввела кілька ефективностей.
LoadedPrograms забезпечив глобальний перегляд кешованих програм з урахуванням розгалужень, зменшуючи дублювання облікових даних і дозволяючи потокам виконання транзакцій спільно завантажувати нові програми, запобігаючи конфліктам компіляції. Ключовою особливістю цієї системи було відстеження слота, де програма стає активною (відома як ефективна висота слота), щоб виявляти анулювання кешу, коли оновлюються дані програми в ланцюжку.
Ефективна висота слота більшості програм була отримана з їхнього слота розгортання, який зберігався в їхньому обліковому записі в мережі. Однак програми, розгорнуті за допомогою застарілих завантажувачів, не зберегли цей слот розгортання у своїх облікових записах. LoadedPrograms призначив цим програмам ефективну нульову висоту слота як обхідний шлях.
Виняток виникав, коли була виявлена інструкція розгортання, яка сигналізувала про заміну байт-коду програми. У цьому випадку LoadedPrograms тимчасово вставили запис з правильною ефективною висотою слота. Однак, оскільки в угоді ніколи не згадувався цей запис, вона була дуже вразливою до виселення. При виселенні вихід JIT відкидався, а програма позначалася як розвантажена, але ефективна висота слота зберігалася.
Якщо транзакція пізніше посилалася на цю незавантажену програму, LoadedPrograms перекомпілював її і повторно вставляв запис на ефективній висоті слота. Як правило, це робить програму доступною для виконання на наступній ітерації. Однак, для застарілих програм-завантажувачів, новому виводу JIT було присвоєно нульову висоту слота sentinel, що помістило його позаду попереднього незавантаженого запису. В результаті, LoadedPrograms ніколи не розпізнавав програму як завантажену, запускаючи безперервний цикл перекомпіляції на кожній ітерації.
У версії Agave v1.16 LoadedPrograms не підтримував кооперативну завантаження, що дозволяло упаковувати транзакцію, що спричинила блок. Цей блок потім поширювався по мережі, викликаючи кожному валідатору переосмислити його і потрапити в той же нескінченний цикл повторної компіляції. Оскільки під час збою понад 95% загального стейку кластера використовувало Agave v1.17, більшість валідаторів застрягли на цьому блоку, зупинивши мережу.
Цей баг був виявлений минулого тижня під час розслідування випадку відмови кластера Devnet, і планувалося впровадження патча.@jeff.washington/2024-02-06-solana-mainnet-beta-outage-report-619bd75b3ce0">Вибраним заходом було відкатити зміни до Agave v1.17 та негайно видалити відзнаку функції під час перезавантаження мережі. Це вимкнуло старий завантажувач, що відповідав за викликання помилки, запобігаючи подальших випадків.
Час простою: відсутній
Коренева проблема: неправильне припущення про вирівнювання адреси ELF
Виправлення:
5 серпня,Основні інженери Anza були попереджені про вразливість у клієнті Agave, про що повідомив зовнішній дослідник. Зловмисник міг використати цей недолік для збою валідаторів-лідерів, що призвело до зупинки роботи всієї мережі. У відповідь інженери Anza швидко розробили патч, який потім перевірили кілька сторонніх охоронних фірм.
Програми Solana компілюються за допомогою LLVM в Виконуваний і зв'язуваний формат (ELF). Уразливість виникла через неправильне припущення про вирівнювання адрес у цих згенерованих файлах ELF. Хоча дезінфекція ELF зазвичай примушує до різних перевірок цілісності, вона не перевіряє вирівнювання розділу .text. Ця помилка могла призвести до того, що шкідливий файл ELF визначив неправильно вирівняний розділ .text, що призвело б до переходу віртуальної машини на недійсну адресу. Це призведе до помилки сегментації хоста, що призведе до збою валідатора.
Зловмисник міг би використати цю вразливість, виконавши наступне:
Будь-яке загальнодоступне оновлення патчу негайно зробить вразливість зрозумілою для всіх. Це може дати зловмиснику достатньо часу, щоб реконструювати вразливість і зупинити мережу до того, як достатня кількість стейкінгу буде оновлена. Критична маса валідаторів повинна буде прийняти будь-який патч-реліз якомога швидше, щоб уникнути такого сценарію.
До 7 серпня численні члени Solana Foundation зв'язалася з валідаторами через приватні повідомлення на різних комунікаційних платформах, повідомивши їх про наближений критичний патч та поділившись захешованим повідомленням, яке підтвердило дату та унікальний ідентифікатор події. Кілька відомих членів Anza, Jito та Фонду Solana поділилися цим хешем на X, GitHub та LinkedIn, щоб підтвердити точність повідомлення. Приклад поділених хешів:
Протягом наступного дня члени ядра продовжували звертатися до валідаторів, наголошуючи на важливості терміновості та конфіденційності. У заздалегідь визначений час, 8 серпня, о 14:00 UTC, оператори валідаторів отримали ще одне повідомлення, що містить інструкції щодо завантаження, перевірки та застосування патча. Патч був розміщений у репозиторії Github відомого інженера Anza, а не в основному репозиторії Agave . Інструкції включали перевірку завантажених файлів патчів на відповідність наданих шасумів.
До 20:00 за координованим всесвітнім часом 8 серпня було виправлено супербільшість ставок, що забезпечує безпеку мережі. Після цього вразливість та відповідний патч були публічно оприлюднені, супроводжуються закликом до всіх залишкових валідаторів щодо оновлення.
Тихе розподілання патчу та тендітна координація валідаторів викликали побоювання щодо децентралізації Solana. Незабаром після інциденту виконавчий директор Фонду Solana, Ден Альберт, звернувся до цих критик в інтерв'ю для ЗМІ.
«Я думаю, що важливо не плутати централізацію з можливістю координації. У всьому світі налічується 1500 вузлів, що виробляють блоки, якими керує майже стільки ж людей.... Можливість спілкуватися з ними, або з деякими з них, добровільно, не слід плутати з централізацією».
Корейський тиждень блокчейну (KBW) 2024
Я думаю, що важливо не плутати централізацію з можливістю координації. У всьому світі налічується 1500 вузлів, що виробляють блоки, якими керує майже стільки ж людей.... Можливість спілкуватися з ними, або з деякими з них, добровільно, не слід плутати з централізацією.
На момент написання цієї статті Solana провела більше року без збоїв, досягнувши ключової віхи для видалення тегу «beta» з основної бета-версії. Частота відключень, схоже, зменшується в міру дозрівання мережі, і очікується, що впровадження Firedancer підвищить різноманітність клієнтів, зменшивши ризик невиявлених помилок або крайніх випадків, що спричиняють повне відключення всього кластера. Однак деякі лідери спільноти, зокрема засновник Helius Мерт Мумтаз, прогнозують, що відключення триватимуть. Час покаже.
Велика подяка Зантетсу (Shinobi Systems) та OxIchigo за перегляд попередніх версій цієї роботи.