Анализ данных блокчейн-голосования 2019 года в Московскую Городскую Думу
Мне посчастливилось участвовать в написании доклада, посвященного блокчейн-голосованию в МГД 2019 года в составе команды Романа Юнемана, и в этой статье я подробно расскажу о части связанной с анализом данных.
Несколько слов об исходных данных. Изначально ко мне в руки попал файл выгрузки из блокчейна. Уже потом, когда я сделал первичный анализ, я вышел на контакт с командой Романа Юнемана, в моём распоряжении оказались свидетельские показания наблюдателей, которые присутствовали на "избирательном участке" и фотографировали мониторы с данными о ходе голосования.
Метрики
Я решил посмотреть на всё происходящее глазами разработчика. Первый вопрос который я себе задал: "а что бы сделал я если бы начал проектировать такую систему?". Система голосования — должна быть системой высокой доступности, и содержать в себе наблюдательную компоненту, а это не только логгирование. Соответственно для наблюдения за ней потребовалось выбрать ряд величин, которые служили бы метриками. Поскольку система была основана на блокчейне, то в состав этих метрик должны войти метрики самого блокчейна. Одной из таких метрик является время вычисления блока — block time. Эта догадка и послужила началом всего исследования. До меня та же Medusa обращала внимание на неполадки, но они рассматривали только голоса и по ним всё было далеко не очевидно.
Для начала поясню что означает время блока и почему за этой метрикой нужно следить пока работает блокчейн. Время блока, это время за которое осуществляется вычисление и запись блока. Под этим названием может скрываться две величины: это ожидаемое время вычисления блока и среднее время блока. Ожидаемое время блока в случае Proof of authority (PoA) блокчейна задается параметрами системы. Среднее время блока, это уже реальное время, которое вычисляется так: если за время T блокчейн сеть вычислила n блоков, то среднее время блока это T/n. Аномальное изменение этой метрики подсказывает о возникновении проблем и позволяет эти проблемы оперативно устранять.
Давайте взглянем на эту метрику, рассчитанную на основе выгрузки данных из блокчейна. Поскольку я всё же разработчик, а не аналитик, то для облегчения работы по анализу данных я параллельно итеративно писал программу для анализа, которая постоянно мне в этом помогала. Ссылку на её исходный код вы найдете в конце статьи. Здесь и далее все графики являются выгрузкой из неё.
По оси X — номер блока, по оси Y — среднее время.
Смотря на эту метрику, мы можем зафиксировать участки стабильной работы блокчейна, участки резкого увеличения среднего времени блока (Зоны 1А,1Б,2) и участок деградации вычислительной сети блокчейна, а также подозрительный участок чем-то отдаленно напоминающий пульс (Зона 3).
Во-первых, я утверждаю, что данная метрика должна была быть выведена на мониторы на участке голосования, т.к. по ней наглядно можно судить о работоспособности одного из основных компонентов системы. Во-вторых, я утверждаю что из этих данных следует, что работу блокчейна останавливали. Давайте рассчитаем сколько раз и на сколько времени.
Мы имеем три участка с подозрительным временем блока названные мной "Зона 1А","Зона 1Б" и "Зона 2". Время вычисления блока до блока 2046 было в пределах между 3 и 4 секундами. Для оценки мы возьмем верхний предел в 4 секунды и вычислим время когда блокчейн был остановлен.
№ блока начало | № блока конец | число блоков | время начала | время конца | T интервала | оценка времени вычисления | оценка времени остановки |
---|---|---|---|---|---|---|---|
2046 | 2525 | 479 | 09:26:04 | 10:20:12 | 0:54:08 | 0:31:56 | 0:22:12 |
2525 | 2651 | 126 | 10:20:12 | 11:08:22 | 0:48:10 | 0:08:24 | 0:39:46 |
2818 | 2956 | 138 | 11:19:08 | 12:29:18 | 1:10:10 | 0:09:12 | 1:00:58 |
Описание столбцов таблицы
- Номер блока начала зоны
- Номер блока конца зоны
- Количество блоков в зоне
- Время начала зоны
- Время окончания зоны
- Длительность зоны
- Оценочное время когда блокчейн проводил вычисления из расчета времени блока в 4 секунды
- Оценочное время когда блокчейн был отключен
Отмечу, что я взял для времени блока верхнюю оценку, соответственно это дает верхнюю оценку времени вычисления и нижнюю оценку времени остановки. Т.е. реальное время остановки скорее всего еще больше. Т.е. суммарное время полной остановки блокчейна составляет около 2 часов.
Следующей любопытной зоной является "зона 3". В ней наблюдается странная по частоте запись блоков, по сравнению с предыдущими периодами, но эту зону мы рассмотрим отдельно когда будем смотреть распределение голосов по блокам.
И наконец с момента в 14:20 и до конца голосования мы наблюдаем постоянный рост времени вычисления. Напомню что речь идет о PoA-блокчейне и там не предусмотрено усложенение операций как в случае ETH, когда подобное поведение было обусловлено "бомбой сложности" в PoW-блокчейне. Т.е. мы наблюдаем неожиданное поведение метрики блокчейна, которое свидетельствует о деградации системы.
Анализ распределения голосов
Сразу оговорюсь, что то тут я буду максимально объективен и не буду касаться странностей в распределении голосов по кандидатам и этот анализ не будет никак вестись в разрезе отдельных кандидатов. В написанной мной программе я тем не менее оставил возможность это сделать любой заинтересованной стороне. В этой статье меня интересует только работоспособность системы. Если же вас интересуют эти странности — то вам следует обратиться к докладу, там всё описано максимально подробно.
Распределение голосов выглядит так
По оси X — номер блока, по оси Y — количество голосов в блоке.
В зонах остановки блокчейна (1А,1Б,2) записей голосов ожидаемо нет, потому что это зоны неисправности. А вот зона 3 дает поводы для размышлений. Там есть небольшое число блоков по 1-3 голосам, пара всплесков 4-5 голосов и огромный всплеск голосов в конце этой зоны. Я объединил эти события основываясь на метрике block time, поскольку деградация пошла уже после этих событий, а запись этих блоков шла в допустимых пределах. В зоне 3 не было остановки блокчейна, но данные по каким-то причинам практически не попадали в блокчейн.
Общая длительность этих зон — около 4-ех часов. Т.е. если учесть что всё голосование длилось 12 часов, то где-то треть времени данные по разным причинам не записывались в блокчейн.
В зоне связанной с деградацией мы отчетливо видим что режим записи изменился и данные стали писаться чаще, в отличии от мест где блокчейн работал стабильно. С чем это связано точно не известно, потому что точная конфигурация нам недоступна, но есть предположение что это может быть связанно с переполнением очереди транзакций (Transaction Queue) в Parity. Подобное поведение вызывает вопросы к команде выполнявшей интеграцию Parity с бэкендом, а также говорит о теоретической возможности потери голосов связанной с выбраковкой транзакций.
Интересным является то, что количество голосов в блоке ограничено числом 100. Мы так и не нашли в опубликованном коде эту константу — ни в настройках, ни в коде её нет.
Объяснений происхождения всплеска голосов, после которого началась деградация, на этом этапе анализа я не получил, и я попытался найти объяснение на фотографиях данных с экранов голосования, которые сделали наблюдатели.
Анализ данных доступных наблюдателям
Здесь пойдет речь о данных доступных наблюдателям, их позиционировали как альтернатива присутствия наблюдателей на реальном избирательном участке. Фотографии на основе которых они собраны вы можете получить из доклада.
Сразу оговорюсь, что я считаю, что наблюдателям намеренно не предоставили данные в том объеме, который необходим им для понимания и отслеживания процессов происходивших в системе
- Наблюдатели не видели метрики системы и как следствие не могли даже поверхностно оценить степень её работоспособности
- Наблюдателям не была предоставлена нода наблюдения за блокчейном
- Табличное представление данных не давало наблюдателям возможность оценить происходящее
Данные выводили 4 числа, которые показывали по сути воронку конверсии
- Сколько человек перешли к началу процесса голосования
- Сколько человек ввели регистрационную СМС
- Сколько человек получили бюллетень
- Сколько человек проголосовало
Поскольку это воронка, то все четыре параметра связаны между собой:
- Не зайдя на страницу нельзя получить СМС
- Не получив СМС нельзя получить бюллетень
- Не получив бюллетень нельзя проголосовать
Дополнительно следует учесть что время жизни бюллетеня — 15 минут. Это значит получив бюллетень, можно проголосовать только в течении 15 минут.
Время | Зарегистр. | Ввели СМС | получили | Проголосовали |
---|---|---|---|---|
08:30:00 | 575 | 289 | 274 | 236 |
08:45:00 | 858 | 428 | 406 | 372 |
09:30:00 | 1825 | 831 | 783 | 710 |
09:45:00 | 1825 | 831 | 783 | 710 |
10:00:00 | 1898 | 1007 | 957 | 710 |
10:15:00 | 1898 | 1007 | 957 | 710 |
10:30:00 | 1898 | 1007 | 957 | 710 |
10:45:00 | 1898 | 1007 | 957 | 710 |
11:00:00 | 1898 | 1007 | 957 | 710 |
11:15:00 | 2675 | 1090 | 1045 | 736 |
11:30:00 | 2787 | 1104 | 1079 | 748 |
11:45:00 | 2787 | 1104 | 1079 | 748 |
12:00:00 | 2787 | 1104 | 1079 | 748 |
12:15:00 | 2787 | 1104 | 1079 | 748 |
12:30:00 | 2887 | 1178 | 1103 | 759 |
12:45:00 | 3245 | 1274 | 1213 | 868 |
13:00:00 | 3866 | 1321 | 1295 | 973 |
13:16:00 | 4147 | 1420 | 1352 | 1045 |
13:31:00 | 4436 | 1495 | 1393 | 1085 |
13:46:00 | 4524 | 1588 | 1460 | 1114 |
14:01:00 | 4451 | 1783 | 1548 | 1138 |
14:16:00 | 4451 | 1783 | 1700 | 1165 |
14:31:00 | 4451 | 1783 | 1846(+63) | 1582 |
14:46:00 | 4451 | 1783 | 1926(+143) | 1669 |
15:01:00 | 4464 | 1786 | 1992(+206) | 1731 |
15:15:00 | 5153 | 1905 | 2045(+140) | 1784 |
15:30:00 | 5337 | 2024 | 2095(+71) | 1838 |
15:45:00 | 5337 | 2143 | 2095 | 1838 |
16:00:00 | 5337 | 2262 | 2095 | 1838 |
16:15:00 | 5337 | 2381 | 2095 | 1838 |
16:30:00 | 7161 | 2683 | 2230 | 2000 |
16:45:00 | 7260 | 2717 | 2259 | 2028 |
17:00:00 | 7388 | 2755 | 2293 | 2069 |
17:15:00 | 7500 | 2787 | 2317 | 2096 |
17:30:00 | 7622 | 2817 | 2340 | 2127 |
17:45:00 | 7731 | 2850 | 2361 | 2153 |
18:00:00 | 7839 | 2885 | 2386 | 2184 |
18:15:00 | 7920 | 2908 | 2405 | 2214 |
18:30:00 | 8005 | 2932 | 2418 | 2235 |
18:45:00 | 8091 | 2951 | 2434 | 2256 |
19:00:00 | 8199 | 2973 | 2451 | 2275 |
19:15:00 | 8287 | 2996 | 2469 | 2292 |
19:30:00 | 8394 | 3035 | 2495 | 2325 |
19:45:00 | 8503 | 3064 | 2512 | 2358 |
20:00:00 | 8581 | 3077 | 2525 | 2376 |
По оси 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/
Автор: Алексей