NOVO: Helius adquire a Light Protocol
O que é Firedancer? Uma análise aprofundada da Solana 2.0
Blog/Pesquisa

O que é Firedancer? Uma análise aprofundada da Solana 2.0

Developer Experience Engineer0xIchigo no X0xIchigo no LinkedIn0xIchigo no GitHub
46 min de leitura

Agradecemos imensamente à equipe do Firedancer pela revisão deste artigo.

Sobre o que é este artigo?

A Solana é a blockchain mais rápida. Mas pode ser ainda mais rápida. O atual cliente validador da Solana Labs é bom, mas foi otimizado para chegar rapidamente ao mercado. Com uma visão retrospectiva, a oportunidade de começar do zero e décadas de experiência em computação de alto desempenho, a Jump está empenhada em tornar a Solana ainda mais rápida e confiável. Aplicando sua experiência em negociações de alta frequência, a Jump está desenvolvendo o Firedancer. Este é o cliente validador de maior desempenho entre todas as blockchains. Ele propõe uma reescrita completa do atual cliente validador da Solana na linguagem de programação C.

Este artigo aborda validadores e a importância da diversidade de clientes validadores. Em seguida, veremos por que a Jump está criando um novo cliente validador e como sua experiência em negociações de alta frequência faz dela a equipe perfeita para desenvolver o Firedancer. Depois, explicaremos o que é Firedancer, como ele funciona, por que é rápido, como sua segurança é garantida e qual é seu estado atual.

Ao final deste artigo, você terá uma compreensão completa do novo cliente validador da Jump. Conhecerá suas otimizações revolucionárias, que fazem dele o cliente validador de maior desempenho em qualquer blockchain. Também entenderá por que o Firedancer é essencial para o desempenho e a confiabilidade da rede Solana. Este é o único artigo de que você precisa para conhecer o Firedancer.

A seção de Apêndice contém uma introdução totalmente opcional a hardware de computadores e redes. Ela foi adicionada para fornecer ao leitor comum o contexto necessário para compreender os conceitos mais avançados de hardware e redes abordados neste artigo. Ainda assim, apresentamos contexto sempre que necessário. O objetivo deste artigo é ser acessível para que qualquer pessoa que use a Solana possa entender o Firedancer e sua importância.

O que são validadores e o que é diversidade de clientes validadores?

Um validador é um computador que participa de uma blockchain de Proof of Stake. Os validadores formam a espinha dorsal da rede Solana. Eles são responsáveis por processar transações e participar do consenso. Um validador ajuda a proteger a rede bloqueando uma determinada quantidade do token nativo da Solana como stake. Pense nisso como um depósito de segurança que expõe financeiramente o validador à rede. Essa exposição incentiva os validadores a executar suas tarefas de forma correta e eficiente, pois eles recebem recompensas por suas contribuições. Os validadores também são penalizados por atividades maliciosas ou incorretas. O stake de um validador é reduzido por comportamento impróprio em um processo conhecido como slashing. Portanto, é do interesse do validador cumprir corretamente suas funções para aumentar seu stake.

Clientes validadores são aplicações que os validadores usam para cumprir suas funções. O cliente serve de base para os validadores e usa a identidade criptograficamente exclusiva deles para participar do consenso.

Ter vários clientes distintos melhora a tolerância a falhas caso uma implementação apresente problemas. Por exemplo, se nenhum cliente controlar mais de 33% do stake, uma falha ou um bug que afete a atividade da rede não será capaz de derrubá-la. Da mesma forma, se um bug em um cliente causar uma transição de estado inválida, a rede poderá evitar uma falha de segurança se menos de 33% do stake usar esse cliente. Isso ocorre porque a maior parte da rede permanecerá em um estado válido, impedindo uma divisão ou bifurcação da blockchain. Portanto, a diversidade de clientes validadores aumenta a resiliência da rede, pois um bug ou uma vulnerabilidade em um cliente não comprometerá toda a rede.

A diversidade de clientes é medida pela porcentagem de stake executada por cada cliente e pelo número total de clientes disponíveis. No momento da redação deste artigo, há 1979 validadores na rede Solana. Os dois clientes que esses validadores usam na mainnet são fornecidos pela Solana Labs e pela Jito Labs. A Solana foi lançada com um cliente validador em março de 2020, desenvolvido pela Solana Labs. Em agosto de 2022, a Jito Labs lançou um segundo cliente validador. Esse cliente é um fork do código da Solana Labs, mantido e implantado pela Jito. O cliente otimiza a extração de MEV (valor máximo extraível) dentro dos blocos. O cliente da Jito cria um pseudo-mempool, pois a Solana transmite blocos sem usar um. A propósito, um mempool, ou pool de memória, é um acúmulo de transações pendentes e não confirmadas. Um pseudo-mempool permite que os validadores pesquisem essas transações, agrupem-nas de forma otimizada e as enviem ao Block Engine da Jito.

Em outubro de 2023, o cliente da Solana Labs detinha 68,55% do stake ativo, enquanto a Jito detinha 31,45%. O número de validadores que usam o cliente da Jito aumentou 16% desde o Relatório de integridade anterior da Solana Foundation. O uso crescente do cliente da Jito indica uma tendência positiva para a diversidade de clientes.

Embora essa notícia de crescimento seja animadora, a situação ainda não é perfeita. É essencial destacar que o cliente da Jito é um fork do cliente da Solana Labs. Isso significa que a Jito compartilha muitos componentes com a base de código original do validador e está potencialmente vulnerável a bugs ou explorações que afetariam o cliente da Labs. Em um futuro ideal, a Solana teria pelo menos quatro clientes validadores independentes. Equipes diferentes desenvolveriam esses clientes em linguagens de programação distintas. Nenhuma implementação teria mais de 33% do stake, pois cada cliente manteria ~25%. Essa configuração idealizada eliminaria qualquer ponto único de falha de toda a pilha de validadores.

Desenvolver um segundo cliente validador independente é essencial para concretizar esse futuro, e a Jump está empenhada em fazer isso acontecer.

Por que a Jump está criando um novo cliente validador?

A mainnet da Solana já enfrentou quatro interrupções na produção de blocos. Todas exigiram correções manuais de centenas de validadores. Essas interrupções colocaram em evidência as preocupações com a confiabilidade da rede Solana. A Jump afirma que o protocolo é sólido. Em vez disso, atribui o tempo de inatividade a problemas nos módulos de software que afetam o consenso. Por isso, a Jump está desenvolvendo um novo cliente validador para resolver esses problemas. O objetivo geral desse cliente é aumentar a estabilidade e a eficiência da rede Solana.

Desenvolver um cliente validador independente é uma tarefa difícil. No entanto, esta não é a primeira vez que a Jump constrói uma rede global confiável. No passado, as transações de valores mobiliários (ou seja, compra e venda de ações) eram executadas manualmente por especialistas de mercado. Com o surgimento das plataformas eletrônicas de negociação, as bolsas de valores se tornaram mais abertas. Essa abertura aumentou a concorrência e a automação, além de reduzir o tempo e o custo das negociações para os investidores. Isso desencadeou uma corrida tecnológica entre os especialistas de mercado.

Traders vivem para negociar. A experiência ideal de negociação não permite concessões em software, hardware ou soluções de rede. Esses sistemas devem ter alta inteligência computacional, baixa latência em tempo real, alto throughput, alta adaptabilidade, alta escalabilidade, alta confiabilidade e alta responsabilização.

Soluções comerciais prontas (ou seja, softwares que uma empresa pode simplesmente comprar) não representam uma vantagem competitiva. Enviar a ordem correta para uma bolsa dez vezes em segundo lugar é uma maneira cara de perder dinheiro. A concorrência acirrada nas negociações de alta frequência gera um ciclo perpétuo de desenvolvimento para criar uma infraestrutura global de negociação de alto nível.

