hbs2/docs/drafts/pep-03.md

210 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

PEP-03: update-reference
Задача: необходимо обеспечить контроль прав доступа при постинге
блоков (куда? TBD).
Пока существует только BlockAnnounce, который просто декларирует, что
пир X имеет блок Y.
Решение, скачивать его или нет принимает узел на основании каких-то
своих настроек.
Нужно ввести какую-то сущность (reference? topic?) которая даёт
возможность постить блоки "куда-то", на что бы принимающая сторона
имела возможность решать - принимать эти блоки или нет, и если
принимать --- то скачивать данные блоки у узла.
```
[A] [B]
| (suggest-ref-update ref (upd sign block) |
+---------------------------------------------->+
| | (check sign)
| | (check perm ACB)
| (get-blok-size block) |
+<----------------------------------------------+ (if ok)
| |
| (get-block-chunks) |
+<----------------------------------------------+
| |
| (chunk X ...) |
+---------------------------------------------->+
| |
| |
```
Открытые пока что вопросы:
1. Предлагать новую голову топика или предлагать блоки в топик?
2. Если предлагать новую голову, сойдется ли вообще когда-либо
топик?
3. Если мы считаем, что
```
topic ::= set blob
```
то это даёт нам возможность запрашивать разницу между тем, что есть у
нас, и тем, что есть у узла.
Таким образом, мы можем считать, что "topic" (reference) это merkle
tree включённых в него блоков + ACB.
Поскольку алгоритм упорядочивания блоков может отличаться в
зависимости от применения, а где-то и не требоваться вовсе, то сами
блоки могут упорядочиваются исключительно лексикографически (TBD?!) по
их хэшам. Что приводит нас к тому, что merkle tree данных и merkle
tree топика это разные вещи (!!!). Так как как данных
обязателен порядок узлов дерева.
Отсюда у нас два выхода:
1. Ввести вариант merkle tree где явно задан порядок блоков (файл!)
2. Ввести вариант merkle tree, где порядок не задан и определяется
только самими хэшами. Открытый вопрос --- сортировать тексты хэшей
или их бинарное представление.
Мы можем:
1. Получить difference (merkle опять?) между нашим содержимым и
содержимым пира
2. Скачать блоки из difference
3. Упорядочить топик
4. Получить difference
5. Если сошлось, то успокоиться
6. Если не сошлось, то вернуться на шаг 1.
Если не делать какого-то рода барьеров (аналог высоты в БЧ), то при
большом количестве узлов, которые пишут данные, данный алгоритм,
КАЖЕТСЯ, не сходится (доказать или очевидно? При отсутствии какого-то
рода барьера, обязательного для всех, в любой момент времени может
найтись узел, который добавит узлы в топик, таким образом, его
состояние и состояние всех других узлов будет различным. Если мы
упорядочим состояние между N узлами и этим узлом, то всегда может
найтись другой узел, который добавит "пост" в "топик" и состояние
между ним и теми N узлами опять окажется различным.
Каким образом можно ввести барьеры?
1. Ограничить число узлов, которые могут принимать решение о включении
блока в "топик".
Если их ограничить до одного, а этот один будет определяться тем, что
он смог посчитать какое-то значение, удовлетворяющее условиям ---
получится PoW.
Если их ограничить N узлами, которые должны подписать транзакцию
своими ключами, например, k/N ключей --- то получится что-то наподобие
PoA.
Если их ограничить N узлами, которые должны согласовать контент и в
реальном времени принять решение о включении --- то получится что-то
наподобие PoS/PBFT.
Нам нужен такой способ, который не требует обязательного ответа от
всех известных уполномоченных участников. Подходит: PoW, PoA (с
вариациями). PoW требует каких-то издержек на вычисления, что может
при малом числе участников приводить к каким-то ненужным задержкам
при добавлении блоков.
В данном применении (последовательность постов от ограниченного числа
участников) у нас нет необходимости решать задачу отсутствия double
spend, т.к. нет объекта для double spend. Решаемая задача ---
включать блок в set, или нет.
2. Какого-то рода временнЫе барьеры?
Например, некие узлы уполномочены выдавать некие токены, зависящие,
например, от времени, или просто гарантированно уникальные и для
которых определена последовательность. Тогда нам нужно просто
гарантировать, что в каждый момент времени будет принят (по некоему
алгориму) только один такой токен, с неким временем жизни (пока не
выдан следующий токен).
Тогда каждый узел для каждого топика ведёт список известных ему
токенов.
Когда узел предлагает блок --- он запрашивает у авторизованных узлов
этот токен либо же генерирует его сам, если он сам авторизованный узел
и сообщает его остальным.
При постинге блока постящий узел --- узнаёт токен и включает его в
предложение блока. Принимающий узел --- узнаёт токен и если
предлагаемый токен устарел --- то блок отвергается, если не устарел --
то принимается.
Таким образом, мы принуждаем узлы к коммуникациям и синхронизации,
избегаем ситуации, когда какой-то узел постит блоки сам себе, а потом
своё состояние выкидывает всем, принуждая всех участников
пересчитывать состояние.
Таким образом, при постинге блока мы:
1. Опрашиваем всех известных нам узлов
2. Получаем с каждого токен
3. Выбираем токен, который есть у большинства участников
4. Публикуем блок (рассылаем известным узлам)
5. Каждый узел, получивший блок --- принимает его, если верны
доказательства валидности блока (ACB + токен актуален)
6. Если (и обязательно) в токен ввести что-то хэш от известного состояния
топика --- то мы обязуем постящую сторону выяснить это состояние,
то есть, как минимум, скачать этот топик или узнать его состояние.
То есть, синхронизироваться.
Еще раз: мы не решаем задачу BFT. Может быть, она решается таким
путём, может быть, нет, неизвестно. Наша задача --- принудить узлы к
синхронизации перед публикацией своего контента и ввести некий
порядок для блоков.
Можно ли включать в токен время, как естественное, известное всем,
монотонно возрастающее значение? Никакого Proof-Of-Time не существует.
Наша задача --- выбирать актуальные, добросовестные узлы и
сотрудничать с ними.
Вопрос, почему узел должен быть актуальным и добросовестным мы выведем
за рамки данного документа.
Итого, примерный алгоритм, кажется, выглядит так:
1. Посчитать x = f1(известное-нам-состояние-топика)
2. Узнать текущий токен t = T(топик) у известных нам узлов
3. Посчитать значение y = f2(t,x)
4. Опубликовать (разослать всем известным узлам? или тем, с которыми
разговаривали? или всем, но в приоритете тем, с кем разговаривали?)
контент, включающий y.
5. Принимающая сторона рассматривает y, если он актуален (TBD), то
включает блок. Если нет -- то отвергает.
Более простой вариант:
1. Постящий узел включает число, определяемое предыдущим известным ему
состоянием
2. Принимающий узел смотрит: было ли такое состояние вообще когда-либо
ранее, и если было --- то как давно (Сколько голов тому назад).
Если было слишком давно (TBD), то блок не выключается, принуждая
постящий блок синхронизироватьсяи перересчитать число.
Если к этому варианту добавить nonce + "красивые хэши" мы получим
защиту от того, что блоки постятся слишком часто и состояние топика не
сходится у большинства.