1315 sierpnia 2010

Dzień, w którym powstały 184 miliardy bitcoinów

Jedna transakcja ominęła kontrolę kwot i stworzyła liczbę bitcoinów wielokrotnie przekraczającą planowaną podaż. Poprawka pojawiła się w ciągu kilku godzin. Incydent pokazał jednak, że reguły pieniężne są tak niezawodne jak kod, który je egzekwuje.

W niedzielę 15 sierpnia 2010 roku Jeff Garzik zwrócił uwagę na świeżo wydobyty blok 74 638 i kwotę, która nie powinna istnieć. Jedna transakcja utworzyła dwa wyjścia, każde o wartości ponad 92 miliardów BTC. Ich suma była niemal dziewięć tysięcy razy większa niż planowana podaż Bitcoina. O 18:08:49 UTC Garzik założył na forum wątek „Strange block 74638” i zamieścił dane bloku. W ciągu kilku minut stało się jasne, że to nie błąd eksploratora ani źle postawiony przecinek dziesiętny. Sieć zaakceptowała blok, który naruszał jej własną regułę monetarną. Jeśli użytkownicy mieli nadal wierzyć, że monet nie można tworzyć wedle uznania, musieli znaleźć błąd, naprawić oprogramowanie i przekonać wystarczająco wielu uczestników, by kontynuowali inną gałąź historii.

01

Dziwny blok 74 638

Wpis Garzika był krótki i rzeczowy. Pokazywał hash transakcji i dwa ogromne wyjścia. Późniejszy wydruk printblock w tej samej dyskusji podawał ich dokładną wartość: każde zawierało 92 233 720 368,54275808 BTC. Blok obejmował również osobną transakcję coinbase, wypłacającą górnikowi 50,51 BTC. Przy zwykłej podstawowej nagrodzie pięćdziesięciu bitcoinów te dwa wyjścia wyglądały absurdalnie: ktoś właśnie utworzył ponad 184 miliardy jednostek.

Nie znamy nazwiska autora transakcji ani jego publicznego wyjaśnienia. Zachowany łańcuch pokazuje, co się wydarzyło, ale nie mówi, kto wykorzystał błąd i w jakim celu. Przypisanie ataku konkretnemu hakerowi oznaczałoby dodanie informacji, której nie potwierdzają źródła. Wiadomo, że transakcję skonstruowano tak, by wykorzystała słaby punkt walidacji.

Sieć zaakceptowała transakcję, ponieważ stary kod sprawdzał najpierw poszczególne wyjścia, a potem ich sumę. Każda z ogromnych kwot mieściła się w zakresie używanego typu liczbowego, lecz ich suma przekroczyła jego górną granicę. Wynik zawinął się do zakresu liczb ujemnych. Kolejna kontrola błędnie uznała więc, że nie powstaje niedozwolona wartość dodatnia.

Nie chodziło więc o sfałszowanie podpisu, zmianę starszej transakcji ani przejęcie większości hashratu. Atakujący wykorzystał sposób, w jaki konkretna implementacja radziła sobie z liczbami całkowitymi. Matematyczna reguła „nie wydawaj więcej, niż wchodzi” była prawidłowa; program z powodu przepełnienia nie zastosował jej tak, jak ludzie zamierzali.

Blok należał już do łańcucha, za którym podążała sieć. Każdy węzeł korzystający z wadliwej wersji uznawał go za prawidłowy, a kolejni górnicy mogli na nim budować. Samo ujawnienie problemu nie wystarczało. Trzeba było zareagować, zanim błędna historia rozprzestrzeni się dalej, a ogromne wyjścia zaczną być wydawane.

02

Błąd między regułą a maszyną

Limit 21 milionów często przedstawia się jako niezmienne prawo Bitcoina. Incydent pokazał dokładniej, co to oznacza. Za limitem stoją reguły konsensusu, które każdy program i każdy pełny węzeł muszą poprawnie stosować. Jeśli wszystkie powszechnie używane wersje węzłów mają ten sam błąd, mogą na pewien czas zaakceptować stan sprzeczny z zamierzoną zasadą.

Przepełnienie liczby całkowitej to od dawna znany problem programistyczny. Rejestr komputera ma ograniczony zakres. Po jego przekroczeniu wynik obliczenia może znaleźć się po zupełnie innej stronie osi liczbowej. W systemie księgowym taki szczegół ma zasadnicze znaczenie. Sumę trzeba sprawdzać w trakcie obliczeń, a nie dopiero na końcu, i każda kwota musi pozostać w dozwolonym zakresie.