Esse cenário pode parecer familiar. As exigências de um sistema de negociação bem-sucedido se assemelham às de uma blockchain bem-sucedida. Blockchains precisam ser redes de alto desempenho, tolerantes a falhas e com baixa latência. Uma blockchain lenta é uma tecnologia fracassada que não consegue atender às exigências das aplicações corporativas modernas — ela apenas prejudica a inovação, a escalabilidade e a utilidade no mundo real. Com mais de duas décadas de experiência na expansão de redes globais e no desenvolvimento de sistemas de alto desempenho, a Jump é a equipe perfeita para criar um cliente validador independente. Kevin Bowers, diretor científico da Jump Trading, supervisiona esse processo.

Por que a velocidade da luz é lenta demais?

Kevin Bowers já falou extensamente sobre a velocidade da luz ser lenta demais. A velocidade da luz é uma constante finita que impõe um limite natural ao número de cálculos que um único transistor pode processar. Atualmente, os bits são representados por elétrons que se deslocam por transistores. O Teorema da Capacidade de Shannon (ou seja, a quantidade máxima de dados sem erros que pode ser enviada por um canal) restringe o número de bits transmitidos por um transistor. Devido aos fundamentos da física e da teoria da informação, a velocidade de computação é limitada pela rapidez com que um elétron se move através da matéria e pela quantidade de dados que pode ser enviada. Essas restrições ficam evidentes quando supercomputadores são levados ao limite. Como resultado, existe uma “incompatibilidade drástica entre a capacidade dos computadores de processar números e a capacidade de movimentá-los.”

Considere como exemplo uma CPU Intel Core i9 13900K. Ela tem 24 núcleos x86 com clock base de 2,2 GHz e clock turbo máximo de 5,8 GHz. No pior cenário, a luz teria que percorrer uma distância total de ~52,0 mm através dessa CPU. A distância Manhattan da CPU (ou seja, a distância entre dois pontos medida ao longo de eixos perpendiculares) é de ~73,6 mm. Na velocidade máxima do clock turbo da CPU, de 5,8 GHz, a luz pode percorrer ~51,7 mm no ar. Isso significa que um sinal quase consegue fazer uma viagem completa de ida e volta entre dois pontos quaisquer da CPU durante um único ciclo de clock.

A realidade é muito pior. Essas medições usam a velocidade da luz no ar, enquanto os sinais se deslocam pelo dióxido de silício (SiO2). A luz pode percorrer ~26,2 mm no dióxido de silício durante um ciclo de clock de 5,8 GHz. No silício (Si), ela só consegue percorrer ~15,0 mm durante um ciclo de clock de 5,8 GHz — pouco mais da metade da borda mais longa da CPU.

A equipe do Firedancer argumenta que os avanços tecnológicos recentes na computação se concentraram em colocar mais núcleos em uma CPU, e não em torná-los mais rápidos. Quando as pessoas precisavam de mais desempenho, eram incentivadas a comprar mais hardware. Por enquanto, isso funciona quando o throughput é o gargalo. O verdadeiro gargalo é a velocidade da luz. Essa restrição natural provoca uma paralisia na tomada de decisões. Nenhuma otimização isolada oferece retorno imediato, pois um sistema tem muitos componentes e nenhum deles está bem otimizado. As partes que não forem otimizadas piorarão com o tempo porque terão menos capacidade computacional disponível. Então, o que fazer agora?

No mundo da computação de alto desempenho, tudo precisa ser otimizado em algum momento. O resultado é a criação de sistemas para negociações em produção e pesquisas quantitativas que operam nos limites da física e da teoria da informação em escala planetária. Isso inclui desde a criação de tecnologias personalizadas de comutação de rede até algoritmos sem bloqueio projetados considerando esses limites físicos. A Jump é tanto uma empresa de tecnologia quanto uma empresa de negociação. Na fronteira entre a ficção científica e a realidade, e diante das notáveis semelhanças entre os problemas enfrentados atualmente pela Jump e pela Solana, a Jump está desenvolvendo o Firedancer.

O que é Firedancer?

Firedancer é um novo cliente validador totalmente independente, desenvolvido pela equipe do Firedancer na linguagem de programação C. O Firedancer foi criado com foco em confiabilidade graças à sua arquitetura modular, às dependências mínimas e ao amplo processo de testes. Ele propõe uma grande reescrita dos três componentes funcionais do cliente da Solana Labs: rede, runtime e consenso. Cada camada é otimizada para o desempenho máximo, permitindo que o cliente opere com uma capacidade limitada apenas pelo hardware do validador. Isso difere dos limites de desempenho que os validadores enfrentam atualmente devido às ineficiências do software. Com o Firedancer, a Solana escalará de acordo com a largura de banda e o hardware.

Os objetivos do Firedancer são:

  • Documentar e padronizar o protocolo da Solana (ao final, uma pessoa deverá conseguir criar um validador da Solana apenas consultando a documentação, sem precisar examinar o código do validador em Rust)
  • Aumentar a diversidade de clientes validadores
  • Melhorar o desempenho do ecossistema

Como o Firedancer funciona?

Arquitetura modular

O Firedancer se diferencia dos clientes validadores atuais da Solana por sua arquitetura modular singular. Ao contrário do cliente validador da Solana Labs em Rust, que opera como um único processo, o Firedancer é composto por vários processos individuais Linux em C, conhecidos como tiles. Um tile consiste em um processo e uma porção de memória. Essa arquitetura de tiles é fundamental para a filosofia operacional do Firedancer e para sua abordagem de robustez e eficiência.

Um processo é uma instância de um programa em execução. Ele é um componente fundamental dos sistemas operacionais modernos e representa a execução de um conjunto de instruções. Cada processo tem seu próprio espaço de memória e recursos, que o sistema operacional aloca e opera independentemente de outros processos. Um processo é como um trabalhador independente em uma grande fábrica, responsável por uma tarefa específica com suas próprias ferramentas e seu próprio espaço de trabalho.

No Firedancer, cada tile é um processo individual com uma função definida. Por exemplo, o tile QUIC é responsável por processar o tráfego QUIC recebido e encaminhar as transações encapsuladas para o tile de verificação. O tile de verificação é responsável pela verificação de assinaturas, e assim por diante para cada tile. Esses tiles operam de forma independente e simultânea, contribuindo para a funcionalidade geral do sistema. Processos Linux individuais permitem domínios de falha pequenos e independentes. Isso significa que problemas em um tile têm impacto mínimo — ou um pequeno “raio de impacto” — sobre o sistema como um todo. Essa abordagem difere do cliente da Solana Labs em Rust porque um único ponto de falha não tem o potencial de comprometer instantaneamente todo o validador.

Uma das principais vantagens da arquitetura do Firedancer é a capacidade de substituir e atualizar cada tile em segundos, sem qualquer tempo de inatividade. Esse recurso contrasta fortemente com a exigência do cliente da Solana Labs em Rust de ser completamente desligado antes das atualizações. A diferença decorre da ausência de estabilidade de ABI (Application Binary Interface) no Rust. Isso impede atualizações em tempo real em um ambiente exclusivamente Rust. O uso de processos em C, que se beneficiam da estabilidade binária do modelo de runtime da linguagem, reduz significativamente o tempo de inatividade relacionado às atualizações. Isso é possível porque os tiles gerenciam o estado do validador em espaços de trabalho diferentes. Esses objetos de memória compartilhada persistem enquanto o validador estiver ligado. Cada tile pode retomar o processamento de onde parou durante uma reinicialização ou atualização.

De modo geral, o Firedancer foi criado com uma arquitetura baseada em tiles e compatível com NUMA. Abordaremos o significado disso na próxima seção. Por enquanto, isso significa que ele fornece recursos de hardware dedicados por thread. Nessa arquitetura, um núcleo de CPU é usado por tile. Ela oferece troca de mensagens de alto desempenho entre os tiles, otimizada para localidade de memória, distribuição de recursos e latências dos componentes.

Processamento de rede

O processamento de rede do Firedancer foi projetado para lidar com as exigências intensivas da rede Solana à medida que ela escala para velocidades de gigabits por segundo. Esse processo é dividido entre atividades de entrada e saída.

As atividades de entrada envolvem principalmente o recebimento de transações dos usuários. O desempenho do Firedancer é essencial porque mensagens de consenso podem ser perdidas se um validador ficar atrasado no processamento de pacotes. A largura de banda operacional atual de um nó da Solana é de ~0,2 Gbps, enquanto o maior pico registrado em um nó da Jump foi de ~40 GBps. Esse pico de largura de banda demonstra a necessidade de uma solução robusta e escalável para processar o tráfego de entrada.

As atividades de saída incluem o empacotamento de blocos, a criação de blocos e o envio de shreds. Cada uma dessas etapas é crucial para a operação segura e eficiente da rede Solana. O desempenho dessas tarefas afeta não apenas o throughput, mas também a confiabilidade geral da rede.

O Firedancer busca corrigir as fragilidades históricas da interface ponto a ponto da Solana no processamento de transações. Uma grande deficiência dessa interface no passado era a ausência de controle de congestionamento para as transações recebidas. Essa deficiência causou interrupções significativas da rede em 14 de setembro de 2021 (17 horas) e 30 de abril de 2022 (7 horas).

Em resposta, a Solana realizou várias atualizações de rede para lidar adequadamente com altas cargas de transações. O Firedancer segue a mesma abordagem ao adotar o QUIC para o controle de fluxo. QUIC é um protocolo multiplexado de transporte de rede que forma a base do HTTP/3. Ele é essencial para a proteção contra DDoS e para o gerenciamento do tráfego de rede. No entanto, é importante observar que, em alguns casos, os custos superam os benefícios. O QUIC, combinado com o hardware especializado dos data centers para mitigar ataques DDoS, elimina o incentivo por trás do excesso deliberado de transações.

A especificação de 151 páginas do QUIC trouxe uma complexidade considerável ao desenvolvimento. Incapaz de encontrar uma biblioteca C existente que atendesse às suas necessidades de licenciamento, desempenho e confiabilidade, a equipe do Firedancer criou sua própria implementação. A implementação de QUIC do Firedancer, apelidada de fd_quic, introduz estruturas de dados e algoritmos otimizados para garantir uma alocação mínima de memória e evitar seu esgotamento.

A pilha de rede personalizada do Firedancer está no centro de suas capacidades de processamento. Ela foi projetada do zero para aproveitar o receive-side scaling (RSS). RSS é uma forma de balanceamento de carga de rede acelerado por hardware que distribui o tráfego entre vários núcleos de CPU para aumentar o paralelismo do processamento de rede. Cada núcleo da CPU processa uma parte do tráfego recebido com o mínimo de sobrecarga. Essa abordagem supera o balanceamento de carga tradicional baseado em software porque elimina a necessidade de agendadores complexos, bloqueios e operações atômicas.

O Firedancer apresenta um novo framework de troca de mensagens para compor uma aplicação formada por tiles de alto desempenho. Esses tiles podem contornar a pilha de rede do kernel, que é limitada por sua natureza baseada em sockets, usando AF_XDP. AF_XDP é uma família de endereços otimizada para o processamento de pacotes de alto desempenho. O uso de AF_XDP permite que o Firedancer leia diretamente dos buffers da interface de rede.

Esse sistema de tiles viabiliza vários conceitos de computação de alto desempenho na pilha do Firedancer. Entre eles estão:

  • Compatibilidade com NUMA - NUMA (acesso não uniforme à memória) é um design de memória de computador no qual um processador pode acessar sua própria memória mais rapidamente do que a memória associada a outro processador. Para o Firedancer, ser compatível com NUMA significa que o cliente pode gerenciar a memória com eficiência em configurações com vários processadores. Isso é importante para o processamento de grandes volumes de transações, pois otimiza o uso dos recursos de hardware disponíveis.
  • Localidade de cache - Localidade de cache se refere ao uso de dados que já estão em um cache próximo ao processador. Normalmente, ela é uma forma complexa de localidade temporal (ou seja, dados acessados recentemente). No Firedancer, o foco na localidade de cache significa que ele foi projetado para processar dados de rede minimizando a latência e maximizando a velocidade.
  • Concorrência sem bloqueio - Concorrência sem bloqueio se refere ao desenvolvimento de algoritmos que não exigem mecanismos de bloqueio, como mutexes, para gerenciar operações simultâneas. Para o Firedancer, a concorrência sem bloqueio permite que várias operações de rede ocorram em paralelo sem atrasos causados por bloqueios. Ela amplia a capacidade do Firedancer de processar simultaneamente um grande número de transações.
  • Páginas de memória grandes - Usar páginas grandes no gerenciamento de memória ajuda a lidar com conjuntos de dados ao reduzir as consultas às tabelas de páginas e a possível fragmentação da memória. Para o Firedancer, isso significa maior eficiência no gerenciamento da memória. Esse recurso é benéfico para processar grandes volumes de dados de rede.

Sistema de compilação

O sistema de compilação do Firedancer foi projetado com um conjunto de princípios orientadores para garantir confiabilidade e consistência. Ele prioriza a redução das dependências externas e trata como dependências todas as ferramentas envolvidas no próprio processo de compilação. Isso inclui fixar cada dependência, inclusive os compiladores, em versões exatas. Um aspecto fundamental desse sistema é o isolamento do ambiente durante as etapas de compilação. O isolamento do ambiente aumenta a portabilidade, pois o processo de compilação não é afetado pelo ambiente do sistema.

Como o Firedancer é tão rápido?

Paralelismo avançado de dados

A abordagem do Firedancer para tarefas criptográficas, como a verificação de assinaturas ED25519, usa o paralelismo avançado de dados disponível nos processadores modernos. CPUs modernas têm instruções de Instrução Única, Múltiplos Dados (SIMD) para processar vários elementos de dados simultaneamente, além de otimizações para executar várias instruções por ciclo de CPU. Em geral, é mais eficiente em termos de área, tempo e energia fazer com que uma única instrução opere em paralelo sobre um array ou vetor de elementos de dados. Nesse aspecto, as melhorias no processamento paralelo de dados podem ter um impacto maior no throughput do que os avanços na velocidade bruta de processamento.

Uma das áreas em que o Firedancer usa o paralelismo de dados é a otimização do cálculo de verificações de assinatura. Essa abordagem permite processar arrays ou vetores de elementos de dados simultaneamente para maximizar o throughput e minimizar a latência. No centro dessa implementação do ED25519 está a aritmética de Campos de Galois. Essa forma de aritmética é adequada para algoritmos criptográficos e cálculos binários. Nos Campos de Galois, operações como adição, subtração, multiplicação e divisão são definidas de maneira compatível com a natureza binária dos sistemas computacionais. Veja um exemplo de Campo de Galois definido por 23:

O único problema é que o ED25519 usa um Campo de Galois definido por 2255-19. Pense nos elementos do campo como números de 0 a 2255-19. Estas são as operações básicas:

  • x + y → adição convencional mod 2255-19
  • x - y → subtração convencional mod 2255-19
  • x * y → multiplicação convencional mod 2255-19
  • 1/x → x elevado a 2255-21 mod 2255-19

Adição, subtração e multiplicação são quase operações matemáticas com uint256_t (ou seja, operações com inteiros sem sinal, em que o maior valor é 2256-1). A divisão é difícil de calcular. CPUs e GPUs comuns não executam operações com uint256_t, muito menos “quase operações com uint256_t” e, menos ainda, uma divisão incomum e extremamente difícil. Implementar esse tipo de cálculo com alto desempenho depende de quão bem conseguimos emulá-lo.

A implementação do Firedancer decompõe a aritmética ao tratar os números de forma mais flexível. Se aplicarmos os princípios da divisão longa e da multiplicação longa ensinadas na escola, em que transportamos números de uma coluna para a seguinte, podemos processar essas colunas em paralelo. A maneira mais rápida de emular esse tipo de cálculo é representar um uint256_t como seis dígitos de 43 bits, com um “vai um” de 9 bits. Isso permite usar as operações existentes de 64 bits nas CPUs, mantendo espaço suficiente para os bits de transporte. Essa organização dos números reduz a necessidade de propagação frequente do transporte e permite que o Firedancer processe números grandes com mais eficiência.

Essa implementação aproveita o paralelismo de dados reorganizando os cálculos aritméticos em somas de colunas paralelizadas. Processar as colunas em paralelo acelera o cálculo como um todo, pois transforma um gargalo sequencial em uma tarefa paralelizável. O Firedancer também usa conjuntos de instruções vetorizadas, como o AVX512 e sua extensão IFMA (AVX512-IFMA). Esses conjuntos permitem processar a aritmética de Campos de Galois explicada acima, aumentando a velocidade e a eficiência.

A implementação acelerada por AVX512 do Firedancer é rápida. Em um único núcleo de servidor Icelake de 2,3 GHz, seu desempenho por clock de núcleo é mais que o dobro do apresentado na demonstração do Breakpoint 2022. A implementação oferece 100% de utilização das vias vetoriais e uma enorme paralelização de dados. Esta é mais uma demonstração magistral da equipe do Firedancer de que, devido aos atrasos impostos pela velocidade da luz, é muito mais fácil executar tarefas independentes em paralelo do que fazer uma coisa de cada vez, mesmo usando hardware personalizado.

Uso de FPGAs para comunicações de rede em alta velocidade

As CPUs conseguem processar ~30.000 verificações de assinatura por segundo por núcleo. Embora sejam uma opção energeticamente eficiente, não atendem às necessidades de operações em grande escala. Essa limitação decorre de sua abordagem de processamento sequencial. As GPUs elevam essa capacidade para ~1 milhão de verificações por segundo por núcleo. No entanto, são prejudicadas pelo alto consumo de energia, em torno de ~300 W por unidade, e pela latência inerente ao processamento em lote.

As FPGAs surgem como a melhor alternativa. Elas alcançam o mesmo throughput das GPUs, mas com consumo de energia significativamente menor: cerca de 50 W por FPGA. Sua latência também fica abaixo dos dez milissegundos das GPUs. As FPGAs oferecem uma solução muito mais responsiva para processamento em tempo real, com latência de ~200 microssegundos. Ao contrário do processamento em lote das GPUs, as FPGAs no Firedancer processam cada transação individualmente e em streaming. O uso de FPGAs pelo Firedancer resulta em um impressionante throughput de 8 milhões de assinaturas por segundo, com um orçamento de energia inferior a 400 W para 8 FPGAs.

A equipe apresentou o processo de verificação de assinaturas ED25519 do Firedancer no Breakpoint 2022. Esse processo envolveu várias etapas, incluindo o cálculo de SHA-512 em um pipeline RTL puro, com diversas verificações e cálculos em um pipeline de processador ECC-CPU personalizado. Em resumo, a equipe do Firedancer escreveu um compilador e um assembler para seu processador personalizado, usou o código Python do RFC (Request for Comments), executou-o com objetos com sobrecarga de operadores para gerar código de máquina e, então, colocou esse código de máquina sobre a ECC-CPU.

É importante observar que o Firedancer usa um formato de acelerador da AWS para equilibrar robustez e conectividade de rede. Essa escolha resolve os desafios associados à conectividade direta com a rede, um recurso frequentemente limitado pelos provedores de nuvem. Assim, o Firedancer garante a integração fluida de seus recursos avançados dentro das restrições da infraestrutura baseada em nuvem.

É essencial reconhecer que diferentes operações exigem espaço físico real, não apenas espaço conceitual para dados. O Firedancer aplica esse entendimento organizando estrategicamente os componentes físicos para que fiquem próximos e possam ser reutilizados. Essa configuração permite maximizar a eficiência da FPGA, alcançando 8 milhões de TPS com uma FPGA de 7 anos em uma máquina de 8 anos.

Otimização da codificação Reed-Solomon para comunicações de rede

O desafio fundamental das comunicações de rede é transmitir novas transações para o mundo todo. A natureza ponto a ponto da Internet, a largura de banda finita e os problemas de latência limitam a implementação de ideias tradicionais, como o uso da rede para transmissão direta. Distribuir dados em uma estrutura de anel ou árvore resolve parcialmente esses problemas, mas ainda é insuficiente, pois pacotes de dados podem ser perdidos durante a transmissão.

A codificação Reed-Solomon é uma solução elegante para esses problemas. Ela introduz redundância na transmissão de dados, ou seja, informações de paridade, para recuperar pacotes perdidos. O conceito se baseia no princípio de que dois pontos definem uma reta e de que quaisquer dois pontos dessa reta podem regenerar os pontos de dados originais. Ao construir um polinômio baseado nos pontos de dados e distribuir diferentes pontos dessa função em pacotes separados, é possível reconstruir os dados originais, desde que o destinatário receba pelo menos dois pacotes.

Construímos um polinômio porque usar a fórmula tradicional para pontos em uma reta (y = mx + b) é computacionalmente lento. O Firedancer usa Polinômios de Lagrange, um método especializado de construção de polinômios, para acelerar o processo. Eles simplificam a criação do polinômio necessário à codificação Reed-Solomon. Isso também transforma o processo em um produto matriz-vetor mais eficiente, que funciona com polinômios de ordem superior. Essa matriz é altamente estruturada, com padrões que se repetem recursivamente, de modo que a primeira linha desse padrão a determina por completo. Essa estrutura permite multiplicar tudo mais rapidamente. O Firedancer usa uma abordagem O(n log n) apresentada em um artigo de 2016 para multiplicar por essa matriz, a abordagem teórica mais rápida conhecida para a codificação Reed-Solomon. O resultado é um cálculo eficiente das informações de paridade em comparação com os métodos tradicionais:

  • Mais de ~120 Gbps/núcleo na codificação RS
  • Até ~50 Gbps/núcleo na decodificação RS
  • Todas essas métricas são comparadas aos atuais ~8 Gbps/núcleo da codificação RS (rust-rse)

Com essa abordagem otimizada da codificação Reed-Solomon, o Firedancer consegue calcular a paridade 14 vezes mais rápido que os métodos tradicionais. Isso resulta em um processo rápido e confiável de codificação e decodificação de dados, essencial para manter alto throughput e baixa latência em escala global.

Como o Firedancer é protegido?

Oportunidades

Atualmente, todos os validadores usam software baseado no cliente validador original. O Firedancer pode melhorar a diversidade de clientes e da cadeia de suprimentos da Solana se for diferente do cliente da Solana Labs. Isso inclui o uso de dependências semelhantes e de Rust para desenvolver seu cliente.

Os clientes validadores da Solana Labs e da Jito são executados como um único processo. É difícil adicionar segurança a uma aplicação monolítica depois que ela entra em produção. Os validadores que executam esses clientes precisariam ser desligados para receber atualizações de segurança em tempo real feitas exclusivamente em Rust. Com seu novo cliente, a equipe do Firedancer pode criar uma arquitetura segura desde o início.

O Firedancer também tem a vantagem de aprender com a experiência. A Solana Labs desenvolveu o cliente validador em um ambiente de startup. Nesse ambiente acelerado, a Labs precisou agir rapidamente para lançar o produto no mercado. Isso criou condições desfavoráveis para o desenvolvimento futuro. A equipe do Firedancer pode analisar o que a Labs e as equipes de outras redes fizeram e perguntar o que fariam de outra forma se pudessem desenvolver um cliente validador do zero.

Desafios

