«А давайте на блокчейне соцсеть построим!» (с) Часть 2.1

Часть 1 - https://set.ki/post/KY7Cdrw

Конечно, я не опишу все детали проекта, но постараюсь выделить наиболее яркие задачи, которые приходилось решать именно мне. В большинстве мест я пишу «мы», а не «я» — это осознанно: большинство идей мне не принадлежат, много технических решений придумывалось коллективно в ходе брейнстормов.

## Начало

Поясню, в чём вообще была проблема. Мы хотели хранить данные «социальных» транзакций сильно рядом с транзакциями блокчейна. Не на отдельном сервере, не ссылаться на них, а именно внутри блокчейна. Поэтому сделали так: у биткоина есть возможность записи произвольной информации в транзакцию — т. н. OP_RETURN. Там немного данных, 80 байт, но нам хватило, чтобы положить туда sha256 от Payload — как раз те самые социальные данные: идентификатор поста для лайка, текст комментария, направление подписки и т. д.

OP_RETURN является частью транзакции, а значит, социальные данные защищены, где бы они ни находились. Но даже тут мы не пошли по пути отдельного хранилища — нам нужна была полная децентрализация.

Началось с того, что мы посмотрели код биткоина, поняли, что он использует LevelDB, и быстро приняли решение: строить сложную структуру на ней не вариант — нужны выборки, а не только быстрый доступ по ключу. Классическая реляционная БД тоже не подходила из‑за собственного сервера: мы хотели интегрировать БД в код биткоина. Спасением тогда оказался проект [Reindexer](https://github.com/Restream/reindexer) — in-memory БД. Стало повеселее, и мы достаточно быстро запустили первую тестовую сеть, а следом и main.

В тот момент мы создали в Reindexer базу для данных соцсети «как из учебника»: юзеры, посты, лайки, комменты, подписки и т. д. Появилась возможность очень быстро выполнять простые SQL-запросы — база-то в ОЗУ, пока блокчейн занимался своими делами. API изобретать не пришлось: у биткоина есть собственный простой RPC-интерфейс, который для безопасности мы разделили на два — для управления узлом и для доступа к публичным социальным данным. Позже публичный тоже разделили на get/post, уже из соображений производительности.

## Память

Сеть не шардируема: все узлы хранят полную версию, облегчённых узлов тоже нет. А БД — в ОЗУ. Нужно было решение, и быстрое: к этому моменту приходилось докупать оперативку, стали отваливаться держатели узлов, а скорость загрузки узла при запуске растягивалась на десятки минут. Я предложил SQLite, провёл исследование: загрузил всю БД на тот момент, поигрался с индексами и запросами, посмотрел статистику использования диска — и понял, что нам подходит. Это был переломный момент.

Структуру БД мы перенесли как есть: появилось больше свободы в плане SQL, потребление ОЗУ минимизировалось, запас по дисковому объёму был большой. Но столкнулись с другой проблемой — скоростью обработки узлом транзакций. Сам блокчейн с БД делает работы немного: достать «родителя» для проверки новой транзакции и положить транзакцию в БД. С социальными транзакциями сложнее: нужно доставать посты, авторов, комменты. Чтение было хорошим, а запись хромала — узлу приходилось разбирать каждую транзакцию и заполнять таблицы, своего рода десериализация. Появился риск критичного замедления сети, когда узлы не будут успевать строить новые блоки.

Продолжение в Часть 2.2 - https://set.ki/post/mkxk5Gq

// Side effects: // - 2 AI agents damaged during text formatting and proofreading