Этот блог содержит технические инструкции по преобразованию необработанных сообщений, хранящихся в gosssip_store, в базе данных sqlite3 с использованием Node.js.

Хранение сетевых сообщений Lightning

Есть несколько способов решить эту проблему, c-lightning, а также LightningD можно использовать для получения последних сообщений gossip_messages.

Подход, используемый для целей этого проекта, заключается в архивировании всех gossip_messages в базе данных sqlite3 с использованием плагина Historian, созданного для core-lightning (https://github.com/lightningd/plugins/tree/master/historian)

Какие сообщения Lightning Network извлекаются?

С помощью подключаемого модуля архива извлекаются три типа сообщений Lightning Network.

  1. Channel_announcement
  2. Channel_update
  3. node_announcement

Channel_announcement gossip_message отвечает за предоставление информации о владельце канала. Он создает связь между каждым биткойн-ключом в цепочке с каждым ключом узла сети Lightning.

Сообщение Channel_update gossip_message отвечает за обновление информации в сети о каждой стороне канала (узла). Два узла на каждом конце канала обновляют сеть Lightning о своих комиссиях и минимальной дельте срока действия, необходимой для ретрансляции HTLC через этот канал.

node_announcement gossip_message позволяет узлу указывать дополнительные данные, связанные с ним, в дополнение к его открытому ключу.

Разбор Channel_announcement

Необработанное сообщение channel_announcement обычно представляет собой буфер длиной 432 байта. Каждый байт имеет свое значение и должен быть назначен определенному полю, чтобы получить осмысленный вывод из необработанного сообщения.

Преобразование необработанных сообщений в JSON можно выполнить с помощью Node.js или JavaScript. Чтобы узнать больше о полях, связанных с channel_announcement, вы можете ознакомиться со спецификациями сети Lightning по адресу https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#the-node_announcement-message.

Первым шагом для анализа необработанного сообщения является сбор необработанного сообщения, это можно сделать с помощью SCID канала или, если вы анализируете все сообщения channel_announcement, мы можем просто перебрать их.

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

Первые 2 байта буфера channel_announcement содержат информацию о версии.

Следующие 64 байта содержат подпись узла первого узла. Мы можем разобрать их, используя следующий метод:

В приведенном выше методе я создал переменную curr_index, которая значительно упрощает итерацию по буферу по сравнению с вычислением начальной и конечной точки по индексу. Приведенный выше код помогает нам сохранить шестнадцатеричное значение node_signature_1.

Следующие 64 байта содержат подпись узла второго узла, следующие 64 байта содержат подпись биткойна первого узла, а последующие 64 байта содержат подпись биткойна. второго узла.

Вот как выглядит вывод после разбора биткойнов и подписи узлов обоих узлов.

Теперь следующие 2 байта — это flenбайты, мы собираем и анализируем эти байты flen в целочисленном формате.

После синтаксического анализа мы узнаем точное количество байтов, которое нам нужно пройти, чтобы получить переменную feature.

После получения переменной функции мы анализируем следующие 32 байта, чтобы получить chain_hash.

Следующие 8 байтов содержат short_channel_id. Short_channel_id помогает нам проверить канал с блокчейном биткойна, поскольку он содержит номер блока, transaction_id и output_index канал. Первые 3 байта из этих 8 байтов содержат номер блока, следующие 3 байта содержат tx_id, а последние 2 байта содержат output_index. Нам также необходимо преобразовать шестнадцатеричные значения в целые, чтобы сделать их поддающимися проверке.

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

Далее мы анализируем node_id_1, перебирая следующие 33 байта, за которыми следуют еще 33 байта для node_id_2. Таким же образом мы читаем bitcoin_key_1, читая следующие 33 байта, и bitcoin_key_2, читая последний оставшийся 33 байта.

Разбор Channel_update

Необработанное сообщение channel_update обычно представляет собой буфер длиной 138 байт.

Первые 2 байта буфера channel_update содержат информацию о версии.

Первые 64 байта содержат подпись, следующие 32 байта содержат chain_hash. Уникальный факт с chain_hash заключается в том, что он должен быть эквивалентен «000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f», это значение можно использовать для проверки того, можете ли вы правильно проанализировать chain_hash или нет.

Следующие 8 байтов содержат short_channel_id, их анализ аналогичен анализу short_channel_idсообщения channel_annoucement.

Следующие 4 байта содержат отметку времени. Далее нам нужно преобразовать эту отметку времени из шестнадцатеричной в десятичную.

Следующий 1 байт содержит message_flags, следующий 1 байт содержит channel_flags, следующие 2 байта содержат cltv_expiry_delta, следующие 8 байтов содержат htlc_minimum_msat, следующие 4 байта содержат Fee_base_msat, следующие 4 байта содержат fee_proportional_millionths.

Теперь, если длина буфера равна 138, мы можем прочитать оставшиеся 8 байт для htlc_maximum_msat

Разбор node_announcement

Буфер node_annoucement имеет длину 161 байт.

Первые 2 байта буфера node_annoucement содержат информацию о версии.

Следующие 64 байта содержат подписьузла.

Теперь следующие 2 байта — это flenбайты, мы собираем и анализируем эти байты flen в целочисленном формате.

После синтаксического анализа мы узнаем точное количество байтов, которое нам нужно пройти, чтобы получить переменную feature. (То же, что и канал_объявление)

Следующие 4 байта содержат метку времени,мы преобразуем метку времени из шестнадцатеричной в десятичную.

Следующие 33 байта содержат parsed_node_id, следующие 3 байта содержат цвет RGB узла, а следующие 32 байта содержат псевдоним.

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

Первый абайт содержит тип адреса, в зависимости от адреса мы узнаем количество байтов, которые мы должны прочитать, чтобы получить адрес. Адрес может быть следующего типа:

  1. ipv4 (читаем 4 байта)
  2. ipv6 (читаем 16байт)
  3. Луковые сервисы Tor v2 (читаем 10 байт)
  4. Луковый сервис Tor v3 (читаем 35 байт)

далее во всех вышеперечисленных 4 типах мы должны прочитать оставшиеся два байта для получения номера порта.

Окончательный адрес должен выглядеть как приведенный выше объект JSON, адрес на приведенном выше рисунке представляет собой адрес типа ipv6.

Я создал репозиторий GitHub https://github.com/vinayaksh42/clightning-node-server, с помощью которого вы можете легко развернуть свой собственный сервер Node.js для разбора gossip_message. В приведенном выше репозитории вам нужно будет скопировать содержимое файла config/example.default.json и создать файл config/default.json, который будет указывать на ваше собственное развертывание базы данных sqlite3.

Я надеюсь, что этот блог помог вам разобрать ваши gossip_messages!