1511.–12. března 2013
Noc, kdy měl Bitcoin dvě platné historie
Novější a starší verze Bitcoin Core se neshodly na jediném bloku. Vývojáři a těžaři museli během několika hodin rozhodnout, kterou větev podpoří — a zaplatili za to opuštěnou prací.
Večer 11. března 2013 začaly bitcoinové uzly vyprávět dvě různé verze stejné historie. Nový Bitcoin 0.8 přijal blok 225 430 a pokračoval nad ním. Část starších uzlů verze 0.7 jej odmítla, protože množství databázových zámků překročilo praktický limit Berkeley DB. Každá skupina se řídila softwarem, který považovala za správný, a každá viděla svou větev jako platnou. Novější větev měla zpočátku většinu výkonu sdruženého v mining poolech, takže prosté čekání slibovalo spíš prohloubení rozkolu než jeho konec. Vývojáři, burzy a provozovatelé poolů se sešli na IRC. Bez centrálního velína museli najít cestu, po které bude znovu pokračovat dost velká část sítě.
Jeden blok, dva verdikty
Blok 225 430 nebyl vytvořen s úmyslem síť rozdělit. Obsahoval však více transakčních vstupů než dosavadní bloky, a tím zatížil databázi způsobem, který odhalil rozdíl mezi verzemi. Bitcoin 0.8 používal LevelDB a blok zpracoval. Verze 0.7 s Berkeley DB narazila na počet zámků a skončila chybou.
Výsledek byl nebezpečně nenápadný. Obě skupiny uzlů dodržovaly pravidla tak, jak je jejich program dokázal vykonat. Novější větev nebyla podle zamýšlených konsenzuálních pravidel podvodná a starší uzly nebyly napadeny. Síť se rozdělila kvůli nezdokumentovanému praktickému limitu jedné databázové technologie.
Těžaři s verzí 0.8 stavěli nad novým blokem. Těžaři se starší verzí pokračovali od jeho předchůdce. Jakmile obě větve získaly další bloky, platba potvrzená na jedné nemusela existovat na druhé. Uživatel nemohl bezpečně spoléhat na obvyklý počet potvrzení, dokud nebylo jasné, kterou historii přijme ekonomická většina.
Novější větev zpočátku nesla přibližně šedesát procent výkonu. Za běžných okolností by řetězec s větší kumulovanou prací získal náskok. Zde ale starší uzly nemohly nový blok přijmout bez ohledu na jeho práci. Reorganizace sama nepřeklene blok, který místní validační software považuje za neplatný.
Incident tak odhalil hranici jednoduchého pravidla „nejdelší řetězec vyhrává“. Přesněji vyhrává řetězec s největší prací mezi těmi, které uzel nejprve uzná za platné. Když se uzly neshodnou na platnosti, samotný hashrate nestačí k okamžitému sjednocení.
IRC jako provizorní řídicí místnost
Vývojáři si problému všimli, když se začaly lišit výšky a hashe sledovaných uzlů. Komunikace se soustředila na IRC kanál, kde bylo možné porovnávat logy, výkon větví a reakce velkých poolů. Gavin Andresen později v BIP 50 sepsal časovou osu i rozhodnutí, která během noci padla.
Na výběr nebylo mezi čistě správnou a zjevně špatnou větví. Podpora verze 0.8 by zachovala řetězec s větší prací, ale odřízla množství starších uzlů. Návrat k větvi 0.7 znamenal přesvědčit nové těžaře, aby opustili bloky, které už legitimně vytěžili a za které očekávali odměnu.
Praktickým důvodem pro návrat byla kompatibilita. Verze 0.8 dokázala přijmout menší bloky vytvořené pro starší větev, zatímco uzly 0.7 nedokázaly přijmout problematický blok nové větve. Pokud se výkon přesune na větev přijatelnou pro obě skupiny, může se síť znovu spojit bez okamžitého vynuceného upgradu všech starších uzlů.
Rozhodnutí ale nebylo příkazem, který by Andresen rozeslal do protokolu. Vývojáři kontaktovali provozovatele poolů a vysvětlili situaci. Burzy dostaly doporučení zastavit vklady. Bitcoin.org zveřejnil varování a vyzval velké pooly k návratu ke starší verzi softwaru, aby se síť mohla znovu spojit na kompatibilní větvi.
Tato koordinace byla rychlá právě proto, že okruh klíčových účastníků byl ještě relativně malý a lidé se znali z veřejných kanálů. Rychlost pomohla síť zachránit před delším rozkolem, ale zároveň ukázala sociální vazby, na kterých raný provoz závisel. Bitcoin neměl šéfa; měl však lidi, jejichž telefonát nebo zpráva dokázaly přesunout velký podíl výkonu.
Rozhovor na IRC neměl právní sílu ani tajný administrátorský klíč. Jeho význam spočíval v tom, že na jednom místě spojil lidi s odlišnými možnostmi zásahu. Vývojáři uměli vysvětlit příčinu, pooly mohly přesměrovat hashrate, burzy zastavit vklady a provozovatelé uzlů změnit verzi. Každý krok měl vlastní riziko a nikdo nemohl zaručit, že ostatní poslechnou. Rozhodnutí podpořit větev kompatibilní s verzí 0.7 proto nebylo technickým příkazem ze středu sítě, ale koordinovanou sázkou, že tato cesta nejrychleji obnoví společnou historii s nejmenším dopadem na uživatele. Úspěch nelze oddělit od tehdejší malé velikosti komunity ani vydávat za univerzální krizový postup.
Pooly obětují vytěženou práci
Zásadní krok udělaly BTCGuild vedený Michaelem Marseem známým jako Eleuthria a Slush Pool Marka Palatinuse. Oba provozovatelé přešli z verze 0.8 zpět na 0.7 a nasměrovali výkon na starší větev. Tím pomohli změnit poměr práce mezi dvěma historiemi.
Nešlo o bezplatné gesto v tabulce. Bloky vytěžené na opuštěné větvi při reorganizaci přestaly být součástí hlavního řetězce, takže jejich odměny neměly zůstat utratitelné. BIP 50 výslovně připomíná, že pooly obětovaly významné peníze, aby se síť vrátila na společnou větev.
Jakmile starší větev převzala náskok, aktualizované uzly 0.8 ji mohly přijmout a reorganizovat svou historii. Staré uzly na ní už byly. Rozdělení se uzavřelo nikoli tím, že by jedna verze vzdáleně přepsala druhou, ale tím, že dost těžařů vytvořilo více práce nad bodem, který dokázaly ověřit obě.
Během incidentu došlo nejméně k jednomu velkému double spendu, který byl popsán jako experiment, nikoli plánovaný útok. Událost přesto ukázala reálné riziko: transakce mohla být potvrzena na větvi, jež bude později opuštěna. Doporučení zastavit vklady nebylo panikou; chránilo služby před účetními zůstatky založenými na dočasné historii.
Pooly v této chvíli nevlastnily síť. Mohly ovlivnit pořadí bloků výkonem, který jim svěřili těžaři, ale nemohly donutit každý plný uzel přijmout libovolná pravidla. Jejich úspěch závisel na úzkém cíli: vytvořit větev, kterou staré i nové uzly považovaly za platnou, a dodat jí nejvíce práce.
Rozbor incidentu místo vítězného mýtu
Gavin Andresen incident později popsal v BIP 50. Dokument netvrdí, že síť fungovala bezchybně. Vysvětluje příčinu, průběh, ztracené bloky, dvojí útratu i opatření, která mají podobný rozpor zachytit dřív. Díky zveřejněnému rozboru nezůstala zkušenost z krizové noci jen v paměti jejích účastníků. Mohli z ní vycházet i další vývojáři.
Jedním poučením bylo, že konsenzus nezahrnuje jen pravidla napsaná v komentáři nebo dokumentaci. Praktické chování široce nasazeného programu se může stát omezením sítě, i když nikdo nezamýšlel, aby mělo měnový význam. Migrace databáze proto nesmí být považována za čistě interní změnu, pokud může změnit přijetí bloku.
Dalším poučením byla potřeba koordinovat upgrady opatrněji a testovat bloky blízko provozních limitů. Verze 0.8 přinesla výkonové zlepšení, ale rozdíl se projevil až ve skutečném řetězci. Po incidentu vývojáři zavedli dočasné limity a připravili cestu, která dovolila staré závislosti později bezpečně opustit.
Příběh se někdy používá jako důkaz, že Bitcoin řídí několik vývojářů, jindy jako důkaz, že je automaticky nezničitelný. Ani jedna zkrácená verze nesedí. Lidé dokázali naléhavě koordinovat opravu, ale potřebovali spolupráci poolů, burz a provozovatelů uzlů. Software rozhodoval na každém počítači zvlášť a společný výsledek vznikl teprve jejich souběhem.
Noc z 11. na 12. března skončila jedním hlavním řetězcem, nikoli proto, že by rozdíly zmizely samy. Někteří účastníci upozornili na problém, jiní pozastavili služby a těžaři zaplatili ztracenou prací za návrat ke kompatibilní historii. Bitcoin přežil svou dvojí minulost díky kombinaci pravidel, ekonomických nákladů a lidí ochotných přiznat, že novější software tentokrát musí ustoupit.
BIP 50 má cenu právě proto, že incident neuzavírá větou o vítězství decentralizace. Zaznamenává konkrétní příčinu, časovou osu, ztracenou práci i kroky, které měly podobnému překvapení zabránit. Z nepříjemného selhání tak vzniká podklad pro další testování. Současně zůstává otevřená otázka: kolik nepsaných předpokladů se skrývá mezi dvěma verzemi programu, které obě považujeme za kompatibilní? Konsensus není jen seznam pravidel na papíře. Nezávislé implementace a uzly musí dojít ke stejnému výsledku i v okrajových případech. Jak důležitá je tato shoda, ukáže nejzřetelněji chvíle, kdy se rozpadne.
Postavy a pojmy v Atlasu
Prameny a hranice příběhu
- 01BIP 50 — March 2013 Chain Fork Post-Mortem
Primární technická zpráva o příčině, hashratu, koordinaci BTCGuild a Slush Poolu, double spendu a nápravě.
- 02Bitcoin.org — 11/12 March 2013 Chain Fork Information
Dobová veřejná upozornění pro obchodníky a uživatele během rozdělení sítě.
- 03Bitcoin Core — version 0.8.0 release notes
Kontext nové databázové vrstvy a změn verze, na níž se nečekaná nekompatibilita projevila.