1511–12 marca 2013
Noc, kiedy Bitcoin miał dwie prawidłowe historie
Nowniejsza i starsza wersja Bitcoin Core nie zgadzały się co do jednego bloku. Deweloperzy i górnicy musieli w ciągu kilku godzin zdecydować, którą gałąź wesprą — i zapłacili za to opuszczoną pracą.
Wieczorem 11 marca 2013 roku węzły Bitcoina zaczęły kontynuować dwie wersje tej samej historii. Nowa wersja Bitcoin 0.8 przyjęła blok 225 430 i budowała na nim kolejne bloki. Część starszych węzłów z wersją 0.7 go odrzuciła: przetworzenie bloku wymagało więcej blokad bazy danych, niż pozwalał praktyczny limit Berkeley DB. Obie grupy postępowały zgodnie ze swoim oprogramowaniem i uznawały własną gałąź za prawidłową. Początkowo nowsza gałąź miała za sobą większość mocy skupionej w pulach wydobywczych. Samo czekanie groziło więc pogłębieniem rozłamu. Deweloperzy, giełdy i operatorzy pul spotkali się na IRC. Bez centralnego dowództwa musieli znaleźć drogę, którą wystarczająco duża część sieci mogłaby znów podążać wspólnie.
Jeden blok, dwa werdykty
Blok 225 430 nie został stworzony z zamiarem podzielenia sieci. Zawierał jednak więcej wejść transakcyjnych niż poprzednie bloki, i tym samym obciążył bazę danych w sposób, który ujawnił różnicę między wersjami. Bitcoin 0.8 używał LevelDB i przetworzył blok. Wersja 0.7 z Berkeley DB napotkała na liczbę blokad i zakończyła się błędem.
Przyczyna rozłamu była niepozorna, a przez to niebezpieczna. Obie grupy węzłów stosowały reguły tak, jak pozwalało im na to oprogramowanie. Nowsza gałąź nie łamała zamierzonych zasad konsensusu, a starsze węzły nie zostały zaatakowane. Sieć rozdzielił nieudokumentowany praktyczny limit jednej z technologii baz danych.
Górnicy z wersją 0.8 budowali nad nowym blokiem. Górnicy ze starszą wersją kontynuowali od jego poprzednika. Jak tylko obie gałęzie uzyskały kolejne bloki, płatność potwierdzona na jednej nie musiała istnieć na drugiej. Użytkownik nie mógł bezpiecznie polegać na zwykłej liczbie potwierdzeń, dopóki nie było jasne, którą historię zaakceptuje większość ekonomiczna.
Nowa gałąź początkowo nosiła około sześćdziesiąt procent mocy. W normalnych okolicznościach łańcuch z większym nakładem pracy wygrałby. Tutaj jednak starsze węzły nie mogły zaakceptować nowego bloku bez względu na jego pracę. Reorganizacja sama w sobie nie przekracza bloku, który lokalny program walidacyjny uważa za nieprawidłowy.
Incident ujawnił granicę prostego regułu „najdłuższy łańcuch wygrywa”. Dokładniej wygrywa łańcuch z największym nakładem pracy wśród tych, które węzeł najpierw uzna za prawidłowe. Kiedy węzły nie zgadzają się co do prawidłowości, sam hashrate nie wystarcza do natychmiastowego zjednoczenia.
IRC jako prowizoryczna sala dowodzenia
Deweloperzy zauważyli problem, kiedy zaczęły się różnić wysokości i hasze śledzonych węzłów. Komunikacja koncentrowała się na kanale IRC, gdzie można było porównywać logi, moc gałęzi i reakcje dużych pooli. Gavin Andresen później w BIP 50 opisał chronologię i decyzje, które zapadły w nocy.
Nie było wyboru między czysto prawidłową a oczywiście złą gałęzią. Wspieranie wersji 0.8 utrzymałoby łańcuch z większym nakładem pracy, ale odcięłoby liczbę starszych węzłów. Powrót do gałęzi 0.7 oznaczał przekonanie nowych górników, aby opuścili bloki, które już legitinnie wydobyli i za które oczekiwali nagrody.
Praktycznym powodem powrotu była kompatybilność. Wersja 0.8 mogła zaakceptować mniejsze bloki stworzone dla starszej gałęzi, podczas gdy węzły 0.7 nie mogły zaakceptować problematycznego bloku nowej gałęzi. Jeśli moc przechodzi na gałąź akceptowalną dla obu grup, sieć może się ponownie połączyć bez natychmiastowego wymuszonego uaktualnienia wszystkich starszych węzłów.
Nie był to rozkaz, który Andresen mógł rozesłać przez protokół. Deweloperzy skontaktowali się z operatorami pul wydobywczych i wyjaśnili sytuację. Giełdom zalecono wstrzymanie wpłat. Bitcoin.org opublikował ostrzeżenie i wezwał duże pule do powrotu do starszej wersji oprogramowania, aby sieć mogła znów połączyć się na zgodnej gałęzi.
Ta koordynacja była szybka właśnie dlatego, że krąg kluczowych uczestników był jeszcze względnie mały, a ludzie znali się z publicznych kanałów. Szybkość pomogła sieci uniknąć dłuższego rozłamu, ale jednocześnie ujawniła społeczne więzi, na których wczesny przebieg zależał. Bitcoin nie miał szefa; miał jednak ludzi, których telefon lub wiadomość mogli przenieść duży udział mocy.
Rozmowa na IRC nie miała mocy prawnej, a jej uczestnicy nie dysponowali tajnym kluczem administratora. Połączyła jednak ludzi, którzy mogli zadziałać na różne sposoby. Deweloperzy potrafili wyjaśnić przyczynę, pule wydobywcze przekierować hashrate, giełdy wstrzymać wpłaty, a operatorzy węzłów zmienić wersję oprogramowania. Każdy krok niósł ryzyko i nikt nie mógł zagwarantować współpracy pozostałych. Poparcie gałęzi zgodnej z wersją 0.7 nie było więc rozkazem z centrum sieci. Było wspólnie podjętym ryzykiem, opartym na przekonaniu, że ta droga najszybciej przywróci wspólną historię przy możliwie małych skutkach dla użytkowników. Sukcesu nie można oddzielić od niewielkiego wówczas rozmiaru społeczności ani traktować jako gotowej procedury na każdy kryzys.
Pule ofiarują wydobywaną pracę
Decydujący krok wykonały BTCGuild, kierowany przez Michaela Marsee, znanego jako Eleuthria, oraz Slush Pool Marka Palatinusa. Obaj operatorzy wrócili z wersji 0.8 do 0.7 i skierowali moc obliczeniową na starszą gałąź. Pomogli w ten sposób zmienić proporcje skumulowanej pracy między dwiema historiami.
Nie było to bezpłatne gestem w tabeli. Bloki wydobyte na opuszczonej gałęzi podczas reorganizacji przestały być częścią głównego łańcucha, więc ich nagrody nie mogły pozostać do wydania. BIP 50 wyraźnie przypomina, że pule ofiarowały znaczne pieniądze, aby sieć wróciła na wspólną gałąź.
Jak tylko starsza gałąź przejęła przewagę, zaktualizowane węzły 0.8 mogły ją zaakceptować i zreorganizować swoją historię. Stare węzły były już na niej. Podział się zamknął nie dlatego, że jedna wersja zdalnie przepisała drugą, ale dlatego, że wystarczająco dużo górników stworzyło więcej pracy nad punktem, który mogli zweryfikować obie.
Podczas incydentu doszło przynajmniej do jednego dużego double spendu, który został opisany jako eksperyment, a nie planowany atak. Wydarzenie pokazało jednak rzeczywiste ryzyko: transakcja mogła być potwierdzona na gałęzi, która zostanie później opuszczona. Zalecenie zatrzymania depozytów nie było paniką; chroniło usługi przed księgowymi saldami opartymi na tymczasowej historii.
Pule w tym momencie nie władały siecią. Mogły one wpływać na kolejność bloków mocą, którą im powierzyli górnicy, ale nie mogły zmusić każdy pełny węzeł do zaakceptowania dowolnych reguł. Ich sukces zależał od wąskiego celu: stworzenia gałęzi, którą stare i nowe węzły uważały za prawidłową, i dostarczenia jej najwięcej pracy.
Analiza incydentu zamiast legendy o zwycięstwie
Gavin Andresen opisał później incydent w BIP 50. Dokument nie twierdzi, że sieć działała bezbłędnie. Wyjaśnia przyczynę, przebieg wydarzeń, utracone bloki, podwójne wydanie środków oraz działania, które mają pozwolić wcześniej wykrywać podobne rozbieżności. Dzięki opublikowanej analizie doświadczenie kryzysowej nocy nie pozostało wyłącznie w pamięci jej uczestników. Mogli z niego korzystać także inni deweloperzy.
Jednym z wniosków było to, że konsensus nie obejmuje tylko reguł napisanych w komentarzu lub dokumentacji. Praktyczne zachowanie szeroko wdrożonego programu może stać się ograniczeniem sieci, nawet jeśli nikt nie zamierzał, aby miało znaczenie walutowe. Migrowanie bazy danych nie powinno być więc uważane za czysto wewnętrzną zmianę, jeśli może zmienić akceptację bloku.
Kolejnym wnioskiem była potrzeba koordynowania uaktualnień bardziej ostrożnie i testowania bloków blisko operacyjnych limitów. Wersja 0.8 przyniosła poprawę wydajności, ale różnica ujawniła się dopiero w rzeczywistym łańcuchu. Po incydencie deweloperzy wprowadzili tymczasowe limity i przygotowali drogę, która pozwoliła starszym zależnościom później bezpiecznie opuścić.
Historia jest czasem używana jako dowód, że Bitcoin jest kontrolowany przez kilku deweloperów, a czasem jako dowód, że jest automatycznie niezniszczalny. Żadna z tych skrótowych wersji nie jest prawdziwa. Ludzie byli w stanie pilnie skoordynować naprawę, ale potrzebowali współpracy pooli, giełd i operatorów węzłów. Oprogramowanie decydowało na każdym komputerze oddzielnie, a wspólny wynik powstał dopiero dzięki ich współdziałaniu.
Noc z 11 na 12 marca zakończyła się powrotem do jednego głównego łańcucha, ale rozbieżności nie zniknęły same. Jedni uczestnicy zauważyli problem, inni wstrzymali usługi, a górnicy poświęcili wykonaną już pracę, aby przywrócić zgodną historię. Bitcoin przetrwał rozdwojenie dzięki połączeniu reguł, poniesionych kosztów i gotowości ludzi do uznania, że tym razem nowsze oprogramowanie musi ustąpić.
Wartość BIP 50 polega na tym, że nie zamyka incydentu hasłem o zwycięstwie decentralizacji. Dokument zapisuje konkretną przyczynę, chronologię, utraconą pracę i kroki przewidziane, by uniknąć podobnej niespodzianki. Nieprzyjemna awaria staje się podstawą do kolejnych testów. Pozostaje też pytanie: ile niepisanych założeń dzieli dwie wersje programu, które uważamy za zgodne? Konsensus to więcej niż lista reguł na papierze. Niezależne implementacje i węzły muszą dojść do tego samego wyniku nawet w przypadkach brzegowych. Znaczenie tej zgodności widać najwyraźniej wtedy, gdy jej zabraknie.
Postacie i pojęcia w Atlasie
Źródła i granice opowieści
- 01BIP 50 — Raport z przebiegu zdarzeń rozszczepienia łańcucha z marca 2013
Główny techniczny raport o przyczynie, hashracie, koordynacji BTCGuild i Slush Poolu, double spendzie i naprawie.
- 02Bitcoin.org — Informacje o rozszczepieniu łańcucha z 11/12 marca 2013
Czasowe publiczne ostrzeżenie dla handlowców i użytkowników podczas rozszczepienia sieci.
- 03Bitcoin Core — notatki do wydania wersji 0.8.0
Kontekst nowej warstwy bazy danych i zmian wersji, na której nieoczekiwana niezgodność ujawniła się.