Jak działa Gravity?

September 25, 2015
Guides

Jak działa Gravity

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.

Krok po kroku

Gravity należy używać w następujący sposób:

  • Wysyłasz 25 DAI do kontraktu Gravity na Ethereum, określając, że twój adres w sieci Cosmos powinien otrzymać DAI.
  • Walidatorzy w łańcuchu sieci Cosmos widzą, że to miało miejsce, i walidują 25 DAI w sieci Cosmos dla twojego adresu.
  • Teraz DAI mogą zostać wysłane do innych kont w sieci Cosmos, używanych przez aplikacje Cosmos, przesyłane do innych łańcuchów Cosmos poprzez IBC itp.
  • Aby powrócić do Ethereum, wysyłasz pieniądz DAI do modułu Gravity w łańcuchu sieci Cosmos, określając, że twój adres na Ethereum powinien go otrzymać.
  • Walidatorzy sieci Cosmos spalają DAI w łańcuchu sieci Cosmos i wysyłają transakcję Ethereum, zmuszając kontrakt Gravity.sol do wysłania 25 DAI na twój adres Ethereum.

Elementy Gravity

Gravity składa się z 4 elementów:

  • Kontraktu Ethereum o nazwie Gravity.sol
  • Modułu Gravity Cosmos
  • Programu koordynującego, używanego przez walidatorów sieci Cosmos wraz z kodem łańcucha bloków Cosmos
  • Rynku przekaźników (ang. relayers), które konkurują między sobą o to, kto ma przesyłać transakcję do Ethereum w imieniu walidatorów sieci Cosmos.

Gravity.sol

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.

updateValset

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.

sendToCosmos

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 pierwszej kolejności sprawdza, czy partia ma podpisy 2/3 zestawu walidatorów w obecnym punkcie kontrolnym.
  • Następnie sprawdza, czy partia ma jednorazowy identyfikator, który jest wyższy niż jakakolwiek inna partia tokenów tego samego typu, która została już przesłana.

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 sieci Cosmos i koordynator

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.

Oracle sieci Ethereum

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.

Tworzenie partii transakcji

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ę:

  • Wyszukiwanie wszystkich transakcji dla tokena
  • Wybranie 100 transakcji o najwyższej opłacie i umieszczenie ich w partii. Liczba transakcji nie może wynosić 1oo w przyszłości. Może być możliwa do skonfigurowania, a nawet dynamiczna.
  • Jeśli w puli partii znajduje się partia o wyższej sumie opłat niż nowo stworzona partia, nowa partia jest odrzucana. W przeciwnym wypadku umieszczana jest w puli partii. Omówimy to bardziej szczegółowo w dalszej części.

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

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:

  • Moduł Gravity w rzeczywistości nie zna punktu kontrolnego obecnie zapisanego w Gravity.sol. Z powodu EthBlockDelay wszystkie informacje modułu Gravity o Ethereum są nieaktualne. To przekaźniki muszą zdecydować, czy aktualizacja zestawu walidatorów ma wystarczającą ilość podpisów, aby mogła zostać przesłana.
  • Przekaźniki nie otrzymują żadnej nagrody za przesłanie aktualizacji zestawu walidatorów. Aktualizacjom nie towarzyszą żadne opłaty, tak jak w przypadku partii transakcji. To może ulec zmianie w przyszłej aktualizacji. Takie opłaty można dodać na wiele sposobów — po stronie Cosmos lub po stronie Ethereum. Jednak na dzień dzisiejszy walidatorzy łańcucha sieci Cosmos korzystający z Gravity prawdopodobnie po prostu skorzystają z usług altruistycznego przekaźnika do przesłania aktualizacji zestawu walidatorów.
  • Gravity.sol nie jest lekkim klientem (ang. light client) i nie ma wiedzy o pełnym konsensusie sieci Cosmos i procesie stakingu. Jest ogólnie rzecz biorąc systemem wielosygnaturowym (ang. multisig), którego podpisy mają być zestawem walidatorów określonego łańcucha sieci Cosmos. Osiągamy taki stan rzeczy poprzez stosowanie slashingu po stronie sieci Cosmos.

Slashing

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.

Slashing żywotności dla partii i zestawów walidatorów

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.

Slashing za fałszywe partie i zestawy walidatorów

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.

Adam Jastrzębski

Zajmuję się tematyką blockchainową od 2017 roku. Moje pierwsze kroki wydeptywaałem wokół BTC i ETH, aktualnie angażuję się w rozwój łańchów POS, w tym Cosmosu.

Related Posts