Três mini-protocolos são vitais para a operação da rede
(Postado originalmente por Marcin Szamotulski em 09/07/2020, traduzido por Joselmo Cabral)
Os próximos lançamentos do Cardano e do protocolo Ouroboros contêm mudanças que nos orientam em direção a descentralização e a era de Shelley. Este post do Deep Dive explica como estamos nos aproximando dessa fase. Com o lançamento do algoritmo Praos para Shelley, que vem com o processo de staking, os stake pools podem ser configurados para que os proprietários de ada possam delegar seu stake. A equipe de rede está focada agora em dois recursos que nos permitirão executar um sistema totalmente descentralizado. Deixe-me primeiro descrever brevemente como a rede é projetada e desenhada e dar uma visão geral de onde estamos no momento. Esta postagem começará no topo de nossas abstrações e percorrerá a pilha. Felizmente, esta será uma jornada interessante através do nosso design.
Protocolos tipados
No topo da pilha está a estrutura de protocolos tipados da IOHK, que nos permite projetar protocolos em nível de aplicativo. O objetivo de nível superior do projeto de protocolo para Ouroboros é distribuir cadeias de blocos e transações entre os participantes da rede e isso é alcançado por três mini protocolos:
- chain-sync é usada para sincronizar eficientemente uma cadeia de cabeçalhos;
- block-fetch nos permite puxar blocos;
- tx-submission é usado para enviar transações.
Todos os três mini protocolos foram cuidadosamente projetados após considerar as ameaças que podem surgir na execução de um sistema descentralizado. Isso é muito importante, porque os ataques cibernéticos são muito comuns, principalmente contra alvos que apresentam fortes incentivos. Há uma série de ataques possíveis nesse nível que precisamos nos defender e um tipo com o qual tivemos muito cuidado é o ataque ao consumo de recursos. Para se defender de tais ataques, os protocolos permitem que o lado do consumidor fique no controle da quantidade de dados que receberá e, finalmente, mantenha o uso de seus recursos (por exemplo, memória, CPU e descritores de arquivos abertos) abaixo de um determinado nível.
Se você estiver interessado em mais detalhes sobre protocolos tipados, realizamos palestras e realizamos workshops nos eventos de Haskell no ano passado e estes foram muito bem recebidos pela comunidade de engenharia. Em particular, veja a palestra de Duncan Coutts no Haskell eXchange e o workshop que realizei no Monadic Party.
Papel do multiplexador
Os protocolos TCP / IP formam o conjunto de protocolos mais onipresente implantado na Internet. Eles também são alguns dos protocolos mais estudados e estão disponíveis em quase todos os sistemas operacionais e arquiteturas de computadores; portanto, são uma boa primeira opção para nossos propósitos. O TCP / IP nos dá acesso a um canal de comunicação bidirecional entre servidores na Internet. O único requisito de alto nível dos protocolos digitados é uma entrega ordenada de pacotes de rede, garantida pelo protocolo TCP.
Os sistemas operacionais limitam o número de conexões a qualquer momento. Por exemplo, o Linux, por padrão, pode abrir 1.024 conexões por processo, mas no macOS o limite é de apenas 256. Para evitar o uso excessivo de recursos, usamos um multiplexador. Isso nos permite combinar os canais de comunicação em um único, para que possamos executar os três mini protocolos em uma única conexão TCP. Outra maneira de economizar recursos é usar a bidirecionalidade do TCP: isso significa que é possível enviar e receber mensagens nos dois extremos simultaneamente. Não usamos esse recurso na era Byron Reboot, mas queremos tirar proveito dele na era descentralizada de Shelley.
O governador ponto a ponto
Queremos usar conexões bidirecionais, executando todos os três mini protocolos nas duas direções, por isso precisamos de um componente que saiba quais conexões estão em execução no momento. Quando um nó se conecta a um novo par, podemos primeiro verificar se ele já tem uma conexão aberta com esse par, o que seria o caso se o par já estivesse conectado a ele. Mas essa é apenas uma parte do gerenciamento de conexões que precisaremos.
Outro requisito vem do governador ponto a ponto. Essa parte do sistema é responsável por encontrar pares e escolher alguns deles para se conectar. A conexão leva algum tempo, dependendo de fatores como a qualidade da conexão de rede e a distância física. Ouroboros é um sistema em tempo real, por isso é bom esconder alguma latência aqui. Não seria bom se o sistema estivesse sob pressão e ainda assim precisasse se conectar a novos pares; é muito melhor se o sistema mantiver um punhado de conexões sobressalentes prontas para executar qualquer nova tarefa. Um nó deve poder tomar uma decisão informada sobre quais conexões existentes promover para obter o melhor desempenho. Por esse motivo, decidimos ter três tipos de pares:
- pares frios sabem de sua existência, mas não há conexão de rede estabelecida.
- pares mornos têm uma conexão, mas é usada apenas para medições de rede e nenhum dos mini-protocolos nó a nó é usado;
- os pares quentes têm uma conexão que está sendo usada pelos três miniprotocolo de nó a nó.
Um nó pode potencialmente conhecer milhares de pares frios, manter até centenas de pares mornos e ter dezenas de pares quentes (20 parece uma figura razoável no momento). Existem questões complexas e desafiadoras sobre o desenho de políticas que orientarão as decisões do governador ponto a ponto. A escolha de tais políticas afetará a topologia da rede e alterará as características de desempenho da rede, incluindo desempenho sob carga ou ação maliciosa. Isso moldará a distribuição oportuna da difusão de bloco (parametrizada por tamanhos de bloco) ou transações. Como a execução de um sistema desse tipo tem muitas incógnitas, gostaríamos de transformá-lo em duas partes. Para a primeira fase, que será lançada em poucas semanas (provavelmente logo após o Praos, também conhecido como o lançamento de Shelley), queremos estar prontos com todos os componentes ponto a ponto, mas ainda executando no modo federado. Além disso, entregaremos o gerenciador de conexões juntamente com a implementação de um servidor que aceita conexões e sua integração com o governador ponto a ponto. Nesta fase, o governador ponto a ponto será usado como um mecanismo de assinatura. A execução de várias redes de teste públicas e privadas, juntamente com nosso extenso teste, deve nos dar confiança suficiente antes de liberá-lo para a rede principal.
Na segunda fase, estenderemos os mini protocolos com um protocolo de fofocas. Isso permitirá a troca de informações sobre pares, finalizará as medidas de qualidade da rede e as conectará à lógica de busca de bloco (que decide de quem baixar um bloco), bem como ao governador ponto a ponto. Nesse estágio, gostaríamos de projetar e executar algumas experiências para descobrir como as políticas ponto a ponto moldam a rede e verificar como elas se recuperam de quaisquer topologias abaixo do ideal (ou adversárias).
Espero que isso lhe dê uma boa noção de onde estamos com o design e a implementação da descentralização para Cardano e o nosso roteiro para a era Shelley. Você pode acompanhar mais progressos em nossos relatórios semanais.
Este é o terceiro dos posts técnicos do Developer Deep Dive de nossas equipes de engenharia de software.