---
# System prepended metadata

title: Infraestrutura Blockchain na ShapeShift
tags: [PT-Onedao]

---

# Infraestrutura Blockchain na ShapeShift

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbae5efc62b1120b46150_1_F0R4y3MkSpLjbo0bRB10Yw%20(1).png)

Nodes na Blockchain (coin daemons) são programas que validam totalmente transações e blocos. Eles são as portas de entrada para as criptomoedas que apoiamos. A [**ShapeShift**](http://shapeshift.com/) conta com nodes na blockchain para receber e retransmitir dados de transações, o que faz com que eles sejam essenciais para nossas operações comerciais. 

Controlar centenas de nodes é um ponto problemático com o qual muitos no setor têm de lidar. Para dimensionar as operações afim de suportar mais do que algumas centenas de transações, esses nodes de moedas precisam ser executados em paralelo para reduzir o estresse colocado sobre eles. Alguns nodes na blockchain não são confiáveis, possuem severas limitações de desempenho e muitas vezes carecem de documentação adequada.

Além de tudo, a maioria dos nodes na blockchain exigem vastas quantias de capacidade de armazenamento para que se armazene o histórico de transações. Alguns desses volumes de dados podem chegar a ter vários Terabytes em tamanho.

Procuramos criar uma estrutura que gerenciasse a construção, aplicação e monitoramento de nodes na blockchain. Essa estrutura precisaria atender a vários requisitos:

*	Compilações automatizadas
*	100% conteinerização
*	Várias versões aplicadas simultaneamente
*	Altamente-avaliável/resiliente (multi-datacenter)
*	Escalável (sobe novos nodes rapidamente)

Depois de repetir o enunciado “Coin Daemon Container” muitas vezes, decidimos nomear a estrutura de Cointainers.

## Ferramentas da Plataforma

Para construir a plataforma Cointainers, precisávamos de ferramentas que nos permitissem  rapidamente repetir compilações e aplicações. O Docker foi uma escolha fácil nesse sentido, permitindo-nos criar compilações reproduzíveis em plataformas com pouquíssima configuração.

Para executar as compilações do Docker dentro de sistemas de produção, optamos pelo Kubernetes, que oferece suporte para [aplicações *stateful*](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) [e plug-ins de armazenamento para todas as principais nuvens](https://kubernetes.io/docs/concepts/storage/).

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbb02efc62b44b7b47b60_1*FHxwJvmHucRhWCvEIUXfKw.png)

Também precisávamos que todas as compilações e infraestrutura fossem reproduzíveis, então isso significava incorporar alguma forma de infraestrutura-como-código (IaC, infrastructure-as-code) nisso tudo. A [Terraform](https://www.terraform.io/) geralmente é a solução mais abrangente para isso, é a maior e mais usada estrutura de IaC. A Hashicorp (a empresa por detrás da Terraform) também anunciou recentemente o [suporte de primeira classe para o Kubernetes na Terraform.](https://www.hashicorp.com/blog/first-class-kubernetes-support-for-hashicorp-products)

No entanto, a Terraform requer o aprendizado de uma nova linguagem, a [HCL DSL](https://github.com/hashicorp/hcl). Usá-la aumentaria a barreira de entrada para nossos engenheiros aprenderem e trabalharem na Cointainers. É aí que a Pulumi entra.

Pulumi é uma estrutura de infraestrutura de código muito semelhante ao da Terraform, melhor descrita pela empresa em sua [página de comparação](https://www.pulumi.com/docs/reference/vs/terraform/):

*A Pulumi é como a Terraform, pois você cria, aplica e gerencia a infraestrutura como código em qualquer nuvem. Ao contrário da Terraform, no entanto, você usará linguagens e ferramentas familiares de uso geral para fazer isso. Assim como o Terraform, a Pulumi é [open source no GitHub](https://github.com/pulumi/pulumi) e é [gratuita para uso](https://www.pulumi.com/docs/quickstart/)*.

Ao usar a Pulumi, podiamos tirar proveito de linguagens de alto nível com as quais a maioria de nossos engenheiros já estava confortável. Também nos permitiu sermos mais expressivos com nossa IaC, evitando as limitações da Hashicorp Configuration Language (HCL). Isso é descrito na comparação também.

*Por causa do uso de linguagens reais, você obtém compilações familiares como loops, funções e classes. Isso melhora significativamente a capacidade de romper com o padrão e aplicar as melhores práticas. Em vez de criar um novo ecossistema de módulos e compartilhamento, a Pulumi permite que você aproveite as ferramentas e técnicas de gerenciamento de pacotes existentes.*

## Compilação

Um cointainer começa com uma imagem do Docker. Dentro, colocamos o coin daemon's binary (software de node na blockchain). Também construímos um segundo container (sidecar), que é executado junto com o software do node para monitorá-lo.

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbb03533c77038410f85b_1*z9XydSqnB12ApvEF3Gt8fw.png)

Como precisamos dar suporte a várias versões, nosso processo de compilação se parece com isso:

1.	Ler a lista de nodes de moedas que precisamos construir (por exemplo, Bitcoin, Dogecoin, Ethereum, etc.)
2.	Baixar as últimas N* versões do coin daemon (por exemplo, bitcoin-0.18.0, bitcoin-1.17.1, bitcoin-0.17.0.1, etc.)
3.	Compilar containers do Docker para conter o software coin daemon
4.	Compilar containers do Docker para nodes de monitoramento
5.	Teste de Integração de todos os containers
6.	Levar os Containers para o Repositório de Imagens

** Personalizável por moeda *

Usando o módulo [@pulumi/docker](https://github.com/pulumi/pulumi-docker), podemos criar repositórios de containers do Docker, compilar nossas imagens do Docker e enviá-las para os repositórios, tudo em um só workflow.

$ make deploy<br/><br/>Previewing deploy<br/><br/>    |   Type                         | Name           | Plan<br/>--------------------------------------------------------------<br/> +   ├─ cointainer:Deploys             ethereum         create<br/> +   │  ├─ container:Deploy            ethereum:2.4.5   create<br/> +   │  |  ├─ container:StatefulSet    ethereum:2.4.5   create<br/> +   │  |  ├─ container:AutoScaler     ethereum:2.4.5   create<br/> +   │  |  ├─ container:IngressRule    ethereum:2.4.5   create<br/> +   │  |  ├─ container:MonitorAlert   ethereum:2.4.5   create<br/> +   │  └─ container:Deploy            ethereum:2.6.5   create<br/> +   │     ├─ container:StatefulSet    ethereum:2.6.5   create<br/> +   │     ├─ container:AutoScaler     ethereum:2.6.5   create<br/> +   │     ├─ container:IngressRule    ethereum:2.6.5   create<br/> +   │     ├─ container:MonitorAlert   ethereum:2.6.5   createResources:<br/>    + 8 resources to create<br/><br/>Você quer aplicar essas mudanças?<br/>  Sim<br/>> Não<br/>  Detalhes<br/> 

## Implementação

Também usamos a Pulumi em nosso processo de implementação para criar os recursos necessários dentro de nossos clusters do Kubernetes. O módulo [@pulumi/kubernetes](https://github.com/pulumi/pulumi-kubernete) nos permite criar *IngressRules*, *StatefulSets* e *HorizontalPodAutoscalers*.

Para que nossos desenvolvedores sempre tenham as versões mais recentes de nodes disponíveis para trabalhar, configuramos uma automação que verifica novas versões e as implementa de forma recorrente.

Nosso fluxo de trabalho de implementação cria nossos recursos e monitoramento de uma só vez:

1. Encontrar todas as versões de nodes que compilamos anteriormente

2. Implementar as versões que não estão no ambiente

4. Criar monitoramentos e alertas para cada versão implementada

$ make deploy

Previewing deploy

 |   Type                         | Name           | Plan<br/>--------------------------------------------------------------<br/> +   ├─ cointainer:Deploys             ethereum         create<br/> +   │  ├─ container:Deploy            ethereum:2.4.5   create<br/> +   │  |  ├─ container:StatefulSet    ethereum:2.4.5   create<br/> +   │  |  ├─ container:AutoScaler     ethereum:2.4.5   create<br/> +   │  |  ├─ container:IngressRule    ethereum:2.4.5   create<br/> +   │  |  ├─ container:MonitorAlert   ethereum:2.4.5   create<br/> +   │  └─ container:Deploy            ethereum:2.6.5   create<br/> +   │     ├─ container:StatefulSet    ethereum:2.6.5   create<br/> +   │     ├─ container:AutoScaler     ethereum:2.6.5   create<br/> +   │     ├─ container:IngressRule    ethereum:2.6.5   create<br/> +   │     ├─ container:MonitorAlert   ethereum:2.6.5   createResources:<br/>    + 8 resources to create<br/><br/>Você quer aplicar essas mudanças?<br/>  yes<br/>> no<br/>  details<br/> 


Leia mais sobre como usar a Pulumi com Kubernetes [aqui](https://www.pulumi.com/blog/pulumi-a-better-way-to-kubernetes/)

## Arquitetura

Durante a inicialização de cada node, verificamos se o volume de dados possui uma cópia da blockchain. Se for uma nova réplica do node e não tiver blocos, ou se a cadeia estiver muito atrasada, baixamos um backup para evitar esperar que o node sincronize manualmente (o que pode levar semanas para ser concluído).

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbb0354b6e3785920e526_1*zbFYJNWGRzpdYp8GSPu8Qg.png)

Após o download do backup e o software do node ser inicializado, nossos sistemas aguardam até estarem 100% sincronizados antes de disponibilizá-lo.

Nosso container de monitoramento verifica a altura do bloco do node em relação aos exploradores de blocos externos e também se o node relata que ainda está sincronizando blocos. Depois que o node estiver totalmente sincronizado e sua altura de bloco estiver acima ou igual ao explorador de blocos, nós o colocamos atrás do balanceador de volume (load-balancer).

Se o node ficar para trás, nós o retiramos do balanceador de volume e esperamos que ele se recupere novamente antes de colocá-lo novamente em serviço para os clientes.

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbb03efc62b63e2b47b93_1*00OwEzzfIBPJliOyj3wMjA.png)

O tráfego vai apenas para nodes íntegros/sincronizados 
Mantemos um mínimo de 3 nodes para cada versão de moeda em vários datacenters: um reservado para backups e dois para manter a confiabilidade. Na medida em que a carga aumenta nos nodes de moedas, nossos sistemas iniciam automaticamente mais bides para acompanhar a demanda.

Em um nível superior, usamos várias versões dos nodes para nossos aplicativos. Isso permite que nossas equipes de desenvolvimento alternem as versões a qualquer momento, dando-lhes a capacidade de reverter imediatamente, se necessário.

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbb03df8913769e880eb2_1*3tI4eIfns6iJEmvzUO6q9Q.png)

Várias versões do Bitcoin
Depois que todos os nossos aplicativos migram da versão antiga para a nova, nós os descomissionamos e mantemos os demais dos quais nossos aplicativos ainda dependem.

## Monitorando

Usando os monitores criados na implementação, nossos sistemas verificam a integridade dos Cointainers a cada 15 segundos para garantir que eles estejam acessíveis e respondam com dados válidos. Também monitoramos a quantidade de réplicas de nodes que executamos para cada versão de moeda. Se alguma versão da moeda tiver menos de 2 nodes ativos, nossos sistemas de monitoramento soam alarmes que notificam nossas equipes de engenheiros e de membros dos serviços.

Se você estiver interessado em trabalhar em projetos como Cointainers, confira nossa página de [Carreiras](http://shapeshift.com/careers)! Estamos procurando: Engenheiros de Software, VP de Marketing e unicórnios 🦄!

![](https://assets.website-files.com/5e9a09610b7dce71f87f7f17/5e9fbb037e6909591b3c32e2_1*0CtbPVcRkofblk3ZXkUuXw.png)

---

Este documento foi publicado originalmente em 13/08/2019 por Azamat Mukhiddinov e pode ter sido ligeiramente modificado para tradução pelo fluxo de trabalho de Informação e Globalização para um projeto de arquivamento em andamento.
 
O artigo original pode ser encontrado [aqui](https://shapeshift.com/library/blockchain-infrastructure-at-shapeshift).

###### tags: `PT-Onedao`