La criptovaluta IOTA (ed un FPGA per l’RPi) – Parte 2: PiDiver – una scheda FPGA per calcoli rapidi

Nella parte precedente dell'articolo "La criptovaluta IOTA (ed un FPGA per l'RPi)" vi abbiamo presentato IOTA, la criptovaluta che permette ai nodi IoT di pagare gli altri utenti iscritti, ad esempio per l'archiviazione dei dati [1]. Al fine di eseguire le transazioni IOTA, prima di tutto bisogna risolvere il task di calcolo proof of work; questo protocollo serve a proteggere il database (tangle) dallo spam. Anche i computer x86 fanno fatica ad eseguire questo task aritmetico, ma IOTA consente ai piccoli nodi IoT di delegare il lavoro a device esterni specializzati. La seconda parte dell'articolo introduce la piattaforma basata su una scheda add-on FPGA per il Raspberry Pi.

Introduzione

Questa sezione dell'articolo descrive una soluzione rapida ed efficiente in termini energetici per la problematica inerente al PoW (Proof of Work) di IOTA; i calcoli necessari vengono eseguiti da un FPGA. Questo raggiunge un tempo medio PoW di 300 ms, che non solo risulta più veloce della libreria multithread ottimizzata SSE su Core i5 (circa 1.7 s), il consumo energetico di 2 Watt è anche significativamente diminuito.

Proof of Work di IOTA

Per fare in modo che una transazione venga accettata dal tangle, gli ultimi 14 step [1] dell'hash della transazione devono corrispondere a zero. Se un hash non rispetta questa condizione, un counter (vedere Figura 1) viene incrementato nella transazione e l'hash di quest'ultima viene ricalcolato. Questo processo viene ripetuto finché non si trova un hash valido. In media, per risolvere questo problema di calcolo sono necessari 314/ hps secondi, considerando che hps corrisponde al numero di funzioni hash che possono essere calcolate al secondo. Questo risulta in una media di 4.78 milioni di interazioni eseguite prima che il problema venga risolto.
L'idea di fondo è che il tangle può essere protetto dallo spam, dato che la velocità massima di transazione raggiungibile viene nettamente ridotta dallo sforzo computazionale. La fase di verifica invece richiede una insignificante quantità di tempo, poiché l'unica cosa da controllare è l'hash della transazione. Un hash di transazione valido viene dunque definito proof of work perché consiste nella prova verificata della correttezza del calcolo eseguito.

L'algoritmo di hashing CURL-P81 utilizzato -simile a SHA3- è progettato in costruzione di spugna. Nuovi blocchi con una dimensione (velocità) fissa, vengono assorbiti nello stato interno, il quale si caratterizza per dimensioni (e capacità) 3 volte maggiori a quelle di un blocco singolo.
L'intero stato viene poi convertito nello stato successivo utilizzando una funzione spugna (Figura 2). Una volta che tutti i blocchi sono stati assorbiti, l'hash può essere esternato. Una transazione IOTA consiste in 33 blocchi, di cui ognuno contenente 81 trits (B1-B33 nel diagramma). L'ultimo blocco contiene il counter, che viene incrementato se l'hash della transazione non soddisfa le condizioni della rete principale (ci sono altre reti tangle per sviluppo e test). Dal momento che il counter si trova solo nell'ultimo dei 33 blocchi, lo stato successivo all'assorbimento del 32esimo blocco (stato intermedio) può essere utilizzato come stato iniziale per il 33esimo blocco. Dopo aver incrementato il counter dell'ultimo blocco, è necessario attribuire un hash a un singolo blocco, al fine di calcolare l'hash dell'intera transazione; ciò permette di risparmiare molto tempo.

Una panoramica sul PiDiver

Il PiDiver - il nome deriva dall'unione della parola Raspberry Pi e dell'algoritmo PoW "Pearl-Diver" [1] - è un HAT (Hardware Attached on Top) per Raspberry Pi, capace di eseguire i calcoli di proof of work di IOTA in maniera celere ed efficiente in termini energetici. La Figura 3 mostra la connessione del blocco del PiDiver. Al centro si trova un FPGA Cyclone 10 LP di Intel. Si tratta di un membro relativamente nuovo della famiglia Cyclone (pubblicato nel 2018) e progettato da Intel per soddisfare in particolare quel target di applicazioni IoT caratterizzate da un basso costo e da un consumo energetico ridotto.


Gli FPGA, che offrono molte risorse logiche, sono interessanti non solo perché hanno un basso costo e un'alta efficienza energetica, ma anche perché è possibile trovarne molte varianti sul mercato, con alloggiamenti differenti DIY e relativamente "friendly" (EQFP), e ciò li rende perfetti per questo progetto. L'FPGA è regolato a 200 MHz e può calcolare un giro completo di hashing a ogni ciclo di orologio (CURL-P81 utilizza 81 giri). Inoltre, può calcolare sette funzioni di hash con counter differenti (non-cents) in modo simultaneo. Oltre agli 81 cicli, sono richiesti altri due cicli per il controllo del risultato, il ripristino dello stato precedente (stato intermedio in Figura 2) e l'impostazione dei valori del nuovo counter. Si ottiene circa 16.8 MHash/s. Nel caso della rete principale IOTA, il tempo medio per la fase PoW corrisponde approssimativamente a 300 ms o 3.33 PoW/s, trasferimento dati incluso. Inoltre, vi è un microcontroller STM32 (STM32F302) nel circuito, che consente di operare l'FPGA tramite USB. Il proof of work può così essere eseguito sia attraverso l'interfaccia SPI di Raspberry Pi, sia su PC tramite USB (senza Raspberry Pi). Avrai notato che non c'è memoria flash per la configurazione di FPGA. Di conseguenza, la configurazione viene ricaricata nell'FPGA dopo ogni ciclo. Anche questo può essere eseguito sia con Raspberry Pi, sia con USB. La configurazione viene rilevata automaticamente ed eseguita dalla libreria PiDiver. Per le estensioni future, è provvista una memoria flash SPI su STM32, ampia abbastanza per salvare il bitstream completo di FPGA. Questo permette una configurazione automatica dopo l'accensione, che potrebbe essere interessante per le applicazioni integrate (per esempio con microcontroller ESP32) dato che il bitstream di circa 800 kB è troppo grande per la memoria flash di molti microcontroller. Il diagramma del circuito in Figura 4 non offre più di questo. Ci sono 3 tensioni di alimentazione, ognuna delle quali possiede il suo regolatore di tensione. Due di questi sono regolatori di tensione fissi a bassa caduta (LDO) e sono connessi in serie per 3.3 V e 2.5 V, il terzo è un regolatore di commutazione settato su 1.2 V, che può fornire una corrente fino a 3 A (1 A è il minimo richiesto). La scheda può essere alimentata a 5 V con un connettore Raspberry GPIO oppure tramite USB. Secondo il produttore, i due "diodi ideali" (tipo MAX40200) combinano entrambi una tensione a 5 V in modo che le due sorgenti potenziali di tensione non siano mai in contatto diretto tra loro. MAX40200 non è di fatto un diodo, ma un MOSFET logico con una caduta di tensione di soli 85 mV a 1 A. Questa caratteristica di dissipazione di corrente minima rende ogni diodo Shottky verde d'invidia!

Il circuito mostra alcune possibilità di estensione per altri progetti. Ci sono due estensioni header, nelle quali si localizzano 14 I/Os dell'FPGA e la porta a 10 pin del microcontroller STM32 per le tue applicazioni. Ci sono anche dei LED e dei pulsanti su FPGA e anche su STM32. Il circuito è stato progettato in modo da rendere il bootloader DFU interno di STM32 utilizzabile. Un pulsante BOOT separato deve essere premuto durante l'accensione in modo da avviare il controller in modalità bootloader. Il consumo totale di corrente di 350 mA è così basso che è possibile effettuare le operazioni su un USB standard senza alcun problema.

Sovrastruttura

Il PCB del PiDiver [2] in Figura 5 ha 4 livelli ed è quasi esclusivamente popolato da SMD. Alcune (U6, U7 e FL1) non possono essere saldate con un saldatore, perché i pad sono nascosti sotto l'alloggiamento. Per un adeguato assemblaggio sono quindi raccomandate pasta per saldatura ed aria calda. Dovresti lasciare R8 (un resistore 0-Ω in uscita del regolatore di switching U4) nella sua scatola per il momento, dato che non viene inizialmente popolato. I componenti depennati nel diagramma di assemblaggio (vedi [2]) non sono richiesti come acceleratori PoW per l'operazione. I componenti R12, R13, R14, Q1 e P2 sono interessanti solo se vuoi sviluppare un software per il microcontroller STM32 sulla scheda. Questi abilitano una resistenza pull-up commutabile tramite software per la linea dati D+ dell'USB. Tutto ciò è particolarmente interessante per il debug del software STM32: l'host viene notificato in caso di reset del microcontroller e il dispositivo USB deve essere enumerato nuovamente. Sfortunatamente, il bootloader standard integrato in ogni STM32F302 non supporta la resistenza pull-up commutabile, perciò vi è una resistenza pull-up fissa (R26) che si occupa dell'esecuzione di questa funzione. Anche il pin header P2 è particolarmente interessante per il debugging, al quale l'interfaccia di debugging SWD viene indirizzata.

