tl; dr: Divida um bloco El (= carga útil) em vários mini -bloqueios (“pedaços”) Do orçamento fixo de gás (por exemplo 2**24 = 16.77M) que se propaga independentemente como carros laterais. Cada parcela carrega o pré -estado necessário para executar sem estado e se compromete com seu diferencial pós -estado. Pedaços são ordenados, mas pode ser executado totalmente independentemente em paralelo. CL se compromete com o conjunto de cabeçalhos de pedaços; Sidecars carregam corpos e provas de inclusão.
A validação se torna mais um fluxo contínuo.

Motivação

Hoje, os blocos são objetos grandes e monolíticos que se tornarão ainda maiores no futuro. A validação requer que o recebimento do bloco antes que a execução possa começar. Isso cria gargalos de latência na propagação e execução de blocos.

Depois que o bloco é recebido pela rede P2P, as transações são executadas sequencialmente. Não podemos começar a validar durante o download ou a execução paralela.

As mensagens na camada P2P geralmente são compactadas usando o Snappy. O formato de bloco de Snappy que é usado no Ethereum não pode ser transmitido. Assim, precisamos cortar o bloco em pedaços antes compressão.

Com as listas de acesso ao nível de bloco EIP-7928: a situação melhora, mas ainda estamos aguardando o download terminar antes de iniciar a validação do bloco. Com 4 núcleos, obtemos o seguinte gráfico de Gantt:

Em vez disso, podemos stream blocos como pedaços:

  • Cada pedaço contém ≤ 2**24 gás de transações.
    • Também se pode ter o tamanho do pedaço aumentando geometricamente (2**22Assim, 2**23…, 2**25) em gás. Isso nos daria latências variadas para pedaços, permitindo uma melhor paralelização – mas não tenho certeza de que valeria a complexidade.
  • Transações permanecer ordenado. Os pedaços são indexados e ordenados, mas independente um do outro, para que eles possam ser validados em paralelo. Ainda assim, o pós-estado de Chunk 0 é o pré-estado do pedaço 1.
  • (opcional) Cada pedaço carrega o estado em que precisa ser executado sem estado.

Isso muda a validação de “Faça o download do bloco completo e depois processe ”→“ Processe ao receber o restante.


Alterações da camada de execução

Estendemos o formato El Block para apoiar o Chunking:

class ELHeader:
    parent_hash: Hash32
    fee_recipient: Address
    block_number: uint64
    gas_limit: uint64
    timestamp: uint64
    extra_data: ByteList(MAX_EXTRA_DATA_BYTES)
    prev_randao: Bytes32
    base_fee_per_gas: uint256
    parent_beacon_block_root: Root
    blob_gas_used: uint64
    excess_blob_gas: uint64
    transactions_root: Root
    state_root: Root
    receipts_root: Root
    logs_bloom: Bloom
    gas_used: Uint
    withdrawals_root: Root
    block_access_list_hash: Bytes32
    # New fields
    chunk_count: int  # >= 0

não compromisso para os pedaços individuais no cabeçalho El. Nós apenas adicionamos a contagem de pedaços a ele. As saídas de execução (state_rootAssim, logs_bloomAssim, receipts_rootAssim, gas_used) deve ser o mesmo que o valor no último pedaço (aplica -se à raiz do estado e nas retiradas da raiz) ou a raiz após agregar os valores do pedaço (aplica -se a transações, recibos, logs, gás usado e lista de acesso ao bloco).

Pedaços de execução

Os pedaços nunca são colocados na cadeia; Apenas suas raízes estão comprometidas.

Os pedaços contêm os campos que normalmente esperávamos no corpo do bloco El. As transações são divididas em pedaços com um limite de 2**24 gás por pedaço. Os saques devem ser incluídos apenas no último pedaço. Listas de acesso ao nível do bloco espelhado, pedaços vêm com sua própria lista de acesso a pedaços e pode-se adicionar adicionalmente valores pré-estadual aos pedaços, desbloqueando a apatridia.

class Chunk:
    header: ChunkHeader
    transactions: List(Tx)
    withdrawals: List(Withdrawal)  # only in chunk at index -1
    chunk_access_list: List(ChunkAccessList)
    pre_state_values: List((Key, Value)) #  optional

Cada pedaço vem com um cabeçalho, incluindo o índice de pedaços. As transações são ordenadas por chunk.header.index e seu índice no pedaço. Os compromissos com a saída de execução de cada pedaço estão incluídos no cabeçalho.

class ChunkHeader:
    index: int
    txs_root: Root
    post_state_root: Root
    receipts_root: Root
    logs_bloom: Bloom
    gas_used: uint64
    withdrawals_root: Root
    chunk_access_list_root: Root
    pre_state_values_root: Root  # optional

Para impedir que os proponentes dividam seus blocos em muitos pedaços, o protocolo pode fazer cumprir que os pedaços devem estar pelo menos metade completa (\ geq \ frac {chunk \ _gas \ _limit} {2}) OU chunk.header.index == len(beaconBlock.chunk_roots) (= Último pedaço naquele bloco).


Alterações na camada de consenso

Beacon blocks rastrear pedaços com novos campos:

class BeaconBlockBody:
    ...
    chunk_roots: List(ChunkRoot, MAX_CHUNKS_PER_BLOCK)  # SSZ roots of chunks

class ExecutionPayloadHeader:
    ...
    chunk_count: int

O CL recebe os pedaços de execução do EL por meio de um novo ChunkBundle contêiner que inclui o cabeçalho El e os pedaços (= semelhante a Blobs).
O CL calcula raízes de pedaços usando o SSZ’s hash_tree_root e os coloca no corpo do bloqueio do farol.

Design Sidecar

Pedaços são transportados Sidecars:

class ExecutionChunkSidecar:
    index: uint64  #  chunk index
    chunk: ByteList(MAX_CHUNK_SIZE)  # Opaque chunk data
    signed_block_header: SignedBeaconBlockHeader
    chunk_root_inclusion_proof: Vector(Bytes32, PROOF_DEPTH)

A camada de consenso garante chunk_roots (= semelhante a Blobs).

Networking

O proponente fofoca apenas o bloco de farol leve com compromissos (chunk_countAssim, chunk_headers_root) no normal beacon_block tópico, enquanto os dados de execução pesados ​​são transmitidos separadamente como ExecutionChunkSidecars de outro lado X sub -redes paralelas (beacon_chunk_sidecar_{0..X}), deduzido por (block_root, index).

Inicialmente, todos os nós devem assinar todas as sub -redes e custódia de todos os pedaços. Embora isso ainda não reduza os requisitos de largura de banda/armazenamento, ele permite os benefícios imediatos da paralelização. A custódia parcial pode ser adicionada em uma atualização futura quando o mecanismo básico for comprovado e/ou a provação de ZK se tornar viável.

Escolha do garfo

A escolha do garfo exige que todos os sidcars estejam disponíveis e validados com sucesso antes que um bloco seja considerado válido. O bloqueio do farol com o chunk_roots propaga-se rapidamente, mas o bloco só se torna elegível para a garfo, uma vez que cada pedaço foi recebido e comprovado por inclusão contra a raiz. O bloco Beacon ainda contém o cabeçalho El com todos os compromissos necessários (=comprometendo -se com saídas de bloqueio pai e execução). O que sabíamos como Bloquear o corpo No El fica vazio neste design.


Benefícios

  • Validação de streaming: A execução pode iniciar enquanto outras partes do bloco ainda estão baixando ou ocupadas carregando do disco. Os pedaços são independentes (se pré-estatal fornecidos) ou confiam na lista de acesso a pedaços (com diferenças de estado no nível de pedaços) e o pré-bloqueio; Várias CPUs/núcleos podem validar pedaços simultaneamente; Distribua o uso da largura de banda sobre o slot em vez de explosões de início de slot.
  • Provando simplificado: O ZK Provers pode paralelizar a comprovação de múltiplos pedaços ao mesmo tempo, beneficiando -se da independência de pedaços.
  • Amizade sem estado: Como um único pedaço é menor que um bloco, podemos considerar adicionar valores pré-estados, de modo que não há necessidade de acesso ao estado local. Um meio termo prático é incluir valores pré-estados apenas em pedaços 0garantindo que pelo menos um pedaço sempre possa ser executado enquanto o nó carrega o estado necessário para outros pedaços do disco em cache.
  • Extensibilidade futura: Caminho claro para integrar a prova de ZK em pedaços ou optar por execução fragmentada.

Espaço de design

Tamanho do pedaço

2**24 O gás (~ 16,7m) emergiu como um tamanho de pedaço natural:

  • Tamanho máximo da transação: A partir de Fusaka (EIP-7825), 2**24 é o tamanho máximo da transação possível.
  • Blocos atuais: Blocos de gás de 45m se dividem naturalmente em ~ 3 pedaços, proporcionando paralelismo imediato
  • Blocos futuros: Escalas bem – 100m a gás blocos teriam ~ 6 pedaços

Validador

  1. Engine de execução divide o bloco em pedaços internamente (opaco para CL) e os passa para o CL através de um ExecutionChunkBundle.
  2. Propositor Envolva cada pedaço em um carro lateral com prova de inclusão. O proponente também calcula a raiz da árvore de hash de cada pedaço e os coloca no corpo do bloqueio do farol.
  3. Publicação acontece em paralelo em todas as sub -redes
  4. Atestadores Espere por todos os pedaços e valide -os antes de votar

Construtores

Os proponentes podem publicar pedaços à medida que terminarem, e os validadores podem começar a validá -los mesmo antes de receber o bloco de beacon. Como os pedaços contêm o cabeçalho do bloco de farol assinado e uma prova de inclusão contra ele, pode -se validar (= executar) pedaços quando eles entram, confiando em sua fonte (= propositor).

Perguntas abertas e trabalho futuro

Tamanhos progressivos de pedaços?

A idéia de aumentar geometricamente tamanhos de pedaços (2**22Assim, 2**23…, 2**25) parece benéfico, mas acrescenta complexidade. O primeiro pedaço pode ser menor (5m de gás) com valores pré-estatal para execução imediata, enquanto os pedaços posteriores são maiores. Esta continua sendo uma área para experimentação.

Caminho de custódia parcial

Embora a implementação inicial exija custódia total, a arquitetura suporta naturalmente a custódia parcial:

  • Nós poderia custódia apenas Y sub -redes de x
  • Os mecanismos de reconstrução (semelhantes ao DAS) podem recuperar pedaços ausentes

Compatível com EPBS e execução tardia

À primeira vista, o design proposto parece compatível com o EIP-7732 e o EIP-7886. Sob EPBS, as raízes de pedaços provavelmente se moveriam para o ExecutionPayloadEnvelopee colocamos uma raiz adicional sobre as raízes de pedaços no ExecutionPayloadHeader. O PTC não apenas teria que verificar se uma única carga útil do EL está disponível, mas também que todos os pedaços são. Isso não é muito diferente dos blobs.

As vantagens da escala de bloqueio e validação independente com limites de gás mais altos e podem contribuir para reduzir o pico no consumo de largura de banda do nó.

Fontesethresear

By victor

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *