
Uma história completa das interrupções da Solana: causas, correções e lições aprendidas
Índice
- Introdução
- Vivacidade e segurança
- Reinicializações da rede
- Comunicação de bugs
- Casos de interrupção
- Bug no Turbine: dezembro de 2020
- O IDO do Grape Protocol: setembro de 2021
- Um segundo bug: estouro de inteiro
- Congestionamento intenso: janeiro de 2022
- Spam no Candy Machine: abril/maio de 2022
- Taxa para bots do Candy Machine
- Bug de durable nonce: junho de 2022
- Bug de bloco duplicado: setembro de 2022
- Bloco grande sobrecarrega o Turbine: fevereiro de 2023
- Loop infinito de recompilação: fevereiro de 2024
- Patch coordenado de vulnerabilidade: agosto de 2024
- Processo de atualização do patch
- Conclusão
- Outros recursos
Bip, bip, bip. Bip, bip, bip.
O sono de Steven é interrompido pelos toques estridentes do celular, arrancando-o abruptamente de seus sonhos. No escuro, a tela brilha intensamente enquanto o aparelho vibra sem parar sobre a mesa de cabeceira. Bip, bip, bip. Ele resmunga, esfrega os olhos ainda sonolento e pega o aparelho. Ao apertar os olhos para ler a mensagem, sente o coração afundar: o node está fora do ar. Sem hesitar, salta da cama sem terminar de se vestir e tenta desbloquear o celular enquanto mais mensagens chegam. Então ele percebe: todo o cluster está fora do ar.
Nesse exato momento, em diferentes cidades e fusos horários ao redor do mundo, centenas de operadores de nodes olham para seus celulares com a mesma constatação: chegou o momento que temiam — uma interrupção.
Introdução
Como todos os sistemas distribuídos, a Solana opera sob a realidade de que uma única falha de implementação ou um caso extremo obscuro pode causar uma falha em toda a rede. Embora causem transtornos, as interrupções são uma parte inevitável da manutenção de uma infraestrutura distribuída complexa — seja em blockchains descentralizadas, exchanges centralizadas ou até mesmo em grandes provedores de serviços de nuvem, como Amazon ou Microsoft.
A questão não é se ocorrerão falhas, mas quando — e como a rede evoluirá para se adaptar e se fortalecer contra incidentes futuros. Apesar de testes rigorosos em ambientes simulados, uma testnet incentivada e um programa ativo de recompensas por bugs, nenhum sistema — por melhor que seja seu projeto — consegue prever todos os possíveis modos de falha. As lições mais valiosas vêm das operações no mundo real.
Nos últimos cinco anos, a Solana passou por sete incidentes distintos de interrupção, cinco causados por bugs de cliente e dois pela incapacidade da rede de lidar com enxurradas de spam de transações. As primeiras versões da Solana não tinham mecanismos essenciais de gerenciamento de congestionamento, como taxas de prioridade e mercados de taxas locais, que depois se mostraram fundamentais para reduzir o estresse da rede. A ausência desses mecanismos levou a períodos prolongados de desempenho degradado e congestionamento ao longo de 2022, pois a rede essencialmente incentivava o spam.
Este artigo analisará detalhadamente cada interrupção da Solana, examinando as causas fundamentais, os eventos desencadeadores e as medidas tomadas para resolvê-las. Além disso, discutiremos os principais aspectos das reinicializações da rede, da comunicação de bugs e dos conceitos fundamentais de falhas de vivacidade e segurança. Embora seja melhor ler essas seções em ordem, cada uma foi criada para funcionar de forma independente, permitindo que você avance diretamente para os tópicos ou incidentes de interrupção que mais lhe interessam.
Vivacidade e segurança
Segundo o teorema CAP, também conhecido como Teorema de Brewer, um sistema distribuído só pode alcançar duas de três propriedades:
- Consistência - Toda leitura vê todas as gravações anteriores.
- Disponibilidade - Toda solicitação recebe uma resposta.
- Tolerância a partições - O sistema continua operando apesar das partições de rede.
Para blockchains, a tolerância a partições é essencial — interrupções de rede são inevitáveis. Isso exige uma escolha entre AP (Disponibilidade + Tolerância a Partições) e CP (Consistência + Tolerância a Partições). Como a maioria das redes PoS com finalização rápida, a Solana prioriza a consistência em vez da disponibilidade, o que a torna um sistema CP. Ela para durante falhas críticas em vez de fornecer dados desatualizados ou permitir gravações inseguras. Embora isso signifique que o software do node possa entrar em um estado irrecuperável que exija intervenção manual, também garante que os fundos dos usuários permaneçam seguros.
Falha de vivacidade: ocorre quando a blockchain para de avançar, impedindo a confirmação de transações e a produção de blocos devido à indisponibilidade de validadores, partições de rede ou paralisações do consenso. No contexto do teorema CAP, isso corresponde à perda de disponibilidade.
Falha de segurança: ocorre quando o estado finalizado da blockchain é alterado ou bifurcado incorretamente. Isso pode gerar históricos conflitantes ou gastos duplos, geralmente causados por bugs de consenso ou ataques maliciosos. No contexto do teorema CAP, isso corresponde à perda de consistência.
A Solana prioriza a segurança em vez da vivacidade. Portanto, a rede para em casos de estresse extremo ou falha de consenso, em vez de arriscar a corrupção do estado. Embora as interrupções causem transtornos e possam afetar aplicativos, usuários e validadores, elas são preferíveis às consequências catastróficas de um ledger inconsistente ou corrompido.
Reinicializações da rede
Reiniciar a rede Solana envolve identificar o último slot de bloco confirmado de forma otimista e reinicializar os nodes a partir de um snapshot confiável do estado local desse slot. Como o slot de reinicialização não é determinado on-chain, os operadores de validadores precisam chegar a um consenso off-chain para definir um ponto seguro de reversão. Essa coordenação ocorre publicamente no canal #mb-validators do Discord da Solana Tech, onde operadores profissionais de validadores se comunicam em tempo real. A maioria dos operadores tem sistemas automatizados de alerta que os notificam assim que a produção de blocos é interrompida, garantindo uma resposta rápida.
Depois de chegar a um consenso sobre o slot correto para a reinicialização, os operadores usam a ferramenta de ledger para gerar um novo snapshot local, reinicializam seus validadores e aguardam até que pelo menos 80% do stake total volte a ficar online. Só então a rede retoma a produção e a validação de blocos. Verificar se no máximo 20% do stake está offline quando o cluster reinicia garante uma margem de segurança suficiente para que a rede permaneça online caso os nodes criem forks ou voltem a ficar offline logo após a reinicialização.
Comunicação de bugs
Programas de recompensas por bugs remuneram pesquisadores de segurança por identificar e comunicar vulnerabilidades de software. Essa é uma linha de defesa essencial, pois incentiva proativamente a detecção de bugs antes que possam ser explorados. Pesquisadores de segurança e desenvolvedores que identificarem possíveis vulnerabilidades no cliente Agave são incentivados a comunicá-las pelos canais de segurança apropriados. As diretrizes detalhadas de divulgação estão disponíveis no repositório do Agave no GitHub.
Relatos válidos de vulnerabilidades críticas recebem recompensas, com valores definidos conforme a gravidade:
- Perda de fundos: até 25.000 SOL
- Violações de consenso ou segurança: até 12.500 SOL
- Vivacidade ou perda de disponibilidade: até 5.000 SOL
Além disso, o cliente FireDancer tem um programa separado de recompensas por bugs hospedado pela Immunefi, com recompensa máxima de US$ 500.000 em USDC para descobertas críticas.
Casos de interrupção
As seções a seguir apresentam uma análise cronológica e detalhada das interrupções e dos períodos de desempenho degradado da Solana, começando pelo lançamento da Mainnet Beta em 16 de março de 2020. Esta análise destacará os principais incidentes, suas causas fundamentais e as melhorias posteriores da rede, mostrando como a Solana evoluiu para aumentar sua estabilidade e resiliência ao longo do tempo.
Bug no Turbine: dezembro de 2020
Tempo de inatividade: aproximadamente seis horas
Problema fundamental: bug na propagação de blocos
Correções:
- Rastrear blocos pelo hash em vez do número do slot
- Corrigir pontos no Turbine em que a falha pode ser detectada mais cedo
- Propagar a primeira falha detectada para todos os validadores via gossip
Essa interrupção foi causada por um problema já conhecido de reparo de blocos e processamento de código, desencadeado por um bug não identificado no Turbine, o mecanismo de propagação de blocos da Solana. A falha ocorreu quando um validador transmitiu dois blocos diferentes para o mesmo slot e os propagou para duas partições distintas (A e B), enquanto uma terceira partição detectou a inconsistência de forma independente.
Como cada partição detinha apenas uma parcela minoritária do stake, nenhuma conseguiu alcançar o consenso de uma supermaioria para avançar a rede. O problema subjacente estava na forma como as estruturas de dados internas da Solana rastreavam os blocos e seus estados calculados. O sistema usava o número do slot de Proof of History (PoH), um identificador u64, para referenciar o estado e o bloco naquele slot. Depois que a rede se dividiu em partições, os nodes interpretaram incorretamente os blocos A e B como idênticos, impedindo o reparo e a sincronização adequados dos blocos.
Cada partição presumia que a outra tinha o mesmo bloco, gerando um conflito fundamental:
- Nodes com o bloco A rejeitavam forks derivados do bloco B
- Nodes com o bloco B rejeitavam forks derivados do bloco A
Como as transições de estado eram diferentes entre as partições, os validadores não conseguiam reparar nem reconciliar os forks, impedindo a finalização.
A solução para esse problema foi permitir que os serviços rastreassem blocos pelo hash em vez do número do slot. Se qualquer quantidade de blocos para o mesmo slot criar partições, elas serão tratadas da mesma forma que partições com blocos em slots diferentes. Os nodes poderão reparar todos os forks possíveis, e o consenso poderá resolver as partições.
Embora o bug tenha sido a causa inicial da interrupção, a maior parte do tempo de inatividade ocorreu devido à espera pelo retorno de uma quantidade suficiente de stake, pois a Solana exige a participação de pelo menos 80% do stake para retomar a produção de blocos.
O IDO do Grape Protocol: setembro de 2021
Tempo de inatividade: 17 horas
Problema fundamental: estouro de memória causado por transações de bots
Correções:
- Ignorar bloqueios de gravação em programas
- Limites de taxa no encaminhamento de transações
- Comportamento configurável de novas tentativas de RPC
- Priorização de transações de voto na TPU
Em 14 de setembro de 2021, a rede Solana sofreu uma grande paralisação após o lançamento da oferta inicial on-chain em DEX (IDO) do Grape Protocol na plataforma de financiamento coletivo Raydium AcceleRaytor. Em até 12 minutos após o IDO, a rede foi sobrecarregada por uma enxurrada inédita de transações geradas por bots e parou de produzir slots enraizados. Na prática, esses bots executaram um ataque distribuído de negação de serviço (DDoS), elevando a carga de transações além da capacidade da rede.
No pico do congestionamento:
- Alguns validadores recebiam mais de 300.000 transações por segundo.
- Os dados brutos de transações ultrapassaram 1 Gbps, com 120.000 pacotes por segundo.
- Às vezes, o tráfego ultrapassava os limites físicos das interfaces de rede, causando perda de pacotes na porta do switch antes mesmo de chegar aos validadores.
Um dos bots estruturou suas transações para bloquear a gravação em 18 contas importantes, incluindo o programa global de tokens SPL e o extinto programa da DEX Serum. Isso bloqueou todas as transações que interagiam com essas contas, reduzindo drasticamente a capacidade de processamento paralelo da Solana. Em vez de executar as transações de forma independente, a rede ficou limitada por um gargalo e passou a processá-las sequencialmente, agravando o congestionamento.
Uma correção que ignorava bloqueios de gravação em programas já havia sido desenvolvida e estava programada para lançamento. Posteriormente, a reinicialização da rede permitiu aplicar essa atualização, eliminando permanentemente esse vetor de ataque.
Durante o evento de IDO, os validadores receberam uma enxurrada de transações geradas por bots e, por sua vez, encaminharam o excesso de transações ao próximo líder, ampliando o congestionamento. A reinicialização da rede introduziu limites de taxa no encaminhamento de transações para evitar que futuras tempestades de transações sobrecarregassem os líderes.
Os nodes RPC da Solana repetem automaticamente as transações que falham, um recurso criado para melhorar a confiabilidade. No entanto, esse mecanismo de repetição agravou a enxurrada de transações sob congestionamento extremo, mantendo transações antigas em circulação em vez de permitir a recuperação da rede. A Solana 1.8 introduziu um comportamento configurável de novas tentativas de RPC, permitindo que os aplicativos otimizassem as tentativas com prazos de expiração mais curtos e estratégias de backoff exponencial.
Sob congestionamento intenso, os líderes da Solana deixaram de incluir transações de voto, essenciais para manter o consenso. Como resultado, a falta de votos confirmados paralisou o consenso e interrompeu a produção de novos blocos raiz. Versões posteriores do cliente Solana introduziram um mecanismo para priorizar transações de voto, evitando que elas fossem suprimidas por transações comuns em eventos futuros.
Um segundo bug: estouro de inteiro
Durante a reinicialização da rede, surgiu um segundo problema. Os validadores relataram grandes oscilações nos valores de stake ativo. O problema veio de um bug que multiplicava incorretamente a porcentagem de stake por 100, excedendo o valor máximo possível. O mecanismo de inflação havia criado tantos novos tokens SOL que causou o estouro de um inteiro sem sinal de 64 bits. O bug foi rapidamente identificado e corrigido antes de uma segunda reinicialização.
Congestionamento intenso: janeiro de 2022
Tempo de inatividade: nenhum
Causa fundamental: excesso de transações duplicadas Correção parcial:
- Lançamentos da Solana 1.8.12 e 1.8.14
- Otimização da desduplicação do SigVerify
- Melhorias no desempenho do cache do executor
Entre 6 e 12 de janeiro de 2022, a mainnet da Solana enfrentou congestionamento severo, causando desempenho degradado e interrupções parciais. A instabilidade foi provocada por bots que enviavam um excesso de transações duplicadas, reduzindo significativamente a capacidade da rede. O processamento dos blocos demorava mais que o esperado, fazendo o próximo líder criar um fork e reduzindo ainda mais a capacidade de processamento. No pico, as taxas de sucesso das transações caíram até 70%. O cliente teve dificuldades para lidar com as transações cada vez mais complexas e computacionalmente intensivas da rede, expondo limitações em sua capacidade de atender à demanda.
Houve mais instabilidade entre 21 e 23 de janeiro, com a persistência do congestionamento. Em 22 de janeiro, o endpoint RPC público (https://api.mainnet-beta.solana.com) ficou offline devido ao uso abusivo, pois chamadas RPC em lote usadas para spam sobrecarregaram o sistema.
Para resolver esses problemas, o lançamento da Solana 1.8.12 tratou especificamente do esgotamento do cache de programas, enquanto a versão 1.8.14 introduziu melhorias no cache de Sysvar, no descarte do SigVerify e na desduplicação do SigVerify.
Spam no Candy Machine: abril/maio de 2022
Tempo de inatividade: oito horas
Problema fundamental: spam de transações por contas de bots
Correções:
- Taxa para bots no programa Candy Machine
- Melhorias de memória na Solana v1.10
Em 30 de abril de 2022, a Solana registrou um aumento sem precedentes nas solicitações de transações. Alguns nodes relataram seis milhões de solicitações por segundo, gerando mais de 100 Gbps de tráfego por node. O aumento foi provocado por bots que tentavam garantir NFTs recém-criados por meio do programa Metaplex Candy Machine. Esse mecanismo de criação operava por ordem de chegada, gerando um forte incentivo econômico para inundar a rede com transações e conseguir criar os NFTs.
Com o aumento vertiginoso do volume de transações, os validadores ficaram sem memória e falharam, o que acabou paralisando o consenso. A capacidade insuficiente de processamento de votos impediu a finalização dos blocos anteriores e a remoção dos forks abandonados. Como resultado, os validadores ficaram sobrecarregados pelo enorme número de forks que precisavam avaliar, excedendo sua capacidade mesmo após reinicializações e exigindo intervenção manual para restaurar a rede.
Embora essa interrupção tivesse semelhanças com o incidente de setembro de 2021, a Solana demonstrou maior resiliência. Apesar de receber 10.000% mais solicitações de transações do que na interrupção anterior, a rede permaneceu operacional por muito mais tempo, refletindo as melhorias feitas pela comunidade de validadores em resposta aos desafios de escalabilidade anteriores.
A reinicialização da rede levou menos de 1,5 hora após a definição do snapshot canônico. A Solana v1.10 incluiu melhorias no uso de memória para prolongar o tempo durante o qual os nodes conseguem suportar um consenso lento ou paralisado.
No entanto, alguns problemas fundamentais continuaram sem solução. O líder ainda processava por ordem de chegada as transações que disputavam os mesmos dados de conta, sem prevenção eficaz contra spam, o que impedia os usuários de priorizar a urgência de suas transações. Para resolver isso, três mecanismos de longo prazo foram propostos como soluções práticas.
A adoção do QUIC: antes, a Solana usava o protocolo de rede UDP (User Datagram Protocol) para enviar transações pelo Gulf Stream dos nodes RPC ao líder atual. Embora rápido e eficiente, o UDP não usa conexão e não oferece controle de fluxo nem confirmações de recebimento. Portanto, não há uma forma significativa de desestimular ou reduzir comportamentos abusivos. Para controlar o tráfego da rede, o protocolo de ingestão de transações do validador (ou seja, o Fetch Stage da TPU) foi reimplementado com QUIC.
O QUIC tenta oferecer o melhor do TCP e do UDP. Ele permite comunicação rápida e assíncrona, semelhante ao UDP, mas com as sessões seguras e as estratégias avançadas de controle de fluxo do TCP. Isso permite impor limites a fontes individuais de tráfego para que a rede se concentre no processamento de transações legítimas. O QUIC também adota o conceito de streams separados. Assim, se uma transação for descartada, ela não bloqueia as demais. O QUIC acabou sendo integrado ao cliente Solana Labs no lançamento 1.13.4.
Qualidade de serviço ponderada por stake (SWQoS): foi introduzido um novo sistema que prioriza o tráfego da rede conforme o stake dos validadores, garantindo que aqueles com mais stake possam enviar transações com maior eficiência. Nesse mecanismo, um validador com 3% do stake total pode enviar até 3% do total de pacotes ao líder. O SWQoS atua como uma medida de resistência a ataques Sybil, dificultando que agentes mal-intencionados inundem a rede com transações de baixa qualidade. Essa abordagem substitui o antigo modelo por ordem de chegada, que aceitava transações indiscriminadamente sem considerar sua origem.
Introdução das taxas de prioridade: depois de ingeridas, as transações ainda disputam o acesso aos dados compartilhados das contas. Antes, essa disputa era resolvida simplesmente por ordem de chegada, sem oferecer aos usuários uma forma de indicar a urgência de suas transações. Como qualquer pessoa pode enviar transações, a ponderação por stake não é adequada para a priorização nessa etapa. Para resolver isso, uma nova instrução foi adicionada ao programa Compute Budget, permitindo que os usuários especifiquem uma taxa adicional cobrada após a execução e a inclusão no bloco. A proporção entre a taxa e as unidades computacionais determina a prioridade de execução de uma transação, garantindo uma abordagem mais dinâmica e orientada pelo mercado para ordenar transações.
Taxa para bots do Candy Machine
A Metaplex introduziu rapidamente uma taxa fixa de 0,01 SOL para bots em transações de criação que interagiam com o programa Candy Machine para combater o spam gerado por bots. Esse mecanismo antispam aplicava uma taxa mínima para desestimular atividades maliciosas sem penalizar usuários legítimos que cometessem erros acidentais. A taxa era aplicada em cenários específicos, incluindo:
- Tentar criar um NFT quando o Candy Machine não estava ativo
- Tentar criar um NFT quando não havia mais itens
- Transações em que criar ou definir a coleção não era a instrução final
- Uso de um ID de coleção incorreto
- Instruções Set Collection incompatíveis
- Incompatibilidade entre o signatário-pagador nas instruções de definição da coleção e de criação
- Transações suspeitas envolvendo programas não permitidos
- Tentar criar um NFT em um Candy Machine protegido por AllowList sem possuir o token de allowlist exigido
Esse desincentivo econômico se mostrou muito eficaz. Os fundos dos snipers de criação se esgotaram rapidamente, e o spam cessou. Nos primeiros dias, os operadores de bots perderam coletivamente mais de 426 SOL.
Bug de durable nonce: junho de 2022
Tempo de inatividade: quatro horas e meia
Problema fundamental: bug de durable nonce que causou uma falha de consenso
Correções:
- Desativação temporária de transações com durable nonce
- Atualização da Solana 1.10.23
Um bug de runtime permitia que algumas transações com durable nonce fossem processadas duas vezes — uma como transação comum e outra como transação de nonce — caso usassem um blockhash recente em vez de um durable nonce no campo recent_blockhash. Isso gerou um comportamento não determinístico entre os validadores, pois alguns nodes rejeitaram a segunda execução enquanto outros a aceitaram. O mais grave é que, como mais de um terço dos validadores aceitou o bloco, não foi possível alcançar a maioria de dois terços exigida para o consenso.
Diferentemente das transações comuns, as transações com durable nonce não expiram e exigem um mecanismo exclusivo para impedir a execução dupla. Elas são processadas em série usando um valor de nonce on-chain vinculado a cada conta, que é alterado sempre que uma transação com durable nonce é processada. Após essa alteração, a mesma transação de nonce não deve ser válida novamente.
Para reduzir o problema, as transações com durable nonce foram temporariamente desativadas. Depois, uma correção foi implementada na Solana 1.10.23, impedindo a execução duplicada por meio da separação dos domínios de nonce e blockhash. A atualização garantiu que, ao avançar contas de nonce, o blockhash fosse transformado em hash junto a uma string fixa, tornando um blockhash inválido como valor de nonce. Assim, uma transação executada uma vez como transação comum não pode ser reexecutada como transação durável e vice-versa. Além disso, um novo tipo DurableNonce substituiu os valores anteriores de blockhash no estado da conta de nonce, adicionando segurança de tipos e evitando problemas semelhantes no futuro.
Leia nosso artigo anterior no blog da Helius para entender melhor os durable nonces e seus usos.
Bug de bloco duplicado: setembro de 2022
Tempo de inatividade: oito horas e meia
Problema fundamental: um bug nas regras de escolha de forks causou uma falha de consenso
Correção:
- Patch do cliente
Essa interrupção foi desencadeada por um validador que produziu incorretamente blocos duplicados na mesma altura de bloco. Isso ocorreu porque o node principal e o node reserva do validador ficaram ativos ao mesmo tempo, usando a mesma identidade de node, mas propondo blocos diferentes. Essa condição persistiu por pelo menos 24 horas antes da interrupção, período em que a rede lidou corretamente com os slots de líder duplicados do validador.
O cluster acabou parando quando a rede encontrou um fork irrecuperável devido a um bug na lógica de seleção de forks. O bug impediu que os produtores de blocos desenvolvessem o bloco anterior, causando uma falha no consenso.
Forks são ocorrências rotineiras na Solana, e os validadores normalmente os resolvem alinhando-se ao fork com a maioria dos votos, o fork mais pesado. Quando um validador seleciona o fork errado, ele precisa mudar para o fork mais pesado a fim de permanecer sincronizado com a rede. Nesse caso, porém, os validadores não conseguiam reverter para o banco mais pesado se o slot dele fosse igual ao último slot em que haviam votado. Essa falha deixou os validadores travados, impediu o avanço do consenso e acabou paralisando a rede.
No exemplo acima, o validador defeituoso C produz blocos duplicados para seus slots de líder de 5 a 8. Quando o validador G assume como próximo líder, ele observa apenas uma das duplicatas e estende seu fork de acordo. No entanto, o líder seguinte, o validador D, detecta os dois blocos duplicados do validador C e decide descartá-los, construindo seu fork sobre o slot 4.
Conforme a rede avança, o fork construído pelo validador G recebe votos da maioria do stake e se estabelece como a cadeia canônica. Ao perceber que seu fork está perdendo, o validador D tenta mudar para o fork do validador G. No entanto, a transição falha devido a um bug na lógica de seleção de forks. O problema ocorre porque o ancestral comum dos dois forks — um bloco duplicado no slot 5 — não foi tratado corretamente, impedindo que o validador D reconhecesse o fork majoritário. Como resultado, o validador D permanece travado em seu próprio fork e não consegue voltar à cadeia principal.
O problema foi resolvido após uma análise da equipe principal. Um patch foi integrado à branch master e retroportado para todas as branches de lançamento.
Bloco grande sobrecarrega o Turbine: fevereiro de 2023
Tempo de inatividade: quase 19 horas
Problema fundamental: falha na lógica de desduplicação dos serviços de encaminhamento de shreds
Correções:
- Várias melhorias na lógica de desduplicação e filtragem do Turbine
- Adição de um patch ao cliente que força os produtores de blocos a cancelar a operação caso gerem blocos grandes
O serviço personalizado de encaminhamento de shreds de um validador apresentou defeito e transmitiu um bloco excepcionalmente grande, com quase 150.000 shreds e várias ordens de grandeza acima de um bloco comum, durante seu slot de líder. Isso sobrecarregou os filtros de desduplicação dos validadores e fez com que os dados fossem continuamente reencaminhados. O problema se agravou com a produção de novos blocos e acabou saturando o protocolo.
O aumento anormal do tráfego de rede sobrecarregou o Turbine, obrigando a transmissão dos dados dos blocos pelo protocolo alternativo Block Repair, que é muito mais lento. Embora o Turbine tenha sido projetado para suportar blocos grandes por meio de filtragem, os serviços de encaminhamento de shreds operam antes dessa lógica de filtragem, reduzindo sua eficácia. Durante o período de degradação, os líderes de blocos mudaram automaticamente para o modo somente de voto, um mecanismo de segurança no qual os líderes excluem transações econômicas que não sejam de voto.
A causa fundamental foi uma falha na lógica de desduplicação dos serviços de encaminhamento de shreds, que não impediu a retransmissão redundante dos shreds. Além disso, o filtro de desduplicação no pipeline de retransmissão não havia sido originalmente projetado para impedir loops na árvore do Turbine, o que agravou o problema.
A rede foi reiniciada manualmente com um downgrade para a última versão estável conhecida do software dos validadores. Para reduzir esses problemas, a Solana v1.13.7 e a v1.14.17 introduziram melhorias na lógica de desduplicação, aumentando sua capacidade de impedir a saturação dos filtros e garantindo um desempenho de rede mais robusto.
Loop infinito de recompilação: fevereiro de 2024
Tempo de inatividade: quase cinco horas
Problema fundamental: bug que causava um loop infinito de recompilação no cache JIT
Correções:
- Desativação do loader legado na v1.17.20
O validador Agave usa compilação just-in-time (JIT) em todos os programas antes de executar transações que fazem referência a eles. Para otimizar o desempenho, a saída JIT dos programas usados com frequência é armazenada em cache, reduzindo recompilações desnecessárias. Como parte do Agave v1.16, o mecanismo de cache existente, LoadedPrograms, foi substituído por uma nova implementação chamada ExecutorsCache, que introduziu várias melhorias de eficiência.
O LoadedPrograms fornecia uma visão global e ciente de forks dos programas em cache, reduzindo a duplicação de dados contábeis e permitindo que as threads de execução de transações carregassem novos programas de forma cooperativa, evitando conflitos de compilação. Um recurso importante desse sistema era rastrear o slot em que um programa se tornava ativo, conhecido como altura efetiva do slot, para detectar invalidações de cache quando os dados on-chain do programa fossem atualizados.
A altura efetiva do slot da maioria dos programas era derivada do slot de implantação, armazenado na conta on-chain correspondente. No entanto, programas implantados com loaders legados não mantinham esse slot de implantação em suas contas. Como solução alternativa, o LoadedPrograms atribuía a esses programas uma altura efetiva de slot igual a zero.
Uma exceção ocorria quando uma instrução de implantação era detectada, indicando que o bytecode de um programa havia sido substituído. Nesse caso, o LoadedPrograms inseria temporariamente uma entrada com a altura efetiva correta do slot. No entanto, como nenhuma transação fazia referência a essa entrada, ela era altamente suscetível à remoção. Quando removida, a saída JIT era descartada e o programa era marcado como não carregado, mas a altura efetiva do slot era mantida.
Se uma transação fizesse referência a esse programa não carregado posteriormente, o LoadedPrograms o recompilava e reinseria uma entrada em sua altura efetiva de slot. Normalmente, isso disponibilizaria o programa para execução na iteração seguinte. Porém, para programas de loaders legados, a nova saída JIT recebia a altura de slot sentinela igual a zero, ficando atrás da entrada anterior não carregada. Como resultado, o LoadedPrograms nunca reconhecia o programa como carregado, acionando um loop contínuo de recompilação a cada iteração.
No Agave v1.16, o LoadedPrograms não oferecia suporte ao carregamento cooperativo, o que permitia incluir em um bloco a transação que acionava o problema. Esse bloco era então propagado pela rede, fazendo todos os validadores reproduzi-lo e entrar no mesmo loop infinito de recompilação. Como mais de 95% do stake do cluster executava o Agave v1.17 durante a interrupção, a maioria dos validadores ficou paralisada nesse bloco, interrompendo a rede.
Esse bug havia sido identificado na semana anterior durante uma investigação sobre uma interrupção no cluster da Devnet, e a implantação de um patch já estava programada. A mitigação escolhida foi retroportar as alterações para o Agave v1.17 e remover imediatamente um feature gate durante a reinicialização da rede. Isso desativou o loader legado responsável por acionar o bug, evitando novas ocorrências.
Patch coordenado de vulnerabilidade: agosto de 2024
Tempo de inatividade: nenhum
Problema fundamental: suposição incorreta sobre o alinhamento de endereços ELF
Correções:
- Atualização de patch
Em 5 de agosto, os principais engenheiros da Anza foram alertados sobre uma vulnerabilidade no cliente Agave, relatada por um pesquisador externo. Um invasor poderia explorar essa falha para derrubar validadores líderes, causando uma paralisação de toda a rede. Em resposta, os engenheiros da Anza desenvolveram rapidamente um patch, que depois foi auditado por várias empresas terceirizadas de segurança.
Os programas da Solana são compilados com LLVM no formato Executable and Linkable Format (ELF). A vulnerabilidade resultava de uma suposição incorreta sobre o alinhamento de endereços nos arquivos ELF gerados. Embora a sanitização de ELF normalmente aplique várias verificações de integridade, ela não validava o alinhamento da seção .text. Essa omissão poderia permitir que um arquivo ELF criado de forma maliciosa definisse uma seção .text desalinhada, fazendo a máquina virtual saltar para um endereço inválido. Isso causaria uma falha de segmentação no host e derrubaria o validador.
Um invasor poderia explorar essa vulnerabilidade da seguinte forma:
- Criando um programa malicioso da Solana que usasse o opcode CALL_REG.
- Manipulando o arquivo ELF para desalinhar a seção .text.
- Implantando e invocando o programa na rede para provocar falhas nos validadores.
Processo de atualização do patch
Qualquer atualização de patch lançada publicamente revelaria imediatamente a vulnerabilidade a todos. Isso poderia dar a um invasor tempo suficiente para fazer engenharia reversa da vulnerabilidade e paralisar a rede antes que uma quantidade suficiente de stake fosse atualizada. Para evitar esse cenário, uma massa crítica de validadores precisaria adotar qualquer patch lançado o mais rápido possível.
Até 7 de agosto, vários integrantes da Solana Foundation haviam contatado validadores por mensagens privadas em diversas plataformas de comunicação, informando-os sobre um patch crítico iminente e compartilhando uma mensagem com hash que confirmava a data e o identificador exclusivo do incidente. Vários integrantes de destaque da Anza, da Jito e da Solana Foundation compartilharam esse hash no X, no GitHub e no LinkedIn para confirmar a autenticidade da mensagem. Exemplo de hash compartilhado:
Ao longo do dia seguinte, os principais integrantes continuaram contatando validadores e enfatizando a importância da urgência e da confidencialidade. No horário predeterminado, às 14h UTC de 8 de agosto, os operadores de validadores receberam outra mensagem com instruções para baixar, verificar e aplicar o patch. O patch foi hospedado no repositório do Github de um conhecido engenheiro da Anza, e não no repositório principal do Agave. As instruções incluíam verificar os arquivos de patch baixados comparando-os com os shasums fornecidos.
Até as 20h UTC de 8 de agosto, uma supermaioria do stake já havia recebido o patch, garantindo a segurança da rede. Em seguida, a vulnerabilidade e o patch correspondente foram divulgados publicamente, junto a uma solicitação para que todos os validadores restantes fizessem a atualização.
A distribuição discreta do patch e a coordenação dos validadores nos bastidores geraram preocupações sobre a descentralização da Solana. Pouco depois do incidente, Dan Albert, diretor executivo da Solana Foundation, respondeu a essas críticas em uma entrevista à imprensa.
“Acho importante não confundir centralização com a capacidade de coordenação. Existem 1.500 nodes produtores de blocos em todo o mundo, operados por quase o mesmo número de pessoas… A possibilidade de se comunicar voluntariamente com eles, ou com alguns deles, não deve ser confundida com centralização.”
Acho importante não confundir centralização com a capacidade de coordenação. Existem 1.500 nodes produtores de blocos em todo o mundo, operados por quase o mesmo número de pessoas… A possibilidade de se comunicar voluntariamente com eles, ou com alguns deles, não deve ser confundida com centralização.

Conclusão
Até o momento desta publicação, a Solana passou mais de um ano sem interrupções, alcançando um marco importante para remover o rótulo “beta” da mainnet-beta. A frequência das interrupções parece estar diminuindo à medida que a rede amadurece, e a introdução do Firedancer deve aumentar a diversidade de clientes, reduzindo o risco de bugs desconhecidos ou casos extremos causarem a paralisação de todo o cluster. No entanto, alguns líderes da comunidade, incluindo Mert Mumtaz, fundador da Helius, previram que as interrupções continuarão. Só o tempo dirá.
Agradecemos muito a Zantetsu (Shinobi Systems) e OxIchigo pela revisão das versões anteriores deste trabalho.
Outros recursos
Artigos relacionados
Assine a Helius
Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos


