WEB3DEV

Cover image for Polkadot - Execute uma Atualização sem Bifurcação de um Palete do Substrate
Paulo Gio
Paulo Gio

Posted on

Polkadot - Execute uma Atualização sem Bifurcação de um Palete do Substrate

Aprenda como atualizar um palete do Substrate sem bifurcar a blockchain

Introdução

A descentralização de blockchains tem vantagens e desvantagens. Uma das principais vantagens é que não existe uma única unidade que tenha poder completo sobre um sistema. Por outro lado, uma desvantagem é que no ambiente sem controle centralizado, a atualização é difícil devido à necessidade de coordenar vários nós ao mesmo tempo. Uma das soluções mais conhecidas de atualização de blockchains é o chamado “hard fork” (bifurcação rígida), porém este possui muitos vetores potenciais de ataque e é difícil de coordenar.

A solução mais recente para atualizar sistemas descentralizados com base na estrutura Substrate é chamada de runtime-upgrade. A solução funciona sem problemas e neste tutorial, mostrarei como você pode atualizar facilmente sua cadeia baseada em Substrate. Examinaremos como a adaptabilidade é implementada na estrutura do Substrate.

Pré-requisitos

Para seguir este tutorial com sucesso, você deve ter um conhecimento básico sobre a linguagem de programação Rust e o framework Substrate da Polkadot.

Começando

https://github.com/figment-networks/learn-tutorials/raw/master/assets/runtime-upgrade.png

Durante o tutorial, vamos progredir através destas etapas:

  1. Compile a mais simples blockchain baseada em Substrate;
  2. Execute a cadeia do Substrate localmente (em seu próprio hardware);
  3. Adicione um novo recurso ao tempo de execução;
  4. Crie um arquivo WebAssembly (WASM);
  5. Verifique a atualização verificando a versão.

A atualização da função de transição de estado de tempo de execução consiste nas seguintes etapas:

  • Acresça (aumente) o spec_version
  • Compile o arquivo WASM: WASM_TARGET_DIRECTORY="$(pwd)" cargo build
  • Use o comando sudo para iniciar o tempo de execução

Compilando uma simples blockchain do Substrate

Veja a ramificação (branch) master de https://github.com/TomaszWaszczyk/substrate-runtime-upgrade-tutorial, e então execute o comando make init e após cerca de 10 minutos (depende do desempenho da sua máquina) você deverá ver algo como:

Compiling sc-finality-grandpa v0.8.0
Compiling rocksdb v0.15.0
Compiling kvdb-rocksdb v0.9.1
Compiling sc-client-db v0.8.0
Compiling sc-service v0.8.0
Compiling sc-cli v0.8.0
Compiling frame-benchmarking-cli v2.0.0
Finished dev [unoptimized + debuginfo] target(s) in 13m 01s
Enter fullscreen mode Exit fullscreen mode

Nota: Se você deseja construir uma versão otimizada do projeto, execute cargo build --release

Execute o nó Substrate localmente

Use o comando make run:

Running `target/debug/node-template --dev -lruntime=debug`
Sep 29 18:18:09.106  WARN Running in --dev mode, RPC CORS has been disabled.    
Sep 29 18:18:09.106  INFO Substrate Node    
Sep 29 18:18:09.106  INFO ✌️  version 2.0.0-73d7748-x86_64-linux-gnu    
Sep 29 18:18:09.106  INFO ❤️  by Substrate DevHub <https://github.com/substrate-developer-hub>, 2017-2021    
Sep 29 18:18:09.106  INFO 📋 Chain specification: Development    
Sep 29 18:18:09.106  INFO 🏷  Node name: frantic-insect-7496    
Sep 29 18:18:09.106  INFO 👤 Role: AUTHORITY    
Sep 29 18:18:09.107  INFO 💾 Database: RocksDb at /home/tomek/.local/share/node-template/chains/dev/db    
Sep 29 18:18:09.107  INFO ⛓  Native runtime: node-template-1 (node-template-1.tx1.au1)    
Sep 29 18:18:10.070  INFO 🔨 Initializing Genesis block/state (state: 0x0f2a...c2cc, header-hash: 0x1e1d...f017)    
Sep 29 18:18:10.073  INFO 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.    
Sep 29 18:18:10.294  INFO ⏱  Loaded block-time = 2000 milliseconds from genesis on first-launch    
Sep 29 18:18:10.295  WARN Using default protocol ID "sup" because none is configured in the chain specs    
Sep 29 18:18:10.296  INFO 🏷  Local node identity is: 12D3KooWNo1348XGxpiA9uFJn4GJdptp7NcX72pFXsGZXghPKLYa (legacy representation: 12D3KooWNo1348XGxpiA9uFJn4GJdptp7NcX72pFXsGZXghPKLYa)    
Sep 29 18:18:10.618  INFO 📦 Highest known block at #0    
Sep 29 18:18:10.620  INFO 〽️ Prometheus server started at 127.0.0.1:9615    
Sep 29 18:18:10.624  INFO Listening for new connections on 127.0.0.1:9944.    
Sep 29 18:18:12.249  INFO 🙌 Starting consensus session on top of parent 0x1e1dd820c46a22dbd297afd5a62e73511208bafe64c6dc9e6a171562c443f017    
Sep 29 18:18:12.397  INFO 🎁 Prepared block for proposing at 1 [hash: 0x3b7c2d4f453358a70095cc0ad55a5f157a5be3d145c42213ea88c419b48966bf; parent_hash: 0x1e1d...f017; extrinsics (1): [0xff0f...0d06]]    
Sep 29 18:18:12.515  INFO 🔖 Pre-sealed block for proposal at 1. Hash now 0xc61a8f6ea035c0fd2e8acef986a60ec92abbaaa1f30c4781603d4ec83591b216, previously 0x3b7c2d4f453358a70095cc0ad55a5f157a5be3d145c42213ea88c419b48966bf.    
Sep 29 18:18:12.517  INFO ✨ Imported #1 (0xc61a...b216)    
Sep 29 18:18:14.123  INFO 🙌 Starting consensus session on top of parent 0xc61a8f6ea035c0fd2e8acef986a60ec92abbaaa1f30c4781603d4ec83591b216
Enter fullscreen mode Exit fullscreen mode

Acesse o front-end do nó local no link: https://polkadot.js.org/apps/#/extrinsics?rpc=ws://127.0.0.1:9944

https://github.com/figment-networks/learn-tutorials/raw/master/assets/before-upgrade.png

Podemos ver que o palete Kitties (gatinhos) possui apenas uma função create(), que é a nossa função de transição de estado atual em tempo de execução. Para demonstrar como as blockchains baseadas em Substrate são adaptáveis, podemos adicionar um novo recurso - a função breed() (raça).

Adicionando um recurso ao tempo de execução

Antes de fazer uma atualização, o spec_version seria 1. Agora que estamos fazendo uma atualização, incrementamos o campo e então agora ele será 2, conforme mostrado abaixo:

pub const VERSION: RuntimeVersion = RuntimeVersion {
    spec_name: create_runtime_str!("node-template"),
    impl_name: create_runtime_str!("node-template"),
    authoring_version: 1,
    spec_version: 2, // incremented version
    impl_version: 1,
    apis: RUNTIME_API_VERSIONS,
    transaction_version: 1,
};
Enter fullscreen mode Exit fullscreen mode

Nossa atualização adicionará uma nova função ao palete Kitties chamada breed, aqui está a implementação:

/// Breed e kitties
#[weight = 1000]
pub fn breed(origin, kitty_id_1: u32, kitty_id_2: u32) {
  let sender = ensure_signed(origin)?;
  let kitty1 = Self::kitties(&sender, kitty_id_1).ok_or(Error::<T>::InvalidKittyId)?;
  let kitty2 = Self::kitties(&sender, kitty_id_2).ok_or(Error::<T>::InvalidKittyId)?;

  ensure!(kitty1.gender() != kitty2.gender(), Error::<T>::SameGender);

  let kitty_id = Self::get_next_kitty_id()?;

  let kitty1_dna = kitty1.0;
  let kitty2_dna = kitty2.0;

  let selector = Self::random_value(&sender);
  let mut new_dna = [0u8; 16];

  // Combine os pais e o seletor para criar um novo gatinho
  for i in 0..kitty1_dna.len() {
    new_dna[i] = combine_dna(kitty1_dna[i], kitty2_dna[i], selector[i]);
  }

  let new_kitty = Kitty(new_dna);

  Kitties::<T>::insert(&sender, kitty_id, &new_kitty);
  Self::deposit_event(RawEvent::KittyBred(sender, kitty_id, new_kitty));
}
Enter fullscreen mode Exit fullscreen mode

Depois de adicionar a função breed ao palete Kitties, precisamos construir o arquivo WASM.

Aqui está um link para toda a nova implementação: https://github.com/TomaszWaszczyk/substrate-runtime-upgrade-tutorial/blob/after-runtime-upgrade/pallets/kitties/src/lib.rs

Após realizar a atualização, esperamos que o palete Kitties contenha a nova função breed sem a necessidade de reiniciar o nó Substrate em execução. Adaptabilidade real da blockchain!

Compilando o arquivo WASM de tempo de execução

Execute o comando de terminal WASM_TARGET_DIRECTORY="$(pwd)" cargo build para compilar o arquivo WASM de tempo de execução.

Após uma compilação bem-sucedida, esperamos ter um novo arquivo no diretório atual:

https://github.com/figment-networks/learn-tutorials/raw/master/assets/wasm.png

Atualizando o tempo de execução

Temos um nó Substrate em execução com a versão 1 e queremos atualizar o tempo de execução para a versão 2. A prova de uma atualização bem-sucedida será nossa função recém-adicionada, breed. Vamos verificar, usando o front-end.

Para realizar a atualização, vá para a guia Developer e selecione Sudo. Certifique-se de ter selecionado o palete system e setCode(code), marque a opção file upload e selecione o arquivo WASM recém-criado na etapa anterior: node_template_runtime.wasm. Em seguida, marque a opção “with weight override” (substituição com peso) e no campo unchecked weight for this call (peso desmarcado para esta chamada) digite um valor como 100, por exemplo. Para confirmar a atualização, clique em Submit Sudo Unchecked (Enviar Sudo Desmarcado).

https://github.com/figment-networks/learn-tutorials/raw/master/assets/upgrade.png

Após a atualização com sucesso, você deverá ver spec_version atualizado e ter acesso à nossa nova função:

https://github.com/figment-networks/learn-tutorials/raw/master/assets/after-upgrade.png

Na captura de tela acima, podemos ver o resultado de uma atualização bem-sucedida. Observe que spec_versionfoi incrementado para 2 (onde diz "node-template/2").

Solução de problemas

Problema: Erros do Rust ao compilar

Você pode encontrar um erro durante a compilação, como o mostrado abaixo. Isso significa que você não tem a versão correta do Rust instalada.

Compiling prost-derive v0.6.1
error[E0034]: multiple applicable items in scope
   --> /home/tomek/.cargo/registry/src/github.com-1ecc6299db9ec823/prost-derive-0.6.1/src/lib.rs:111:14
    |
111 |             .intersperse(quote!(|));
    |              ^^^^^^^^^^^ multiple `intersperse` found
    |
    = note: candidate #1 is defined in an impl of the trait `Iterator` for the type `Map<I, F>`
    = note: candidate #2 is defined in an impl of the trait `Itertools` for the type `T`
help: disambiguate the associated function for candidate #1
    |
107 ~         let tags = Iterator::intersperse(field
108 +             .tags()
109 +             .into_iter()
110 +             .map(|tag| quote!(#tag)), {
111 +         let mut _s = $crate::__private::TokenStream::new();
112 +         $crate::quote_each_token!(_s $($tt)*);
  ...
help: disambiguate the associated function for candidate #2
    |
107 ~         let tags = Itertools::intersperse(field
108 +             .tags()
109 +             .into_iter()
110 +             .map(|tag| quote!(#tag)), {
111 +         let mut _s = $crate::__private::TokenStream::new();
112 +         $crate::quote_each_token!(_s $($tt)*);
  ...

For more information about this error, try `rustc --explain E0034`.
   Compiling asn1_der_derive v0.1.2
error: could not compile `prost-derive` due to previous error
warning: build failed, waiting for other jobs to finish...
error: build failed
make: *** [Makefile:11: build-full] Error 101
Enter fullscreen mode Exit fullscreen mode

Solução - configure e defina a versão padrão adequada da linguagem Rust em sua máquina

Você precisa instalar e definir como padrão a compilação noturna especificada do Rust: Linguagem Rust rustup update nightly-2020-08-23

  1. Instalação
rustup update nightly-2020-08-23
Enter fullscreen mode Exit fullscreen mode
  1. Faça dela a versão padrão
rustup default nightly-2020-08-23-x86_64-unknown-linux-gnu
Enter fullscreen mode Exit fullscreen mode
  1. Verificação da versão padrão

rustup show e na saída você deve ver o seguinte:

active toolchain
----------------

nightly-2020-08-23-x86_64-unknown-linux-gnu (default)
rustc 1.47.0-nightly (663d2f5cd 2020-08-22)
Enter fullscreen mode Exit fullscreen mode

Conclusão

Parabéns! Você já entendeu a importância de como a adaptabilidade é importante em blockchains descentralizadas e como o recurso é implementado no framework Substrate.

Durante a leitura do tutorial, você aprendeu o básico da linguagem Rust, como compilar uma cadeia baseada em Substrate e como gerar e enviar o arquivo wasm para fornecer novos recursos para a cadeia.

Sobre o autor

O tutorial original foi criado por Tomasz Waszczyk. Em caso de dúvidas, você pode entrar em contato com Tomasz no Fórum da Figment e no Github para obter ajuda ou esclarecer dúvidas relacionadas ao ecossistema Polkadot/Kusama e a este guia. Traduzido por Paulinho Giovannini.

Referências

Quando tiver concluído o tutorial, você estará pronto para aprender mais lendo o tutorial sobre atualização de tempo de execução sem bifurcação de Jimmy Chu.

Top comments (0)