Conheça as Melhorias da Linguagem Go para o Node Waves
Neste post, abordaremos sobre como surgiu e como iniciar o node Waves na linguagem Go.
Graças à simplicidade da Go, o node com essa linguagem vem atraindo novos desenvolvedores para a comunidade Waves.
Erro de código
No começo de janeiro de 2018, período de ano-novo na Rússia, o blockchain Waves passou por um período de inatividade que durou cerca de 40 minutos. A análise subsequente revelou que a causa foi um simples erro no código do node. Erros desse tipo são extremamente difíceis de detectar, e aquele em questão estava no código por mais de seis meses antes de “disparar”.
No entanto, o erro não estava no protocolo da Waves, mas em sua implementação. A existência de apenas uma implementação deixava a rede da Waves vulnerável, em situações como essa. Portanto, foi tomada a decisão de fazer outra implementação do node Waves.
A escolha da linguagem teve como base os seguintes critérios:
- Existência de bibliotecas criptográficas
- Popularidade em outros projetos e na comunidade de criptomoedas
- Simplicidade da linguagem para desenvolvedores
Havia duas linguagens candidatas principais, Go e Rust. Mas a Rust dificilmente poderia ser chamada de linguagem simples por causa de seu modelo de gerenciamento de memória e consequente multiplicação de unidades. Ao contrário da Rust, a Go possui um número mínimo de conceitos e, consequentemente, seu código é legível.
Outras vantagens de desenvolver um node pela Go incluíram a oportunidade de testar novas abordagens para a implementação de algoritmos já existentes e a adição às especificações do protocolo da Waves de detalhes de implementação ocultos no código Scala.
O caminho para a implementação
O projeto para desenvolver um node Waves em Go ocorreu no outono de 2018. A equipe contou com três desenvolvedores, embora a programação tenha mudado parcialmente diversas vezes.
O plano de desenvolvimento era simples. O ponto de partida foram as primitivas básicas do protocolo Waves, incluindo funções criptográficas, transações e mensagens de rede. Em seguida, para beneficiar a comunidade, foi implementada uma biblioteca client para a REST API do node em Scala. Isso foi utilizado em vários serviços internos da Waves. Posteriormente, para demonstrar as capacidades da biblioteca client, foi desenvolvida a ferramenta utilitária chaincpm e os serviços de Fork Detector (detector de fork) , Retransmitter (retransmissor) e Market Data Waves.
Na outono de 2019, o desenvolvimento do node começou. Os desenvolvedores foram encarregados de garantir a alta velocidade de operação do node e acelerar as importações de blocos. Foram implementados algoritmos para consenso, bloqueio e verificação de transação, como parte do desenvolvimento da ferramenta utilitária importer.
Simultaneamente, foi criado um conceito para o estado de armazenamento do bloco e do node. Na implementação Go, foi abandonado o armazenamento do bloco em leveldb: novos blocos são adicionados por completo a um arquivo binário simples e suas meta informações são armazenadas em leveldb.
Outra melhoria utilizando a Go foi um buffer adaptativo de blocos solicitados. O node Scala solicita blocos em lotes iguais de 100 e o node Go rastreia constantemente o tamanho do bloco e ajusta o número de blocos no buffer, com base em seu tamanho. Ou seja, se os blocos estiverem vazios, o node Go pode solicitá-los em lotes de vários milhares e, se os blocos contiverem um grande número de transações, o buffer pode ser reduzido dinamicamente a várias dezenas de blocos. Este mecanismo facilita consideravelmente a aceleração de importação inicial do blockchain Waves.
Algumas melhorias também foram adicionadas ao node Scala. Por exemplo, a adição de filtros bloom ao solicitar o estado de armazenamento ajudou a reduzir o número de transações de alto custo para chaves não existentes, o que é de suma importância para a importação do blockchain, pois todos os blocos e transações são novos naquele momento e, como regra, estão fora do armazenamento. O node Scala teve a implementação de filtros bloom desativáveis, o que ajudou a acelerar a importação do blockchain.
O node Go foi desenvolvido sob o modelo caixa cinza (grey-box model). A implementação de uma funcionalidade só começaria com base em dados relevantes documentados. Para o teste, foram usados dados de blockchain existentes e, apenas no estágio final de implementação, foram feitas as comparações com a implementação do Scala.
Como resultado, no verão de 2019, foi concluída a implementação de um node de validação na linguagem Go. A única limitação era a incapacidade do node de gerar novos blocos. Essa foi a próxima tarefa dos desenvolvedores e, no outono de 2020, os nodes geradores na linguagem Go foram lançados na testnet e, algumas semanas depois, na mainnet.
Simultaneamente, os desenvolvedores do Scala expandiram a funcionalidade do node e prepararam a versão 1.2 Malibu, lançada em agosto de 2020. Em outubro, adicionaram o suporte para o protocolo Waves 1.2 Malibu na versão Go.
No futuro, todos os principais lançamentos do protocolo da Waves vão ocorrer simultaneamente nas linguagens Scala e Go.
No processo de desenvolvimento, foi dada uma atenção especial ao intérprete do script Ride. Diversas versões de intérpretes foram desenvolvidas, com diversos graus de otimização. Atualmente, uma máquina virtual para execução do script Ride está em estágio de desenvolvimento. Espera-se que a criação de uma máquina virtual aumente ainda mais a velocidade de operação do node e possibilite o crescimento do blockchain.
Durante o trabalho das novas funções do protocolo 1.2 Malibu, vários erros na implementação do node Scala foram detectados, os quais foram prontamente corrigidos antes de chegar aos computadores dos usuários.
Possibilidades de Melhorias
A implementação do node Waves na linguagem Go é um produto relativamente novo, que não oferece tantas interfaces de usuário quanto o do node Scala. Com a linguagem Go, o node recebeu uma nova interface gRPC (API gRPC), para acessar os dados do node e do blockchain. Mas a implementação do suporte para a REST API original do node foi parcial. Isso impõe algumas restrições ao uso do node com a linguagem Go.
No entanto, o node Go pode ser usado para o desenvolvimento e operação de novos serviços que obtêm dados sobre a API gPRC, assim como para a geração de blocos no testnet e stagenet. Ainda assim, o registro do node Go na geração de blocos não é grande o suficiente, então, para esta finalidade, recomendamos que o uso dele seja limitado na rede principal.
A equipe de desenvolvimento do node Go não tem intenção de desacelerar e irá trabalhar na introdução de novas funcionalidades, bem como no suporte a interfaces familiares aos usuários. Os próximos planos incluem adicionar o node Go para testes de integração do ciclo completo, depuração e melhoria da segurança.
Nós convidamos os desenvolvedores para estudar o node Waves, detectar e corrigir erros, propor melhorias ou novos recursos. Graças à implementação da linguagem Go, isso ficou muito mais fácil de fazer.
Lançando um node Go
O processo é muito simples. Vá para a página do lançamento no Github, baixe um arquivo executável e o execute, seguindo as diretrizes.
Se você tiver algum problema, dúvidas ou sugestões, crie um Github issue ou converse com os desenvolvedores no Telegram ou Discord.