Już wiadomo. Dzisiejszy pad mBanku oraz wyłączenie systemu MultiBanku to największy fuckup w historii polskiej bankowości.

Czas zatem na króciutką analizę tego co się stało.

Oficjalne info mówi, że:

Informujemy, że zgodnie z wcześniejszymi informacjami, z powodów technicznych część zewnętrznych przelewów przychodzących, zaksięgowanych na rachunkach Klientów mBanku w trakcie pierwszej sesji (w dniu 29 listopada br.), mogła zawierać niepoprawne dane (np. dotyczące nadawcy lub tytułu operacji).

co w kontekście tej informacji oraz tej informacji może oznaczać trzy rzeczy:

  • Dziś schodziły przelewy wysłane przez weekend do ELIXIRa, w których nadawcą byli klienci Multi, a odbiorcami klienci mBanku. Te przelewy zostały zaksięgowane „podwójnie” i z błędami.
  • Nie sprawdzono systemu pod kątem prawidłowego rozpoznawania transakcji w plikach z ELIXIRa. O tym za chwilę.
  • Nastąpił niespodziewany wzrost promieniowania kosmicznego. Co oznacza błąd ludzki w trakcie przenoszenia systemu. Bywa.

Co do pierwszej opcji to wątpię, że to było przyczyną. Po pierwsze mBank i MultiBank działają w ramach jednej platformy teleinformatycznej. W dodatku jednej w sensie ==, a nie tylko equlas. Współdzielona jest baza danych, serwery, łącza. Jedynymi oddzielnymi elementami są przyłącza do ELIXIRa.
Do niedawna banki te rozliczały się pomiędzy sobą z pominięciem KIRu, ale w ramach sesji ELIXIRa. Było to spowodowane kosztami jakie ponosi bank za nadanie komunikatu w ELIXIRze. Koszty może nie są „per klient”, ale przy skali rocznej są to już poważne kwoty (choć nadal nie za duże jak na bank). Nowy system pozwala na księgowanie „w czasie rzeczywistym”, czyli rozciąga to co było obecnie dostępne tylko w ramach banku na całą grupę kapitałową.
Dlaczego tutaj nie jest możliwy tego typu błąd? Ano dlatego, że cała komunikacja przebiega wewnątrz jednego systemu. Zatem nawet pobieżne testy pozwoliły by na stwierdzenie, że „nie bangla”. Problem dotyczy na równi klientów mBanku jak i MultiBanku. Jeżeli poczytamy sobie jeszcze forum to można na 100% stwierdzić, że chodzi o transakcje, które przyszły z ELIXIRa.

No to jestem w domu.

Punkt drugi. Wydaje mi się najbardziej prawdopodobny. Żeby zrozumieć co mogło być przyczyną takiej awarii trzeba wiedzieć jak banki komunikują się pomiędzy sobą. Dla naszego przypadku wystarczy wiedzieć, że pojedynczy komunikat w systemie ELIXIR składa się w uproszczeniu z dwóch elementów. Części stałej, w której zapisane jest kto, komu, ile kiedy i jak, oraz części zmiennej w której jest zapisane dlaczego. Mówiąc inaczej komunikat poza informacjami o nadawcy i odbiorcy zawiera też pole „tytuł przelewu”, które stanowi osobny zestaw danych. Część zmienna o dziwo jest… stała. To znaczy, że może być przesyłana wraz z częścią stałą jeżeli jest stosunkowo krótka. W przeciwnym wypadku ostaje przeniesiona do osobnego pliku, a zamiast niej idzie wskaźnik na plik z częściami zmiennymi.
Dlaczego tak? Ponieważ, system EIXIR działa w oparciu o standardy komunikacji międzybankowej, które to standardy powstały w czasach COBOLa łupanego. Języki w tamtym okresie nie miały zazwyczaj dynamicznego alokowania pamięci, zatem zanim przystąpiliśmy do obróbki danych musieliśmy znać ich długość. Stąd też wymuszona długość w komunikacie, a co za tym idzie zamiana dłuższych informacji na wskaźnik i przepisywanie ich do osobnych plików.
Podejrzewam, że w systemach BRE padł właśnie odczyt tych plików. Są ku temu pewne przesłanki. W części stałej nie ma informacji o nadawcy i odbiorcy podanej w prost. Zarówno nadawca jak i odbiorca są numerami banku odbierającego/nadającego, odbierającego/nadającego oddziału uczestnika ELIXIR, oddziału odbierającego/nadającego jeżeli nie są one oddziałami uczestnikami. Dane tekstowe przeniesione są do części zmiennej co za tym idzie znajdują się w osobnym pliku. Co ważne KIR nie operuje nawet na numerach konkretnych kont! Te dane są w części zmiennej, która nie podlega obróbce poza odpowiednim routingiem pomiędzy uczestnikami.
Odczytując część zmienną należy mieć na uwadze kilka rzeczy. Po pierwsze należy prawidłowo zinterpretować sygnaturę z części stałej. Po drugie, należy prawidłowo odnaleźć rekord. Po trzecie wszystko to jest w kodowaniu EBCDICW. Widzicie zatem gdzie może być pies pogrzebany? Zapewne tam i leży.

Przyczyna trzecia – promieniowanie kosmiczne.
Nie odrzucam tej przyczyny. Jest, mało, ale prawdopodobna. Źródłem mogły być złe skrypty migrujące bazę danych, które pozmieniały miejscami relacje pomiędzy kontami, a danymi tekstowymi. Mógł być to jakiś nietrywialny błąd, który nie wyszedł w testach (a testy były). Mógł być to w końcu błąd ludzki związany z jakąś „magią” na linii system bankowy – interfejs WEB. Jeżeli zatem nie jest to błąd w odczycie ELIXIRa to ta ostatnia przyczyna jest na miejscu numer 2.

Zagrożenia.
Widzę dwa bardzo poważniejsze.
Pierwsze jest oczywiste. Wspólny system dla dwóch banków. Wpadka w jednym powoduje duży impakt na drugi. Jeżeli założymy, że największym zagrożeniem jest biointerfejs to jakiś mściwy baran może zrobić kuku nie tyle co własnej firmie, co teoretycznie całkowicie innemu bankowi.
Drugie mniej oczywiste. Niska jakość testów, a co za tym idzie większe ryzyko wpadki. Możliwe, że wymieniono fragment oprogramowania na zasadzie „dodam adaptera i proxy, będzie git, bo to tylko zmiana nazw”, a jednocześnie olano testy nowej warstwy. W takim przypadku nie dziwią pierwsze doniesienia, że „system leży, nie może wstać, nie wiadomo co pił”. Nie ma możliwości sprawdzenia co konkretnie padło. Nie ma możliwości przeprowadzenia symulacji awarii za pomocą testów poprzez wprowadzenie danych produkcyjnych. Nie ma w końcu i samych testów, które zazwyczaj mówią jak ma coś działać zdaniem programisty.

I tym optymistycznym akcentem kończę dzisiejszy wpis. Jutro się okaże, że był to „błąd ludzki”, a szczegółów nigdy nie poznacie 😀

//edit: wdał się mały fauckup z nazwami grup… poprawione