Apesar de ser diferente do cliente da Solana Labs, o Firedancer precisa reproduzir fielmente seu comportamento. Caso contrário, pode surgir um problema de segurança, pois a incompatibilidade pode introduzir bugs de consenso. Esse risco pode ser mitigado incentivando uma porcentagem do stake a operar nos dois clientes e mantendo o Firedancer abaixo de 33% do stake total por um período prolongado. De qualquer forma, a equipe do Firedancer precisa implementar todos os recursos do protocolo, independentemente da dificuldade para fazer isso de forma correta ou segura. Tudo precisa estar alinhado ao Firedancer. Portanto, a equipe não pode desenvolver o código de forma isolada e precisa analisá-lo em relação às funcionalidades do cliente da Labs. A falta de especificações e documentação agrava o problema e obriga o Firedancer a introduzir construções ineficientes vindas do protocolo.

A equipe do Firedancer também precisa estar ciente de que está desenvolvendo seu novo cliente em C. C não oferece nativamente as garantias de segurança de memória de linguagens como Rust. Um dos principais objetivos da base de código do Firedancer é reduzir a ocorrência e o impacto das vulnerabilidades de segurança de memória. Esse objetivo exige atenção especial porque o Firedancer é um projeto que avança rapidamente. O Firedancer precisa encontrar uma forma de manter a velocidade de desenvolvimento sem introduzir esses bugs. O sandboxing de OS é a prática de isolar os tiles do OS. Os tiles só podem acessar os recursos e realizar as chamadas de sistema necessárias para suas funções. Como os tiles têm finalidades claramente definidas e a equipe do Firedancer desenvolveu a maior parte do código do cliente, as permissões de cada tile são reduzidas de acordo com o Princípio do Menor Privilégio.

Implementação de um design de defesa em profundidade

Todo software terá uma vulnerabilidade de segurança em algum momento. Partindo da premissa de que o software terá bugs, o Firedancer opta por limitar o impacto potencial de cada vulnerabilidade. Essa abordagem é chamada de defesa em profundidade. A defesa em profundidade é uma estratégia que usa várias medidas de segurança para proteger um ativo. Se um invasor comprometer uma parte do sistema, outras medidas impedem que a ameaça afete toda a stack. O Firedancer foi projetado para criar barreiras entre as etapas de vulnerabilidade e exploração. Por exemplo, seria difícil para um invasor explorar uma vulnerabilidade de segurança de memória.

Isso ocorre porque a prevenção desse tipo de ataque é um problema amplamente estudado. As extensas pesquisas sobre segurança de memória em C resultaram em um arsenal de técnicas de proteção e recursos de compilador que a equipe usa no Firedancer. Mesmo que um invasor conseguisse contornar as melhores práticas do setor, seria difícil para a exploração comprometer o sistema. Isso se deve ao isolamento dos tiles e ao sandboxing do OS.

O isolamento dos tiles é resultado da arquitetura paralela do Firedancer. Cada tile tem uma única finalidade bem definida, pois executa seu próprio processo Linux. Por exemplo, um tile de QUIC é responsável por processar o tráfego QUIC recebido e encaminhar as transações encapsuladas para o tile de verificação. Depois, o tile de verificação é responsável por verificar as assinaturas. A comunicação entre os tiles de QUIC e de verificação ocorre por uma interface de memória compartilhada, ou seja, os processos Linux podem transferir dados entre si. Essa interface de memória compartilhada entre dois tiles funciona como um limite de isolamento. Se o tile de QUIC tivesse um bug que permitisse a um invasor executar código arbitrário durante o processamento de um pacote QUIC malicioso, nenhum outro tile seria afetado. Em um processo monolítico, isso causaria um comprometimento imediato. Um invasor poderia prejudicar toda a rede se explorasse essa vulnerabilidade em vários validadores. Ele talvez conseguisse reduzir o desempenho do tile de QUIC, mas o design do Firedancer limitaria sua ação somente a esse tile.

O sandboxing de OS é a prática de isolar os tiles do OS. Os tiles só podem acessar os recursos e realizar as chamadas de sistema necessárias para suas funções. Como os tiles têm finalidades claramente definidas e quase todo o código foi desenvolvido pela equipe do Firedancer, as permissões de cada tile são reduzidas de acordo com o Princípio do Menor Privilégio. Os tiles são colocados em seus próprios namespaces do Linux, o que fornece uma visão limitada do sistema. Essa visão restrita impede que um tile acesse a maior parte do sistema de arquivos, a rede e qualquer outro processo em execução no mesmo sistema. Os namespaces criam um limite que prioriza a segurança. No entanto, ele ainda pode ser contornado se um invasor tiver um exploit do kernel para elevar privilégios. A interface de chamadas de sistema é o último vetor de ataque no kernel que pode ser acessado pelos tiles. Como proteção, o Firedancer usa o seccomp-BPF para filtrar as chamadas de sistema antes que o kernel as processe. O cliente pode restringir os tiles a um grupo selecionado de chamadas de sistema. Em alguns casos, os parâmetros das syscalls podem ser filtrados. Isso é importante porque o Firedancer pode garantir que as syscalls de leitura e gravação operem apenas em descritores de arquivo específicos.

Implementação de um programa de segurança integrado

O Firedancer foi projetado com um programa de segurança abrangente, incorporado a todas as etapas de seu desenvolvimento. O programa de segurança do cliente é uma colaboração contínua entre as equipes de desenvolvimento e segurança, estabelecendo um novo padrão para a tecnologia blockchain segura.

O processo começa com uma infraestrutura de fuzzing de autosserviço. Como observação, fuzzing é uma técnica que detecta automaticamente falhas ou condições de erro indicativas de vulnerabilidades. Isso é feito por meio de testes de estresse em todos os componentes que aceitam entradas de usuário não confiáveis, incluindo a interface P2P (parsers) e a máquina virtual SBPF. O OSS-Fuzz mantém uma cobertura contínua de fuzzing durante as alterações no código. A equipe de segurança também configurou uma instância dedicada do ClusterFuzzer para fuzzing contínuo orientado por cobertura. Desenvolvedores e engenheiros de segurança também contribuem com estruturas de fuzzing, ou seja, versões especiais de testes unitários para componentes críticos de segurança. Os desenvolvedores também podem contribuir com novos testes de fuzzing, que são coletados e executados automaticamente. O objetivo é submeter todas as partes a fuzzing intensivo antes que avancem para a próxima etapa.

As revisões internas de código ajudam a identificar bugs que as ferramentas não detectaram. Nessa etapa, o foco está nos componentes de alto risco e grande impacto. Essa etapa funciona como um mecanismo de feedback para o restante do programa de segurança. A equipe aplica tudo o que aprendeu e usa essas revisões para melhorar a cobertura de fuzzing, introduzir novas verificações de análise estática para determinadas classes de bugs e até mesmo realizar grandes refatorações no código para eliminar vetores de ataque complexos por meio do design. Revisões externas de segurança conduzidas pelos principais especialistas do setor e um programa ativo de recompensas por bugs complementarão essas revisões internas antes e depois do lançamento.

O Firedancer também passou por extensos testes de estresse em várias redes de teste. Essas redes de teste serão submetidas a ataques e falhas, como duplicação de nodes, falhas em links de rede, inundações de pacotes e violações de consenso. Essas redes enfrentam cargas significativamente maiores do que qualquer cenário realista na mainnet.

Isso nos leva à seguinte pergunta: qual é o status atual do Firedancer?

Qual é o status atual do Firedancer e o que é o Frankendancer?

A equipe do Firedancer está desenvolvendo o Firedancer de forma incremental para modularizar o cliente validador. Isso está alinhado aos seus objetivos de documentação e padronização. Essa abordagem garante que o Firedancer acompanhe os avanços mais recentes da Solana. Isso levou à criação do Frankendancer. O Frankendancer é um modelo de cliente híbrido no qual a equipe do Firedancer integra os componentes desenvolvidos à infraestrutura existente do cliente validador. Esse processo de desenvolvimento permite melhorar e testar novos recursos gradualmente.

O Frankendancer é como colocar um carro esportivo no meio do trânsito. O desempenho aumentará à medida que mais componentes forem desenvolvidos e os gargalos forem removidos. Esse processo modular de desenvolvimento promove um ambiente de validadores personalizável e flexível. Nele, os desenvolvedores podem modificar ou substituir componentes específicos do cliente validador de acordo com suas necessidades.

O que está realmente em execução?

O Frankendancer implementa todos os recursos de rede de um validador da Solana:

  • Entrada: QUIC, TPU, Sigverify, Dedup
  • Saída: empacotamento de blocos e criação/assinatura/envio de shreds (Turbine)

O Frankendancer usa o código de rede de alto desempenho em C do Firedancer sobre o runtime e o código de consenso em Rust da Solana Labs.

A arquitetura do Frankendancer foi projetada com foco na otimização para hardware avançado. Embora ofereça suporte a hosts básicos e comuns na nuvem que executam sistemas operacionais Linux padrão, a equipe do Firedancer está otimizando o Frankendancer para servidores com muitos núcleos. O objetivo de longo prazo é aproveitar o hardware já disponível na nuvem para aumentar a eficiência e o desempenho. O cliente aceita várias conexões simultâneas, aceleração por hardware, direcionamento aleatório de fluxos para distribuição de carga, ou seja, para garantir que o tráfego de rede seja distribuído uniformemente, e diversos limites de processo para aumentar a segurança entre os componentes.

A eficiência técnica é um dos pilares do Frankendancer. O sistema evita alocações de memória e operações atômicas no caminho crítico, e todas as alocações são otimizadas para NUMA durante a inicialização. Esse design garante o máximo de eficiência e desempenho. Além disso, a capacidade de inspecionar componentes do sistema de forma assíncrona e remota, combinada com a flexibilidade para gerenciar tiles — iniciá-los, interrompê-los e reiniciá-los de modo assíncrono —, adiciona robustez e adaptabilidade ao sistema.

Qual é o nível de desempenho?

O Frankendancer consegue processar 1.000.000 de transações por segundo (TPS) por tile no lado de entrada da rede. Esse desempenho aumenta linearmente com o número de núcleos usados, pois cada tile utiliza 1 núcleo de CPU. O Frankendancer alcançou esse resultado usando apenas quatro núcleos e esgotando a capacidade de uma placa de interface de rede (NIC) de 25 Gbps.

O Frankendancer trouxe melhorias significativas às operações de saída da rede com suas otimizações do Turbine. Atualmente, o hardware padrão de um node alcança uma velocidade de 6 Gbps por tile. Isso inclui ganhos substanciais de velocidade no processo de shredding, ou seja, na divisão e no envio dos dados de blocos pela rede aos validadores. Em comparação com os nodes padrão atuais da Solana, o Frankendancer apresenta um aumento de ~22% na velocidade de shredding sem árvores de Merkle e quase o dobro com árvores de Merkle. Essa é uma enorme melhoria em relação ao desempenho atual de propagação de blocos e ingestão de transações dos validadores.

O desempenho de rede do Firedancer demonstra que ele atingiu o limite do hardware. Ele alcançou o máximo desempenho possível com o hardware padrão usado hoje pelos validadores. Isso representa um importante marco técnico e demonstra a capacidade do cliente de processar cargas extremas com eficiência e eficácia.

Frankendancer está ativo na testnet

Atualmente, o Frankendancer tem stake, vota e produz blocos na testnet. Ele coexiste de forma compatível com cerca de ~2.900 outros validadores da Solana Labs e da Jito. Essa implantação ativa demonstra o desempenho robusto do Firedancer em hardware comum. No momento, ele está em um servidor Equinix Metal m3.large.x86 equipado com uma CPU AMD EPYC 7513. Muitos outros validadores usam o mesmo tipo de servidor. Ele oferece uma solução econômica com preços sob demanda que variam conforme a localização. As tarifas vão de US$ 3,10 a US$ 4,65 por hora.

O progresso do Firedancer rumo ao lançamento na mainnet abre várias possibilidades para o hardware dos nodes:

  • O hardware atual dos validadores pode oferecer uma capacidade de desempenho muito maior por node
  • A eficiência do Firedancer permite que os validadores usem hardware mais acessível e com especificações inferiores, mantendo níveis semelhantes de desempenho
  • O design do Firedancer permite aproveitar os avanços em hardware e largura de banda

Esses avanços, junto a outras iniciativas como o Wiredancer, ou seja, os experimentos da equipe do Firedancer com aceleração por hardware, e um Runtime/SVM modular baseado em Rust, posicionam o Firedancer como uma solução preparada para o futuro.

O progresso do Firedancer também abre discussões sobre a possibilidade de os validadores executarem o cliente da Solana Labs junto ao Firedancer em um processo conhecido como side-caring. Essa abordagem poderia maximizar a atividade da rede ao aproveitar os pontos fortes dos dois clientes e reduzir o possível impacto de problemas em qualquer um deles sobre a rede como um todo. Além disso, também gera especulações sobre a possibilidade de projetos como a Jito criarem um fork do Firedancer. Isso poderia resultar em novas otimizações na extração de MEV e na eficiência do processamento de transações. Só o tempo dirá.

Conclusão

Os desenvolvedores normalmente conceituam as operações como ocupando espaço de dados, e não espaço físico. Com a velocidade da luz como uma limitação natural, essa suposição resulta em sistemas lentos que não otimizam corretamente o hardware. Em um cenário altamente competitivo e adversarial, não podemos simplesmente adicionar mais hardware à Solana e esperar um desempenho melhor. Precisamos otimizar. Firedancer revoluciona a estrutura e a operação esperada dos clientes validadores. Ao desenvolver um cliente validador confiável, altamente modular e eficiente, a equipe do Firedancer prepara a Solana para a adoção em massa.

Seja você um desenvolvedor iniciante ou um usuário comum da Solana, é fundamental entender o Firedancer e sua importância. Esse feito tecnológico torna ainda melhor a blockchain mais rápida e eficiente atualmente disponível no mercado. A Solana foi projetada para ser uma máquina de estados global de alto throughput e baixa latência. Firedancer representa um enorme avanço rumo ao aperfeiçoamento desses objetivos.

Se você leu até aqui, agradecemos, anon! Insira seu endereço de e-mail abaixo para nunca perder uma atualização sobre as novidades da Solana. Quer se aprofundar? Entre no nosso Discord e comece hoje mesmo a construir o futuro na blockchain de maior desempenho.

Recursos adicionais / Leituras complementares

Apêndice

Introdução ao hardware de computadores e às redes

Um computador é uma máquina que pode ser programada para executar automaticamente sequências de operações aritméticas ou lógicas. Essas operações vão desde a automação de cálculos básicos até o processamento complexo de dados. Em sua essência, um computador combina componentes de hardware e software para executar instruções e gerenciar dados. O hardware compreende os componentes físicos, enquanto o software inclui os programas e sistemas operacionais que instruem o hardware sobre como funcionar.

A computação útil geralmente envolve quatro recursos: processamento, memória, armazenamento em disco e rede. O processamento, realizado principalmente por CPUs, GPUs e possivelmente FPGAs, é extremamente rápido e capaz de executar bilhões de operações por segundo. O acesso à RAM geralmente é mais lento do que executar um cálculo na CPU. O armazenamento em disco oferece uma solução de longo prazo útil para a computação. No entanto, acessar dados em unidades de estado sólido (SSDs) e unidades de disco rígido (HDDs) é muito mais lento do que executar operações na CPU. SSDs costumam ser milhares de vezes mais lentos, enquanto HDDs são dezenas de milhares de vezes mais lentos. Além disso, a rede, incluindo a Internet e as redes locais, é o recurso mais lento. Ela pode ser mais de um milhão de vezes mais lenta do que a CPU.

