Autor: Tia, Techub News
Blockchain obětoval efektivitu kvůli svému decentralizovanému designu, proto byla zlepšení rychlosti provádění jedním z naléhavých problémů, které je třeba řešit. „Prováděcí vrstva“ blockchainu je klíčová část, která zpracovává každou transakci a přidává ji do řetězce. Aby se urychlila zpracovatelská kapacita, stalo se zlepšení prováděcí vrstvy jednou z klíčových strategií, a paralelní provádění je v této oblasti důležitým průlomem.
Tradiční blockchainy obvykle zpracovávají transakce postupně, což výrazně omezuje rychlost transakcí, zejména v hustě transakčních sítích, což může způsobit zácpy. Nicméně, díky paralelnímu provádění lze zpracovávat více transakcí současně, čímž se výrazně zvyšuje efektivita provádění a zmírňuje tlak na řetězec.
Abychom lépe pochopili, co je paralelní, začneme s prováděním a jako příklad si vezmeme Ethereum v režimu PBS po sloučení, abychom vysvětlili, co je provádění, a zároveň ukázali, jaké místo má provádění v celém životním cyklu transakcí.
Konkrétní fáze provádění transakcí
Transakce vstupuje do paměťového poolu a je filtrována a tříděna: to je fáze předzpracování po podání transakce, zahrnuje interakci mezi Mempool, Searcher a Builder, aby se dokončila filtrace a třídění transakcí.
Builder sestavuje blok (ale neprovádí): Builder uspořádává ziskové transakce do jednoho bloku, aby dokončil balení a třídění transakcí.
Proposer ověřuje a předkládá blok: po dokončení sestavení bloku Builder odešle návrh bloku Proposerovi. Proposer ověřuje strukturu bloku a obsah transakcí, poté oficiálně předkládá blok do sítě, aby zahájil provádění.
Provádění transakcí: po předložení bloku uzly provádějí transakce v bloku jednu po druhé. To je klíčová fáze pro aktualizaci stavu, každá transakce vyvolá volání smart kontraktu, změnu zůstatku účtu nebo změnu stavu.
Svědkové svědčí: Ověřovatelé svědčí o výsledcích provádění bloku a kořeni stavu a používají je jako konečné potvrzení. To zajišťuje pravost a platnost bloku na prováděcí vrstvě a zabraňuje nesrovnalostem.
Synchronizace stavu: Každý uzel synchronizuje výsledky provádění bloku (například změny zůstatku účtu, aktualizace stavu smlouvy atd.) do svého místního stavu. Po provedení každé transakce uzel vypočítá a uloží nový kořen stavu, který se použije jako počáteční stav v dalším bloku.
Samozřejmě, to je pouze synchronizace stavu transakcí na úrovni bloků, aby se udržel nejnovější stav na řetězci, obvykle uzly synchronizují data po blocích a neustále ověřují bloky a stavy. Ale aby se dosáhla konečnosti v mechanismu POS, je také nutné, aby agregátor shromáždil podpisy svědků z každého slotu do jednoho kompletního podpisu a předal ho navrhovateli v dalším slotu, a ověřovatelé musí po jednom epochu potvrdit stav všech bloků v tomto epochu na základě počtu hlasů, aby vytvořili dočasný konsensuální stav kontrolního bodu. Když dva po sobě jdoucí epochy získají podporu většiny ověřovatelů, bloky a transakce dosáhnou konečnosti.
Z pohledu celého životního cyklu transakcí se provádění odehrává poté, co Proposer ověří strukturu bloku a obsah transakcí, které Builder poslal. Skutečný proces provádění musí zpracovávat transakce postupně a aktualizovat příslušné stavy účtů nebo smluv. Po dokončení všech transakcí Proposer spočítá nový kořen stavu (merkle kořen), což je shrnutí výsledků provádění všech transakcí v aktuálním bloku a konečného globálního stavu. Zjednodušeně řečeno, celý proces provádění bloku zahrnuje sérii výpočtů potřebných k přechodu Etherea z předchozího stavu na další stav, od provádění každé transakce po výpočet merkle kořene.
Sekvenční provádění
Proti paralelnímu provádění je sekvenční provádění, což je v současnosti běžný způsob provádění blockchainu. Obvykle se transakce provádějí postupně v pořadí. Jakmile je jedna transakce dokončena, Ethereum aktualizuje stav účtu a související informace (například zůstatek, data o uložení smlouvy) ve stavovém stromu účtu, a nový hash stavu účtu je vygenerován. Po dokončení aktualizace všech stavových stromů účtů se vytvoří kořenový hash stavu, který se nazývá merkle kořen stavu. Po dokončení merkle kořene stavu, merkle kořene transakce a merkle kořene potvrzení se bloková hlava podrobuje hashovacímu výpočtu, aby se vygeneroval hash bloku.
A v tom všem je pořadí provádění transakcí zásadní. Protože merkle strom je binární strom hashů, hodnoty merkle kořene vytvářené v různých pořadích budou odlišné.
Paralelní provádění
V prostředí paralelního provádění se uzly pokoušejí provádět transakce v bloku paralelně. Neprovádí se tedy transakce jedna po druhé v pořadí, ale transakce jsou rozděleny do různých „prováděcích cest“, aby je bylo možné provádět současně. Díky paralelnímu provádění může systém efektivněji zpracovávat transakce v bloku a zvyšovat propustnost.
Po dokončení provádění všech transakcí uzly shrnují výsledky provádění (tj. aktualizace stavu způsobené transakcemi) a vytvářejí nový stav bloku. Tento stav bude přidán do blockchainu a představuje nejnovější globální stav na řetězci.
Konflikty stavu
Protože paralela zpracovává transakce současně na různých cestách, jedním z hlavních problémů paralely jsou konflikty stavu. To znamená, že může existovat více transakcí, které současně čtou nebo zapisují stejné části dat (stavu) na blockchainu. Pokud se s touto situací nezachází správně, může to vést k neurčitým výsledkům provádění. Protože pořadí aktualizace stavu je různé, konečné výpočty se také liší. Například,
Předpokládejme, že existují dvě transakce, transakce A a transakce B, které se pokoušejí aktualizovat zůstatek stejného účtu:
Transakce A: zvýšení zůstatku účtu o 10.
Transakce B: zvýšení zůstatku účtu o 20.
Počáteční zůstatek účtu je 100.
Pokud provádíme sériově, výsledek pořadí provádění je určen:
1. Nejprve provést transakci A, poté provést transakci B:
Zůstatek účtu se nejprve zvýší o 10, stane se 110.
Přidáním 20 se konečný výsledek stane 130.
2. Nejprve provést transakci B, poté provést transakci A:
Zůstatek účtu se nejprve zvýší o 20, stane se 120.
Přidáním 10 se konečný výsledek stane 130.
V obou těchto pořadích je konečný zůstatek 130, protože systém zajišťuje konzistenci pořadí provádění transakcí.
Ale v prostředí paralelního provádění mohou transakce A a B současně číst počáteční zůstatek 100 a provádět své vlastní výpočty:
Transakce A čte zůstatek 100, po výpočtu aktualizuje zůstatek na 110.
Transakce B také čte zůstatek 100, po výpočtu aktualizuje zůstatek na 120.
V tomto případě, protože transakce byly prováděny současně, konečný zůstatek se aktualizoval pouze na 120, místo aby byl 130, protože operace transakcí A a B „přepsaly“ výsledek jeden druhého a došlo ke konfliktu stavu.
Tento typ konfliktu stavu se obvykle nazývá „překrytí dat“, což znamená, že když se transakce pokouší současně měnit stejná data, mohou vzájemně překrýt výsledky výpočtů, což vede k nesprávnému konečnému stavu. Další problém, který může způsobit konflikt stavu, je, že není zaručena sekvence provádění. Protože různé transakce dokončují operace v různých časových obdobích, může to vést k různým pořadím provádění. Různá pořadí mohou mít za následek různé výpočtové výsledky, což činí výsledky neurčitými.
Aby se předešlo této nejistotě, systémy paralelního provádění blockchainu často zavádějí mechanismy detekce konfliktů a zpětného převrácení, nebo provádějí analýzu závislostí transakcí předem, aby zajistily, že mohou být prováděny paralelně, aniž by to ovlivnilo konečnou konzistenci stavu.
Optimistická paralela a deterministická paralela
Existují dva způsoby, jak se vypořádat s možnými problémy konfliktu stavu: deterministická paralela a optimistická paralela. Tyto dva režimy mají své vlastní vyvážení efektivity a složitosti designu.
Deterministická paralela vyžaduje předem deklarovat přístup k stavu, ověřovatelé nebo sekvencer zkontrolují deklarovaný přístup k stavu při řazení transakcí. Pokud se více transakcí pokouší zapisovat do stejného stavu, označí se tyto transakce jako konfliktní, aby se zabránilo jejich paralelnímu provádění. Různé řetězy mají konkrétní implementace předběžného deklarování přístupu k stavu, ale obecně zahrnují následující metody:
Omezením prostřednictvím specifikace smlouvy: vývojáři přímo uvádějí rozsah přístupu k stavu ve smart kontraktech. Například převod tokenů ERC-20 vyžaduje přístup k poli zůstatku odesílatele a příjemce.
Prostřednictvím strukturalizovaných dat v transakcích: přidáním speciálních polí do transakcí pro označení přístupu k stavu.
Prostřednictvím analýzy kompilátoru: kompilátory vyšších programovacích jazyků mohou staticky analyzovat kód smlouvy a automaticky generovat soubor přístupu k stavu.
Prostřednictvím rámce, který vyžaduje deklaraci: některé rámce požadují, aby vývojáři explicitně uváděli stav, který potřebují přístup při volání funkcí.
Optimistická paralela nejprve zpracovává transakce optimisticky a čeká, až dojde ke konfliktům, než zasažené transakce znovu provede v pořadí. Aby se co nejvíce předešlo konfliktům, je jádrem designu optimistické paralely rychlá předpověď a předpoklady o stavu prostřednictvím historických dat, statické analýzy a dalších metod. To znamená, že systém předpokládá, že určité operace nebo aktualizace stavu jsou platné, aniž by byly plně ověřeny, a snaží se vyhnout čekání na všechny ověřovací procesy, čímž zvyšuje výkon a propustnost.
I když optimistická paralela může pomocí rychlé předpovědi stavu a předpokladů co nejvíce předejít konfliktům, stále existují některé nevyhnutelné výzvy, zejména pokud jde o provádění smluv nebo mezikontinentální transakce. Pokud k častým konfliktům dochází, opětovné provádění může výrazně zpomalit výkon systému a zvýšit spotřebu výpočetních zdrojů.
Deterministická paralela se vyhýbá konfliktům, které by mohly vzniknout optimistickou paralelou, tím, že před transakcí provádí kontrolu závislostí stavu, ale protože je nutné před odesláním transakce přesně deklarovat závislosti stavu, klade to na vývojáře vyšší nároky a zvyšuje složitost realizace.
Dilema paralelního EVM
Při řešení konfliktů stavu nelze rozlišit pouze mezi deterministickou a optimistickou paralelou, ale je také třeba zvážit architekturu databáze řetězce. Problém konfliktů stavu v rámci paralely je v EVM pod architekturou merkle stromu obzvláště obtížný. Merkle strom je hierarchická hash struktura, a po každé transakci, která mění určité stavové údaje, je třeba aktualizovat kořenový hash merkle stromu. Tento proces aktualizace je rekurzivní, počínaje od listových uzlů a postupně se počítá směrem k kořenovému uzlu. Protože hash je nevratný, lze výpočty nad vyššími úrovněmi provádět pouze po dokončení změn na nižších úrovních, což činí paralelní aktualizaci velmi obtížnou.
Pokud dvě transakce provádějí paralelně a přistupují ke stejnému stavu (například zůstatek účtu), může to vést ke konfliktu uzlů merkle stromu. Řešení těchto konfliktů obvykle vyžaduje dodatečné mechanismy řízení transakcí, aby bylo zajištěno, že se i v rámci více větví dosáhne konzistentní kořenový hash. To není pro EVM snadné realizovat, protože to vyžaduje vyvážení mezi paralelizací a konzistencí stavu.
Ne-EVM paralelní řešení
Solana
Na rozdíl od globálního stavového stromu Etherea, Solana používá model účtů. Každý účet je nezávislý úložný prostor, uložený v účetnictví, což eliminuje problémy s konfliktem cest.
Solana je deterministická paralela. V Solaně každá transakce musí při odeslání jasně deklarovat, které účty a jaká potřebná oprávnění (pouze pro čtení nebo pro čtení a zápis) budou přístupné. Tento design umožňuje uzlům blockchainu analyzovat potřebné zdroje pro každou transakci ještě před jejím provedením. Protože transakce jasně deklarují všechny závislosti účtů před zahájením provádění, uzly mohou určit, které transakce budou přistupovat ke stejným účtům a které transakce mohou být bezpečně prováděny paralelně, což umožňuje inteligentní plánování, vyhýbání se konfliktům a tím i základ pro paralelní plánování.
Protože každá transakce má před provedením deklarovány účty a oprávnění, které potřebuje, může Solana zkontrolovat, zda mezi transakcemi existují závislosti na účtech (model Sealevel). Pokud mezi transakcemi nejsou sdílené účty pro čtení a zápis, systém je může přiřadit k různým procesorům pro paralelní provádění.
Aptos
Design paralelního provádění Aptos se značně liší od Etherea, provádí některé klíčové inovace v architektuře a mechanismech, zejména v oblasti modelu účtů a ukládání stavu.
Ethereum při provádění transakcí často aktualizuje globální stavový strom (MPT). Všechny stavy účtů a smluv jsou uloženy v jednom sdíleném stavovém stromu, jakákoli transakce musí přistupovat a aktualizovat část tohoto stavového stromu. Aptos však rozděluje účty na nezávislé stavové jednotky, přičemž každý objekt je samostatným párem klíč-hodnota, které mohou existovat nezávisle na sobě a vzájemně se neovlivňují, pouze když existuje jasný vztah odkazu. Mezi objekty nejsou žádné společné cesty ve stromu, což eliminuje konflikty zamykání a umožňuje plnou paralelnost.
Základní datová struktura Aptos je Jellyfish Merkle Tree. Každý stav objektu je nakonec uložen v JMT jako nezávislý pár klíč-hodnota. Na rozdíl od MPT Etherea, Jellyfish Merkle Tree má strukturu úplného binárního stromu, což zjednodušuje cesty pro uložení a dotazování uzlů a výrazně zkracuje čas ověřování. A každá účet v tomto stromu má své pevné umístění a uzly ve stromě jsou uloženy nezávisle, což umožňuje paralelní aktualizaci a vyhledávání více účtů.
Aptos je optimistická paralelní technologie, která nevyžaduje předem deklarovat všechny závislosti účtů. K tomu Aptos používá Block-STM, který odhaduje závislosti na základě předem stanoveného pořadí transakcí, čímž snižuje počet přerušení.
Paralelní EVM
Ve srovnání s ne-EVM paralelou čelí paralelní EVM větším technickým výzvám při řešení závislostí stavu, detekce konfliktů, správy plynu a mechanismů zpětného převrácení. Abychom lépe porozuměli této problematice, můžeme se podívat na některé projekty paralelního EVM (například Sui, Monad, Canto) a jak tyto problémy řeší.
Sui
Sui, stejně jako Aptos, také používá objektový model k řešení stavu, přičemž každý objekt (například účet, stav smart kontraktu) je považován za nezávislý zdroj. Tyto objekty jsou rozlišovány podle jedinečných identifikátorů objektů. Když transakce zahrnují různé objekty, mohou být prováděny paralelně, protože manipulují s různými stavy a nevytvářejí přímé konflikty.
I když Sui používá objektový model pro správu stavu, pro kompatibilitu s EVM jeho architektura používá dodatečné adaptační vrstvy nebo abstraktní mechanismy pro spojení objektového modelu s modelem účtů EVM.
V Sui se plánování transakcí používá s optimistickou paralelní strategií, předpokládající, že mezi transakcemi nejsou konflikty. Pokud k konfliktu dojde, systém použije mechanismus zpětného převrácení k obnovení stavu.
Sui používá objektový model a technologii izolace stavu, což efektivně zabraňuje problémům se závislostí stavu. Každý objekt jako nezávislý zdroj může být prováděn paralelně, což zvyšuje propustnost a efektivitu. Ale tento přístup má trade-off v podobě složitosti objektového modelu a nákladů na mechanismus zpětného převrácení. Pokud dojde ke konfliktu mezi transakcemi, je třeba některé stavy vrátit, což zvyšuje zátěž systému a může ovlivnit efektivitu paralelního zpracování. Ve srovnání s ne-EVM paralelními systémy (například Solana) potřebuje Sui více výpočetních a úložných zdrojů k udržení efektivní paralelnosti.
Monad
Stejně jako Sui, i Monad používá optimistickou paralelu. Ale optimistická paralela Monad provede předpověď závislostí na některé transakce před konkrétním prováděním transakcí, a to hlavně prostřednictvím statického analyzátoru kódu Monad. Předpověď vyžaduje přístup k stavu, a způsob, jakým Ethereum ukládá stavy v databázi, činí přístup k nim velmi obtížným. Aby byla paralela v procesu čtení stavu efektivnější, Monad také přepracoval databázi.
Stavový strom Monad je rozdělen do oblastí, přičemž každá oblast udržuje svůj vlastní podstrom stavu. Při aktualizaci je třeba změnit pouze příslušné fragmenty, což eliminuje nutnost znovu vytvářet celý stavový strom. Rychlé určení umístění stavu v oblasti pomocí indexu stavu snižuje interakci mezi oblastmi.
Shrnutí
Jádrem paralelního provádění je zvýšení efektivity provádění vrstvy pomocí provádění více cestami, a aby se dosáhlo provádění více cestami, musí řetězec provést řadu opatření, jako je detekce konfliktů a mechanismy zpětného převrácení, aby zajistil, že mohou být prováděny paralelně, aniž by to ovlivnilo konečnou konzistenci stavu, a provést určité úpravy databáze.
Samozřejmě, zvyšování efektivity prováděcí vrstvy není omezeno pouze na paralelu. Optimalizace fáze provádění může být také dosažena snížením potřebných čtecích a zápisových operací v databázi pro jednu transakci. Celkové zrychlení řetězce zahrnuje širší oblasti, včetně zvyšování efektivity konsensuální vrstvy.
Každá technologie má svá specifická omezení. Paralela je pouze jedním ze způsobů, jak zvýšit efektivitu, a konečné rozhodnutí o použití této technologie musí brát v úvahu, zda je přívětivá pro vývojáře a zda ji lze realizovat bez obětování decentralizace. Akumulace technologií není vždy prospěšná, alespoň pokud jde o Ethereum, paralela není tak atraktivní. Pokud se podíváme pouze na zvyšování efektivity, přidání paralely není optimálním řešením pro Ethereum, ať už z hlediska jednoduchosti nebo z pohledu současné roadmapy Etherea zaměřené na Rollup.