La maggior parte dei restanti componenti non necessita di commenti particolari (se non che molti di loro sono estremamente minuti), ma un'attenzione speciale va dedicata alla superficie metallica della parte inferiore dell'FPGA (U1) e del regolatore di switching (U3): entrambi vanno saldati. Per l'assemblaggio manuale, quindi, vengono posizionati dei larghi fori passanti sotto questi componenti per permettere la saldatura delle superfici metalliche. È consigliabile riscaldare queste piastre metalliche dal retro, facendo passare l'aria calda attraverso i fori passanti finché la lega per la saldatura non si scioglie su di esse. L'uso di un saldatore è fortemente sconsigliato in questo caso, dato che il calore reso disponibile si dissipa molto velocemente negli strati intermedi della scheda: le superfici metalliche si riscalderebbero con difficoltà e non raggiungerebbero la temperatura necessaria. Nel peggiore dei casi, rischieresti di danneggiare la stessa scheda del circuito!

Prima messa in esercizio

Una volta assemblata la scheda del circuito, è consigliabile prima di tutto controllare la tensione. Controlla la tensione 1.2 V dell'output del regolatore di commutazione. Il nucleo dell'FPGA verrà in seguito alimentato da questa tensione. Può accadere rapidamente che i resistori del partitore di tensione di retroazione siano invertiti e che l'eccessiva tensione distrugga l'FPGA. Se invece la tensione è ok, allora R8 può essere saldato. Dopodiché, puoi controllare tutte le tensioni sui pad di saldatura del pin header J2 disassemblato (Figura 5). In ogni caso, l'alimentazione 1.2 V può essere misurata solo dopo aver assemblato R8. Se la scheda è alimentata da corrente, il LED D1 dovrebbe accendersi, segnalando così che la tensione di esercizio di 3.3 V è presente. Successivamente bisogna testare se il microcontroller STM32 viene riconosciuto dall'USB. Per eseguire questo passaggio, connetti il PC alla scheda tramite cavo USB mentre il pulsante BOOT viene premuto, al che il microcontroller si collega al computer come "DFU Bootloader".

Software
Flashare il microcontroller STM32

Per eseguire il flash del microcontroller, bisogna prima avviare quest'ultimo con il bootloader DFU. Per eseguire questo step, tieni premuto il pulsante BOOT mentre connetti la scheda all'USB. In breve tempo il controller dovrebbe connettersi al computer come "DFU Bootloader". Con Linux puoi usare il tool dfu-util [3] per eseguire il flash del firmware:

dfu-util -v -d 0483:df11 -a 0 -s 0x08000000 -D
 usbdiver.bin

Dopo aver effettuato il flashing e il reset con successo, il controller dovrebbe venire segnalato come USBDiver.

Installazione GoLang

Le librerie sono state scritte nel linguaggio di programmazione GoLang, il quale deve prima essere scaricato e installato. GoLang è disponibile in [4] per architetture e sistemi operativi multipli. Puoi trovare le istruzioni di installazione anche sul sito web. Dopo l'installazione e il set up delle variabili d'ambiente, riavvia il computer.

Installazione del programma di test

Se GoLang è stato installato correttamente, il programma di test può essere compilato. Inizialmente otterrai (su Raspi o Linux-PC) il pacchetto GIT:

go get gitlab.com/microengineer18/pidiver1.3/golang/
 pidiver
 cd $GOPATH/src/gitlab.com/microengineer18/pidiver1.3/
 golang/pidiver/main
 go get -d ./…
 go build

Ora la fase di test può cominciare. Se vuoi usare PiDiver su Raspberry Pi, avvia il programma in questo modo:

$ sudo ./main -t pidiver

(Nota: sudo è importante, senza di esso non è possibile effettuare alcun accesso hardware diretto a SPI).
Se vuoi utilizzare PiDiver con USB, digita il seguente codice su PC Linux:

$ ./main -t usbdiver

L'output risulta simile in entrambi i casi:

…
 2018/07/14 09:09:02 Found nonce: 0005e423 (mask:
 00000010)
 2018/07/14 09:09:02 PoW-Time: 172ms (15.62MH/s)
 2018/07/14 09:09:02 Nonce-Trytes:
 PIDIVER9V9999999OMKVVNGMMMM
 2018/07/14 09:09:02 hash: RIRQYZKVJIDQIO9RBPLCJTSRTJ
 CWFVOODAMKXFHRJMFZQLR9AJPLCNYEPW9IJCEJWRBTVTRIWZY
 DA9999
 2018/07/14 09:09:03 Found nonce: 00094b5e (mask:
 00000020)
 2018/07/14 09:09:03 PoW-Time: 265ms (16.03MH/s)
 2018/07/14 09:09:03 Nonce-Trytes:
 PIDIVER9T9999999UNGEKTVMMMM
 2018/07/14 09:09:03 hash: EIW9MEACXYGVAQFCUGAKGMXKNC
 PGMMSPQWOLGMHZWHZKUEOLNRFKJGMNSELCSLRAEVCLYCBREBW
 TZ9999
 …

Il programma di test calcola i noncents di transazioni random e dà come risultato di output l'hash della transazione, che, nel caso della rete principale IOTA, finisce sempre con "9999" (3 trits, che sono 0, corrispondono a 9 quando emesse -in uscita- come un tryte).
C'è anche un server (eseguito su Raspberry Pi, ma anche su Linux PC) che accetta il comando attachToTangle [5] della API di IOTA e calcola i noncents per le transazioni reali.
A questo punto, comunque, le referenze consistono in un'ulteriore documentazione [6] di cui non ci occuperemo al momento, poiché si discosta dall'argomento chiave trattato nell'articolo.

Potere al Pi!

Per poter operare in modo adeguato, è importante utilizzare cavi in grado di trasportare la corrente necessaria. Per alimentare Raspberry Pi dovresti usare un cavo USB come quello utilizzato per batterie Powerbank. L'alimentazione deve essere in grado di fornire 5 V effettivi a 2 A effettivi! Le operazioni che implicano l'uso dell'USB del PC richiedono cavi capaci di sopportare una corrente di almeno 500 mA. Se utilizzi il cavo sbagliato, oppure un'alimentazione di corrente (anche lievemente) troppo debole, l'FPGA perderà la configurazione subito dopo aver avviato il processo di proof of work.

Lo sviluppo del PiDiver

Il protocollo proof of work di IOTA ha il compito di proteggere il tangle dallo spam, ma diventa anche un ostacolo per molte applicazioni valide, le quali hanno bisogno di inviare dati al tangle in maniera rapida.
L'intera questione è piuttosto complessa a livello di CPU, anche quando si tratta dei computer più potenti, figuriamoci per i sistemi IoT più piccoli. Per esempio, Raspberry Pi necessita di 90 secondi in media per risolvere il problema relativo a PoW.
Per questa ragione è stato lanciato il progetto PiDiver. Innanzitutto, un "proof-of-concept" è stato sviluppato su una scheda di sviluppo (Altera DE1) vecchia dieci anni. L'ambiente di sviluppo Altera Quartus 13.0.1 è stato utilizzato perché l'FPGA Cyclone non è più supportato dalle versioni più recenti. Il nucleo del PiDiver è stato scritto in VHDL, basato sul codice di riferimento "Pearl-Diver" (in Java) da Sergey Ivancheglo [12]. Prima di tutto si ottiene una performance di hashing di circa 4.6 MHash/s, performance che può subito dopo essere migliorata fino a raggiungere 12.9 MHash/s. Per poter utilizzare l'FPGA con le librerie IOTA [7], la libreria "dcurl" [8] è stata estesa dal controller hardware SPI per Raspberry Pi e da un modulo di implementazione del set di comandi per FPGA.
La libreria dcurl è un'alternativa più veloce della libreria ccurl del proof of work (libreria della Fondazione IOTA [9]), perché supporta l'implementazione PoW in C e anche il set di istruzioni GPU e CPU con SSE o AVX. L'allora ufficiale wallet della Fondazione IOTA [10] - un'app Electron - utilizzava ccurl come libreria esterna, dato che lo stesso wallet era scritto in Javascript, ma si trattava di una soluzione relativamente lenta per PoW. Questa libreria poteva essere sostituita con dcurl. Più tardi una libreria separata PiDiver e un programma di test sono stati sviluppati in GoLang, rendendo così dcurl obsoleta e non più necessaria. Durante le prime fasi di ottimizzazione PoC, il design del PCB di PiDiver veniva sviluppato con KiCad. Lo schema base del circuito è stato preso dalla scheda dati di Intel e alcune raccomandazioni inerenti al design sono state usate per il layout. La prima scheda di circuito è stata testata con successo nel maggio del 2018, con una performance di hashing approssimativamente di 14.8 MHash/s. La prima versione della scheda di circuito è stata testata nel maggio del 2018. Complessivamente esistono 4 versioni di questa scheda.
Le prime due erano equipaggiate con un microcontroller STM32F1 poi rimpiazzato, dalla terza versione in poi, da un STM32F3 per funzionalità bootloader. Nella seconda versione, è stata utilizzata un'alimentazione elettrica ottimizzata perché i regolatori di switching della prima versione erano troppo grandi. La versione 3 comprende una protezione ESD, filtri EMC su USB, i due MAX40200 ("diodi ideali") e un DFU con funzione bootloader. La quarta versione include dei fori di montaggio per un dissipatore di calore, dei pulsanti e dei pin header più compatti (e quindi più numerosi) per le tue estensioni. Il firmware per il microcontroller STM32 è stato sviluppato in C++ con Eclipse.

