Título original: "Introdução ao Mecanismo de Inclusão de Força do Rollup"

Autor: NIC Lin, chefe do Taipei Ethereum Meetup

 

Ainda ontem, aconteceu algo que chocou inúmeras pessoas: Linea, a segunda camada do Ethereum lançada pela Consensys, controladora da Metamask, foi encerrada proativamente. As autoridades disseram que o objetivo disso era reduzir o impacto do incidente de hacking da Velocore. E isso não pode deixar de lembrar as pessoas do encerramento anterior da Cadeia BSC (Cadeia BNB) sob coordenação oficial, a fim de reduzir as perdas com ataques de hackers. Sempre que as pessoas falarem sobre esse tipo de coisa, vão duvidar do valor descentralizado defendido pela Web3.

É claro que a principal razão para os incidentes acima mencionados reside mais na imperfeição da própria infra-estrutura, ou seja, na descentralização insuficiente: se uma cadeia for suficientemente descentralizada, então não deve parar num piscar de olhos. Devido à estrutura única da segunda camada do Ethereum, a maior parte da Camada 2 depende do sequenciador centralizado. Embora tenha havido cada vez mais argumentos para sequenciadores descentralizados nos últimos anos, considerando o propósito da segunda camada e sua estrutura, provavelmente. pode-se considerar que o classificador da Camada 2 provavelmente não será muito descentralizado e, no final, poderá não ser tão descentralizado quanto a cadeia BSC. Se este for realmente o caso, o que devemos fazer?

Na verdade, para a segunda camada, o dano mais direto causado pela não descentralização do classificador reside na sua resistência e atividade à censura. Se houver muito poucas entidades (Sequenciadores) que processam transações, então ela tem poder absoluto sobre se deve atendê-lo: pode rejeitá-lo se quiser, e você pode não ser capaz de fazer nada a respeito. Como resolver o problema anticensura da Camada 2 é obviamente um tópico importante.

Nos últimos anos, as principais segundas camadas do Ethereum propuseram várias soluções para questões anticensura, como Loopring e Degate, funções de retirada forçada e escotilha de escape da StarkEx, e Arbitrum e outras funções de inclusão de força do OP Rollup, esses métodos podem criar. verificações e equilíbrios no Sequenciador sob certas condições para evitar que ele rejeite qualquer solicitação de transação do usuário sem motivo.

No artigo de hoje, NIC Lin da Taipei Ethereum Association dá seu próprio relato, experimentou pessoalmente as funções de transação resistentes à censura de quatro Rollups convencionais e analisou profundamente o design do mecanismo de Inclusão de Força a partir de aspectos como fluxo de trabalho e métodos de operação, que é muito importante para Ethereum. É especialmente valioso para a comunidade e grandes investidores com enormes ativos.

Revisão de transação e inclusão forçada

A resistência à censura de transações (Resistência à censura) é muito importante para um blockchain. Se o blockchain puder revisar e rejeitar arbitrariamente as transações iniciadas pelos usuários, não será diferente de um servidor Web2. A atual resistência das transações do Ethereum à censura vem de seu grande número de validadores. Se alguém quiser revisar as transações de Bob e impedir que suas transações sejam carregadas na cadeia, ele deve tentar subornar a maioria dos validadores da rede ou enviar spam para toda a rede. rede. Envie continuamente transações inúteis com taxas de manuseio mais altas do que Bob para ocupar espaço em bloco. De qualquer forma, o custo será muito alto.

Nota: Na atual estrutura PBS do Ethereum, o custo de revisão das transações será bastante reduzido. Você pode consultar a proporção de blocos que cooperam com o OFAC para revisar as transações do Tornado Cash. A atual resistência à censura depende de verificadores e retransmissores independentes fora do OFAC e da jurisdição governamental.

Mas e o Rollup? O Rollup não requer um grande número de validadores para garantir a segurança. Mesmo que o Rollup tenha apenas uma função centralizada (Sequenciador) para gerar blocos, é tão seguro quanto L1. Mas segurança e resistência à censura são duas coisas diferentes. Mesmo que um Rollup seja tão seguro quanto o Ethereum, com apenas um sequenciador centralizado, as transações de qualquer usuário podem ser censuradas.

O sequenciador pode se recusar a processar a transação do usuário, fazendo com que os fundos do usuário sejam retidos e impossibilitados de sair do Rollup.

Mecanismo de forçar inclusão

Em vez de exigir que o Rollup tenha um grande número de sequenciadores descentralizados, é melhor utilizar diretamente os recursos anticensura do L1:

Originalmente, o Sequencer deveria empacotar os dados da transação e enviá-los para o contrato Rollup L1. É melhor adicionar um design ao contrato para que os próprios usuários possam inserir transações no contrato Rollup. Enquanto o Sequencer não puder censurar usuários no nível L1, ele não poderá impedir que os usuários insiram transações à força em L1. Desta forma, Rollup pode herdar a resistência à censura de L1.

O sequenciador não pode revisar as transações L1 do usuário sem pagar um custo alto

Como as transações forçadas devem ocorrer?

Se as transações puderem ser gravadas diretamente no contrato de Rollup por meio da Inclusão Forçada (ou seja, com efeito imediato), o status do Rollup mudará imediatamente. Por exemplo, Bob insere uma transação de "transferir 1000 DAI para Carol" por meio da Inclusão Forçada. mecanismo Se a transação entrar em vigor imediatamente, o saldo de Bob no estado mais recente será 1.000 DAI a menos e o saldo de Carol será 1.000 DAI a mais.

Se a Inclusão Forçada puder gravar a transação diretamente no contrato Rollup e entrar em vigor imediatamente, o status mudará imediatamente.

Se o sequenciador também estiver coletando transações fora da cadeia neste momento e enviar o próximo lote de transações para o contrato Rollup, ele poderá ser afetado pelas transações que Bob insere à força e entrarão em vigor imediatamente. Esse tipo de problema deve ser evitado tanto quanto possível, portanto, o Rollup geralmente não faz com que a transação Forçar Inclusão entre em vigor imediatamente. Em vez disso, primeiro permite que o usuário insira a transação na fila de espera em L1 e entre no estado de "preparação". .

Quando o Sequencer empacota as transações fora da cadeia e as envia para o contrato Rollup, ele escolhe se deseja inserir as transações mencionadas na sequência de transações. Se o Sequencer estiver ignorando essas transações no estado de "preparação", após o término do período de janela, o usuário. pode forçar a inserção dessas transações no contrato Rollup.

O sequenciador pode decidir quando "receber acidentalmente" transações aguardando na fila

O Sequenciador ainda pode recusar processar transações na fila de espera.

Se o Sequenciador recusar por um longo período, após um período qualquer pessoa poderá forçar a transação no contrato Rollup por meio da função Forçar Inclusão.

A seguir, apresentaremos em ordem a implementação do mecanismo de Inclusão de Força de quatro Rollup bem conhecidos, incluindo Optimism, Arbitrum, StarkNet e zkSync.

Mecanismo de Inclusão de Força do Otimismo

Primeiro, apresentaremos o processo de Depósito do Otimismo. Este depósito não se refere apenas ao depósito de dinheiro no Otimismo, mas também inclui o “envio de informações enviadas pelos usuários para L2”. Após receber a mensagem recém-depositada, o nó L2 converterá a mensagem em uma transação L2 para execução e a enviará ao destinatário designado da mensagem.

Mensagem do usuário do depósito L1 para L2

Contrato L1CrossDomainMessenger

Quando um usuário deseja depositar tokens ETH ou ERC-20 no Optimism, ele irá interagir com o contrato L1StandardBridge em L1 através da página front-end, especificando quanto depositar e qual endereço L2 para receber esses ativos.

O contrato L1StandardBridge passará a mensagem para o contrato L1CrossDomainMessenger de próximo nível. Este contrato é usado principalmente como um componente para comunicação mútua entre L1 e L2 e se comunica com o L2StandardBridge em L2 por meio deste componente de comunicação geral para decidir quem pode lançar o token. em moedas L2, ou quem pode desbloquear tokens de L1.

Se um desenvolvedor precisar desenvolver um contrato que comunique e sincronize o status entre L1 e L2, ele poderá construí-lo no contrato L1CrossDomainMessenger.

A mensagem do usuário é passada de L1 para L2 através do contrato CrossDomainMessenger

Nota: Em algumas imagens deste artigo, CrossDomainMessager é escrito como CrossChainMessager

Contrato do Portal Otimismo

O contrato L1CrossDomainMessenger enviará a mensagem para o contrato OptimismPortal de nível inferior. Depois que o contrato OptimismPortal for processado, ele lançará um evento chamado TransactionDeposited. Os parâmetros incluem "a pessoa que enviou a mensagem", "a pessoa que recebeu a mensagem. ", e parâmetros de execução relacionados. .

Em seguida, o nó L2 Optimism ouvirá o evento Transaction Deposited lançado pelo contrato OptimismPortal e converterá os parâmetros do evento em uma transação L2. O iniciador desta transação será o "remetente da mensagem" especificado no parâmetro do evento Transaction Deposited. o receptor da transação é a "pessoa que recebe a mensagem" nos parâmetros do evento, e outros parâmetros da transação também são derivados dos parâmetros nos eventos acima.

O nó L2 converterá o parâmetro de evento Transaction Deposited do OptimismPortalemit em uma transação L2

Por exemplo, esta é uma transação em que um usuário deposita 0,01ETH através do contrato L1StandardBridge. Esta mensagem e o ETH são transmitidos até o contrato OptimismPortal (o endereço é 0xbEb5...06Ed) e depois convertidos em L2. transação alguns minutos depois:

O iniciador da mensagem é o contrato L1CrossDomainMessenger; o receptor é o contrato L2CrossDomainMessenger em L2; o conteúdo da mensagem é que L1StandardBridge recebeu o depósito de 0,01ETH do BoB. Após isso, alguns processos serão acionados, como a emissão de 0,01 ETH adicional para L2StandardBridge, que será então transferido para Bob.

Como acioná-lo especificamente

Quando você deseja forçar uma transação no contrato Rollup do Optimism, o efeito que deseja alcançar é permitir que uma "transação iniciada e executada em L2 a partir de seu endereço L2" seja executada sem problemas. envia a mensagem diretamente para o contrato OptimismPortal (observe que o contrato OptimismPortal está na verdade em L1, mas o formato de endereço do OP é o mesmo que o formato de endereço L1. Você pode chamar diretamente o contrato acima usando a conta L1 com o mesmo endereço que o conta L2).

O "iniciador" da transação L2 convertida pelo evento Transaction Deposited lançado pelo contrato será sua conta L2. Neste momento, o formato da transação é consistente com a transação L2 normal.

Na transação L2 convertida do evento Transaction Deposited, o iniciador será o próprio Bob; o destinatário será o contrato Uniswap e será acompanhado pelo ETH especificado, assim como o próprio Bob iniciou a transação L2;

Se você deseja chamar a função Forçar Inclusão do Optimism, você precisa chamar diretamente a função depositTransaction do contrato OptimismPortal e preencher os parâmetros da transação que deseja executar em L2.

Eu fiz um experimento simples de Forçar Inclusão. Esta transação queria realizar uma coisa: usar meu endereço para autotransferência em L2 (0xeDc1...6909) e anexei uma mensagem de texto de "forçar inclusão".

Esta é a transação L1 onde executei a função depositTransaction através do contrato OptimismPortal. Você pode ver que no evento Transaction Deposited ela lança, tanto de quanto para mim.

Os valores na coluna de dados opaca restante codificam "quanto ETH vem com a pessoa que chama a função de transação de depósito", "quanto ETH o iniciador da transação L2 deseja enviar ao destinatário", "transação L2 GasLimit" e " aos dados do receptor L2" e outras informações.

Após decodificar as informações acima, você obterá:

“Quanto ETH foi anexado pela pessoa que convocou a transação de depósito”: 0, porque não depositei ETH de L1 a L2;

"Quanto ETH o iniciador da transação L2 deseja enviar ao destinatário": 5566 (wei)

"GasLimit para transações L2": 50.000

"Dados para receptor L2": 0x666f72636520696e636c7573696f6e, que é a codificação hexadecimal da string "forçar inclusão"

Pouco tempo depois, apareceu a transação L2 convertida: uma transação L2 na qual transferi dinheiro para mim mesmo, o valor era 5.566 wei e os dados eram a string "forçar inclusão". E você pode notar que o TxnType (tipo de transação) em Outros Atributos na penúltima linha da imagem mostra a transação do sistema 126 (Sistema), o que significa que esta transação não foi iniciada por mim em L2, mas foi depositada pela transação L1 Os eventos são transformados.

Transação L2 convertida