Entender essas diferenças de velocidade é essencial para compreender os princípios de design e as considerações de eficiência em aplicações de computação de alto desempenho, como o Firedancer. A velocidade de cálculo da CPU define a referência, enquanto a memória, o armazenamento em disco e o acesso à rede adicionam, cada um, uma camada de atraso em ordem decrescente de velocidade.

Unidade Central de Processamento (CPU)

A CPU, ou Unidade Central de Processamento, é a base do funcionamento de um computador — ela é o cérebro da máquina. A CPU executa instruções de software, realiza cálculos e toma decisões com base nos dados recebidos. Ela funciona processando sinais binários, que são sequências de zeros e uns. Cada sequência exclusiva de códigos binários corresponde a uma instrução específica que a CPU interpreta e executa. Essas instruções são processadas sequencialmente: a CPU conclui uma operação antes de passar para a próxima. Esse processamento sequencial de instruções é fundamental para a função da CPU e determina como ela realiza cálculos complexos e toma decisões com base nos dados recebidos.

As CPUs modernas geralmente têm vários núcleos. Isso significa que elas contêm várias unidades de processamento, conhecidas como núcleos, em um único chip. Cada núcleo pode executar instruções de forma independente, permitindo o processamento paralelo de tarefas. A arquitetura multinúcleo aumenta a capacidade da CPU de executar operações simultaneamente, melhorando significativamente o desempenho geral. No entanto, é importante observar que, dentro de cada núcleo, as operações ainda são processadas sequencialmente. Isso torna as CPUs adequadas para tarefas complexas e sequenciais, mas ineficientes para grandes volumes de tarefas paralelas mais simples.

As CPUs também têm caches — pequenas unidades de memória de alta velocidade dentro da CPU. Esses caches armazenam dados e instruções acessados com frequência, permitindo recuperá-los mais rapidamente do que ao buscar dados na RAM. Normalmente, há vários níveis de cache (L1, L2, L3 e, às vezes, L4), cada um com tamanhos e velocidades diferentes. O cache L1, por ser o menor e mais rápido, é acessado primeiro. Se os dados necessários não forem encontrados nele, a CPU verifica o cache L2, maior e um pouco mais lento, e assim por diante. Esse sistema hierárquico de cache reduz o tempo que a CPU espera por dados da RAM e aumenta a velocidade geral de processamento. O uso eficiente do cache tem implicações profundas para uma aplicação como o Firedancer, em que a distância entre a CPU e a RAM pode prejudicar o desempenho. Isso é especialmente relevante para nossa discussão sobre a velocidade da luz e o uso de FPGAs.

Como observação, o termo “x86” refere-se a uma família de CPUs que segue uma arquitetura específica desenvolvida inicialmente pela Intel. Essa arquitetura é conhecida por sua compatibilidade com uma ampla variedade de softwares, pois a maioria dos computadores desktop e notebooks vendidos é baseada na família de arquiteturas x86.

Unidade de Processamento Gráfico (GPU)

A GPU é um processador especializado, desenvolvido inicialmente para acelerar a renderização de imagens e vídeos em computação gráfica. Sua principal função é gerenciar e aprimorar o desempenho gráfico, especialmente em tarefas que exigem elementos visuais de alta resolução e cálculos gráficos complexos, como videogames ou modelagem 3D.

Com o tempo, a GPU evoluiu para além de sua finalidade original. Devido à sua arquitetura, as GPUs tornaram-se fundamentais para uma variedade maior de tarefas de processamento de dados. Sua capacidade de processamento paralelo eficiente as torna adequadas para aplicações que precisam lidar simultaneamente com grandes conjuntos de dados. Na tecnologia blockchain, GPUs são amplamente utilizadas na mineração de criptomoedas. Elas se destacam nessa função porque conseguem processar cargas de trabalho paralelas de cálculos criptográficos com mais eficiência do que uma CPU.

Memória de Acesso Aleatório (RAM)

A RAM é a memória de curto prazo de um computador e armazena dados que estão sendo usados ou processados ativamente. É nela que a CPU “lembra” no que está trabalhando no momento e mantém informações relevantes para rápido acesso e processamento.

A RAM com código de correção de erros (ECC) consegue detectar e corrigir tipos comuns de corrupção interna de dados. Esse recurso é essencial em ambientes nos quais a precisão dos dados é importante, como computação científica, transações financeiras ou nós de blockchain. A RAM ECC pode identificar e corrigir automaticamente pequenos erros nos dados armazenados. Esse processo de correção de erros é realizado por hardware adicional nos módulos de RAM, que verifica os dados armazenados.

A RAM não ECC é o tipo de memória mais usado em computadores comuns e dispositivos de consumo. Embora não tenha os recursos de correção de erros da RAM ECC, ela geralmente é mais rápida e barata. A RAM não ECC é a opção preferida para uso geral devido ao seu custo-benefício e ao risco relativamente baixo de erros de dados na computação desktop convencional.

Armazenamento em disco

O armazenamento em disco é responsável pela retenção de dados em longo prazo, mesmo quando o computador está desligado. Há dois tipos principais de armazenamento em disco: unidades de disco rígido (HDDs) e unidades de estado sólido (SSDs).

HDDs são unidades de disco mais antigas que armazenam dados em discos magnéticos conhecidos como pratos. Os pratos são combinados com cabeças magnéticas, geralmente presas a um braço atuador móvel. Uma cabeça de leitura e gravação nesse braço acessa os dados enquanto o disco gira. A natureza mecânica dos HDDs — discos giratórios e cabeças móveis — os torna relativamente mais lentos do que os SSDs. No entanto, eles oferecem maior capacidade de armazenamento por um preço menor. Isso os torna econômicos para o armazenamento em massa.

Por outro lado, SSDs usam memória flash para armazenar dados. A memória flash é uma solução eletrônica de armazenamento não volátil que pode ser apagada e reprogramada. O uso de memória flash significa que, ao contrário dos HDDs, não há peças móveis. Em vez disso, chips de memória flash interconectados armazenam os dados. SSDs são mais rápidos do que HDDs porque podem acessar os dados instantaneamente, sem esperar um disco girar ou uma cabeça de leitura e gravação localizar os dados. Essa velocidade torna os SSDs uma excelente opção para aplicações em que a rápida recuperação de dados é crucial. No entanto, essa velocidade tem um custo por gigabyte maior do que o dos HDDs.

Também existem SSDs NVMe (Non-Volatile Memory Express). Esses SSDs foram projetados para explorar seu potencial de alta velocidade por meio do barramento Peripheral Component Interconnect Express (PCIe) de um computador. Unidades NVMe oferecem velocidades significativamente maiores e latência menor do que SSDs tradicionais. Elas são ideais para cargas de trabalho intensivas, como negociação de alta frequência e aplicações de blockchain, nas quais o rápido processamento e a recuperação de dados são essenciais. Embora unidades NVMe tenham um preço elevado, elas estão começando a se tornar o padrão da computação de alto desempenho.

Placa-mãe

Fonte: Diagrama de uma Gigabyte X570 Elite em uma publicação do Reddit no r/buildapc

A placa-mãe de um computador é uma grande placa de circuito que interconecta os componentes da máquina e permite a comunicação entre eles. Esses componentes incluem CPU, GPU, RAM, dispositivos de armazenamento e periféricos, como teclados e mouses.

A placa-mãe é o núcleo central de atividade. Ela garante que cada componente possa se comunicar de forma eficiente com os demais. Também é essencial para a distribuição de energia, direcionando a eletricidade da fonte de alimentação para cada componente principal. A placa-mãe garante que cada componente receba a energia adequada para funcionar.

A placa-mãe é responsável por gerenciar o fluxo de dados dentro do sistema. Ela supervisiona o encaminhamento dos dados da CPU para a RAM, onde são processados; da RAM para os dispositivos de armazenamento, onde são salvos; e da GPU para as saídas de vídeo, onde são renderizados. Além disso, a placa-mãe também abriga o BIOS (Sistema Básico de Entrada/Saída) do sistema. O BIOS é fundamental para o controle e o monitoramento do sistema. Ele inicializa e testa o hardware de um computador durante a inicialização. Também acompanha a integridade do sistema, monitorando fatores como temperatura, tensão e velocidade das ventoinhas.

No contexto do design do Firedancer, a arquitetura da placa-mãe desempenha um papel central. A proximidade entre a CPU e a RAM afeta significativamente o desempenho, pois distâncias menores aumentam a velocidade de transferência de dados. Essa distância é essencial para aplicações como o Firedancer, que exigem alto throughput e baixa latência. Por isso, uma arquitetura compatível com NUMA e o possível uso de FPGAs estão alinhados à necessidade do Firedancer de otimizar a alocação de memória e a eficiência de processamento. Mais adiante neste artigo, explicaremos o que significa ser compatível com NUMA e o que são FPGAs.

Sistemas operacionais, máquinas virtuais e otimizações no nível do kernel

Um sistema operacional (SO) é o software central que gerencia o hardware e o software de um computador. Ele atua como intermediário, facilitando as interações entre o usuário e o hardware da máquina. Ele oferece uma interface para os usuários interagirem com o sistema, além de alocar e gerenciar recursos para diversas aplicações. Entre os exemplos mais conhecidos estão Windows, macOS e Linux.

O kernel está no centro de todo sistema operacional. Ele é um componente essencial que interage diretamente com o hardware do sistema. O kernel tem controle total sobre tudo no sistema. Ele gerencia a alocação de memória, o agendamento de processos e as solicitações de entrada e saída. Por operar nesse baixo nível, o kernel desempenha um papel fundamental no desempenho e na estabilidade do sistema.

As chamadas de sistema (syscalls) fazem a interface entre as aplicações do usuário e o kernel. Quando uma aplicação precisa executar uma operação que requer acesso a um recurso do sistema — por exemplo, ler um arquivo ou enviar dados pela rede —, ela faz uma syscall. O kernel então executa a operação solicitada em nome da aplicação. Esse mecanismo garante o acesso controlado aos recursos do sistema para manter sua segurança e estabilidade.

Máquinas virtuais (VMs) são emulações de computadores físicos por software. Elas reproduzem toda a funcionalidade de um computador físico em um ambiente isolado, enquanto operam sobre um hipervisor — ou seja, um tipo de software que cria e gerencia ambientes virtuais em uma máquina host. VMs oferecem as vantagens da segurança por isolamento, da eficiência de recursos e da flexibilidade para testes e desenvolvimento.

Entender esses conceitos é essencial no contexto do Firedancer. Firedancer usa várias otimizações no nível do kernel para melhorar o desempenho:

  • Grande alocação estática: Firedancer minimiza as alocações dinâmicas de memória usando grandes alocações estáticas, ou seja, alocações de memória compartilhada que outros processos podem utilizar. Nesse caso, a memória é alocada uma vez e reutilizada, reduzindo a sobrecarga associada a alocações e desalocações frequentes.
  • Contorno das bibliotecas padrão: As funções de bibliotecas padrão geralmente adicionam camadas extras de abstração e podem ser menos eficientes para determinadas operações. Firedancer contorna essas bibliotecas padrão e faz syscalls diretamente. Abordaremos isso em mais detalhes ao explicar a arquitetura de tiles do Firedancer e como ela otimiza o desempenho da rede.

Firedancer tenta evitar ao máximo syscalls e interações com o SO, pois essas operações tornam as tarefas significativamente mais lentas.

Entrada e saída

Entrada e saída são termos usados para descrever o fluxo de dados que entra e sai de um sistema de computador ou de uma rede.

Entrada refere-se ao ingresso de dados em um sistema. É um termo geral que pode incluir diversas atividades, como receber dados da Internet, aceitar entradas de usuários ou coletar informações de sensores em dispositivos de IoT (Internet das Coisas). Em sistemas de rede, como servidores ou blockchains, a entrada envolve tarefas essenciais, como receber solicitações de transações, consultas de usuários ou fluxos de dados que precisam ser processados ou armazenados. O tratamento eficiente dos dados de entrada é fundamental para a capacidade de resposta e o funcionamento do sistema.

Saída refere-se aos dados que saem de um sistema. Isso inclui enviar informações pela Internet, gerar respostas a solicitações de usuários ou transmitir dados processados para outros sistemas. Em sistemas conectados em rede, a saída envolve enviar transações validadas, transmitir atualizações da blockchain ou enviar dados para locais de armazenamento externos. O gerenciamento adequado dos dados de saída é essencial para disseminar corretamente as informações e garantir que o sistema se comunique de maneira eficiente com outras partes da rede.

Pipelines e paralelismo de dados

Imagine um pipeline como uma linha de montagem em uma fábrica. Ele divide um processo complexo em etapas sequenciais menores. Cada etapa do pipeline executa uma operação específica. Essa abordagem é altamente eficiente para tarefas de processamento repetitivas ou contínuas, assim como uma blockchain processa transações continuamente.

O paralelismo de dados adota uma abordagem diferente ao processar vários elementos simultaneamente, mas de forma independente. É como se a fábrica tivesse mais de uma linha de montagem para processar os dados. Isso é eficiente para tarefas divididas em subtarefas menores. Para blockchains, especialmente em sistemas como o Firedancer, o paralelismo de dados é essencial para lidar simultaneamente com transações ou tarefas de processamento de dados. Os recursos de processamento paralelo do Firedancer maximizam o throughput computacional e reduzem o tempo de processamento.

Imagine cada etapa do pipeline como uma estação de trabalho individual em uma fábrica. Cada estação pode operar de forma independente e simultânea. Isso significa que, enquanto uma etapa processa uma parte dos dados, a etapa seguinte pode trabalhar em outra parte ao mesmo tempo. Essa abordagem permite que várias etapas do pipeline permaneçam ativas simultaneamente, aumentando significativamente o throughput. Firedancer combina a eficiência sequencial dos pipelines com o poder de processamento simultâneo do paralelismo para processar grandes volumes de transações.

Matriz de Portas Programável em Campo (FPGA)

Matrizes de Portas Programáveis em Campo (FPGAs) são circuitos integrados versáteis que podem ser programados ou reconfigurados após a fabricação. Esses circuitos oferecem um nível de adaptabilidade inexistente nos componentes de hardware tradicionais. Eles consistem em uma vasta grade de blocos lógicos programáveis e interconectados, cada um capaz de executar diversas funções digitais. Esse design permite que FPGAs sejam altamente flexíveis e eficientes em aplicações nas quais velocidade, processamento paralelo e adaptabilidade são essenciais.

Uma FPGA típica consiste em pequenos elementos programáveis, todos conectados por fios programáveis. Essa complexa rede de componentes e conexões permite programar diferentes regiões do chip para executar tarefas específicas. Isso cria um ambiente de processamento totalmente personalizado.

FPGAs se destacam no processamento paralelo ao usar simultaneamente esses pequenos elementos programáveis. Sua estrutura viabiliza pipelines eficientes, nos quais os dados percorrem continuamente as etapas de processamento. Um pipeline bem projetado desacopla o throughput do sistema da latência. Embora esse pipeline possa levar mais tempo para produzir uma saída do que uma CPU convencional, o sistema consegue lidar simultaneamente com vários fluxos de dados de entrada. A latência de cada operação tem pouco impacto sobre o fluxo geral de dados, de forma semelhante à água que passa por uma mangueira.

No contexto do Firedancer, FPGAs oferecem uma vantagem significativa. Elas podem conectar pipelines de dados diretamente às redes. FPGAs são mais eficientes para lidar com o tráfego de rede do que configurações tradicionais, nas quais GPUs dependem de CPUs para movimentar dados. A conectividade direta e a capacidade de criar soluções de processamento personalizadas, como implementar processadores soft na malha da FPGA, tornam esses componentes fundamentais para o desenvolvimento de um cliente validador de alto desempenho.

‍

Assine a Helius

Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos

Imagem ampliada