Dzisiejszy Bitcoin Core wykonuje więc kilka oddzielnych kontroli. Wyjście nie może być ujemne ani przekraczać maksymalnej podaży pieniądza, a sumę sprawdza się ponownie po każdym dodaniu. Te linie kodu nie wynikają z abstrakcyjnej ostrożności. Stoi za nimi doświadczenie zdarzenia, w którym brak jednego zabezpieczenia pozwolił sieci zapisać ekonomicznie niemożliwą transakcję.

Błąd jednocześnie pokazuje różnicę między specyfikacją a oczekiwaniem społecznym. Nikt na forum poważnie nie twierdził, że ogromne monety są prawidłowe tylko dlatego, że stare oprogramowanie je zaakceptowało. Uczestnicy zgadzali się, że chodzi o naruszenie zamierzonej reguły. Ta zgoda wymagała jednak technicznego środka: nowej wersji, która odrzuci wadliwy blok.

Właśnie tutaj spotykają się kod i ludzie. Kod decyduje deterministycznie, jaki blok węzeł zaakceptuje. Ludzie decydują, jaki kod zainstalują, gdy ujawnią sprzeczność z zamierzonymi regułami. Incydent nie był głosowaniem o nowej emisji; był wyścigiem o odnowienie reguły, którą społeczność już uważała za podstawę systemu.

Przepełnienie jest zdradliwe właśnie dlatego, że maszyna nie dostrzega absurdalności, którą człowiek rozpoznaje natychmiast. Procesor operuje na liczbie przechowywanej w ograniczonej przestrzeni; jeśli obliczenie przekroczy jej granicę, wynik może zawinąć się do innej części zakresu. Stary kod sprawdzał poszczególne wyjścia, ale przy dodawaniu nie utrzymywał bieżącej sumy w bezpiecznych granicach. Transakcja przeszła więc przez kilka lokalnie rozsądnych warunków, a mimo to naruszyła ich ogólny sens. Poprawka musiała być konkretna: nie wystarczyło napisać w komentarzu, że bitcoinów nigdy nie będzie więcej niż 21 milionów. Każdy węzeł potrzebował reguły, która potrafi w każdym obliczeniu faktycznie wymusić to stwierdzenie.

03

Naprawa pod presją

Po ogłoszeniu na forum pojawiła się rekomendacja, aby przestać akceptować transakcje i tymczasowo nie wydobywać. Każdy nowy blok nad wadliwą transakcją zwiększyłby ilość pracy, którą trzeba będzie porzucić. W sieci bez centralnego wyłącznika Satoshi nie mógł zatrzymać wydobywania. Mógł tylko wydać naprawę i przekonać operatorów, aby ją uruchomili.

Wersja 0.3.10 wprowadziła poprawne kontrole kwot i odrzuciła blok 74 638. Naprawione węzły wróciły do ostatniego wspólnego prawidłowego punktu i górnicy zaczęli budować alternatywną gałąź bez transakcji inflacyjnej. Dwie historie przez jakiś czas konkurowały na podstawie zgromadzonej pracy.

Satoshi następnie ogłosił, że dobry łańcuch wyprzedził zły. Zaktualizowane oprogramowanie przeprowadziło reorganizację łańcucha i wadliwy blok zniknął z aktywnej historii. Transakcje z gałęzi, które nie były same nieprawidłowe, mogły wrócić do kolejki i być później ponownie włączone; ogromne wyjścia nie mogły jednak istnieć zgodnie z nowymi kontrolami.

Ta naprawa miała cenę. Górnicy na porzuconej gałęzi stracili nagrody i użytkownicy musieli zaakceptować, że kilka godzin historii nie będzie kontynuowane. W 2010 roku sieć była mała i koordynacja była szybka. Ten sam zabieg w znacznie większym ekosystemie oznaczałby więcej uczestników ekonomicznych, wariantów oprogramowania i sporów o to, gdzie dokładnie leży granica naprawy.