Se você deseja chamar o contrato L2 e enviar dados diferentes através da Força de Inclusão, nada mais é do que preencher os parâmetros um por um na função de transação de depósito anterior. Lembre-se de usar o mesmo endereço L1 da sua conta L2 para chamar o. função de transação de depósito, para que quando o evento depositado for convertido em uma transação L2, o iniciador seja sua conta L2.

SequenciadorJanela

O nó Optimism L2 mencionado anteriormente converte o evento Transaction Deposited em uma transação L2. Na verdade, este nó Optimism refere-se ao Sequenciador. Afinal, isso está relacionado ao sequenciamento da transação, portanto apenas o Sequenciador pode decidir quando converter o evento mencionado em. uma transação L2.

Ao ouvir o evento TransactionDeposited, o Sequencer não necessariamente converte o evento em uma transação L2 imediatamente. Pode haver um atraso. O valor máximo deste período é chamado de SequencerWindow.

A janela atual do sequenciador na rede principal do Optimism é de 24 horas, ou seja, quando um usuário deposita uma quantia em dinheiro de L1 ou Force Inclui uma transação, o pior cenário é que ela seja incluída no histórico de transações L2 após 24 horas.

Mecanismo de Inclusão de Força da Arbitrum

No Otimismo, a operação de Depósito de L1 lançará um evento Transação Depositada, e o resto é esperar que o Sequenciador colete as operações acima, mas no Arbitrum, as operações que ocorrem em L1 (economizando dinheiro ou enviando mensagens para L2, etc; .) será armazenado em L1 em ​​uma fila, em vez de simplesmente lançar um evento.

O Sequenciador receberá um período de tempo para incluir as transações da fila acima no histórico de transações L2. Se o Sequenciador não fizer nada quando o tempo acabar, qualquer um poderá concluí-lo para o Sequenciador.

A Arbitrum manterá uma Fila no contrato L1. Se o Sequenciador não processar ativamente as transações na Fila, quando o tempo acabar, qualquer pessoa poderá forçar as transações na Fila a serem incluídas no histórico de transações L2.

No desenho do Arbitrum, operações como depósitos que ocorrem no L1 devem passar pelo contrato Delayed Inbox, como o nome indica, as operações aqui serão atrasadas para entrarem em vigor; O sequenciador carrega transações L2 para L1. Cada vez que o sequenciador carrega uma transação L2, ele pode retirar algumas transações pendentes da caixa de entrada atrasada e gravá-las no histórico de transações.

Quando o Sequencer grava uma nova transação, ele pode retirar a transação do DelayedInbox e escrevê-la junto.

Projetos complexos e extensos materiais de referência

Se os leitores consultarem diretamente o capítulo oficial do Arbitrum sobre Sequenciador e Inclusão de Força, eles verão que ele menciona como funciona aproximadamente a Inclusão de Força, bem como alguns nomes de parâmetros e nomes de funções:

O usuário primeiro acessa o contrato DelayedInbox para chamar a função sendUnsignedTransaction. Se o Sequencer não for incluído em cerca de 24 horas, o usuário poderá chamar a função forceInclusion do contrato SequencerInbox. Então, o oficial da Arbitrum não anexou o link da função ao documento do site oficial, então você só pode ver a função correspondente no código do contrato.

Ao encontrar a função sendUnsignedTransaction, você descobrirá que precisa preencher você mesmo o valor nonce e o valor maxFeePerGas. Qual endereço é o nonce? Em qual rede está maxFeePerGas? Qual a melhor forma de preencher? Não há referência de arquivo, nem mesmo Natpsec. Então você também encontrará várias funções semelhantes no contrato Arbitrum:

SendL1FundedUnsignedTransaction, sendUnsignedTransactionToFork, sendContractTransaction, sendL1FundedContractTransaction, não existe nenhum documento informando a diferença entre essas funções, como usá-las, como preencher os parâmetros, nem mesmo Natpsec.

Você tenta preencher os parâmetros e enviar a transação com a mentalidade de tentar. Você deseja usar tentativa e erro para ver se consegue encontrar o uso correto, mas descobre que todas essas funções farão AddressAliasing em seu L1. endereço, resultando no erro final em L2 O remetente ao iniciar a transação é simplesmente um endereço diferente, então seu endereço L2 permanece imóvel.

enviarL2Message

