[Из песочницы] Анализ данных блокчейн-госолования 2019 года в Московскую Городскую Думу

Мне посчастливилось участвовать в написании доклада, посвященного блокчейн-голосованию в МГД 2019 года в составе команды Романа Юнемана, и в этой статье я подробно расскажу о части связанной с анализом данных.

Несколько слов об исходных данных. Изначально ко мне в руки попал файл выгрузки из блокчейна. Уже потом, когда я сделал первичный анализ, я вышел на контакт с командой Романа Юнемана, в моём распоряжении оказались свидетельские показания наблюдателей, которые присутствовали на «избирательном участке» и фотографировали мониторы с данными о ходе голосования.


Метрики

Я решил посмотреть на всё происходящее глазами разработчика. Первый вопрос который я себе задал: «а что бы сделал я если бы начал проектировать такую систему?». Система голосования — должна быть системой высокой доступности, и содержать в себе наблюдательную компоненту, а это не только логгирование. Соответственно для наблюдения за ней потребовалось выбрать ряд величин, которые служили бы метриками. Поскольку система была основана на блокчейне, то в состав этих метрик должны войти метрики самого блокчейна. Одной из таких метрик является время вычисления блока — block time. Эта догадка и послужила началом всего исследования. До меня та же Medusa обращала внимание на неполадки, но они рассматривали только голоса и по ним всё было далеко не очевидно.

Для начала поясню что означает время блока и почему за этой метрикой нужно следить пока работает блокчейн. Время блока, это время за которое осуществляется вычисление и запись блока. Под этим названием может скрываться две величины: это ожидаемое время вычисления блока и среднее время блока. Ожидаемое время блока в случае Proof of authority (PoA) блокчейна задается параметрами системы. Среднее время блока, это уже реальное время, которое вычисляется так: если за время T блокчейн сеть вычислила n блоков, то среднее время блока это T/n. Аномальное изменение этой метрики подсказывает о возникновении проблем и позволяет эти проблемы оперативно устранять.

Давайте взглянем на эту метрику, рассчитанную на основе выгрузки данных из блокчейна. Поскольку я всё же разработчик, а не аналитик, то для облегчения работы по анализу данных я параллельно итеративно писал программу для анализа, которая постоянно мне в этом помогала. Ссылку на её исходный код вы найдете в конце статьи. Здесь и далее все графики являются выгрузкой из неё.

block_time.png
По оси X — номер блока, по оси Y — среднее время.

Смотря на эту метрику, мы можем зафиксировать участки стабильной работы блокчейна, участки резкого увеличения среднего времени блока (Зоны 1А,1Б,2) и участок деградации вычислительной сети блокчейна, а также подозрительный участок чем-то отдаленно напоминающий пульс (Зона 3).

Во-первых, я утверждаю, что данная метрика должна была быть выведена на мониторы на участке голосования, т.к. по ней наглядно можно судить о работоспособности одного из основных компонентов системы. Во-вторых, я утверждаю что из этих данных следует, что работу блокчейна останавливали. Давайте рассчитаем сколько раз и на сколько времени.

Мы имеем три участка с подозрительным временем блока названные мной «Зона 1А», «Зона 1Б» и «Зона 2». Время вычисления блока до блока 2046 было в пределах между 3 и 4 секундами. Для оценки мы возьмем верхний предел в 4 секунды и вычислим время когда блокчейн был остановлен.

Описание столбцов таблицы


  1. Номер блока начала зоны
  2. Номер блока конца зоны
  3. Количество блоков в зоне
  4. Время начала зоны
  5. Время окончания зоны
  6. Длительность зоны
  7. Оценочное время когда блокчейн проводил вычисления из расчета времени блока в 4 секунды
  8. Оценочное время когда блокчейн был отключен

Отмечу, что я взял для времени блока верхнюю оценку, соответственно это дает верхнюю оценку времени вычисления и нижнюю оценку времени остановки. Т.е. реальное время остановки скорее всего еще больше. Т.е. суммарное время полной остановки блокчейна составляет около 2 часов.

Следующей любопытной зоной является «зона 3». В ней наблюдается странная по частоте запись блоков, по сравнению с предыдущими периодами, но эту зону мы рассмотрим отдельно когда будем смотреть распределение голосов по блокам.

И наконец с момента в 14:20 и до конца голосования мы наблюдаем постоянный рост времени вычисления. Напомню что речь идет о PoA-блокчейне и там не предусмотрено усложенение операций как в случае ETH, когда подобное поведение было обусловлено «бомбой сложности» в PoW-блокчейне. Т.е. мы наблюдаем неожиданное поведение метрики блокчейна, которое свидетельствует о деградации системы.

Сразу оговорюсь, что то тут я буду максимально объективен и не буду касаться странностей в распределении голосов по кандидатам и этот анализ не будет никак вестись в разрезе отдельных кандидатов. В написанной мной программе я тем не менее оставил возможность это сделать любой заинтересованной стороне. В этой статье меня интересует только работоспособность системы. Если же вас интересуют эти странности — то вам следует обратиться к докладу, там всё описано максимально подробно.

Распределение голосов выглядит так
votes_distribution.png
По оси X — номер блока, по оси Y — количество голосов в блоке.

В зонах остановки блокчейна (1А,1Б,2) записей голосов ожидаемо нет, потому что это зоны неисправности. А вот зона 3 дает поводы для размышлений. Там есть небольшое число блоков по 1–3 голосам, пара всплесков 4–5 голосов и огромный всплеск голосов в конце этой зоны. Я объединил эти события основываясь на метрике block time, поскольку деградация пошла уже после этих событий, а запись этих блоков шла в допустимых пределах. В зоне 3 не было остановки блокчейна, но данные по каким-то причинам практически не попадали в блокчейн.

Общая длительность этих зон — около 4-ех часов. Т.е. если учесть что всё голосование длилось 12 часов, то где-то треть времени данные по разным причинам не записывались в блокчейн.

В зоне связанной с деградацией мы отчетливо видим что режим записи изменился и данные стали писаться чаще, в отличии от мест где блокчейн работал стабильно. С чем это связано точно не известно, потому что точная конфигурация нам недоступна, но есть предположение что это может быть связанно с переполнением очереди транзакций (Transaction Queue) в Parity. Подобное поведение вызывает вопросы к команде выполнявшей интеграцию Parity с бэкендом, а также говорит о теоретической возможности потери голосов связанной с выбраковкой транзакций.

Интересным является то, что количество голосов в блоке ограничено числом 100. Мы так и не нашли в опубликованном коде эту константу — ни в настройках, ни в коде её нет.

Объяснений происхождения всплеска голосов, после которого началась деградация, на этом этапе анализа я не получил, и я попытался найти объяснение на фотографиях данных с экранов голосования, которые сделали наблюдатели.

Здесь пойдет речь о данных доступных наблюдателям, их позиционировали как альтернатива присутствия наблюдателей на реальном избирательном участке. Фотографии на основе которых они собраны вы можете получить из доклада.

Сразу оговорюсь, что я считаю, что наблюдателям намеренно не предоставили данные в том объеме, который необходим им для понимания и отслеживания процессов происходивших в системе


  1. Наблюдатели не видели метрики системы и как следствие не могли даже поверхностно оценить степень её работоспособности
  2. Наблюдателям не была предоставлена нода наблюдения за блокчейном
  3. Табличное представление данных не давало наблюдателям возможность оценить происходящее

Данные выводили 4 числа, которые показывали по сути воронку конверсии


  1. Сколько человек перешли к началу процесса голосования
  2. Сколько человек ввели регистрационную СМС
  3. Сколько человек получили бюллетень
  4. Сколько человек проголосовало

Поскольку это воронка, то все четыре параметра связаны между собой:


  1. Не зайдя на страницу нельзя получить СМС
  2. Не получив СМС нельзя получить бюллетень
  3. Не получив бюллетень нельзя проголосовать

Дополнительно следует учесть что время жизни бюллетеня — 15 минут. Это значит получив бюллетень, можно проголосовать только в течении 15 минут.

data_from_photos.png
По оси X — время. По оси Y — количество людей.

Визуальное представление сразу же показывает аномалии.

Факты отсутствия заходов на страницу голосования (зеленая линия линия горизонтальна) говорят о недоступности фронта системы. Нижняя оценка — 17 полных участков (включая один участок где количество возросло, а потом уменьшилось), каждый по 15 минут. Суммарно это приблизительно 4 часов 15 минут. Эти интервалы частично перекрываются с неисправностями связанными с блокчейном, а частично являются новыми (например 14:20 — 15:01, 15:30 — 16:15).

Во время того странного всплеска голосов на сайт почему-то никто не заходил и СМС никто не вводил. Объяснения этому факту я не нашел. Т.е. с большой вероятностью этот всплеск связан с каким-то сторонним вмешательством.

Во время промежутка 15:30 — 16:15 рос только один параметр «Ввели СМС», тут похоже подгоняли статистику, ибо до этого количество выданных бюллетеней стало больше чем число людей (красная линия), которые правильно ввели СМС. Что невозможно с точки зрения логики.

Конечно, есть вероятность что механизм представления данных наблюдателям просто не работал, или работал с серьезными ошибками, но признание этого факта равно по сути недопуску наблюдателей на избирательный участок, потому что помимо этих данных у наблюдателей не было ровным счётом ничего

Традиционно когда говорят о системах высокой доступности начинают разговор с одной девятки — 90% времени система безошибочно работает. Серьезные системы могут обеспечить работу при двух или трех девятках (99% и 99.9% времени система безошибочно обрабатывает запросы). В случае голосования В МГД голосование длилось около 12 часов и количество проголосовавших составило менее 10 тысяч человек. При этом больше 4-ех часов система не работала. Потом пять с половиной часов происходила деградация вычислений в блокчейне и на это никто не среагировал, что показывает проблемы в архитектуре связанные с отсутствием наблюдения за метриками. Лично у меня сложилось мнение, что при таких характеристиках эту систему нельзя считать даже рабочим прототипом.

P.S. Уже когда я неспешно готовил эту статью, на Хабре появилась статья ДИТ, в которой они утверждали что 'В течение всего дня система электронного голосования работала стабильно, за исключением одного часа, но мы смогли оперативно устранить неполадку'. Я искренне надеюсь, что это происходило в параллельной Вселенной и автору дадут Нобелевскую Премию за её открытие, потому что и метрики и данные этому прямо противоречат. По данным полученным мной из этой реальности следует что блокчейн был отключен 2 часа, компоненты связанные с блокчейном не работали 4 часа, а с 14:20 до конца голосования происходила непрерывная деградация вычислительной сети блокчейна, которая не справилась со странным всплеском голосов, который никак не объясняется данными полученными мной от наблюдателей из этой Вселенной.

С содержимым полного доклада вы можете ознакомиться на сайте посвященном электронному голосованию — https://www.evoting.ru/

Исходный код программы-анализатора и данные выложены на Github (.NET Core 3/WPF) — https://github.com/AlexeiScherbakov/Voting2019

С содержимым статьи ДИТ, посвященным архитектуре системы вы можете ознакомиться тут — https://habr.com/ru/article/480152/

© Habrahabr.ru