Escalando horizontalmente Execuções na Sui com Pilotfish
Tags: web3, blockchain
Published: 2024-03-27 00:27:36

Nova pesquisa abre caminho para a blockchain Sui permitir que os Validadores escalem em apoio a um desempenho de execução vastamente aumentado.

![Pilotfish scales execution on sui](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/07lvyyu72wy9yd7ivix5.png)

[Pilotfish](https://arxiv.org/abs/2401.16292?ref=b1gb0tdev), o primeiro motor de execução de contratos inteligentes multi-máquina, permite que os validadores da rede Sui utilizem múltiplas máquinas e escalem automaticamente para executar mais transações quando a carga aumenta. Isso é alcançado sem comprometer a confiabilidade ou a completude dos recursos.

O Pilotfish se recupera de falhas das máquinas de execução internas e suporta as operações dinâmicas completas da Sui. Sua arquitetura de streaming leva a uma sobrecarga de latência muito baixa. Nossas avaliações de desempenho da integração do Pilotfish com a Sui demonstram um aumento de até oito vezes na capacidade de processamento ao usar oito servidores para execução, demonstrando escalonamento linear para cargas limitadas por computação.

### O desafio da execução
Lazy Blockchains são uma arquitetura de design emergente promissora que desacopla a ordenação de transações (consenso) e execução. Neste design, uma camada de ordenação sequencia as transações e, então, em um momento posterior, uma camada de execução executa a sequência de transações. Isso permite que sistemas de blockchain de última geração ordenem um grande número de transações (na ordem de 100.000 transações por segundo), usando algoritmos de consenso modernos como Bullshark e Hammerhead. No entanto, o desempenho de execução tem ficado para trás, e atualmente a execução é o gargalo. Por exemplo, relata-se que a máquina virtual do Ethereum atinge um pico de apenas 20.000 transações por segundo ao executar transações simples.

### Batching: Uma solução de alta latência

Uma solução para o gargalo de execução é o batching (agrupamento). Ao construir lotes ou blocos de um grande número de transações e submetê-los como uma unidade para serem executados, é possível alcançar alta capacidade de processamento sem grandes mudanças na arquitetura. No entanto, o agrupamento vem com o custo de alta latência. Não é incomum que a execução em lote tenha latência na casa das centenas de milissegundos, o que é significativo para blockchains de baixa latência, como a Sui.

O Pilotfish alcança alta capacidade de processamento enquanto introduz apenas uma sobrecarga de latência negligenciável, na faixa de dezenas de milissegundos em vez de centenas, seguindo a abordagem de processamento em fluxo já empregada na Sui para execução multi-core.

### Escalar vertical vs Escalar horizontal

Uma maneira de alcançar alta capacidade de processamento mantendo a latência baixa é escalando vertical. A execução paralela de transações em uma única máquina, e algumas blockchains, incluindo a Sui, empregam com sucesso este modelo. Tem a vantagem de não requerer grandes mudanças arquitetônicas. O validador já está inteiramente localizado em uma única máquina, tornando-se apenas uma questão de executar a transação em paralelo em vez de sequencialmente, preservando a causalidade da transação.

Com a abordagem de escalar vertical, uma vez que a carga atual está além do que sua máquina atual pode lidar, sua única opção é atualizar para uma máquina mais potente. Mas esta solução tem uma pista limitada. Existem apenas tantos núcleos de CPU que podem caber em um servidor, tanta RAM, etc. Então, se a carga continuar crescendo, eventualmente estará além da capacidade de qualquer máquina única de acompanhar. Piorando a situação, não é apenas a CPU que pode ser esgotada, mas qualquer recurso único da máquina. Mesmo que a máquina validadora atual não esteja saturada em termos de CPU para a carga atual, ela pode ficar sem capacidade de RAM e ser forçada a depender de armazenamento persistente lento, assim desacelerando todo o pipeline. Finalmente, depender de máquinas poderosas únicas é desfavorável ao espaço das blockchains, pois máquinas robustas são raras e suportadas por poucos provedores de data center.

A única outra maneira de resolver o gargalo de execução, que o Pilotfish pioneira no espaço da blockchain, é escalar horizontalmente através da execução de transações distribuídas em múltiplas máquinas. A vantagem da abordagem de escalar para fora é que tem o potencial de escalar indefinidamente. Quando a carga aumenta além da capacidade do número atual de máquinas, podemos simplesmente ativar mais máquinas, garantindo essencialmente que nunca ficaremos sem capacidade e nunca teremos que recorrer a armazenamento persistente lento no caminho crítico. Outra vantagem desta abordagem é que ela é ortogonal e compatível com a abordagem de escalar vertical. Finalmente, também permite uma descentralização mais fácil, prevenindo a “monocultura” de provedores de hardware. Há um mercado maior para várias máquinas pequenas do que para máquinas super-poderosas únicas.

### Como o Pilotfish funciona

Aqui está como o Pilotfish distribui a execução de transações em várias máquinas. Cada validador é internamente dividido em três papéis lógicos: (1) o Primário, que lida com o consenso, (2) SequencingWorkers (SWs), que armazenam transações e as despacham para execução; e (3) ExecutionWorkers (EWs), que armazenam o estado da blockchain e executam transações recebidas dos SWs.

![diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ivv4kjn0yadtjj413vv.png)

Cada um desses papéis é instanciado em uma ou mais máquinas, exceto pelo Primário, que é sempre uma única máquina. Note que as máquinas que compõem um validador confiam umas nas outras (são operadas pela mesma entidade), então elas não precisam de protocolos pesados de Tolerância a Falhas Bizantinas (BFT -  Byzantine Fault Tolerant) para coordenar. Apenas o Primário requer BFT, quando interage com outros nós.

O que permite ao Pilotfish escalar é que os SWs e EWs fragmentam o estado. Cada transação é atribuída a um único SW e cada objeto da blockchain é atribuído a um único EW. Note que isso não é o mesmo que a fragmentação entre validadores, na qual validadores são atribuídos diferentes subconjuntos do estado. No Pilotfish, todos os validadores são atribuídos ao estado inteiro, e a fragmentação ocorre dentro de cada validador que usa várias máquinas.

Em um mundo perfeito, cada transação acessaria apenas objetos de um único fragmento, então distribuir a execução de transações seria tão simples quanto despachar cada transação para seu respectivo fragmento de EW. No entanto, no mundo real, transações frequentemente acessam objetos de mais de um fragmento. Para lidar com tais transações entre fragmentos, os EWs do Pilotfish trocam dados de objetos conforme necessário, de modo que o EW designado para executar uma determinada transação sempre tenha os dados do objeto requeridos antes de começar a execução.


![diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hv1yyyjkfy7bhaufqv2c.png)

No diagrama acima, o Primário interage com os primários de outros validadores para ordenar transações (1). O SW recebe a informação de ordenação das transações do primário e despacha transações para os EWs apropriados (2). No nosso exemplo acima, a transação atual T acessa objetos de entrada dos fragmentos EW1 e EW3, então o SW apenas despacha T para esses EWs. Então, EW1 e EW3 agendam T contra outras transações que podem conflitar com T (mais sobre nosso algoritmo de agendamento no papel completo) (3). Uma vez que T está pronta para ser executada, EW1 e EW3 enviam os dados dos objetos apropriados para o executor designado de T (neste caso o executor designado é EW1, então apenas EW3 precisa enviar objetos). Uma vez que EW1 tem todos os dados de objetos necessários, executa T (4) e envia os efeitos da saída para todos os EWs. Cada EW aplica localmente mudanças aos objetos que possui (5).

### Além do básico

Além deste fluxo básico de transações, leia nosso [artigo completo](https://arxiv.org/abs/2401.16292?ref=b1gb0tdev) para descobrir:

Como agendamos transações para permitir a execução paralela de transações não conflitantes.
Como lidamos e nos recuperamos de falhas nos fragmentos.
Como habilitamos leituras e escritas em campos dinâmicos.

### Uma rápida olhada em nossos resultados

Aqui temos uma rápida olhada nos resultados experimentais. O artigo contém detalhes completos da configuração experimental e dos resultados.

No gráfico de latência versus capacidade de processamento abaixo, cada ponto de dado representa uma execução experimental na qual o SequencingWorker submete transações a uma taxa fixa por uma duração de cinco minutos. Aumentamos experimentalmente a carga de transações enviadas ao sistema e registramos a capacidade de processamento média e a latência das transações executadas. Como resultado, todos os gráficos ilustram a latência em estado estável de todos os sistemas sob carga baixa, bem como a capacidade de processamento máxima que podem servir, após a qual a latência cresce rapidamente. Esta é a capacidade de processamento na qual a latência dispara para mais de 20 milissegundos.

Enfatizamos que, em todos os experimentos, as transações são submetidas para execução individualmente, à medida que chegam de forma contínua, sem serem agrupadas. Isso é especialmente importante para a Sui, que processa transações de caminho rápido de forma assíncrona assim que são certificadas, antes de serem agrupadas em um commit de consenso. O Pilotfish também suporta o agrupamento, que aumenta significativamente a capacidade de processamento, mas (claro) também leva a uma maior latência.

Nesta primeira carga de trabalho, cada transação é uma simples transferência de moedas de um endereço para outro. Geramos as transações de tal forma que nenhuma transação conflite com outra. Cada transação opera em um conjunto diferente de objetos das outras transações. Assim, esta carga de trabalho é completamente paralelizável.

![latency](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bfhwkyijj2hehkyr8ar6.png)

Observamos que, para qualquer número de ExecutionWorkers (EW), o Pilotfish mantém uma baixa latência abaixo de 20 milissegundos. Significativamente, também observamos que a latência por transação diminui à medida que adicionamos mais EWs. Com uma baixa latência de 6 a 7 milissegundos, a configuração de oito EW processa cinco a seis vezes mais transferências individuais do que a configuração de um EW.

Note que a latência exibe um aumento linear à medida que a carga de trabalho cresce para um único ExecutionWorker, principalmente por causa dos efeitos do enfileiramento de transações. Mais especificamente, uma única máquina não tem núcleos suficientes para explorar completamente o paralelismo da carga de trabalho, então algumas transações têm que esperar para serem agendadas. Este efeito deixa de existir para um número maior de ExecutionWorkers, ilustrando que adicionar mais hardware tem um efeito benéfico no tempo de serviço ao reduzir a latência de execução.

A escalabilidade do Pilotfish não é perfeitamente linear nesta carga de trabalho. Em particular, a melhoria marginal na capacidade de processamento diminui após dois ExecutionWorkers. Isso se deve à carga de trabalho de transferência simples computacionalmente leve e à capacidade de processamento não ser limitada por computação. Assim, adicionar mais recursos de CPU não melhora mais o desempenho proporcionalmente. O próximo gráfico, mostrado abaixo, ilustra as vantagens de aumentar o número de ExecutionWorkers quando a carga de trabalho é limitada por computação.

Para ilustrar o efeito da intensidade computacional, adicionamos algum cálculo sintético a cada transação. Para simplicidade, usamos o cálculo iterativo de Fibonacci como nosso cálculo sintético. Por exemplo, no gráfico abaixo, "Fib-2500" significa que cada transação calcula o 2500º número de Fibonacci. O gráfico mostra como a capacidade máxima de processamento do Pilotfish escala com o número de EWs para três níveis de intensidade computacional (Fib-2500 é o mais baixo e Fib-10000 é o mais alto). Como linha de base, incluímos o desempenho da base de Sui, que opera em uma única máquina e não pode tirar vantagem de hardware adicional.

Como o gráfico mostra, neste caso, a capacidade de processamento do Pilotfish escala linearmente com o número de EWs disponíveis, até oito vezes a capacidade de processamento com oito EWs, o que é próximo do ideal.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gl5gnipqmnjqgdffcst5.png)

### O que vem a seguir?

Por enquanto, o Pilotfish é uma prova de conceito que mostra ser possível alcançar boa escalabilidade de execução em escala em lazy blockchains, sem comprometer a latência. Em particular, mostramos que um executor altamente distribuído leva a uma execução de baixa latência e maior capacidade de processamento, mesmo para transferências simples. Além disso, para contratos inteligentes intensivos em computação, demonstramos um aumento quase ideal na capacidade de processamento à medida que adicionamos mais recursos de execução.

O Pilotfish abre caminho para computação mais barata em contratos inteligentes, livre de preocupações de que a execução de um contrato limitado por CPU interferiria negativamente com outros contratos inteligentes.

Na próxima iteração, planejamos também implementar e testar suporte para mais de um SW, replicação de fragmentos e recuperação de falhas, e suporte para redes de acesso direto à [memória remota ultra-rápidas](https://en.wikipedia.org/wiki/Remote_direct_memory_access?ref=b1gb0tdev). Estamos trabalhando para melhorar nosso protótipo, adicionando essas características e aprimorando seu desempenho de ponta a ponta através de otimizações de engenharia.

Leia a matéria original: [Clique aqui](https://blog.sui.io/pilotfish-execution-scalability-blockchain/)

Traduzido por: [b1gvini](x.com/b1gb0tdev)

*Considere fazer uma doação - sui wallet: b1gvini.sui*