25 марта 2021 от Prizm Unification
(ред. от 20.01.22г.)
Привет народ ! ✋🏻😎
вчера утром обратил внимание на беседу в одном из чатов, где говорилось буквально следующее:
Таких как наша Prizm на рынке уйма и на нём ежедневно появляются новейшие технологии, лучше, быстрее и интереснее. И либо надо, как минимум не отставать, либо быть лучше !
Я решил поучаствовать в беседе. Разговор перешёл в русло скорости транзакций. Мне хотелось, чтобы кто-то в чате написал, что именно является первопричиной так называемой скорости транзакций и почему некоторые другие криптовалюты эту скорость показывают выше.
К великому сожалению ответил всего один человек, но очень обобщённо - одним словом. Он написал Децентрализация.
Не буду больше томить вас байками призмовских чатов, давайте лучше разберёмся какой, всё же, ценой достигается высокая скорость транзакций некоторых криптовалют и почему PRIZM не такой быстрый ?
Что мы собственно распространяем в блокчейн сети ?
Рассмотрим упрощённую механику появления транзакции в блоке.
На первом этапе на одном из узлов сети появляется какая-либо транзакция. Например Хайни отправляет Денису некоторое количество монет в обмен на доставку «горячего обеда». Это ещё не накладывает ни каких обязательств ни на одну из сторон сделки и не означает, что платёж хоть каким-то образом зафиксирован в сети. Это пока ещё можно назвать только анонсом транзакции.
Для того чтобы транзакция попала в блок о ней должен знать узел, который этот блок сгенерирует. Но поскольку блок будет генерировать узел, выбранный из всех узлов сети случайным образом, то нашу транзакцию мы должны распространить всем.
Итак, первым делом происходит распространение транзакции по прописанному в исходном коде протоколу.
Далее сетью выбирается «лидер». Это узел, который будет генерировать блок и вносить в него нашу транзакцию. После чего он начнёт рассылать свой блок на доступные ему узлы сети .
Теперь весь этот процесс рассмотрим чуть-чуть подробнее
Рассмотрим сразу классическую упрощённую процедуру распространения блока. Любой протокол взаимодействия узлов сети начинается с некоторых предварительных шагов.
В начале "узел 1" приглашает "узел 2" к обмену. Под "узлом 2" на самом деле надо понимать сразу несколько узлов сети доступных "узлу 1" (пиры), но для простоты мы рассмотрим единичный вариант.
Далее "узел 2" отвечает и запрашивает у "узла 1" получение блока.
Далее "узел 1" отправляет "узлу 2" свой блок.
Следующим действием "узел 2" начинает процедуру верификации этого блока.
Время которое нужно на верификацию линейно зависит от размера блока, потому что включает в себя проверку каждой транзакции.
Когда мы говорили о распространении транзакции для того, чтобы о ней узнали все узлы сети, эти узлы не просто бездумно её передавали друг другу, а производили ещё и валидацию. Валидация заключается в проверке корректности подписи. И эта валидация также занимает какое-то время.
В классическом варианте протокола узел не начинает обращение к следующему узлу (для передачи блока дальше) до окончания полной верификации. То есть, по сути, происходит некое дублирование ранее произведённых действий - проверки транзакций, которая в идеале должна была производиться при их распространении.
С точки зрения "узла 2" , который получил блок, резонно проверить транзакции по-новой, ведь есть вариант, что "узел 1" каким-то образом испортил все транзакции. По этому "узлу 2" нужно провалидировать их все заново.
Возникающие проблемы
Такой классический подход в распространении блока до самого последнего узла сети вызывает некую задержку. Основной фактор такой задержки вызван ни какими-то аспектами сетевого взаимодействия, ни какой-то архитектурой сети, хотя и это имеет место быть в каких-то отдельных случаях. Задержка по большей части вызвана затратами времени именно на верификацию, причём повторную.
Таким образом получается, что примерно 10% всех узлов сети получают блок в первые две секунды, но есть узлы, скорость распространения до которых этого же блока превышает минуту.
На самом деле скорость распространения транзакций выглядит не лучше, а может быть даже хуже. Время за которое некоторые транзакции доходят от одного «конца» сети до другого исчисляется в минутах. Такая медленная скорость распространения транзакций позволяет сделать что-то наподобие двойной траты, то есть возможность обмануть получателя перевода.
Применим эту манипуляцию в нашем примере:
В тот момент, когда Хайни делает перевод Денису, одновременно с этим Дмитрий, находящийся в другом месте делает перевод тех же самых монет, но другому получателю (или самому себе). То есть у нас возникает две конфликтующие транзакции, потому что они противоречат друг другу.
Хайни отправляет транзакцию в той части сети, в которой Денис бы её поскорее увидел и подумал, что транзакция уже останется в ней навсегда и отдал свой «горячий обед». С горячим обедом это конечно игровой вариант, но если говорить о какой-то онлайн торговле, в которой происходит поставка какого-то цифрового товара, то там эта скорость может существенно повлиять.
В эту же наносекунду Дмитрий отправляет вторую транзакцию в той части сети, где «густота» узлов гораздо выше, чтобы эта транзакция быстрее появилась в большей части узлов сети. И когда к ним дойдёт конфликтующая транзакция Хайни - они её отвергнут (не провалидируют). Под «густотой сети» условно рассмотрим не просто насыщенность самих узлов, а насыщенность с точки зрения вычислительных мощностей. Это значит, что вероятность того, что именно от сюда будет сгенерирован следующий блок гораздо выше.
Итогом будет то, что в этой «густотой» части появится блок, в котором будет фигурировать транзакция Дмитрия, и он начнёт также медленно распространяться до Хайни, как и его транзакция, попав и к Денису, который к тому времени уже передал «горячий обед» Хайни (ну мы понимаем аналогию с цифровым товаром конечно же)
По этому большое количество исследований, применяя различные оптимизационные механизмы были направлены на то, чтобы уменьшить именно задержку в распространении транзакций по всей сети.
Предлагаемые решения
Одним из решений является декомпозиция процесса верификации чтобы не дожидаясь когда она завершится до конца, начать отправлять блоки дальше по сети.
Процесс верификации разбивается на несколько вещей, первой из которых является проверка сложности (difficulty check), после которой происходит проверка транзакций. В какой-то момент времени возможна такая ситуация, когда сеть разделяется на две не связанные подсети, каждая из которых начинает жить своей жизнью, и в каждой из них будут генерироваться блоки разным (не обязательно) количеством мощностей. В одной поверх блока в котором находится транзакция Хайни. В другой - поверх блока с транзакцией Дмитрия.
Через какое-то время получится так, что базовая цель для генераторов блоков в одной из подсетей будет выше, чем в другой. И однажды блоки с разной накопленной кумулятивной сложностью «встретятся» на каком-то узле, который легко и быстро сможет определить в какой из цепочек блоков накоплено больше сложности. Накопленная сложность цепочки отражает вычислительные мощности задействованные в расчёте хешей блоков этой цепочки.
Таким образом этот узел сделав проверку сложности уже может начать приглашать следующий узел к обмену, а потом заняться проверкой транзакций, которые по-хорошему уже были когда-то кем-то проверены, по этому это не так критично.
Ещё одно из решений заключается в том, что "узел 2" получивший приглашение на обмен от "узла 1" вместе с отправкой запроса блока "узлу 1" сразу начинает рассылать своим пирам (доступным узлам) приглашение на обмен. После получения от них запроса на блок, "узел 2" ставит их в некую очередь и после того как сделана проверка сложности блока, который пришёл от "узла 1", сразу же отправляет блок дальше согласно очереди.
И третий подход к решению проблемы задержки - это сделать «топологию звезды».
Это такая серверная классическая архитектура взаимодействия узлов, когда есть некий центральный узел, через который происходит обмен. При этом уже не так важно сколько времени понадобится на полную валидацию блока перед его отправкой, сам факт того, что от одного узла до другого всего две передачи, позволяет существенно ускорить передачу блоков.
«новейшие технологии, лучше, быстрее и интереснее»
Несомненно и очевидно, что используя третий подход во взаимодействии между узлами, применяется механизм централизованной сети. И это конечно позволяет передавать данные быстрее классического подхода.
Для того чтобы ещё более существенно сократить время передачи, некоторые «новейшие технологии» начинают пренебрегать слишком многим, подгоняя искусственно различные параметры своей сети, создавая некую ранжированность узлов, наделяя только некоторые из них правом валидации блоков или только транзакций, некоторые правом только генерации блоков, а некоторые смешивая различные подходы в зависимости от обстоятельств.
Обстоятельствами является факт того, что пользователям необходимо делегировать монеты таким «избранным» узлам, потому что без набора некоего «веса» такие узлы не смогут обеспечивать возложенные на них обязанности. Такие узлы фактически становятся центральными агентами, от которых блокчейн вообще-то должен нас избавить.
Проблемы таких сетей будут намного очевиднее, если наделить все узлы такими же свойствами, как и у «избранных», сделав всех равными, то есть сделать сеть одноранговой.
После чего она в лучшем случае начнёт делиться на подсети быстрее, чем производить валидацию своих новых блоков, то есть не сможет должным образом синхронизироваться и в итоге достигнет полной рассинхронизации.
Именно для того, чтобы скрыть эти проблемы и заставить все работать быстро и гладко, эти «новейшие технологии» вынуждены пренебрегать самым ценным — а именно децентрализацией. Количество таких «избранных» узлов в некоторых сетях не превышает и двухста ! Потому что если их будет слишком много, то сеть уже не сможет показывать свои искусственно созданные возможности.
А ведь «избранные» отвечают за работу всей сети! Если кто-то условно негативно повлияет на более чем половину этих узлов (а в некоторых случаях достаточно чуть более 30%), считайте, что это повлияет на всю сеть. Здесь можно согласиться с тем, что многие люди находят что-то интересное в работе такого типа сетей и возможно они не плохи для отдельных проектов или компаний, но будут ли такие сети достаточно безопасными в масштабах всего мира ?
PRIZM не создает таких «избранных» валидаторов, поэтому скорость передачи информации для самых отдалённых узлов невысокая. Но справедливо заметить, что такую скорость для одноранговой сети сложно назвать невысокой, тем более, что наблюдать её под нагрузкой не так то просто, из-за детерминированного алгоритма, динамически подстраивающего базовую цель для генерации следующего блока, что позволяет считать транзакции необратимыми, в среднем, уже через 10 минут. И это происходит в одноранговой сети, без искусственных ухищрений с узлами.
Ну а если интересует только скорость, то можно прикупить акции Visa и MasterCard. Технология конечшно не первой свежести, но за то она лучше, потому что ей пользуется весь мир, она быстрее - в сервера компаний вложены киллограмы денег и она очень интересная, потому что ни когда с высокой точностью нельзя предсказать судьбу твоих денег.
P.s. Процесс взаимодействия узлов и валидации в PRIZM можно найти через исходники на prizm.space в классе ProcessBlock, а также в классе BlockchainProcessorImpl в переопределённом методе processPeerBlock.