Gravity jest mostem pomiędzy Ethereum i blokami łańcuchów opartymi na sieci Cosmos. W tym poście spróbuję udokumentować mechanizm działania całego systemu w sposób zrozumiały i ze średnim poziomem szczegółowości.
Najpierw ogólne omówienie: Gravity pozwala ludziom przenosić tokeny z Ethereum do sieci Cosmos i z powrotem poprzez blokowanie tokenów po stronie Ethereum i walidację informacji (ang. minting) po stronie sieci Cosmos. W przeciwieństwie do wielu innych mostów Gravity nie prowadzi żadnego nadzoru — musisz jedynie zaufać zabezpieczeniom łańcucha sieci Cosmos, nie jakimś zewnętrznym administratorom mostu, którzy mogą uciec z twoimi pieniędzmi.
Gravity należy używać w następujący sposób:
Gravity składa się z 4 elementów:
Główną funkcją Gravity.sol jest blokowanie tokenów ERC20 na Ethereum, tak aby mogły zostać poddane walidacji w sieci Cosmos. Tokeny zablokowane w Gravity.sol tworzą kopie tokenów w sieci Cosmos.
Obecni walidatorzy sieci Cosmos kontrolują Gravity.sol w stopniu proporcjonalnym do ich siły walidacji w sieci Cosmos. Gravity.sol zapisuje punkt kontrolny, odpowiadający aktywnemu walidatorowi ustawionemu po stronie sieci Cosmos w danym momencie. Punkt kontrolny jest zestawem adresów i ich siły walidacji. Im większa siła walidacji adresu, tym ważniejszy jest jego głos. Metody stosowane w Gravity.sol są publiczne i mogą być obsługiwane przez dowolny przekaźnik, ale muszą zawierać podpisy 2/3 zestawu walidatorów w obecnym punkcie kontrolnym.
Zestaw walidatorów w sieci Cosmos stale się zmienia w miarę jak właściciele tokenów Cosmos delegują je do różnych walidatorów, zmieniając ich siłę. Walidatorzy sieci Cosmos stosują metodę zwaną updateValset w Gravity.sol, aby aktualizować jego zapisany punkt kontrolny do najnowszego zestawu walidatorów. Jeśli walidator nie podpisze aktualizacji lub, co gorsza, podpisze fałszywą aktualizację, może zostać odcięty, tracąc tym samym fundusze w sieci Cosmos.
Użytkownicy wysyłają tokeny sieci Cosmos do modułu Gravity i określają, który adres w Ethereum powinien je otrzymać. Załączają również opłatę dla przekaźnika, który przesyła ich transakcje. Tokeny przesyłane są z Cosmos do Ethereum partiami, aby oszczędzać gaz. Moduł Gravity tworzy partie transakcji jednego typu tokena, a następnie walidatorzy podpisują je.
Przekaźniki mogą przesyłać partie do metody submitBatch. Gravity.sol:
W kolejnym kroku wysyła transakcje ERC20 Ethererum, przenosząc tokeny do miejsc docelowych. Gravity.sol wysyła również opłaty za transakcje do msg.sender – przekaźnika.
Moduł Gravity jest modułem zbudowanym na bazie Cosmos SDK. Łańcuchy bloków Cosmos składają się z wielu takich modułów, z których ramię w ramię korzystają ich walidatorzy. Każdy walidator korzysta z dokładnie tej samej deterministycznej logiki. Walidatorzy osiągają konsensus dotyczący stanu przechowywania kluczowej wartości. Poszczególne moduły są posiadaczami różnych części tego stanu.
Moduł Gravity jest odpowiedzialny za walidację tokenów sieci Cosmos, reprezentujących tokeny ERC20 w Ethereum. Blisko współpracuje z koordynatorem. Koordynator jest programem pracującym na każdym walidatorze wraz z kodem sieci Cosmos. Ponieważ moduły Cosmos na każdym walidatorze korzystają z tej samej logiki, nie mogą wykonywać czynności, takich jak podpisywanie komunikatów lub transakcji za pomocą unikalnego klucza walidatora. Walidatorzy obsługujący łańcuch z zainstalowanym modułem Gravity wykonują te czynności za pomocą koordynatora.
Moduł Gravity musi wiedzieć o tym, co się dzieje w łańcuchu Ethereum. Dzięki temu może walidować tokeny w sieci Cosmos dla osób, które wysłały tokeny do kontraktu Gravity.sol w sieci Ethereum. Umożliwia również sprawdzenie, czy partia transakcji z sieci Cosmos do Ethereum została przetworzona pomyślnie.
Każdy walidator w łańcuchu sieci Cosmos z modułem Gravity musi również mieć uruchomiony pełny węzeł (ang. full node) sieci Ethereum. Koordynator na każdym walidatorze monitoruje wydarzenia sieci Ethereum za pomocą tego pełnego węzła. Istnieje parametr o nazwie EthBlockDelay. Monitorowanie zdarzeń na łańcuchu Ethereum przez koordynatorów jest znacznie opóźnione. Opóźnienie to ma koordynatorom dać pewność, że dane zdarzenie całkowicie się zakończyło w łańcuchu Ethereum, oraz zapewnić, że każdy walidator ma taki sam widok na łańcuch. Gdy koordynator widzi zdarzenie z kontraktu Gravity.sol, umieszcza takie zdarzenie w komunikacie sieci Cosmos, który podpisuje i nadaje do łańcucha sieci Cosmos.
Moduł Gravity odbiera te komunikaty i rejestruje, którzy walidatorzy zagłosowali na dane zdarzenie w sieci Ethereum. Gdy na zdarzenie zagłosuje 2/3 siły walidatorów, uznawane jest za „obserwowane” i zmienia status sieci Cosmos.
Gdy zdarzenie SendToCosmosEvent jest obserwowane, moduł Gravity waliduje tokeny dla adresu docelowego.
Gdy obserwowane jest zdarzenie TransactionBatchExecutedEvent, moduł Gravity eliminuje partię, która została wykonana z puli partii, i anuluje wszelkie wcześniejsze partie, zawierające tego typu tokeny. Więcej o tym procesie opowiem później.
Transakcje przesyłane z Cosmos do Ethereum są grupowane w partie przed wysłaniem do łańcucha sieci Ethereum. Takie rozwiązanie stosowane jest ze względu na wysoki koszt przetwarzania transakcji w sieci Ethereum, a grupowanie w partie dzieli koszt pomiędzy wszystkimi transakcjami w partii.
Gdy użytkownik chce przesłać tokeny z sieci Cosmos na adres w sieci Ethereum, wysyła tokeny do modułu Gravity. Gravity odlicza tokeny z ich kont, a następnie umieszcza transakcję w puli transakcji. Pula transakcji przechowuje wszystkie transakcje sieci Cosmos i Ethereum, które nie znajdują się jeszcze w partii.
Każdy może wysłać transakcję, żądającą od modułu Gravity złożenie partii określonego typu tokena. Żądania najczęściej wysyłane są przez przekaźniki, aby przesłać partię tokenów dla zysku. Gdy moduł Gravity odbierze ten komunikat, wykonuje poniższą procedurę, aby złożyć partię:
Następnie umieszcza partię w puli partii. Gdy partia znajdzie się w puli partii, wszyscy koordynatorzy walidatorów składają podpisy na partiach, wysyłając te podpisy w komunikatach Cosmos. Każdy podpis jest przechowywany wraz z jego partią.
Przekaźniki stale monitorują partie znajdujące się w puli partii. Gdy partia otrzyma podpisy od co najmniej 2/3 zestawu walidatorów w bieżącym punkcie kontrolnym zapisanym w Gravity.sol, może zostać wysłana do Gravity.sol. Przekaźniki mogą samodzielnie zdecydować, czy wysłanie danej partii będzie rentowne, i wysłać te, które przyniosą zysk. Jeśli opłaty zawarte w partii będą wyższe niż koszt gazu potrzebnego do wysłania jej do sieci Ethereum, partia taka jest rentowna. Oczywiście są to bardzo złożone obliczenia, które biorą pod uwagę bieżące średnie ceny gazu w łańcuchu sieci Ethereum, zagęszczenie w łańcuchu, a także kurs wymiany pomiędzy tym tokenem i gazem sieci Ethereum. Dlatego istnieje wolny rynek przekaźników.
Gdy partia zostanie wykonana w łańcuchu sieci Ethereum, Gravity.sol emituje zdarzenie TransactionBatchExecutedEvent w sposób opisany powyżej. Po zablokowaniu EthBlockDelay w sieci Ethereum walidatorzy wysyłają zdarzenie do modułu Gravity. Gdy to zdarzenie jest w pełni obserwowane (tak jak opisano powyżej), partia jest usuwana z puli, ponieważ została zakończona. Wszelkie partie tego samego tokena z jednorazowym identyfikatorem niższej partii są także usuwane z puli partii, ale ich transakcje są również przywracane do puli transakcji. Dzieje się tak dlatego, że istnieje pewność, że ich wysłanie jest niemożliwe, ponieważ ich jednorazowe identyfikatory partii są zbyt niskie. Ten mechanizm umożliwia przeprowadzanie transakcji, które zostały zgrupowane w nierentowne partie, aby stworzyć szansę na to, aby stworzyć rentowną partię.
Tak jak wspomniano powyżej, moduł Gravity zbuduje nową partię jedynie wtedy, gdy w puli partii nie ma jeszcze żadnych partii o wyższej sumie opłat. To ma na celu zapobieżenie poniższemu scenariuszowi: Gdy w puli transakcji znajduje się wiele transakcji o nieopłacalnie niskiej opłacie, a w blokach nadchodzi po kilka transakcji o wysokiej opłacie, każda transakcja z wysoką opłatą mogłaby trafić do partii z grupą nierentownych transakcji. Wysłanie takich partii byłoby nieopłacalne, w wyniku czego opłacalne transakcje trafiłyby do nieopłacalnych partii i nie zostałyby wysłane.
Poprzez zastosowanie systemu, w którym każda nowa partia musi być bardziej opłacalna od każdej innej partii czekającej na wysłanie, kilka rentownych transakcji, przychodzących w każdym bloku, ma szansę utworzyć partię wystarczająco opłacalną, aby została wysłana.
Aktualizacje zestawów walidatorów mają na celu dbanie o aktualność wiedzy Gravity.sol o zestawie waidatorów w sieci Cosmos. Jest to ważne, ponieważ model pośrednictwa Gravity wymaga, aby zaufanie wobec Gravity.sol było równoznaczne z zaufaniem wobec sieci Cosmos, która go obsługuje. Aktualizacja zestawu walidatorów musi zostać podpisana przez co najmniej 2/3 bieżącego zestawu walidatorów w punkcie kontrolnym, zapisanym w Gravity.sol.
Każdy może wysyłać komunikat Cosmos z żądaniem aktualizacji zestawu walidatorów. Gdy żądanie zostanie wysłane, moduł Gravity zapisuje migawkę bieżącego zestawu walidatorów. Walidatorzy następnie podpisują taką migawkę. Gdy otrzyma podpisy 2/3 zestawu walidatorów w obecnym punkcie kontrolnym Gravity.sol, przekaźnik może przesłać ją do łańcucha Ethereum. Jest kilka subtelnych kwestii, które należy mieć na uwadze:
Slashing jest ważną częścią bezpieczeństwa Gravity. Wobec walidatorów, którzy zachowują się niewłaściwie po stronie sieci Cosmos lub sieci Ethereum mostu, stosowany jest slashing po stronie Cosmos. Właśnie to łączy zabezpieczenia mostu Gravity i zabezpieczenie łańcucha sieci Cosmos, w którym most działa.
Poprzez udział w procesie konsensusu sieci Cosmos walidator bezwarunkowo stwierdza, że wszystkie aktualizacje zestawów walidatorów i partii tworzone przez ten proces są prawidłowe. Jeśli taki walidator nie podpisze tych zestawów walidatorów i partii, oznacza to, że walidator nie działa prawidłowo. Po okresie karencji stosowany jest wobec niego slashing za brak podpisu.
Istnieje możliwość przesyłania partii i zestawów walidatorów do kontraktu Gravity.sol, które nie zostały stworzone przez łańcuch sieci Cosmos, pod warunkiem, że zostaną podpisane przez ponad 2/3 walidatorów w obecnym punkcie kontrolnym kontraktu. Aby uniemożliwić złośliwym walidatorom stworzenie kartelu, którego celem będzie okradanie mostu poprzez fałszywe partie transakcji lub aktualizacje zestawów walidatorów, Gravity odcina walidatorów, których podpisy pojawiają się na partiach i aktualizacjach zestawów walidatorów, które nie zostały wyprodukowane przez łańcuch. Proces ten odbywa się za pośrednictwem mechanizmu ewidencyjnego, do którego każdy może wysłać dowód, że podpis został złożony na fałszywej partii lub zestawie walidatorów, aby umożliwić łańcuchowi odrzucenie odpowiedzialnego za to walidatora.