720 / 736OVFL

Value Overflow Incident

Переповнення значення в блоці 74 638

Value Overflow Incident був критичним інцидентом консенсусу 15 серпня 2010 року: транзакція в блоці 74 638 використала переповнення 64-бітної суми, через що два величезні виходи пройшли перевірку й додали 2^64 зайвих сатоші до гілки, яку майнили.

Помилка була в реалізації правила перевірки, а не в криптографії чи графіку емісії. Кожен вихід був додатним, але їхня сума через переповнення ставала від’ємною. Різниця між входом і цим від’ємним результатом виглядала як комісія. Версія 0.3.10 додала верхні межі для окремих виходів і поточної суми; після реорганізації на виправлену гілку хибний блок зник з активної історії.

15 серпня 2010 року розробник Jeff Garzik звернув увагу на дивний блок 74 638. Транзакція 1d5e512a9723cbef373b970eb52f1e9598ad67e7408077a82fdac194b65333c9 витратила єдиний вхід у 0,50 BTC і створила два величезні виходи. Тогочасний вивід printblock показує для кожного з них 92 233 720 368,54275808 BTC. Автора транзакції, що використала вразливість, достовірно не встановлено: публічний запис підтверджує її дані, а не особу чи мотив творця. [1]

Bitcoin тоді подавав суми як 64-бітові цілі числа зі знаком у сатоші. Цілочисельне значення кожного виходу, також зафіксоване шістнадцятковим записом 0x7ffffffffff85ee0, було додатним і трохи меншим за максимум int64. Проте сума 18 446 744 073 708 551 616 сатоші перевищила допустимий діапазон і перетворилася на −1 000 000 сатоші. Стара перевірка приймала цей від’ємний результат, порівнюючи його з входом. Це була арифметична помилка, а не злам підписів. Перший JSON-вивід у дискусії має інші останні цифри після коми; для точного розрахунку тут використано ціле значення, підтверджене і printblock, і шістнадцятковим записом. [1]

Від’ємна сума виходів −0,01 BTC за входу 0,50 BTC створювала видимість комісії 0,51 BTC. Тому майнер отримав у coinbase 50,51 BTC замість базової винагороди 50 BTC. Якщо відняти витрачений вхід і врахувати надлишок у coinbase, два величезні виходи збільшили пропозицію в хибній гілці рівно на 18 446 744 073 709 551 616 сатоші: 2^64 сатоші, або 184 467 440 737,09551616 BTC. Отже, це число не є просто сумою двох виходів. [2]

Спільнота реагувала публічно й під тиском часу. Lfm назвав помилку серйозною, Gavin Andresen запропонував швидко звіряти кожен вихід із 21 мільйоном BTC, а Satoshi Nakamoto оприлюднив ширше рішення: відхиляти від’ємний або завеликий вихід і завелику поточну суму після кожного додавання. Satoshi також попросив майнерів тимчасово зупинитися, щоб нова дійсна гілка могла швидше наздогнати й замінити хибну. [2]

Satoshi оголосив версію 0.3.10 15 серпня 2010 року о 23:48 за часом форуму, приблизно через п’ять годин сорок хвилин після повідомлення Garzik. Оновлені вузли вважали транзакцію та блок 74 638 недійсними й будували над останнім спільним чинним блоком. Згодом тогочасне оголошення повідомило, що добра гілка випередила погану, тому оновлений клієнт міг автоматично реорганізуватися без ручного видалення файлів blockchain. [3]

Старий блок не редагували в центральній базі. Існували дві конкурентні історії: старі вузли приймали блок за первинними правилами, а виправлені відхиляли його й визнавали лише роботу над чинним предком. Коли виправлена гілка накопичила більше Proof of Work, мережа пішла за нею, а інфляційний блок зник з активної історії; вирішальними були встановлення правил користувачами й майнерами та подальша робота, а не наказ адміністратора. [3]

Запроваджений тоді захист досі видно в Bitcoin Core. CheckTransaction відхиляє від’ємний вихід, вихід понад MAX_MONEY і поточну суму поза MoneyRange; перевірка після кожного додавання не дає небезпечній сумі переповнитися до порівняння. Коментар коду прямо посилається на CVE-2010-5139, а окрема перевірка повторних входів нагадує про інший інцидент CVE-2018-17144. [4]

Інцидент показує, що межа 21 мільйон не є магічною сталою, захищеною самим хешуванням: її забезпечують точні правила перевірки та правильна реалізація. Аудит має охоплювати діапазони значень, безпечне додавання, coinbase й комісії, порядок перевірок, граничні тестові вектори та збіг незалежних реалізацій. Історія водночас показує здатність ранньої спільноти швидко усувати помилки та її тодішню залежність від небагатьох розробників, майнерів і ручної координації. [5]

Для повної картини прочитайте також Bitcoin Core, Правила консенсусу, Транзакція, UTXO, Reorg, Soft Fork.

01Чи існували колись 184 мільярди BTC у чинному Bitcoin?

Вони коротко існували в тоді видобутій хибній гілці як наслідок експлуатаційного блоку. Виправлені вузли відхилили її, а чинна гілка реорганізувала, тож величезні виходи не входять до сучасного активного blockchain чи набору UTXO. Сам історичний інцидент підтверджений блоком і тогочасною реакцією.

02Чи назавжди інцидент порушив межу 21 мільйон?

Ні в історії, яку приймають сьогодні: виправлені правила консенсусу відхилили хибний блок, а його виходи зникли під час реорганізації. Подія показала, що межа залежить від правильної перевірки й фактично запущеного ПЗ; твердження в документації саме по собі не забезпечує пропозицію.

DOC · 001BitcoinTalk — Strange block 74638Первинне джерело DOC · 002BitcoinTalk — overflow bug SERIOUSПервинне джерело DOC · 003BitcoinTalk — Version 0.3.10, block 74638 overflow patchПервинне джерело DOC · 004Bitcoin Core — current CheckTransaction overflow checksДокументація DOC · 005CVE — CVE-2010-5139Документація
Переглянуто: Спочатку джерела · Не інвестиційна порада