Автор оригинала: НИК Лин

Первоисточник: средний

Да пребудет с тобой сила. В этой статье будет представлен механизм антицензуры транзакций Rollup — Force Inclusion, а также в качестве примеров будут использованы дизайн и практика нескольких известных Rollup.

Фото Артура Тумасяна на Unsplash

Необходимые знания:

  • Узнайте, как работает Rollup и почему Rollup необходимо загружать транзакции в L1.

Сопротивление цензуре транзакций

Способность транзакций быть устойчивыми к цензуре (устойчивыми к цензуре) очень важна для блокчейна. Если блокчейн может совершать транзакции для любого пользователя, подвергающегося цензуре, то этот блокчейн ничем не отличается от сервера Web2. Текущая устойчивость транзакций Ethereum к цензуре обусловлена ​​большим количеством валидаторов. Если Алиса захочет просмотреть транзакции Боба и предотвратить загрузку его транзакций в цепочку, тогда Алисе придется попытаться подкупить каждого валидатора в сети, иначе она это сделает. мусор. Вся электронная сеть продолжает рассылать спам-транзакции, превышающие транзакции Боба, чтобы заполнить блоки. В любом случае ее затраты будут очень высокими.

Примечание. В текущей архитектуре PBS Ethereum стоимость проверки действительно значительно снижена. Вы можете обратиться к проверке OFAC доли блоков в транзакциях Tornado Cash. В настоящее время сопротивление цензуре опирается на независимых проверяющих и ретрансляторов за пределами OFAC и государственной юрисдикции.

А как насчет роллапов? Rollup не требует большого количества валидаторов для обеспечения своей безопасности. Кроме того, Rollup имеет только централизованную роль (Sequencer, называемую секвенсором или секвенсором) для пакетной обработки блоков, и он так же безопасен, как L1. Но безопасность и устойчивость к цензуре — это две разные вещи. Создание накопительного пакета так же безопасно, как и у Ethereum, но у него есть только централизованный секвенсор. Тогда секвенсор может просматривать транзакции любого пользователя, если захочет.

Sequencer может отказаться принимать пользовательские транзакции, в результате чего пользователи не смогут использовать Rollup или выйти из него.

механизм принудительного включения

При этом Rollup должен иметь столько же валидаторов, сколько L1, чтобы обеспечить устойчивость к цензуре. Лучше напрямую использовать устойчивость к цензуре L1: секвенсор также сжимает данные транзакций в контракт Rollup L1. функция в контракте Rollup для мониторинга пользователей. Вы также можете вставлять транзакции в сортировку. Этот метод называется принудительным включением. Пока Sequencer не может просматривать «транзакции L1» отслеживаемых пользователей, он не может запретить пользователям принудительно вставлять транзакции Rollup через L1, а работа и безопасность Rollup основаны на антицензурных возможностях L1.

Секвенсор не может просматривать транзакции L1 пользователя, если не существует очень сложной стоимости.

Примечание. Принудительное включение возможно только в том случае, если разработан накопительный пакет. Пользователи определенно могут прорваться через уровень L1 и принудительно вставить транзакции сводного пакета. Если Rollup не предоставляет механизм принудительного включения, то пользователям остается только молиться, чтобы обзор Sequencer не торговался самостоятельно.

Транзакция вступает в силу немедленно, а не с отложенным эффектом

Если мы разрешим запись транзакций, вставленных через принудительное включение, непосредственно в историю транзакций накопительного пакета (вступает в силу немедленно), то статус накопительного пакета будет изменен немедленно. Например, Боб вставляет ручку через механизм принудительного включения: «Он перевел 1000 DAI». к транзакции «Кэрол», если транзакция вступит в силу немедленно, то баланс Боба в последнем состоянии будет на 1000 DAI меньше, а баланс Кэрол — на 1000 DAI больше (конечно, предполагается, что баланс Боба превышает 1000 DAI).

Если транзакция Боба может быть напрямую записана в историю транзакций и немедленно вступит в силу, то статус накопительного пакета немедленно изменится.

Если в это время Sequencer собирает транзакции вне цепочки и ждет, пока следующая транзакция не будет отправлена ​​в контракт Rollup, на нее может повлиять транзакция, которую Боб принудительно вставляет и немедленно вступает в силу. Например, Бобу нужно всего лишь заранее отправить в Sequencer платежную транзакцию «он» переводит 1000 DAI «Алисе». Sequencer эквивалентен проверке отсутствия проблем и обещанию получения дохода. И Алиса, и Боб могут запросить Sequencer, есть ли транзакция будет получена и вычислен результат последнего статуса (у Алисы на 1000 DAI больше, а у Боба на 1000 DAI меньше). Но когда Секвенсер обнаружил, что Боб поспешил принудительно вставить транзакцию, статус выполнения транзакций в его руках изменился. Он знал, что транзакция «Боб передал Алисе 1000 DAI» стала неудачной при выполнении, и Алиса не смогла. получите это до 1000 DAI.

Секвенсор получает транзакцию Боба, поэтому Алиса считает, что получит 1000 DAI.

В результате Боб напрямую заставил принять еще одну конфликтующую транзакцию на L1, в результате чего транзакция в руке Sequencer не была получена, и Алиса не смогла получить DAI.

Это может быть неприятно для пользователя, поэтому Rollup обычно заставляет транзакцию принудительного включения вступить в силу немедленно, но переводит транзакцию в состояние «подготовки». Sequencer может выбрать, добавлять ли транзакции, переходящие в состояние «подготовки», в конец пакета при отправке бюджетной транзакции. Если Sequencer никогда не хочет обрабатывать эти состояния «подготовки», то эти транзакции будут обработаны после a. период времени. Через определенное время его можно принудительно вставить в историю транзакций.

Боб хочет обмануть Алису, форсировав транзакцию дохода, но на самом деле транзакция будет поставлена ​​в очередь первой.

Секвенсор может сам решить, когда «включить» ожидающие транзакции в очередь, поэтому транзакция от Боба к Алисе DAI будет выполнена первой.

Если Sequencer не ждет транзакций в очереди, через определенный период времени пользователь (или кто-либо другой) может самостоятельно принудительно получить доход.

Секвенсор отказывается принимать транзакцию Боба, поэтому Боб ставит транзакцию в очередь от L1.

Секвенсор все еще может продолжать отклонять транзакции в очереди в течение некоторого времени.

Однако Sequencer не всегда может отклонять транзакции, ожидающие в очереди. Через некоторое время любой может вызвать принудительный доход. Далее мы представим реализацию механизма принудительного сдерживания более известных Rollup, таких как Optimism, Arbitrum, StarkNet и zkSync. .

Инклюзивный механизм оптимистической власти

Во-первых, давайте представим процесс внесения Оптимизма. Этот Депозит относится не только к внесению денег в Оптимизм, но и эквивалентен более общему «внесению сообщений для L2» в L2. После получения вновь депонированного сообщения узел L2 передает сообщение, преобразует его в транзакцию порта L2 для выполнения и передает сообщение назначенному получателю.

Сообщение от пользователя, переводящего деньги с L1 на L2

Контракт L1CrossDomainMessenger

Когда пользователь решает внести токены ETH или ERC-20 в Optimism, он взаимодействует (через сеть) с контрактом L1StandardBridge на L1, указывая, какую сумму внести и с какого адреса ее получить и т. д. Затем сообщение о соединении L1StandardBridge передается контракту L1CrossDomainMessenger следующего уровня. Этот контракт в основном используется в качестве общего контракта связи между L1 и L2. L1StandardBridge использует этот общий контракт связи для связи с L2StandardBridge на уровне L2, чтобы решить, кто может начать чеканку. токены из L2 или вывод токенов из L1. Если разработчику необходимо разработать контракт для взаимодействия и состояния синхронизации между L1 и L2, то он может построить его на L1CrossDomainMessenger.

Контракт обмена сообщениями пользователя CrossChainMessenger передается с уровня L1 на уровень L2.

ОптимизмПортальный контракт

Контракт L1CrossDomainMessenger затем отправит сообщение контракту OptimismPortal самого низкого уровня. После обработки контракта OptimismPortal он выдаст событие TransactionDeposited. Параметры события включают «человек, отправивший сообщение», «человек, получивший сообщение». ", и соответствующие параметры выполнения.

Затем узел Optimism уровня L2 будет прослушивать событие TransactionDeposited, выданное соглашением OptimismPortal, и преобразовывать параметры события в транзакцию, записывающую L2. Инициатором этой транзакции L2 может быть «отправитель сообщения» в событии TransactionDeposited. лицо, отправившее транзакцию. Получателем будет «лицо, получившее сообщение» в событии, а другие параметры выполнения также передаются параметрами события.

Узел L2 вставляет событие TransactionDeposited, созданное OptimismPortal, в аннотированные транзакции L2.

Например, это транзакция, в которой пользователь вносит 0,01 ETH через контракт L1StandardBridge. Это сообщение и ETH передаются до контракта OptimismPortal (адрес 0xbEb5...06Ed). После сорока оно преобразуется. в транзакцию L2, а инициатором сообщения является контракт L1CrossDomainMessenger. Получателем является контракт L2CrossDomainMessenger на L2, и он получает 0,01 ETH;

принудительное включение

Когда пользователь хочет заставить свою транзакцию выполняться оптимистично, ему не нужно отправлять сообщение с L1 на L2, поэтому он не будет использовать контракт L1CrossDomainMessenger. Эффект, которого он хочет достичь, состоит в том, чтобы сделать конкретный счет «транзакцией, которую он отправляет и выполняет на L2 со своего адреса L2», чтобы она выполнялась плавно, поэтому он будет напрямую взаимодействовать с контрактом OptimismPortal и позволить своему адресу L2 вызывать контракт OptimismPortal, поэтому что когда событие TransactionDeposited преобразуется в транзакцию L2, «инициатором транзакции» будет его адрес L2», чтобы транзакцию можно было увидеть снова.

В транзакции L2, преобразованной из события TransactionDeposited, инициатором будет сам Боб; получателем является контракт Uniswap, и он будет сопровождаться указанным ETH, точно так же, как сам Боб инициировал транзакцию L2;

Используйте адрес L2 для вызова функции депозита Transaction, подписанной OptimismPortal, и не забудьте заполнить параметры транзакции L2 один за другим.

Я совершил простую транзакцию принудительного включения: перевел деньги себе на свой адрес L2 (0xeDc1...6909) и прикрепил текстовое сообщение «принудительное включение». Это транзакция L1, в которой я выполняю функцию депозита Transaction через контракт OptimismPortal. Вы можете видеть, что в событии TransactionDeposited, от которого и до, указаны я сам и значение в оставшемся поле opaqueData (000000000000000000000000000000000000000000000000000000000). 0000000000000000000000000000000000000000000000000000015BE000000000000C35000666F72636520696E636C7573696F6E) Сколько закодировано ? «Сколько ETH приносит человек», «Инициатор транзакции L2 должен доставить ETH получателю L2», «Лимит газа транзакции L2» и «Данные получателю L2» и другая информация.

Событие TransactionDeposited, созданное транзакцией L1

После интерпретации числовых значений нескольких фрагментов информации в этом opaqueData вы получите:

  • «Сколько ETH привязано к человеку, который позвонил на DepositTransaction»: 0, потому что я не хочу пополнять ETH с L1 на L2

  • «Сколько ETH инициатору транзакции L2 нужно отправить получателю L2»: 5566 (wei), потому что я хочу перевести деньги себе

  • «Лимит газа для транзакции L2»: 50 000

  • «Данные для приемника L2»: 0x666f72636520696e636c7573696f6e, убрать «принудительное включение» шестнадцатеричной кодировки этой строки

Вскоре появилась конвертированная транзакция L2: запишите транзакцию L2, я перевел деньги себе, сумма 5566, а данные — строка «обязательное включение». И вы можете заметить, что Txn Type (тип транзакции) в Other Attributes в предпоследней строке на рисунке — это системная транзакция 126 (System), что означает, что транзакция не была инициирована мной в L2, а была преобразована из событие L1TransactionDeposited.

Конвертированная транзакция L2 завершена

Если пользователь хочет вызвать другие контракты с другими данными, то же самое делается путем заполнения параметров в письмо депозита по одному. Только не забудьте использовать адрес L2 для выполнения на L1, чтобы инициатор транзакции L2. будет адрес L2.

окно секвенсора

Упомянутый ранее узел Optimism L2 преобразует событие TransactionDeposited в транзакцию L2. Фактически, этот узел Optimism относится к узлу Sequencer. В конце концов, речь идет об упорядочивании транзакций, поэтому только Sequencer может решить, когда преобразовать его в транзакцию L2. . При прослушивании события TransactionDeposited секвенсор не обязательно немедленно преобразует событие в транзакцию L2, но может принять решение преобразовать его в течение определенного периода времени. Этот период времени называется окном секвенсора в Optimism. В настоящее время в основной сети 24 часа. Затем, когда пользователь начнет вносить деньги из L1, получит напоминание или принудительно включит транзакцию пополнения, в худшем случае он будет официально включен в историю транзакций L2 через 24 часа. но, по крайней мере, это лучше, чем транзакция, которой невозможно помочь. Результат включения.

Механизм принудительного включения Arbitrum

В оптимистичном случае операция депозита L1 выдаст событие TransactionDeposited, а остальное — дождаться, пока Sequencer получит операцию депозита, но любая операция L1 (внесение денег или отправка сообщений в L2 и т. д.) будет сохранена; в очереди, согласованной L1, вместо того, чтобы просто отправлять события. Секвенсору будет предоставлен период времени для добавления операций L1 из этой очереди в историю транзакций. Если секвенсор израсходован по истечении времени, его можно будет завершить без необходимости замены секвенсора.

Арбитраж будет поддерживать очередь в контракте L1. Если Sequencer не принимает активно транзакции в очереди, по истечении времени любой может принудительно внести транзакции в очереди в историю транзакций.

Все операции L1 являются контрактами Delayed Inbox. Как следует из названия, операции здесь будут отложены и срок действия другого контракта — Sequencer Inbox, который представляет собой интерфейс для загрузки транзакций L2 в Sequencer. Транзакции, загруженные Sequencer, будут напрямую записаны в историю транзакций. Кроме того, при загрузке Sequencer вы можете выбрать, сколько операций L1 взять из папки «Отложенные входящие», и записать их вместе в историю транзакций, чтобы эти операции L1 могли выполняться. эффект.

SequencerInbox содержит историю транзакций. Обычно только Sequencer может напрямую записывать новые транзакции; DelayedInbox содержит транзакции, ожидающие получения.

Когда Sequencer записывает новую транзакцию, он может инициировать транзакцию из DelayedInbox и записать ее вместе.

Сложные конструкции и впечатляющая документация

Если читатели напрямую обратятся к официальной главе Arbitrum, посвященной Sequencer и Force Inclusion, они увидят, насколько упомянутое там Force Inclusion совместимо, а также имена некоторых параметров и названий функций: пользователь сначала заходит в папку «Входящие», чтобы договориться о встрече для вызова функции sendUnsignedTransaction. Если Sequencer не присутствует в Доходе встречи в течение 24 часов, пользователь может вызвать функцию ForceInclusion, подписанную Sequencer Inbox. Таким образом, даже ссылка не включается, и о соответствующей функции в коде программы можно только договориться самостоятельно.

Когда вы найдете функцию sendUnsignedTransaction, вы обнаружите, что вам действительно нужно самостоятельно заполнить значение nonce и значение maxFeePerGas. Какой адрес является nonce? В какой сети указано значение maxFeePerGas? Как лучше всего его заполнить? Никакой документации, даже от Natpsec, нет. Затем вы также найдете функцию, которая накапливает скины: sendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction. Также нет документа, объясняющего разницу между этими функциями, как их использовать и как заполнять параметры, даже нет Natpsec.

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

Отправить сообщение L2

Позже я случайно нажал на ссылку на странице поиска Google и обнаружил, что у Arbitrum изначально была обучающая библиотека. В ней был скрипт, демонстрирующий, как отправлять транзакции L2 из L1 (или что такое Force Inclusion), и ее функция была полностью отключена. отличается от упомянутого выше. Любой из них — это просто функция sendL2Message, а параметр сообщения на самом деле является подписанной транзакцией Arbitrum L2? ? ? Кто бы мог знать, что «отправка сообщений L2» на самом деле будет означать «подписанную транзакцию L2»? ? И опять же, нет документации или Natspec, объясняющих, когда и как использовать эту функцию.

Вывод: генерировать транзакцию принудительного дохода Arbitrum вручную затруднительно. Рекомендуется следовать официальному руководству и запустить Arbitrum SDK. В отличие от других накопительных пакетов, Arbitrum имеет четкую документацию для разработчиков и примечания к коду проекта. Назначение и параметры многих функций не имеют объяснений, из-за чего разработчики тратят больше времени, чем ожидалось, на доступ к ним и их использование. Я также спрашивал людей в Arbitrum об Arbitrum Discord, но не получил удовлетворительного ответа.

Примечание. Когда я спросил в Discord, собеседник просто попросил меня прослушать sendL2Message. Не было необходимости объяснять, для чего используются другие функции (даже sendUnsignedTransaction, упомянутые в обязательном файле включения), как их использовать и когда. используй их.

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

Невозможно доказать несостоятельность транзакции

Причина в том, что система доказательства с нулевым разглашением StarkNet не может доказать транзакции, которые не были зафиксированы, поэтому принудительное кредитование не может быть разрешено. Потому что, если кто-то злонамеренно (или непреднамеренно) принудительно введет транзакцию, которая не удалась и не может быть доказана, StarkNet напрямую застрянет: потому что после принудительного ввода транзакции Прувер должен доказать неудавшуюся транзакцию, но у него нет возможности это доказать. .

StarkNet рассчитывает ввести функцию подтверждения неудачных транзакций в версии v0.15.0, после чего появится возможность дальнейшей реализации механизма обязательного включения.

механизм обязательного включения zkSync

Механизм передачи сообщений L1->L2 и принудительного включения zkSync выполняются с помощью функции requestL2Transaction контракта MailBox. Пользователь указывает вызываемый адрес L2, данные вызова, количество передаваемых ETH, значение L2 Gas Limit и т. д. и разделяет параметры requestL2Transaction. Объединенные в транзакцию L2 и затем моделируемые в приоритетной очереди, Sequencer указывает, сколько транзакций следует извлечь из приоритетной очереди и получить вместе, когда резервная копия транзакции загружается в L1 (функция commitBatches). .

zkSync очень похож на Optimistic с точки зрения интерфейса принудительного включения. Оба используют адрес L2 пользователя для вызова и заполнения соответствующих данных (вызываемого абонента, данные вызова и т. д.), вместо заполнения подписанной транзакции L2, как Arbitrum; с точки зрения дизайна транзакции аналогичны Arbitrum в поддержании очереди сущностей в L1, а Sequencer берет транзакции из очереди и записывает их в историю транзакций.

Пользователь вставляет транзакции L2 в приоритетную очередь через requestL2Transaction, а Sequencer может взаимодействовать с транзакцией из приоритетной очереди при фиксации пакетов.

Если вы пополняете ETH через официальный мост zkSync, который на данный момент эквивалентен транзакции, он вызывает функцию requestL2Transaction контракта MailBox. Он сохранит пополненный ETH в очереди приоритетов транзакций L2 и выдаст событие NewPriorityRequest. Поскольку контракт кодирует данные транзакции L2 в строку байтов, их нелегко прочитать. Если вместо этого вы посмотрите на параметры транзакции L1, вы увидите, что получатель L2 в параметрах также является инициатором транзакции. транзакция потому что (это депозит себе), поэтому через некоторое время, когда транзакция обмена L2 будет вынесена секвенсором из приоритетной очереди и включена в историю транзакций, она будет конвертирована на L2 в транзакцию, записывающую передачу себе, а сумма перевода — это сумма инициатора транзакции в L1. Сумма ETH, внесенная на депозитную биржу ETH.

В транзакции пополнения счета L1 инициатор и получатель транзакции имеют номера 0xeDc1…6909, сумма составляет 0,03 ETH, а данные вызова пусты.

Учет 0xeDc1…6909 появится на L2, транзакции, которую вы передаете себе. Тип транзакции (Txn Type) — 255, это системная транзакция.

Далее я вызывал письмо requestL2Transaction прямо по скрипту и отправлял транзакцию, записавшую звонок, себе: без всяких ETH, данные звонка включали в себя шестнадцатеричную кодировку строки «принудительного включения». Последующая формула преобразуется в транзакцию на уровне L2, которая записывает собственный вызов. Данные вызова содержат строку «принудительного включения»: 0x666f72636520696e636c7573696f6e.

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

С помощью функции requestL2Transaction пользователи могут запросить транзакцию L2 на L1 с адресом L2, указав получателя L2, количество принесенных ETH и данные вызова. Если пользователь хочет вызвать другие контракты с другими данными, ему также необходимо заполнить параметры один за другим в функции requestL2Transaction. Просто не забудьте использовать адрес L2 для выполнения на L1, чтобы инициатором транзакции L2 был L2. адрес. .

Нет функции, позволяющей пользователям принудительно получать доход.

Хотя размещение транзакций L2 в приоритетной очереди автоматически рассчитывает период сбора транзакций L2 Sequencer, текущая конструкция zkSync не включает обязательные связанные функции, которые пользователи могут выполнять самостоятельно, что эквивалентно половине набора. Таким образом, хотя существует «период действия дохода», на самом деле он все еще зависит от того, хочет ли Sequencer получать доход: Sequencer может дождаться перехода, чтобы получить доход, или он никогда не сможет получать какие-либо транзакции в приоритетной очереди. В будущем в zkSync должны быть добавлены соответствующие функции, чтобы пользователи могли принудительно получать доход, когда доход прошел, но еще не был получен Sequencer. Это действительно эффективный механизм принудительного включения.

Подведем итог

  • L1 полагается на большую группу людей для обеспечения «безопасности» и «сопротивления цензуре» Интернета, в то время как Rollup полагается на «сопротивление цензуре L1», чтобы получить «такую ​​же безопасность, как L1», но не включает устойчивость Rollup к цензуре. способность

  • Напротив, поскольку Rollup использует небольшое количество или даже один Sequencer для записи транзакций, его возможности по борьбе с цензурой еще слабее. Поэтому для Rollup необходим механизм принудительного включения, который позволит пользователям обходить Sequencer и записывать транзакции в историю, чтобы избежать проверки Sequencer и невозможности использовать Rollup или выйти из него.

  • Принудительное включение позволяет пользователям принудительно записывать транзакции в историю, но при проектировании им необходимо сделать выбор, может ли транзакция быть немедленно вставлена ​​в историю и немедленно вступить в силу. Если транзакциям разрешено вступить в силу немедленно, это вызовет проблемы для секвенсора и затруднения в работе пользователя, поскольку на транзакции, ожидающие получения на L2, могут повлиять транзакции, принудительно полученные L1.

  • Таким образом, текущий механизм принудительного включения Rollup сначала переводит транзакции, вставленные в L1, в состояние ожидания и дает секвенсору период времени для реакции и выбора, включать ли эти ожидающие транзакции.

  • И zkSync, и Arbitrum поддерживают очередь сущностей на уровне L1 для управления транзакциями уровня 2, отправляемыми пользователями из уровня 1, или сообщениями в уровень 2. Arbitrum называет это отложенным входным ящиком, zkSync называет это приоритетной очередью;

  • Однако способ, которым zkSync отправляет транзакции L2, аналогичен Optimism. Они отправляются на L1 с использованием адреса L2, поэтому инициатором транзакции L2 будет адрес L2. Функция Optimism для отправки транзакций L2 называется DepositTransaction, zkSync называется requestL2Transaction; Arbitrum создает завершенную транзакцию L2 и подписывает ее, а затем отправляет ее через письмо sendL2Message. Arbitrum восстановит подписывающего лица через подпись на L2 как инициатора транзакции L2.

  • В StarkNet на данный момент нет механизма принудительного включения, в zkSync реализована половина набора обязательных включений — есть приоритетная очередь и транзакции L2 в каждой очереди имеют срок действия дохода, но этот срок действия на данный момент предназначен только для украшения. , секвенсор может выбрать вообще больше не получать транзакции L2 в приоритетной очереди.