Mais tarde, acidentalmente cliquei na pesquisa do Google e descobri que o Arbitrum tem uma biblioteca de tutoriais, que contém scripts que demonstram como enviar transações L2 de L1 (que é o que significa Forçar Inclusão), e as funções listadas nela não são nenhuma das funções mencionadas acima, mas uma função chamada sendL2Message, e o parâmetro message é na verdade uma transação assinada com a conta L2?

Quem saberia que a “mensagem enviada para L2 através da Força de Inclusão” seria na verdade uma “transação L2 assinada”? E não há documentação ou Natspec explicando quando e como usar esta função.

Conclusão: É problemático gerar manualmente uma transação forçada do Arbitrum. Recomenda-se seguir o Tutorial oficial e executar o SDK do Arbitrum. Ao contrário de outros Rollups, o Arbitrum possui documentação clara para desenvolvedores e notas de código. A finalidade e os parâmetros de muitas funções carecem de explicação, fazendo com que os desenvolvedores gastem mais tempo do que o esperado para acessá-los e usá-los. Também perguntei ao pessoal da Arbitrum sobre o Arbitrum Discord, mas não obtive uma resposta satisfatória.

Quando perguntei sobre isso no Discord, a outra parte apenas me disse para olhar sendL2Message. Eles não queriam explicar as funções de outras funções (mesmo sendUnsignedTransaction mencionada no documento Forçar Inclusão), para que são usadas, como fazer. usá-los e quando usá-los.

Mecanismo ForceInclusion da StarkNet

Infelizmente, a StarkNet atualmente não possui um mecanismo ForceInclusion. Existem apenas dois artigos discutindo Censura e ForceInclusão no fórum oficial.

Não foi possível provar a transação falhada

A razão acima é, na verdade, porque o sistema de prova de conhecimento zero da StarkNet não pode provar uma transação com falha, portanto, a inclusão forçada não pode ser permitida. Porque se alguém maliciosamente (ou não intencionalmente) forçar a inclusão de uma transação com falha que não pode ser provada, a StarkNet ficará diretamente presa: porque depois que a transação for incluída à força, o Prover deve provar a transação com falha, mas não tem como provar.

A StarkNet espera introduzir a função de provar transações com falha na versão v0.15.0, e então deverá ser possível implementar ainda mais o mecanismo de Forçar Inclusão.

Mecanismo ForceInclusion do zkSync

A transmissão de mensagens L1-> L2 do zkSync e o mecanismo de Força de Inclusão são todos executados por meio da função requestL2Transaction do contrato MailBox. O usuário especifica o endereço L2, dados de chamada, valor ETH adicional, valor L2GasLimit, etc. requestL2Transaction combinará esses parâmetros em um L2. a transação é então colocada na fila de prioridade (PriorityQueue). Quando a transação é empacotada e carregada para L1 (por meio da função commitBatches), o sequenciador indicará quantas transações serão retiradas da fila de prioridade e as incluirá no registro de transação L2. .

zkSync é muito semelhante ao Otimismo na forma de Forçar Inclusão. Ele usa o endereço L2 do iniciador (consistente com o endereço L1) para chamar funções relacionadas e preencher os dados (callee, calldata, etc.), em vez de Arbitrum Fill. em uma transação L2 assinada, mas o design é o mesmo do Arbitrum, ambos mantêm uma fila Fila em L1, e o Sequenciador retira as transações pendentes enviadas diretamente pelo usuário da Fila e as grava no meio do histórico de transações.

Se você for para Deposit ETH através da ponte oficial do zkSync, como esta transação, ele chamará a função requestL2Transaction do contrato MailBox. Ele colocará a transação L2 de Deposit ETH na fila de prioridade e lançará um evento NewPriorityRequest. Como o contrato codifica os dados da transação L2 em uma sequência de bytes, é difícil de ler. Se você observar os parâmetros desta transação L1, verá que o destinatário de L2 nos parâmetros também é o iniciador da transação (. porque é depositado para si mesmo), então depois de um tempo, quando esta transação L2 for retirada da fila de prioridade pelo Sequenciador e incluída no histórico de transações, ela será convertida em uma transação transferida para si mesma em L2, e a quantidade de a transferência é o Depósito do iniciador da transação em L1 A quantidade de ETH transportada na transação ETH.

Na transação L1Deposit, o iniciador e o receptor da transação são 0xeDc1...6909, o valor é 0,03ETH e os dados de chamada estão vazios.

Haverá uma transação de 0xeDc1...6909 transferindo dinheiro para você mesmo em L2. O tipo de transação (TxnType) é 255, que é uma transação do sistema.

Em seguida, chamei diretamente a função requestL2Transaction do zkSync e enviei uma autotransferência, assim como fiz antes, quando experimentei a função de transação forçada do OP: sem qualquer ETH, os calldata trouxeram a codificação HEX da string de "inclusão forçada".

Em seguida, ele é convertido na última transação de L2 para si mesmo. O calldata é a string hexadecimal de "inclusão forçada": 0x666f72636520696e636c7573696f6e.

Quando o sequenciador retira a transação do PriorityQueue e a grava no histórico de transações, ela será convertida na transação L2 correspondente em L2.

Através da função requestL2Transaction, os usuários podem usar a conta L1 com o mesmo endereço L2 para enviar informações em L1, especificando o destinatário L2, o valor ETH que o acompanha e os dados de chamada. Caso o usuário queira chamar outros contratos com Dados diferentes, o mesmo é feito preenchendo os parâmetros da função requestL2Transaction um por um.

Não há função que permita aos usuários forçar a inclusão

Embora após a transação L2 ser colocada na fila de prioridade, o período de espera para a transação L2 ser incluída no sequenciador será calculado. No entanto, o design zkSync atual não possui uma função de Forçar Inclusão que os usuários possam aplicar, o que é equivalente. para apenas meio conjunto. Ou seja, embora haja um “período de espera para inclusão”, na verdade ainda é “ver se o Sequenciador deseja receber receita”: o Sequenciador pode esperar até que expire antes de receber a transação, ou nunca poderá receber quaisquer transações na fila de prioridade.

No futuro, zkSync deve adicionar funções relacionadas para que os usuários possam forçar a inclusão da transação no histórico de transações L2 quando o período de validade da receita tiver passado, mas não tiver sido incluído no Sequenciador. Este é um mecanismo de Força de Inclusão verdadeiramente eficaz.

Resumir

L1 depende de um grande número de validadores para garantir a "segurança" e a "resistência à censura" da rede. O Rollup usa um pequeno número ou até mesmo um único sequenciador para escrever transações, e sua resistência à censura é ainda mais fraca. Portanto, o Rollup precisa de um mecanismo de Força de Inclusão para permitir que os usuários ignorem o Sequenciador e gravem transações no histórico para evitar serem revisados ​​pelo Sequenciador e impossibilitarem o uso e retirada de fundos do Rollup.

Forçar Inclusão permite que os usuários forcem a gravação de transações no histórico, mas no design, eles precisam escolher se a transação pode ser inserida imediatamente no histórico e entrar em vigor imediatamente. Se as transações puderem entrar em vigor imediatamente, isso terá um impacto negativo no Sequenciador, porque as transações que aguardam para serem recebidas em L2 podem ser afetadas por transações recebidas à força em L1.

Portanto, o atual mecanismo de Rollup de Força de Inclusão colocará primeiro as transações inseridas em L1 no estado de espera e dará ao Sequenciador um período de tempo para reagir e escolher se deseja incluir essas transações em espera.

Tanto zkSync quanto Arbitrum mantêm uma fila Queue em L1 para gerenciar transações L2 enviadas por usuários de L1 ou mensagens para L2. Arbitrum é chamado DelayedInbox; zkSync é chamado PriorityQueue;

No entanto, a forma como o zkSync envia transações L2 é semelhante à do Optimism. Ele usa o endereço L2 para enviar mensagens para L1. Após a conversão para uma transação L2, o iniciador será o endereço L2. A função do Optimism para enviar transações L2 é chamada depositTransaction; zkSync é chamada requestL2Transaction. O Arbitrum gera e assina uma transação L2 completa e, em seguida, envia-a por meio da função sendL2Message. O Arbitrum restaurará o signatário por meio da assinatura em L2 como o iniciador da transação L2.

StarkNet atualmente não possui um mecanismo de Força de Inclusão; zkSync é como meio conjunto de Força de Inclusão - há uma PriorityQueue e cada transação L2 na Fila tem um período de validade de inclusão, mas esse período de validade é atualmente apenas para decoração. O sequenciador pode optar por não incluir nenhuma transação L2 no PriorityQueue