decen{BR}

Inserindo a blockchain Bitcoin no MySQL

O software crypto.bi Bitcoin Toolbox possui uma ferramenta chamada blocks_inserter que permite ler os arquivos de dados de blocos dos arquivos .dat do Bitcoin Core e inserir diretamente no MySQL.

Para usar a ferramenta, primeiramente é preciso gerar generate o schema MySQL em sua máquina local rodando scripts/sql/mysql/cryptobitoolbox_bitcoin.sql em sua instância do banco de dados.

Então será preciso configurar o Toolbox com as credenciais corretas para que o Toolbox consiga acessar o servidor MySQL.

Quanto a configuração estiver completa, execute toolbox/db/test_connection para verificar a conectividade do Toolbox com o MySQL.

Se o programa retornar o nome e versão do MySQL, então tudo está configurado corretamente. De outra forma você provavelmente receberá uma exceção e terminação anormal do programa. Caso isso aconteça, verifque o host, usuario e senha e tente novamente.

Se tudo estiver configurado corretamente, agora você pode rodar a ferramenta para importar a blockchain do Bitcoin para MySQL:

$ ./toolbox/db/blocks_inserter

A depender da capacidade de seu hardware, cada arquivo de blocos pode levar alguns minutos para ser processado.

Atualmente há mais de 1800 arquivos de blocos de dados na blockchain Bitcoin. Em um equipamento razoavelmente veloz, este processo pode levar alguns dias para terminar.

OBS: Este é um processo que exige muito do subsistema de entrada/saída de seu equipamento. Os discos rígidos (ou SSD) trabalharão pesado durante a importação, especialmente se o servidor MySQL se encontrar na mesma máquina que a ferramenta blocks_inserter.

É recomendado reservar pelo menos 1 TB de espaço em sua partição de dados MySQL para a inserção completa da blockchain MySQL. Lembrando que o armazenamento da blockchain em MySQL requer maior espaço em disco que a soma dos arquivos .dat. Isso ocorre porque o MySQL agrega metadados e índices. Esses últimos ocupam, pelo menos, o dobro do armazenamento da blockchain sem indexação. No entanto, após a indexação diversos metadados dos blocos podem ser buscados rapidamente, o que é impossível com a blockchain em estado bruto.

Lidando com Interrupções

Se o programa sofrer interrupção e continuar sua execução, há algumas observações sobre as quais você deve saber.

Primeiramente, a inserção não é algo como este algoritmo:

if (!inserted(block or tx or ...)) {
 insert(block or tx or ...);
}

Qualquer processamento nesse sentido tornaria o processo muito mais lento, especialmente nos dados mais específicos (transações, entradas e saídas).

Em vez disso, o programa tenta encontrar o último arquivo de dados de blocos (.dat) que foi processado, o último bloco, a última transação (TX) e, dentro dessa TX, as últimas entradas e saídas – nessa ordem. E então o programa tenta recomeçar daí.

Conforme o programa encontra o último bloco e reinicia, você pode encontrar mensagens deste tipo:

[2019-11-23 16:35:58.006] [stderr] [info] Error inserting block 000000000000015a13e8efa95791e183d11513d82cf32c6ccb5a8ce913023619
[2019-11-23 16:35:58.006] [stderr] [info] Duplicate entry 'xE8x8FgxE4Ytx96x98x80xA7Ux99l^x08x81x8CxAAxB3Tx1A+' for key 'hash_merkle_root'
[2019-11-23 16:35:58.069] [stderr] [info] Error inserting block 0000000000000105a091184edde7b17b96869992b9391803b8ca1dbee33f5c57
[2019-11-23 16:35:58.069] [stderr] [info] Duplicate entry '=xB0IxABx86+x86rxB9x91x89Zx7FxECzxC9x82x7FxFD5xF8' for key 'hash_merkle_root'
[2019-11-23 16:35:58.254] [stderr] [info] Error inserting block 000000000000007f8626a95609e54aebbea1c454ae066d57af9777357bfe9073
[2019-11-23 16:35:58.254] [stderr] [info] Duplicate entry 'x81xDCxC0xE9ixA2xCExAFx12xB0x7Fx0BNxE6EP/x03xA6vx' for key 'hash_merkle_root'
[2019-11-23 16:35:58.330] [stderr] [info] Error inserting block 000000000000015af92e0eb8a0761c81704711eff9380aa18f40c270daba4f9d
[2019-11-23 16:35:58.330] [stderr] [info] Duplicate entry 'x+FoxBDxDCxC5xFEx85xD3xD6xCEx80xDDzx02(xBEx96x93x' for key 'hash_merkle_root'

Essas mensagens são benignas, desde que você as veja após uma reinicialização do inserter e os arquivos de dados não tenham sido totalmente processados.

Também não há problema caso encontre mensagens sobre “hash de TX duplicadas”. Isso ocorria antes da ativação do BIP30 quando transações podiam ser mineradas em mais de um bloco. Era um bug que apenas gerava TX’s aparentemente duplicadas, mas não ocasionavam double-spends. Em função dessas TX’s serem identicas, porém contidas em múltiplos blocos, o Toolbox reclama que a hash é duplicada. Apenas ignore.

Essas mensagens são benignas quando ocorrem após uma reinicilização do sistema porque, conforme explicamos anteriormente, o sistema não verifica uma a uma das TX’s inseridas. Em vez disso ele tenta reiniciar a inserção a partir de um ponto estimado. Caso existam alguns blocos, TX’s e entradas/saídas já processadas a partir do ponto selecionado, haverá tentativas de reinserir dados. Apenas ignore, pois provavelmente o sistema passará do ponto anterior e, em breve, prosseguirá adiante processando dados novos.

É mais eficiente deixar essas mensagens de erro ocorrerem que tentar verificar cada item inserido durante a inserção. Erros são a exceção, não a regra, por isso seria um grande desperdício verificar erros a cada inserção ao invés de deixar algumas exceções acontecerem.

Por outro lado, se estiver vendo esses erros constantemente durante todo o processo, mesmo após o ponto do BIP30, pode haver algum outro problema com sua base de dados. Aqui vale a experiência do operador em identificar se há um problema estrutural subjacente ou se é apenas transiente.

Modo Multitarefa

blocks_inserter pode ser executado em modo multitarefa (multithreaded).

Como o Bitcoin não prescreve que blocos devem ser armazenados em ordem sequencial no disco rígido, podemos processar vários arquivos de blocos em paralelo e o banco de dados não será prejudicado.

Podemos ativar o processamento paralelo de arquivos de blocos usando os parâmetros threaded e threads na linha de comando. Por exemplo:

./toolbox/db/blocks_inserter --threaded 1 --threads 8

O argumento --threaded 1 aciona a multitarefa e --threads 8 diz ao blocks_inserter para rodar 8 threads.

Se --threads for passado sem --threaded essa opção será ignorada e o processo rodará em única thread, como se não tivesse recebido qualquer instrução multitarefa.

Rodando em modo multitarefa normalmente acelera muito a inserção de blocos. Porém, tenha em mente que todo o processo de inserção do Toolbox é limitado pelo hardware de IO. Se a vazão máxima de seu disco rígido for atingida com 1 thread, não adiantará executar diversas threads. É preciso realizar medições e aferir se a multitarefa está ajudando ou atrapalhando em seu hardware específico.

A inserção em modo multitarefa pode processar arquivos de blocos fora de ordem, sem problemas. Por exemplo:

% ./toolbox/db/blocks_inserter --threaded 1 --threads 8
[2019-11-25 12:27:35.243] [console] [info] Starting blocks inserter
[2019-11-25 12:27:37.324] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00007.dat IN 2.08143s 1 FILES DONE
[2019-11-25 12:27:37.609] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00006.dat IN 0.285143s 2 FILES DONE
[2019-11-25 12:27:37.723] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00003.dat IN 0.113904s 3 FILES DONE
[2019-11-25 12:27:37.766] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00005.dat IN 0.0422754s 4 FILES DONE
[2019-11-25 12:27:37.792] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00002.dat IN 0.0260299s 5 FILES DONE
[2019-11-25 12:27:37.859] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00001.dat IN 0.067636s 6 FILES DONE
[2019-11-25 12:27:37.901] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00004.dat IN 0.0416559s 7 FILES DONE
[2019-11-25 12:27:39.512] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00008.dat IN 1.61126s 8 FILES DONE

Observe como o arquivo número 7 terminou antes dos arquivos 3,2,1 e assim por diante. Não há qualquer problema, pois os dados são indexados no banco e serão ordenados nas consultas.

Taxa de Inserção

Aqui uma tela real de saída, mostrando a taxa de inserção obtida usando discos rígidos comuns (não SSD), criptografados e em hardware Intel i7 com 64GB de RAM:

[2019-11-23 17:05:32.753] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00074.dat IN 95.9256s 75 FILES DONE
[2019-11-23 17:07:04.953] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00075.dat IN 92.2s 76 FILES DONE
[2019-11-23 17:08:40.038] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00076.dat IN 95.0859s 77 FILES DONE
[2019-11-23 17:10:14.149] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00077.dat IN 94.1105s 78 FILES DONE
[2019-11-23 17:11:50.829] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00078.dat IN 96.6806s 79 FILES DONE
[2019-11-23 17:13:25.720] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00079.dat IN 94.8907s 80 FILES DONE
[2019-11-23 17:15:06.487] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00080.dat IN 100.767s 81 FILES DONE
[2019-11-23 17:16:45.271] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00081.dat IN 98.7836s 82 FILES DONE
[2019-11-23 17:18:25.443] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00082.dat IN 100.172s 83 FILES DONE
[2019-11-23 17:20:06.218] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00083.dat IN 100.775s 84 FILES DONE
[2019-11-23 17:21:45.005] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00084.dat IN 98.7866s 85 FILES DONE
[2019-11-23 17:23:24.334] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00085.dat IN 99.3292s 86 FILES DONE
[2019-11-23 17:25:02.200] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00086.dat IN 97.8662s 87 FILES DONE
[2019-11-23 17:26:40.933] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00087.dat IN 98.733s 88 FILES DONE
[2019-11-23 17:28:17.914] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00088.dat IN 96.9807s 89 FILES DONE
[2019-11-23 17:29:57.812] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00089.dat IN 99.8985s 90 FILES DONE
[2019-11-23 17:31:36.852] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00090.dat IN 99.0392s 91 FILES DONE
[2019-11-23 17:33:12.134] [console] [info] DONE BLOCKS FILE /disk5/bitcoindata/blocks/blk00091.dat IN 95.2829s 92 FILES DONE

Acelerando a Inserção

Conforme mencionado, a amostra acima foi obtida em hardwareIntel(R) Core(TM) i7-6700K CPU @ 4.00GHzIntel(R) Core(TM) i7-6700K CPU @ 4.00GHz com 64 GB RAM, utilizando criptografia de disco LUKS em HD’s 5400 RPM.

Como é um processo limitado por IO, teríamos uma considerável melhora utilizando discos SSD sem criptografia. Nesse caso, a criptografia é desnecessária porque os dados da blockchain são públicos e não exigem sigilo.

Para acelerar ainda mais, o servidor MySQL deve encontrar-se em máquina separada, utilizando SSD para armazenamento. Dessa forma o processamento dos blocos em uma máquina não interfere com a entrada/saída pesada do MySQL em máquina separada. Observe que não adianta rodar máquinas virtuais no mesmo hardware, pois a limitação é no IO de disco e não no processamento.

Na amostra citada, consumindo 100 segundos por arquivo de blocos, levaríamos 2 dias e 6 horas para inserir a blockchain completa, ou algo em torno de 2000 arquivos de blocos. Com SSD e otimizações, esse processo pode ser reduzido consideravlmente, talvez até para algumas poucas horas.

Conclusão

Inserir a blockchain em banco de dados MySQL tem muitas vantagens. Pode-se analisar estatísticas, cruzar endereços, buscar padrões que não são possíveis usando a blockchain em estado bruto.

O processo é pesado em termos de IO, porém vale a pena caso deseje analisar a blockchain Bitocoin de forma local, sem depender de APIs externas.

Referências

Storing and Querying Bitcoin Blockchain Using SQL Databases [PDF]

To create a blockchain using MySQL database

Bitcointalk: SQL schema for the blockchain ?

sqlChain is a compact SQL layer that runs on top of bitcoind

Reddit: How to store the blockchain in a MYSQL database?

Sobre @ Autor(@)
Publicado por decen{BR} - decen{BR} é nosso avatar coletivo, @ qual usamos na editoria do site. Normalmente, os conteúdos publicados pel@ decen{BR} são traduções de nosso site parceiro crypto.bi - (ou contribuições indiretas de um de seus autores). Confira nossa página Sobre (menu lateral) para conhecer a nossa equipe! Saiba Mais o Decen{BR}
Somos 100% livres de anúncios e rastreadores. Apoie este projeto doando para X-avax1qw9mfew4pgs03kxn9l3400suy0za983g293686. Obrigado! ❤
Autor(a)
Publicado
20 de dezembro de 2019
Atualizado
29 de novembro de 2020
Não rastreamos nossos usuários. Este site não emprega Javascript ou anúncios.