###### tags: `prir` `studia` # Problem bizantyjskich generałów W systemach rozproszonych możliwe są **awarie** - węzeł przestaje odpowiadać - węzeł wysyła błędne komunikaty Możliwe rozwiązania problemów: - system przechodzi w stan bezpieczny, zapisuje stany i bezpiecznie kończy obliczenia - system pozwala na dalszą pracę, prawdopodobnie spada wydajność ## Opis problemu Grupa armii otacza miasto. Wszystkie grupy chcą jednocześnie zaatakować lub jednocześnie się wycofać. Inne akcje to porażka. Niektórzy generałowie armii mogą być zdrajcami i chcieć doprowadzic do porazki. ### System rozproszony Generałowie - węzły Posłańcy - kanały komunikacyjne ### Rodzaje awarii węzłów **załamanie** - zdrajca w dowolnej chwili przestaje wysyłać komunikaty **awarie bizantyjskie** - zdrajca wysyła dowolne (w tym fałszywe) komunikaty ## Algorytm jednorundowy Każdy generał przekazuje reszcie swoją decyzją - atak lub odwrót Załóżmy generałów **A**, **B**, **C**. Generałowie **A** oraz **B** są wierni, **C** jest zdrajcą (załamanie, przestanie przesyłać informacje) **Co otrzyma generał A** A : atak B : odwrót C : atak _decyzja: atak_ **Co otrzyma generał B** A : atak B : odwrót C ; BRAK _decyzja: odwrót_ ## Algorytm dwurundowy W pierwszej rundzie generał przesyła innym swoją decyzję, w drugiej z kolei przesyła decyzje, jakie dostał w pierwszej od innych. Następnie porównuje (np. tablicę decyzji) i większościową wybiera odpowiednią decyzję. ``` Decyzja ostatecznaDecyzja, decyzje[generalowie], wiekszosc[generalowie], przekazane[generalowie] decyzja[mojId] = wybierzAtakLubOdwrot() // runda 1 po wszystkich innych generałach G: send(G, decyzje[mojId]) receive(G, decyzje[G]) // runda 2 po wszystkich innych generałach G: KURWA ILE KODU ``` Niweluje **załamanie** ale nie powstrzyma **awarii bizantyjskiej** **W przypadku załamania** W dwurundowym wymaga się, w przypadku T zdrajców aż 2T+1 generałów **W przypadku awarii bizantyjskiej** Algorytm dwurundowy poprawny dla minimum 4 generałów, gdzie tylko 1 jest zdrajcą Dla T zdrajców potrzeba T+1 rund oraz 3T+1 generałów. Jeśli założymy że jedyną awarią jest załamanie to stosujemy **algorytm rozpływowy** - każdy generał kilkukrotnie rozsyła i odbiera zbiór otrzymanych decyzji - dla T zdrajców wystarczy T+1 rund ## Algorytm króla Wymaga aby przy T zdrajcach było 4T+1 generałów. - w każdej rundzie jeden generał zostaje królem i jego głos jest ważniejszy od reszty Runda pierwsza: - każdy przesyła każdemu swoją decyzję - każdy zapamiętuje wynik głosowania większościowego oraz ilość głosów, którą zdobyła opcja większości Runda druga: - tylko król przesyła swoją decyzje reszcie - gdy generał otrzyma decyzję od króla, sprawdza, iloma głosami była wybrana decyzja w pierwszej rundzie. Jeśli większość była znacząca (większa niż [n/2] + t) to ignoruje decyzję króla. W przeciwnym wypadku generałowie zapominają o pierwszej rundzie i podporządkowują się królowi - następnie algorytm powtarzany jest drugi raz