Skip to content

ADR-004 Blockberry database

AS-IS

Логика

Есть блоки в блокчейне в которых есть события (например был перевод средств/перевод контракта).

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

У одного события в рамках одного блока можен быть несколько target-ов.

Таблица событий.

https://docs.google.com/spreadsheets/d/1eP_HyNlNB_ndgHz0k4_M8_H86dunOmKHHHghZe-xIrQ/edit?usp=sharing

Запись

indexer-syncer закидывает в базу:

  1. Уникальное название события (не ограниченное, скорее всего сотни тысяч, может быть более 2-х миллионов), binay, hex, длинной до 128 байт,
  2. Номер блока в котором оно произошли (в аваланче 270 млн блоков, в бинансе 50 млн).
  3. Сеть.

Фактически говорит вот такое событие произошло в таком блоке. На данный момент сохраняется список всех событий в указанном блоке.

Нагрузка

Во время синхронизации: 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 млн строк.

После обработки нового блока из блокчейна:

  1. Создается файл /blockberry/${network}/blocks/${block_number}-events.txt - построчный список евентов.
  2. Append в файл /blockberry/${network}/events/${event_name}-blocks.txt номер блока.

Use Case

  1. Есть 100 млн блоков. Есть событие XXX. Которое есть в каких-то блоках. Надо сказать номера блоков к которых есть события, пагинировано в порядке номера событий (снизу/сверу). Обычно младщие в начале.
cat /blockberry/${network}/events/{event_name}-blocks.txt
  1. Подкачать события с какого-то момента когда все упало.

Проблемы:

    1. Поиск по нескольким идентификатороам.
    1. Нет транзакционности (много писателей).

Сейчас писатель один и он пишет в файловую систему.

    1. Ограничены на возмоности осуществления запросов. В будущем появляются новые запросы и нужно думать как его сделать.

Да, но решаемо. Красный флаг для Саши.

    1. Проблема с конкурентным доступом на чтение.

Нет проблем, FS на чтение монтируется к неограниченному количество node.

    1. Целостность данных (сами отвечаем)

Понять как в одной транзкции создать файл и добавить в файл строку. Либо принять этот риск.

    1. Сохранность данных (потеря диска)

Скользящий/перманентный бакап в NFS/S3. Учесть транзакционку.

    1. Мониторинг сложнее

Что мониторить:

    1. Не понятно как внедрять таргеты (в начале года)

Ограничения:

  1. Количество файлов в директории в FS. 4 млрд.
  2. Индексация файлов в каталоге.

Варианты:

  1. Использовать S3.

Реализация

Store

  1. Вставка - 2-4 часа.
  2. 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)

Запросы:

  1. Дай все блоки по событиям 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

Структурный план запроса:

  1. index events.address
  2. index block_events.[event_id, block_number]
  3. складываются результаты, сортируются по block_number

Решение 4. postgresql по блокам + array (или jsonb)

Таблица block_events. Содержит запись блок-событие.

  • block_number bigint
  • events text[]

Индексы:

  • block_number
  • events gin, block_number

Запросы:

  1. Дай все блоки по событиям XXX, YYY в порядке block_nunber
select block_number from block_events where {"XXX","YYY"} <@ events order by block_number

Структурный план запроса:

  1. index block_number.events