Szybką reakcję często przedstawia się jako cudowną interwencję Satoshiego. W rzeczywistości składała się ona z konkretnych, widocznych działań: Garzik ujawnił problem, inni przeanalizowali przepełnienie, deweloperzy przygotowali zmianę, operatorzy zainstalowali nową wersję klienta Bitcoina, a górnicy dostarczyli pracę właściwej gałęzi. Autor mógł zaproponować poprawkę, ale sieć musiała ją rzeczywiście przyjąć.

04

Najtwardsze reguły potrzebują najpokorniejszego rozwoju

Po naprawie liczba prawidłowo utworzonych bitcoinów wróciła do zamierzonego zakresu i wadliwe miliardy nie mogły być wydane w kontynuowanym łańcuchu. Incydent nie skończył się więc trwałą inflacją. Nie jest to jednak tylko kuriozum z wersji beta. Jest przypomnieniem, że pewność pieniężna nie wynika z hasła, ale z wielokrotnie weryfikowanego programu.

Bitcoin jest często przedstawiany jako system przeciwny do systemów, w których centralna władza zmienia podaż decyzją. Tutaj również ludzie nie zniknęli. Deweloperzy piszą implementacje, recenzenci szukają błędów, operatorzy wybierają wersje i górnicy tworzą kolejność bloków. Różnica polega na tym, że interwencja jest publiczna i każdy węzeł może samodzielnie odrzucić reguły, z którymi nie zgadza się.

Zdarzenie wyjaśnia również ostrożność, z jaką dzisiaj zmienia się konsensusowy kod. Mała optymalizacja arytmetyki może mieć konsekwencje pieniężne. Testy, więcej kontroli implementacji i powolna recenzja nie są biurokracją dodatkową; są obroną przed powtórzeniem się chwili, gdy kilka bitów sprawiło, że niedozwolona kwota liczona w miliardach została uznana za prawidłową.

Jeff Garzik nie uczynił sieci bezpieczną jednym wpisem na forum, ale pokazał zaletę publicznej księgi rachunkowej. Każdy mógł zobaczyć dziwny blok, ponownie policzyć jego wyjścia i sprawdzić naprawę. Błąd nie był ukryty w wewnętrznej bazie danych operatora. Leżał przed całą społecznością wraz z dowodem, że stare węzły go zaakceptowały.

Limit podaży przetrwał incydent inaczej, niż sugeruje słowo „niezmienny”. Nie dlatego, że oprogramowanie nie mogło zawieść, ale dlatego, że błąd był widoczny, istniała wspólna reguła, do której można było wrócić, i wystarczająca liczba uczestników przeprowadziła naprawę. Historia 184 miliardów bitcoinów nie jest zaprzeczeniem stałej podaży. Jest historią tego, czego naprawdę wymaga jej utrzymanie.

To wydarzenie przypomina również, że publiczny dostęp do kodu sam w sobie nie eliminuje błędu. Otwarty kod umożliwił ludziom odnalezienie, porównanie i naprawienie problemu bez czekania na pojedynczego dostawcę, ale decydująca była uwaga konkretnych uczestników. Ktoś musiał zauważyć niemożliwe liczby, ktoś musiał znaleźć wadliwy warunek, a operatorzy musieli przyjąć aktualizację. Przejrzystość stworzyła możliwość kontroli; dopiero działanie zamieniło ją w obronę sieci. Dlatego ta historia pozostaje ważna nawet po latach: bezpieczeństwo Bitcoina nie leży w wyobrażeniu o doskonałym programie pierwotnym, lecz w połączeniu precyzyjnych reguł, niezależnej weryfikacji i zdolności reagowania na błąd bez jego ukrywania.

Atlas

Postacie i pojęcia w Atlasie

OVFLValue Overflow IncidentGARZIKJeff GarzikTXTransakcjaRULESReguły konsensusuCOREBitcoin CoreNODEFull NodeREORGReorg
  1. 01
    BitcoinTalk — Strange block 74638

    Oryginalne ostrzeżenie Jeffa Garzika, dokładne wyjścia, analiza przepełnienia i czasowa oś reakcji.

  2. 02
    BitcoinTalk — overflow bug SERIOUS

    Koordynacja deweloperów w czasie incydentu, poprawka walidacji i przejście na prawidłowy łańcuch.

  3. 03
    Bitcoin Core — transaction consensus checks

    Bieżąca implementacja kontroli zakresu poszczególnych wyjść i ich sumy.

Następna historia · 14Slush Pool: pomysł z Pragi przeciwko losowaniu wśród górników