Forwarded from Dmitry Zuikov
Не знаю где еще спросить - надо бы построить модель распределенного алгоритма на каком-нибудь из фреймворков. Алгоритм вроде бы простой, но я инструментарием для подобного плана моделирования вообще не владею, и не представляю, сколько это (построение модели) займет времени. Есть ли где-то тусовки по этим инструментам (spin, tla+) или есть кто-то, кто готов приватно пообщаться на эту тему, что бы тут эфир не засорять?
Forwarded from Dmitry Zuikov
курс лекций Лампорта (тот самый Лампорт!) по tla+ https://lamport.azurewebsites.net/video/videos.html
Вообще не собирался в это лезть, если честно, но как всегда — стало надо. Есть ли, интересно, какой-то КМБ по формальной верификации и модел-чекингу (как оно по русски-то хоть)?
консенсус qblf делает вид, что работает на нескольких хостах. какой-то тут должен быть подвох, конечно. отлаживать это всё дико. две реплики расходятся, надо минимум три и желательно с сетью - т.к. что бы блоки подъезжали с задержкой
Внимательный читатель конечно спросит, на кой чёрт тут в hbs2 понадобился вообще консенсус. Суть такова, что есть еще те проекты, за которые деньги платят, и там нужен какой-то "блокчейн", я извиняюсь. У нас был один, но там легче застрелиться, чем на нём делать это вот всё. Честно говоря думалось, что имея в hbs2-peer gossip + pex + библиотеку для реализации протоколов + merkle деревья + подписи + распространение блоков, как-то можно намутить "блокчейн" малой кровью, ну там, CRDT какое-нибудь с подписями, типа такого. Но нет, просто это не решается. Впиливать какой-то прямо tendermint поверх этого всего... Ну такое. Была идея, что можно такие вещи делать внешними процессами, если от hbs2-peer провесить какие-то удобные ручки, и в общем-то, такие ручки нашлись - это unix socket-ы, на них исключительно удобно делать двухстороннюю коммуникацию, без всяких заморочек, как с вебсокетами бы было. Т.е в hbs2-peer решает вопрос организации сети, а FSM крутится во внешнем процессе. Ну и вроде как оно работает. Была еще идея, что множества идемпотентных транзакций можно как-то проще приводить к общему знаменателю, чем вот это вот всё prevote/vote/precommit/commit c лидером, и, вроде, так оно и есть. Еще в библиотеку Raft запиливаем на всякий случай, пусть будет.
Что даёт консенсус в отличие от CRDT: нам не надо вообще заморачиваться структурой, пиры за несколько раундов договорятся и согласуют любые данные, т.е например, блоб репозитория гита. мы можем не париться порядком транзакций в нём, а можем тупо дописывать новые объекты в конец, и новый стейт будет хэшом нового получившегося файла, который будет эффективно расходиться по hbs2 меркл-деревьями (будут докачиваться только отсутствующие блоки). Минус в том, что какое-то количество пиров должно быть всегда онлайн. Причем, пока что это совершенно конкретное количество - типа 2/3 от всех пиров, указанных в настройках канала. Для рефлогов/рефчанов такое необязательно, пира загасил, хоть всех, поднял, они засинкаются. Вот и думай теперь, как с этим быть
Что он еще даёт: стресс-тесты для всего hbs2. Напрягает сеть очень сильно и это воспроизводимая нагрузка, более того, можно иметь определенные начальное и конечное состояние, что даёт возможность сделать повторяемые тесты. Ну, пусть будет. (UPD: и походу, он работает)
Forwarded from Dmitry Zuikov
В QBLF опять сталкиваемся с некоей проблемой, которая
устойчиво повторяется и в других протоколах: большое
количество маленьких объектов, которая отчасти проистекает
из желания видеть каждый маленький объект, всё ж таки,
объектом, адресуемым по его хэшу, и наличием некоего
состояния, как списка ссылок на эти объекты.
Таким образом, у нас есть как сами объекты, так и
хэш-ссылки на них, и множества хэш-ссылок.
Больше объектов - больше блоков - больше раундтрипов, т.к.
у нас преимущественно pull-модель, т.е каждый узел сам
пытается получить, что ему нужно, спрашивая у всех.
Единица запроса --- как раз блок (который еще бьётся на
чанки, т.е *неадресуемые глобально* части, имеющие смысл
только в контексте сессии передачи блока. Смысл чанков ---
помещаться в UDP пакет, т.к системы для работы нужен
минимум UDP).
Практически это означает, что на 100 TPS QBLF начинает
как-то грустнеть, и на текущий момент основной проблемой
видится именно передача состояния --- она прямо заметно
вносит задержки.
C количеством раундтрипов падает скорость, т.к.
критичными становятся задержки.
В hbs2-git вопрос решился переходом от объектов к журналам
объектов, каждый журнал - по сути объекты, создаваемые
каждым push -- то есть все объекты, доступные из git
commit, отсутствующие в текущем состоянии ссылки, куда мы
этот push делаем.
Можно ли сделать так же в QBLF, т.е состоянием сделать не
Можно, но: если транзакция не несёт свой хэш, то придется
его вычислять (каждый раз).
Ок, решается изменением типа
сущность, доступная по её хэшу, или же данные дублируются:
один раз в этом меркл дереве, и еще один раз сами по себе,
при этом, у нас не факт, что есть гарантия
консистентности.
Есть еще вариант --- ввести специальный протокол и
структуру данных для передачи большого числа маленьких
объектов, ключом сделать, например, [HashRef] - т.е список
хэшей, а значением - список объектов в порядке хэшей в
ключе. Еще точнее, ключом будет не [HashRef], а хэш
соответствующего ему merkle tree.
Тогда тот, кто раздаёт --- сам заботится о создании ключа,
и создании журнала.
Тот, кто получает --- может поинтересоваться, а нет ли для
этого запроса ([HashRef]) --- журнала объектов, и если да
-- то выкачать его.
Что плохо: ну, сами журналы прежде всего. Они лежат в том
же хранилище и засоряют его, дублируя инфомацию.
Это с одной стороны. С другой стороны, они могут быть
чем-то типа LRU кэша списка объектов, которые по какой-то
причине всем требуются вместе, т.е при падении
популярности ключа --- можно со временем удалять и сам
журнал.
Можно ли избежать дублирования? Теоретически --- да, видно
несколько путей. Практически, все они выглядят сложными, и
по сравнению с использованием плоского файла неизбежно
замедлят чтение и передачу.
устойчиво повторяется и в других протоколах: большое
количество маленьких объектов, которая отчасти проистекает
из желания видеть каждый маленький объект, всё ж таки,
объектом, адресуемым по его хэшу, и наличием некоего
состояния, как списка ссылок на эти объекты.
Таким образом, у нас есть как сами объекты, так и
хэш-ссылки на них, и множества хэш-ссылок.
Больше объектов - больше блоков - больше раундтрипов, т.к.
у нас преимущественно pull-модель, т.е каждый узел сам
пытается получить, что ему нужно, спрашивая у всех.
Единица запроса --- как раз блок (который еще бьётся на
чанки, т.е *неадресуемые глобально* части, имеющие смысл
только в контексте сессии передачи блока. Смысл чанков ---
помещаться в UDP пакет, т.к системы для работы нужен
минимум UDP).
Практически это означает, что на 100 TPS QBLF начинает
как-то грустнеть, и на текущий момент основной проблемой
видится именно передача состояния --- она прямо заметно
вносит задержки.
C количеством раундтрипов падает скорость, т.к.
критичными становятся задержки.
В hbs2-git вопрос решился переходом от объектов к журналам
объектов, каждый журнал - по сути объекты, создаваемые
каждым push -- то есть все объекты, доступные из git
commit, отсутствующие в текущем состоянии ссылки, куда мы
этот push делаем.
Можно ли сделать так же в QBLF, т.е состоянием сделать не
State = [HashRef]а, например:
HashRef -> Transaction
State = [Transaction]т.е стейтом являются сами транзакции, а не их хэши.
Можно, но: если транзакция не несёт свой хэш, то придется
его вычислять (каждый раз).
Ок, решается изменением типа
State = [Wrapped HashRef Transaction]Что плохо тут: транзакция или теряется, как отдельная
сущность, доступная по её хэшу, или же данные дублируются:
один раз в этом меркл дереве, и еще один раз сами по себе,
при этом, у нас не факт, что есть гарантия
консистентности.
Есть еще вариант --- ввести специальный протокол и
структуру данных для передачи большого числа маленьких
объектов, ключом сделать, например, [HashRef] - т.е список
хэшей, а значением - список объектов в порядке хэшей в
ключе. Еще точнее, ключом будет не [HashRef], а хэш
соответствующего ему merkle tree.
Тогда тот, кто раздаёт --- сам заботится о создании ключа,
и создании журнала.
Тот, кто получает --- может поинтересоваться, а нет ли для
этого запроса ([HashRef]) --- журнала объектов, и если да
-- то выкачать его.
Что плохо: ну, сами журналы прежде всего. Они лежат в том
же хранилище и засоряют его, дублируя инфомацию.
Это с одной стороны. С другой стороны, они могут быть
чем-то типа LRU кэша списка объектов, которые по какой-то
причине всем требуются вместе, т.е при падении
популярности ключа --- можно со временем удалять и сам
журнал.
Можно ли избежать дублирования? Теоретически --- да, видно
несколько путей. Практически, все они выглядят сложными, и
по сравнению с использованием плоского файла неизбежно
замедлят чтение и передачу.
Никогда всёрьез не задумывался про пресловутый KYC, относился к нему, как к некоей докуке. Но если подумать, то главной вещью, отвечающей за KYC как оно сделано у большинства является сложность подмены фото/видео с камеры мобильного. Ну то есть натурально, тебе не дают загрузить фотку, а вынуждают фоткать из самого приложения. Естественно, это выглядит достаточно смехотворно и должно быть наказано. Конечно, по мыльной фотке определить аутентичность, например, российских (да и любых) водительских прав, которые даже реальные выглядят как мутно напечатанный фейк на дешевой картонке — малореально. Доступа к базам никакого нет, особенно сейчас. Это даже не театр безопасности, это утренник в детском саду безопасности. Если что, я вообще KYC считаю порочной практикой, которая только осложняет жизнь нормальным людям. Надо будет с этим разобраться, но потом.
Возвращаясь к передаче стейта в QBLF и вообще. Протокол передачи журналов объектов по хэшу журнала ссылок смущает меня тем, что в p2p сети можно легко генерить и заставлять скачивать мусор, просто генерируя рандомные хэши в ответ на запрос. Должно быть легко проверить и сложно сгенерировать, а тут получается наоборот. Заставлять генерирующего хэш включать туда какие-то элементы PoW - выглядит довольно-таки бредово: становится сложно/сложно. Решений, видимо, два: 1) список доверенных пиров, мы считаем, что они не будут генерить мусор 2) опять же, онлайн-консенсус: по запросу собираем все ответы, выбираем популярный, проверяем все, наказываем вредителей. Минус в том, что это всё сложно и много движущихся частей. Торренты вон тоже потенциально подвержены замусориванию, но на практике этого не происходит в значительных масштабах, т.к. нет экономической мотивации
Меня несклолько пугает, что я не понимаю ментальную модель гита тех, кто не понимает гит. А значительная часть его не понимает, а как тогда они
функционируют. У них ментальная модель - чего? svn ? Кто в наши дни видел svn, даже деды не помнят. А как тогда. Это вообще не праздный вопрос, когда делаешь "распределенный git".
функционируют. У них ментальная модель - чего? svn ? Кто в наши дни видел svn, даже деды не помнят. А как тогда. Это вообще не праздный вопрос, когда делаешь "распределенный git".
Forwarded from Dmitry Zuikov
Что-то бы с hbs2-git балансируем ровно в однгом в шаге от MVP и никак его не сделаем. То тюлень позвонит, то олень. То риалтайм консенсус прикручиваем, то Raft, то теперь программу лояльности на этом хотят запускать мульти-конторную (чисто потому, что можем, других причин нет)
Шаг называется "приватные репозитории"
собственно, структура репо сейчас:
1. протестировать, что история с групповым ключом работает - мы это делали когда-то, надо опять убедиться. прямо сделать ключ, добавить туда всех участников, сделать с ним зашифрованное merkle дерево, раздать участникам и убедиться, что работает.
это само про себе круто, иметь такой примитив, групповое end-to-end шифрование.
2. определить политику работы с ключами в репо. поскольку один репо = одна ссылка, и у репо только один писатель, то, кажется, дело обстоит так:
1. создать групповой ключ
2. добавить настройку в настройки репо - шифровать данным групповым ключом
3. при создании merkle tree - шифровать
4. при import - при чтении - расшифровывать
отягчающие: hbs2-git работает через http api hbs2-peer, постя туда / читая оттуда кусками, каждый кусок = блок, т.е надо или написать ФВП, которая будет расшифровывать, или вручную каждый блок расшифровывать, равно как и шифровать. но это же, блин, несложно.
Шаг называется "приватные репозитории"
собственно, структура репо сейчас:
State = [HashRef]таким образом. что бы перейти к приватным репо, надо
HashRef -> Merkle (GitRepoLog)
1. протестировать, что история с групповым ключом работает - мы это делали когда-то, надо опять убедиться. прямо сделать ключ, добавить туда всех участников, сделать с ним зашифрованное merkle дерево, раздать участникам и убедиться, что работает.
это само про себе круто, иметь такой примитив, групповое end-to-end шифрование.
2. определить политику работы с ключами в репо. поскольку один репо = одна ссылка, и у репо только один писатель, то, кажется, дело обстоит так:
1. создать групповой ключ
2. добавить настройку в настройки репо - шифровать данным групповым ключом
3. при создании merkle tree - шифровать
4. при import - при чтении - расшифровывать
отягчающие: hbs2-git работает через http api hbs2-peer, постя туда / читая оттуда кусками, каждый кусок = блок, т.е надо или написать ФВП, которая будет расшифровывать, или вручную каждый блок расшифровывать, равно как и шифровать. но это же, блин, несложно.
Псто про ментальную модель гита собрал, конечно, лулзовых коментов, но если у человека нет "ментальной модели" то откуда он тогда вообще знает, как работать с системой контроля версий? Конечно же, она есть. Вопрос, какая.
Учитывая, что некоторые вещи в git и придумали, во всяком случае, до него они не были широко известны, т.е понятия такого до git не было.
Конечно же, модель есть. Просто у одних это интуиция, выработанная пробами и ошибками, после обрывочных рассказов тех, кто читал про git flow, а у других это статья (вроде Торвальдса, но не уверен) + выступление Торвальдса, где он разносит svn и рассказывает про git. В принципе этого достаточно, что бы понимать, что ты делаешь, когда что-то делаешь в гите. В первом случае же просто зажмуриваешься и давишь на кнопки.
Но git это прост пачка утилит для работы с базой в специфическом формате, например, можно работать, как описано в git flow, а можно, как в gerrit, и кстати, в gerrit есть резонные причины делать именно так ( repeat (commit —amend) && push) , но можно и сяк ( merge —squash —no-commit && push ) и у того или иного способа есть свои последствия. Не говоря о же о том, что там есть еще и что до git не было известно (cherry-pick, read-tree и еще миллион всего). А можно патчи слать имейлом или телегой. А можно бандлы.
В гите многое сделано концептуально криво, из-за того, что на старте не шарили (бранчи, ссылки).
Мутабельные ссылки в распределенном окружении без механизмов согласования (их можно было бы хотя бы версионировать!)
Что я хочу сказать? Вот ты делаешь что-то гитом (это ответ на вопрос "как". гитом), а откуда ты знаешь, чего ты хочешь добиться и что это делается именно так? Первый вопрос совершенно точно из ментальной модели "распределенный контроль версий и что нам от него надо".
Учитывая, что некоторые вещи в git и придумали, во всяком случае, до него они не были широко известны, т.е понятия такого до git не было.
Конечно же, модель есть. Просто у одних это интуиция, выработанная пробами и ошибками, после обрывочных рассказов тех, кто читал про git flow, а у других это статья (вроде Торвальдса, но не уверен) + выступление Торвальдса, где он разносит svn и рассказывает про git. В принципе этого достаточно, что бы понимать, что ты делаешь, когда что-то делаешь в гите. В первом случае же просто зажмуриваешься и давишь на кнопки.
Но git это прост пачка утилит для работы с базой в специфическом формате, например, можно работать, как описано в git flow, а можно, как в gerrit, и кстати, в gerrit есть резонные причины делать именно так ( repeat (commit —amend) && push) , но можно и сяк ( merge —squash —no-commit && push ) и у того или иного способа есть свои последствия. Не говоря о же о том, что там есть еще и что до git не было известно (cherry-pick, read-tree и еще миллион всего). А можно патчи слать имейлом или телегой. А можно бандлы.
В гите многое сделано концептуально криво, из-за того, что на старте не шарили (бранчи, ссылки).
Мутабельные ссылки в распределенном окружении без механизмов согласования (их можно было бы хотя бы версионировать!)
Что я хочу сказать? Вот ты делаешь что-то гитом (это ответ на вопрос "как". гитом), а откуда ты знаешь, чего ты хочешь добиться и что это делается именно так? Первый вопрос совершенно точно из ментальной модели "распределенный контроль версий и что нам от него надо".
К вопросу о ментальных моделях. Если слово не нравится, предложите как-то другое. Есть вот такая вещь, как syncthing. Хорошая штука, именно она вдохновила делать hbs2, потому, что в целом оно работает и у меня есть расшаренный на все девайсы набор данных (файлы, фотки), но (skipped), но сделать на ней то, что мне надо - нельзя, и модель у неё странная. То есть там есть сущность "устройство". Потом "устройство" "предлагает" "папку" (folder) c квази-уникальным id. Потом ты вручную прописываешь, в какой каталог на диске смотрит эта "папка", и если несколько "папок" смотрят в один каталог, syncthing с переменным успехом пытается мержить редактируемые одновременно каталоги. Даже с одним писателем (мной), это время от времени вызывает конфликты, как оно мержит — непонятно, т.е даже невозможно под него подстроиться. С git это не будет работать, если будет несколько писателей, хотя казалось бы, в git каждый объект уникален. Каждый, да не каждый, есть ссылки (которые просто файлы!) на объекты, и еще пачка неверсионируемого контента. Нельзя каталог с гитом безопасно синхронизировать файловыми операциями. Это правда, косяк скорее гита, можно было более нормально сделать (как у нас в hbs2 бгг. ведь это гит на с стероидах (CAS на самом деле) с разными протоколами репликации). Это я просто обновлял мобилу взамен сгнившей и пытался передать с неё файл приватных ключей на новую мобилу, не через телеграм и не будучи уверен, что файл зашифрован, это ж андроид, gui, в нем непонятно ничего, что происходит. Минут через двадцать плюнул и экспортировал с ноута, убедившись, что зашифровано.
Возвращаясь с syncthing — видно, что модель кривая и в ней много лишнего. Мы хотим: иметь общий (виртуальный) каталог на кучу устройств, данные должны быть гарантированно зашифрованы, и доступ на чтение-запись только ограниченному кругу лиц (ключей, на самом деле). Сущности - каталог, ключ, круг ключей. Устройство - не сущность. Какая мне разница, что устройство afd6fcc5-1f28-43e9-a767-0170dc5b597d XPEH-C-BYGRA предлагает мне папку XXX ? Что мне делать с этой информацией? Даже если мне ip скажут (таже моя мобила, но через мобильную сеть).
Если подразумевается одновременное редактирование — то должен быть какой-то ясный алгоритм мержа. Ну и так-то всё.
git имеет такую великую вещь, как remote protocol helper, то есть можно делать push/fetch куда угодно, хоть в гугл диск, хоть в чат в телеграме, хоть в эхоконференцию в FIDO, лишь бы транслировалось в его понятия, которых у него совсем немного - получить объекты да установить ссылки. ссылки не версионируются (хаха!) поэтому внешнее хранилище должно это делать само, т.е должен быть некий алгоритм для ссылок (у нас в hbs2-git это выбор самой длинной цепочки из множества операций установки ссылки, что иногда приводит к лулзам)
Возвращаясь с syncthing — видно, что модель кривая и в ней много лишнего. Мы хотим: иметь общий (виртуальный) каталог на кучу устройств, данные должны быть гарантированно зашифрованы, и доступ на чтение-запись только ограниченному кругу лиц (ключей, на самом деле). Сущности - каталог, ключ, круг ключей. Устройство - не сущность. Какая мне разница, что устройство afd6fcc5-1f28-43e9-a767-0170dc5b597d XPEH-C-BYGRA предлагает мне папку XXX ? Что мне делать с этой информацией? Даже если мне ip скажут (таже моя мобила, но через мобильную сеть).
Если подразумевается одновременное редактирование — то должен быть какой-то ясный алгоритм мержа. Ну и так-то всё.
git имеет такую великую вещь, как remote protocol helper, то есть можно делать push/fetch куда угодно, хоть в гугл диск, хоть в чат в телеграме, хоть в эхоконференцию в FIDO, лишь бы транслировалось в его понятия, которых у него совсем немного - получить объекты да установить ссылки. ссылки не версионируются (хаха!) поэтому внешнее хранилище должно это делать само, т.е должен быть некий алгоритм для ссылок (у нас в hbs2-git это выбор самой длинной цепочки из множества операций установки ссылки, что иногда приводит к лулзам)
Пользоваться корпоративными продуктами, аналоги которых есть в естественном виде в природе, стыдновато потому, что товаром там является не их сервис, а вы. Т.е они берут ваши деньги, а продают вас. Т.е это стыдно вообще с любой стороны, даже проститутки в менее унизительном положении находятся. Ну а если их EULA запостить в Chat GPT и попросить сделать выжимку, то единственным смыслом там останется ПНАХ. Да, от этого невозможно избавиться совсем, но не значит, что нельзя к этому стремиться. Это не бинарное состояние, это измеримый KPI. Количество позора можно снижать год за годом.
Как вы относитесь к экспериментам вроде взымания абонентской платы за подогрев сидений у BMW?
Anonymous Poll
0%
Абсолютно нормально, большой штат трудится, что бы ваши сиденья могли подогреваться каждый месяц
100%
Выступаю за возврат телесных наказаний и позорного столба в практику в этой связи
В suckless-conf (конфиги на sexp) добавились FromJSON/ToJSON , теперь можно сериализовывать/десериализовывать объекты в sexp-ы и работать с этим конфигом традиционным унылым хаскельным путём. Пользуясь случаем хочу в очередной раз заявить, что sexp-ы сила, json-могила. В json - убогая семантика встроенных когда-то в ecmascript структур данных, а в sexp - вся мощь любых dsl.
hbs2://JAuk1UJzZfbDGKVazSQU5yYQ3NGfk4gVeZzBCduf5TgQ
https://github.com/voidlizard/suckless-conf
hbs2://JAuk1UJzZfbDGKVazSQU5yYQ3NGfk4gVeZzBCduf5TgQ
https://github.com/voidlizard/suckless-conf
Forwarded from Dmitry Zuikov
Сегодня будет коммит в hbs2-git, который в общем-то не ломает совместимость, но меняет способ вычисления значения ссылок (бранчей), и после него те, кто на новой версии и на старой версии могут видеть разное значение бранча. На текущей "стабильной" версии некорректно работали push —force и удаление бранча. На новой будут, но только для новых пушей, т.е если у вас удалённый бранч не хотел удаляться - то надо будет его удалить еще раз.
Другими словами, надо будет обновиться на master, хотя master ветка, вроде как, не стабильная сейчас. Я думал, что следующим большим релизом будет шифрование резиториев / приватные репозитории, но вот нет. Но зато у нас есть каналы с множеством писателей и возможностью их удалять/добавлять (refchan), и демо онлайн BFT консенсуса поверх hbs2, который, вроде как, работает.
Другими словами, надо будет обновиться на master, хотя master ветка, вроде как, не стабильная сейчас. Я думал, что следующим большим релизом будет шифрование резиториев / приватные репозитории, но вот нет. Но зато у нас есть каналы с множеством писателей и возможностью их удалять/добавлять (refchan), и демо онлайн BFT консенсуса поверх hbs2, который, вроде как, работает.
Forwarded from Dmitry Zuikov
commit 0f0085d4b64930b470e3d8356cd492e8202b9d4e (HEAD -> master, hbs2/master, github/master)
Author: Dmitry Zuikov <dzuikov@gmail.com>
Date: Fri Sep 22 07:05:39 2023 +0300
fix: hbs2-git. proper refval calculation
...
WARNING: you **must** move to this commit right now
Как работает hbs2-git раньше и сейчас. hbs2-git пишет в "reflog". "Reflog" это некая мутабельная ссылка, в которую может писать только владелец приватного ключа, который и определяет рефлог, т.е приватный ключ это он и есть. В рефлог пишутся "транзакции", каждая может быть чем угодно, порядок не гарантируется, кроме лексикографического, это append-only growing set. Что внутри транзакций знают только писатели-читатели. Например, там могут быть объекты git. Но не по одному: hbs2-git для каждого push формирует лог в виде файла, куда пишет все новые объекты. Формат лога имеет определенную структуру и последовательность в надежде, что он будет хотя бы частично повторно использован. В любом случае, в каждый журнал операции push пишутся только те объекты, которых еще нет в стейте, где стейт - это объединение всех предыдущих журналов. Помимо самих объектов git, с которыми git знает что делать и порядок их (коммитов) - это DAG и управляетс самим git, есть еще "ссылки", они же бранчи, они же теги. Ссылка в git это текстовый файл, в котором лежит хэш коммита. Таким образом, ссылка указывает на голову цепочки. Это буквально неверсионируемый текстовый файл и нам надо обеспечить консенсус относительно него, т.е ввести порядок операций модификации, что не так-то просто. Как нам определить порядок операций? Можно ввести отдельный CRDT счётчик, хоть там есть нюансы. Ну а можно взять естественный. Раньше это была максимальная глубина DAG git для этого журнала, но поскольку в git как угодно можно (и часто нужно) редактировать историю —- это так себе ориентир. Но вот поскольку журнал транзакций рефлога только растёт, можно в момент git push вычислять этот самый счётчик, который суть число транзакций в журнале. У нас один писатель. Если некто на разных хостах запушит операции с одинаковым rank - то возможна неоднозначность. Однако же, поскольку у нас он является единственным владельцем канала, то таким образом он будет византийствовать только в отношении себя самого. Ну и пожалуйста, ССЗБ.
Мог бы Торвальдс сделать сразу гит нормальным? Т.е сейчас в распределенном окружении невозможно бесконфликтно реплицировать репозиторий, т.к "бранчи" не версионируются. Мог бы, если бы бранч был уникален для каждого "автора" (пары ключей), список авторов подписывался бы подписью "владельца", операции по модификации представляли бы собой журнал, порядок в котором определял бы сам владелец, даром что бранчи уникальны и у каждого один владелец, порядок модификации "бранчей" тоже был бы списком. Т.е бранч была бы первосортная сущность в гите, как коммиты, деревья и блобы. Короче может быть и мог бы, но вот этого всего тогда в обиходе не было и так было не принято, и заняло бы не четыре дня на прототип, а четыре месяца.