(Dalla Parte 1 dell'articolo)

Un Proof of Work (PoW) IOTA richiede molta potenza di elaborazione, il che rende molto lenta la trasmissione delle transazioni su microcontrollori relativamente piccoli. Uno dei motivi principali è che non è raro dover calcolare diversi milioni di hash (usando l'algoritmo Curl-P81) prima di trovare una soluzione al problema di calcolo. Anche con processori x86 avanzati, questa operazione non può essere eseguita in modo molto efficiente. Nella prossima puntata presenteremo un porting open source dell'algoritmo IOTA Pearl Diver su un HAT Raspberry Pi che accelera notevolmente il processo PoW. Questo "PiDiver" può generare fino a 15,8 MH/s, consentendo di ridurre di un fattore 300 il tempo necessario per il proof of work. L'FPGA non è solo più veloce di un processore i5 a quattro core in pieno regime con una libreria SSE multithread ottimizzata, ma consuma anche solo una frazione della potenza.

PiDiver musicale

Il PiDiver è sostanzialmente una scheda FPGA versatile che fornisce pin inutilizzati per le applicazioni tramite pin header.
Per esempio, è stato testato un emulatore hardware C64 capace di riprodurre musica a 8-bit 80s nello stereo tramite un convertitore digitale-analogico I2S connesso alla scheda. La libreria utilizzata è libsidplayfp, la quale fornisce un emulatore di software che può essere usato per riprodurre musica SID su PC. La libreria genera internamente immagini RAM e ROM, che vengono eseguite su C64 emulato. Anche se l'hardware C64 non è stato programmato per la riproduzione di immagini, funziona piuttosto bene. Facciamo i nostri complimenti agli sviluppatori di questa libreria! Trovi un video con PiDiver che riproduce musica in [11].

Web Links

[1] First part of the series: www.elektormagazine.com/180361-02
[2] GIT Project Repository: www.gitlab.com/microengineer18/pidiver1.3
[3] DFU Tool: http://dfu-util.sourceforge.net/
[4] GoLang: https://golang.org/
[5] Attach to Tangle: https://iota.readme.io/reference#attachtotangle
[6] PiDiver Documentation: https://ecosystem.iota.org/tutorials/pidiver-usbdiver-documentation
[7] IOTA Ledger: https://github.com/iotaledger
[8] Library dcurl : https://github.com/DLTcollab/dcurl
[9] Library ccurl : https://github.com/iotaledger/ccurl
[10] IOTA Foundation Wallet: https://github.com/iotaledger/wallet
[11] Musical PiDiver: www.youtube.com/watch?v=GhgDCf9oBEo
[12] PearlDiver: https://github.com/Come-from-Beyond/PearlDiver

ARTICOLO ORIGINALE IN INGLESE AL LINK: IOTA Crypto Currency (and an FPGA for the RPi) | Elektor Magazine

Scarica subito una copia gratis

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend