ADR-004 Blockberry database¶
- Схема базы - https://github.com/safeblock-com/blockberry/blob/main/database/postgres/schema.sql
- По запросам - https://github.com/safeblock-com/blockberry/tree/main/internal/store/pg_store/docs
- По базе - https://github.com/safeblock-com/blockberry/tree/main/database/postgres/docs
AS-IS¶
Логика¶
Есть блоки в блокчейне в которых есть события (например был перевод средств/перевод контракта).
Для того чтобы воркеры проходили только по тем блокам в которых есть события, нам нужно знать в каком блоке были эти события произошли.
У одного события в рамках одного блока можен быть несколько target-ов.
Таблица событий.
https://docs.google.com/spreadsheets/d/1eP_HyNlNB_ndgHz0k4_M8_H86dunOmKHHHghZe-xIrQ/edit?usp=sharing
Запись¶
indexer-syncer закидывает в базу:
- Уникальное название события (не ограниченное, скорее всего сотни тысяч, может быть более 2-х миллионов), binay, hex, длинной до 128 байт,
- Номер блока в котором оно произошли (в аваланче 270 млн блоков, в бинансе 50 млн).
- Сеть.
Фактически говорит вот такое событие произошло в таком блоке. На данный момент сохраняется список всех событий в указанном блоке.
Нагрузка¶
Во время синхронизации: 100+ блоков лопатим, значит 100 сохранений списка событий для всех блоков. В штатном режиме: 10 вставок списка событий
Чтение¶
blockberry-webserver делает запросы. Потребитель данных - клиенты компании blockberry, первый клиент - safeblock. У safeblock потребителем являюется worker-ы:
1) Дай мне номера блоков в которых присутсвуют такие-то события (от 1 до 10), начиная с такого-то блока, такое-то количество блоков (например 100). Время ответа < 1 сек. Количество запросов зависит от пользовательской нагрузки. Один пользователь пораждает несколько запросов в минуту. 3) Дай список событий в этом блоке; редко, требуется для отладки. Сейчас активно не используется, но есть потенциальные покупатели, которые заинтересованы в этой информации. 4) Дайте все события по такому таргету.
TO-BE¶
Все тоже самое, только помимо факта свершившегося события, сохраняется дополнительный аттрибут (target contract hex-строка, порядок 100 тыс). Одно событие в одном блоке может случится для разных адресов. Получается 3D матрица.
Чтение¶
те-же что были +
1) Дай мне номера блоков где есть такое событие и такой target contract; Время ответа < 1 секунды. Количество запросов зависит от пользовательской нагрузки. 2) Дай мне события по такому targed contract-у; Время ответа < 1 секунды. Количество запросов зависит от пользовательской нагрузки. 3) Дай мне блоки в которых есть такой targed contract; Время ответа < 1 секунды. Количество запросов зависит от пользовательской нагрузки.
Получается матрица 270млн х 2млн х 1млн.
Ссылки¶
Опции¶
Решение 1. Хранение через файлы.¶
/blockberry/${network}/blocks/${block_number}-events.txt- построчный список событий - до 5 тыс событий./blockberry/${network}/events/${event_name}-blocks.txt- построчный список блоков - 50-60 млн строк.
После обработки нового блока из блокчейна:
- Создается файл
/blockberry/${network}/blocks/${block_number}-events.txt- построчный список евентов. - Append в файл
/blockberry/${network}/events/${event_name}-blocks.txtномер блока.
Use Case¶
- Есть 100 млн блоков. Есть событие XXX. Которое есть в каких-то блоках. Надо сказать номера блоков к которых есть события, пагинировано в порядке номера событий (снизу/сверу). Обычно младщие в начале.
- Подкачать события с какого-то момента когда все упало.
Проблемы:¶
-
- Поиск по нескольким идентификатороам.
-
- Нет транзакционности (много писателей).
Сейчас писатель один и он пишет в файловую систему.
-
- Ограничены на возмоности осуществления запросов. В будущем появляются новые запросы и нужно думать как его сделать.
Да, но решаемо. Красный флаг для Саши.
-
- Проблема с конкурентным доступом на чтение.
Нет проблем, FS на чтение монтируется к неограниченному количество node.
-
- Целостность данных (сами отвечаем)
Понять как в одной транзкции создать файл и добавить в файл строку. Либо принять этот риск.
-
- Сохранность данных (потеря диска)
Скользящий/перманентный бакап в NFS/S3. Учесть транзакционку.
-
- Мониторинг сложнее
Что мониторить:
-
- Не понятно как внедрять таргеты (в начале года)
Ограничения:¶
- Количество файлов в директории в FS. 4 млрд.
- Индексация файлов в каталоге.
Варианты:
- Использовать S3.
Реализация¶
Store¶
- Вставка - 2-4 часа.
- Select-запросы (называем парсеры) -
Решение 2. Хранение через файлы.¶
/blockberry/${network}/blocks/${block_number}/${event_name}-до 5 тыс событий./blockberry/${network}/events/${event_name}/${block_number}- 50-60 млн файлов.
у нас есть 100 млн блоков
Решение 3. Нормализация данных¶
Таблица events. Содержит адреса событий.¶
- id bigint
- address string
Индексы: * id - uniq, primary key * address- uniq
Таблица block. Содержит номер блока который обработан¶
- block_number bigint
Индесы: * block_number uniq, primary key
Таблица block_events. Содержит запись блок-событие.¶
- block_number bigint
- event_id bigint - идентификатор события
Индексы:
- (event_id, block_number) uniq
- (block_number, event_id)
Запросы:¶
- Дай все блоки по событиям
XXX,YYYв порядке block_nunber
select block_number from block_events where address in (select id from events where address in ("XXX", "YYY")) order by block_number
Структурный план запроса:
- index events.address
- index block_events.[event_id, block_number]
- складываются результаты, сортируются по block_number
Решение 4. postgresql по блокам + array (или jsonb)¶
Таблица block_events. Содержит запись блок-событие.¶
- block_number bigint
- events text[]
Индексы:
- block_number
- events gin, block_number
Запросы:¶
- Дай все блоки по событиям
XXX,YYYв порядке block_nunber
Структурный план запроса:
- index block_number.events