Introduzione A metà settembre 2022, Ethereum ha completato con successo The Merge, l’aggiornamento che ha segnato il passaggio alla cosiddetta Ethereum 2.0 e, in particolare, dalla Proof-of-Work (PoW) alla Proof-of-Stake (PoS). Con questo evento, la Beacon Chain è stata integrata nella mainnet ed è stato adottato Gasper come nuovo meccanismo di consenso. Gasper è un protocollo di consenso ibrido composto da due componenti principali: LMD GHOST (Latest Message Driven Greedy Heaviest Observed SubTree): una fork choice rule impiegata per garantire la liveness del sistema. Casper FFG (Friendly Finality Gadget): un protocollo che introduce la finalità dei blocchi, caratteristica tipica dei sistemi di consenso basati su Proof-of-Stake. L’analisi congiunta del funzionamento di questi due protocolli può risultare complessa. Per questo motivo, in questo articolo ci concentreremo esclusivamente su LMD GHOST, approfondendone il funzionamento nel dettaglio, senza considerare le implicazioni di Casper FFG. LMD GHOST: Una Prima Presentazione LMD GHOST è una fork choice rule che, insieme a Casper FFG, costituisce il cuore del protocollo di consenso Gasper, adottato da Ethereum con il passaggio alla Proof-of-Stake. Il nome è formato da due acronimi distinti: LMD (Latest Message Driven) e GHOST (Greedy Heaviest Observed SubTree), che fanno riferimento a due protocolli separati. Questi sono stati combinati e adattati da Ethereum per dar vita a una propria versione personalizzata del protocollo GHOST. GHOST Il protocollo GHOST nasce nel 2013 dalle menti di Yonatan Sompolinsky e Aviv Zohar, con l’obiettivo di migliorare il funzionamento di Bitcoin. In particolare, l’intento era quello di aumentare il numero di transazioni al secondo (TPS) processabili dalla rete in modo sicuro e affidabile. Due delle strategie comunemente proposte per incrementare il throughput sono: Aumentare la dimensione dei blocchi: in questo modo è possibile inserire più transazioni in ciascun blocco. Ridurre l’intervallo di produzione dei blocchi: si incrementa così il numero di slot disponibili per includere nuove transazioni in un dato intervallo di tempo. Tuttavia, entrambe le soluzioni presentano delle criticità. Blocchi più grandi richiedono più tempo per essere trasmessi e verificati da tutti i nodi della rete. Se la propagazione impiega troppo tempo, aumenta la probabilità che più miner risolvano simultaneamente la Proof-of-Work, producendo blocchi differenti. Questo genera fork e, di conseguenza, reorg. D’altra parte, blocchi prodotti troppo frequentemente rischiano di non raggiungere tutti i nodi in tempo utile. In tal caso, più nodi potrebbero lavorare su blocchi concorrenti, dando origine a blocchi orfani (stale blocks), validi ma non inclusi nella chain principale perché appartenenti a rami secondari. Nozioni in Pillole: Fork e Reorg 💡 Un fork è una situazione in cui due o più blocchi validi vengono prodotti quasi simultaneamente e diffusi nella rete, creando rami paralleli della blockchain. Un reorg (reorganization) avviene quando un nodo abbandona il ramo su cui stava costruendo per adottare un ramo alternativo ritenuto più valido. Ciò comporta la sostituzione delle transazioni presenti nel ramo abbandonato con quelle del ramo scelto, con potenziali ripercussioni sulla sicurezza della rete e sull’affidabilità delle conferme. La gestione dei fork è dunque cruciale per la sicurezza e la stabilità del protocollo. A differenza di Bitcoin, che si basa sulla regola della heaviest-chain rule per determinare quale ramo sia valido, GHOST introduce un approccio differente, da cui prende il nome: (G) → Greedy: un algoritmo è definito Greedy quando va a valutare un problema costruendo la soluzione passo a passo, facendo ogni volta valutazioni locali piuttosto che globali. (H) → Heaviest: GHOST non valuta semplicemente la lunghezza della chain, bensì il peso complessivo di ogni ramo. In Ethereum, ad esempio, questo peso viene calcolato in base al numero e al bilancio effettivo delle attestazioni ricevute da ogni blocco. (O) → Observed: l’algoritmo opera in base alle informazioni effettivamente osservate da ciascun nodo, quindi lavora su una visione locale e non globale della rete. (ST) → SubTree: sebbene la blockchain venga comunemente immaginata come una catena lineare di blocchi, in realtà può essere rappresentata come un albero, dove ogni blocco può avere più figli. GHOST seleziona il sottoalbero (subtree) con il maggior peso cumulato. Se il funzionamento del protocollo GHOST non ti è ancora del tutto chiaro, non preoccuparti: questa sezione è stata pensata per offrire una visione introduttiva e generale. Nelle prossime parti dell’articolo analizzeremo più nel dettaglio l’impiego di GHOST in Ethereum, anche attraverso esempi pratici, così da rendere il tutto più concreto e comprensibile. LMD LMD (Latest Message Driven) è il protocollo utilizzato da Ethereum per estendere GHOST e renderlo in grado di gestire le attestazioni. In Ethereum, un’attestazione è una votazione firmata rilasciata da un validatore, con cui dichiara: La correttezza della chain: Il validatore esprime quale blocco considera come head (cioè il blocco valido più recente) secondo la logica dell’algoritmo LMD GHOST. Lo stato di giustificazione/finalizzazione dei blocchi: il validatore vota per una coppia di checkpoint (source e target) che, a suo giudizio, dovrebbe essere utilizzata per finalizzare la blockchain, come previsto dal protocollo Casper FFG. Tale funzionalità verrà indagata approfonditamente nel prossimo articolo dedicato a Casper FFG. Attraverso le attestazioni è possibile attribuire un peso ai fork concorrenti all’interno della rete Ethereum, e stabilire quale ramo debba prevalere. Queste attestazioni vengono trasmesse nella rete sotto forma di messaggi firmati, il che giustifica il termine Message Driven (MD): il protocollo prende le decisioni in base ai messaggi ricevuti dai validatori. Il termine Latest (L) indica che, per ciascun validatore, viene considerata soltanto l’ultima attestazione ricevuta. Ogni nuova attestazione sovrascrive la precedente, rendendo l’algoritmo efficiente e reattivo agli aggiornamenti della rete. Ethereum Foundamentals In questa sezione verranno introdotti alcuni concetti fondamentali legati alla struttura di Ethereum, al fine di fornire le basi necessarie per comprendere al meglio le sezioni successive. Epoca (Epoch): Un’epoca su Ethereum rappresenta un intervallo di tempo della durata di circa 6 minuti e 24 secondi. Ogni epoca è suddivisa in 32 slot, ciascuno della durata di 12 secondi. In ogni slot viene selezionato un validatore per proporre un nuovo blocco e trasmetterlo alla rete. Bilancio effettivo del validatore: i validatori su Ethereum possiedono due tipi di bilanci: il bilancio attuale, che rappresenta il saldo reale del validatore, e il bilancio effettivo, utilizzato dal protocollo per determinare premi e penalità, con un tetto massimo di 32 ETH. Il bilancio effettivo viene aggiornato periodicamente in funzione del bilancio attuale e varia a scaglioni da 1 ETH. Se, ad esempio, il bilancio attuale supera i 32,25 ETH, il bilancio effettivo raggiunge il limite massimo di 32 ETH. Viceversa, se il bilancio attuale scende a 31,75 ETH, il bilancio effettivo sarà pari a 31 ETH. Checkpoint: Un checkpoint è il primo blocco di ogni epoca e svolge un ruolo centrale nel protocollo di finalità Casper FFG. Due checkpoint presi in coppia (definiti rispettivamente source e target) delimitano un intervallo di 32 blocchi che può essere giustificato o finalizzato in base ai voti espressi dai validatori. I checkpoint sono rilevanti anche per la fork choice rule LMD GHOST, il cui utilizzo verrà analizzato più avanti nel dettaglio. Il Funzionamento di LMD GHOST LMD GHOST, come illustrato in precedenza, è una fork choice rule che unisce due protocolli con l’obiettivo di rendere le attestazioni determinanti nella scelta del ramo prevalente della blockchain. In ogni epoca, ogni validatore emette una singola attestazione. Poiché il numero di validatori su Ethereum è molto elevato, all’inizio di ogni epoca ciascuno viene assegnato a un comitato. Il compito del comitato è duplice: proporre un blocco nello slot assegnato ed emettere l’attestazione relativa. Le attestazioni vengono poi propagate agli altri nodi, sia attraverso l’inclusione nei blocchi, sia tramite messaggi dedicati diffusi sulla rete. Quando un nodo riceve nuove attestazioni, aggiorna il proprio storage locale, sovrascrivendo le attestazioni precedenti dei relativi validatori. Questo storage rappresenta la visione locale della chain da parte del nodo e costituisce la base su cui opera LMD GHOST. Gli elementi essenziali che ogni nodo mantiene aggiornati sono: l’elenco dei blocchi conosciuti della blockchain; l’ultima attestazione valida ricevuta da ciascun validatore; il bilancio effettivo di ogni validatore (utilizzato per pesare i voti). Una volta compreso il processo di emissione e gestione delle attestazioni, possiamo analizzare come viene selezionato il ramo di blocchi prevalente secondo LMD GHOST. Scegliere il fork prevalente significa identificare l’ultimo blocco valido, detto head, sul quale costruire nel prossimo slot. Ipotizziamo che lo stato attuale della nostra blockchain sia il seguente. Dopo la creazione dei blocchi A e B, si è verificato un fork che ha diviso la blockchain in due rami distinti. Il primo ramo prosegue attraverso i blocchi C, E, G, I, mentre il secondo ramo si sviluppa tramite i blocchi D, F, H, L. Quest’ultimo subisce a sua volta un ulteriore fork dopo il blocco F, generando due sequenze alternative: D → F → H e D → F → L. Se applicassimo la fork choice rule di Bitcoin, ovvero la longest-chain rule, il ramo prevalente sarebbe quello più lungo in termini di numero di blocchi. In questo caso, la chain composta da A → B → C → E → G → I verrebbe considerata la blockchain canonica, in quanto contiene più blocchi rispetto alle altre. Tuttavia, per determinare il ramo prevalente secondo l’algoritmo LMD GHOST, abbiamo bisogno di ulteriori informazioni fondamentali: La lista delle attestazioni. Il bilancio effettivo di ciascun validatore (utilizzato per pesare ogni attestazione). Per semplificare il calcolo, supponiamo che tutti i validatori abbiano un bilancio effettivo pari a 32 ETH, così che ogni attestazione abbia lo stesso peso e possa essere trattata come un singolo punto di voto. Nell’immagine che segue, sono rappresentati i blocchi appartenenti ai diversi rami, insieme alle relative attestazioni ricevute (in rosso), che useremo per eseguire il calcolo LMD GHOST. Per determinare il ramo prevalente secondo LMD GHOST, dobbiamo selezionare quello che, combinato con il resto della blockchain, restituisce il peso totale più elevato. Per calcolare il peso di ciascun ramo, è necessario sommare tutte le attestazioni ricevute dai blocchi del rispettivo subtree. Nel nostro esempio, il ramo C → E → G → I ha raccolto un totale di 32 voti (10 + 12 + 7 + 3), mentre il ramo D → F → H → L ha totalizzato 37 voti (5 + 8 + 15 + 9). Applicando LMD GHOST, potremmo concludere che la blockchain canonica sia rappresentata dalla sequenza A → B → D → F → H → L, in quanto corrispondente al ramo con il maggior numero complessivo di voti. Tuttavia, questa conclusione non è corretta. Come accennato in precedenza, il secondo ramo non presenta una sola estensione lineare, bensì due sottorami alternativi: D → F → H e D → F → L. Anche in questo caso, il criterio di selezione rimane invariato: si sceglie il figlio con il maggior numero di voti, ovvero quello che conferisce più peso al blocco padre. Dal momento che entrambi i subtree sono formati da un solo blocco aggiuntivo (rispettivamente H e L), è immediato confrontarli. Se, ad esempio, H ha ricevuto 15 attestazioni e L soltanto 9, la scelta ricadrà su H. La blockchain canonica sarà quindi: A → B → D → F → H, con H che rappresenta la head della blockchain, ovvero l’ultimo blocco valido sul quale verrà costruito il prossimo blocco nella sequenza. Con questo esempio, spero sia ora più chiaro come LMD GHOST determini la head della blockchain. Restano tuttavia alcuni interrogativi che meritano un ulteriore approfondimento. Perchè LMD GHOST per definire la head della blockchain prende in considerazioni tutte le attestazioni del ramo e non solo quelle degli ultimi blocchi? La chiave per rispondere a questa domanda sta nel fatto che ogni voto dato ad un blocco viene considerato come un voto a favore dell’intero ramo a cui appartiene. La logica sottostante è che, se un validatore considera un determinato blocco come head della chain, implicitamente considera validi anche tutti i blocchi che lo precedono. Perchè LMD GHOST è preferito da molti esperti rispetto alla longhest-chain rule? La presenza di fork è spesso indice di un problema di latenza nella propagazione dei blocchi: il tempo che impiega un blocco a diffondersi in rete è diventato comparabile (o addirittura superiore) all’intervallo tra la produzione dei blocchi (slot). In questi scenari, non tutti i validatori riescono a vedere tutti i blocchi in tempo utile per attestarli o per costruirci sopra. In questo contesto, è importante sfruttare quante più informazioni possibili. I voti espressi per due blocchi figli diversi dello stesso genitore possono essere letti come un consenso condiviso sul genitore stesso, anche se esiste disaccordo sul figlio preferito. LMD GHOST tiene di considerazione di questa preferenza permettendo ad ogni voto espresso per un blocco figlio di contribuire al peso anche di tutti i suoi antenati. In questo modo, quando si tratta di scegliere tra più rami, viene favorito quello che raccoglie il supporto complessivo maggiore da parte dei validatori. La longest-chain rule, invece, ignora completamente queste informazioni: considera soltanto la lunghezza della chain, perdendo un’enorme quantità di segnali utili provenienti dal comportamento dei validatori/miner. Come faccio a capire da quale blocco dovrei partire per eseguire LMD GHOST? Nell’esempio abbiamo iniziato dal blocco A, ma in un contesto reale come Ethereum, come si determina questo punto di partenza? LMD GHOST non può essere applicato su tutta la chain indiscriminatamente. Si parte sempre dall’ultimo checkpoint giustificato dato che una volta che un checkpoint viene finalizzato (tramite Casper FFG), tutti i blocchi che lo precedono non possono più essere modificati. Questo significa che non è possibile eseguire le reorg derivanti da LMD GHOST su quella parte di blockchain. LMD GHOST si applica solo alla parte non ancora finalizzata della blockchain, e dunque partendo dall’ultimo checkpoint giustificato. Ricompense e Penalità nel Protocollo LMD GHOST Il protocollo LMD GHOST prevede un sistema di incentivi e penalità per garantire che i validatori seguano correttamente la fork choice rule e contribuiscano al buon funzionamento della rete. Le ricompense per i proposer (coloro che propongono nuovi blocchi) e per gli attester (coloro che validano tramite attestazioni) sono diverse, così come lo sono i rischi di incorrere nello slashing, la principale forma di penalità nel Proof-of-Stake. Ricompense Per i proposer, la ricompensa è implicita: se costruiscono un blocco sulla head corretta della blockchain, aumentano le probabilità che il blocco venga incluso nella catena canonica, ottenendo così la ricompensa prevista per la proposizione del blocco. Al contrario, costruire su una head errata potrebbe comportare l’esclusione del blocco dalla chain e quindi la perdita della ricompensa. Gli attester, invece, ricevono una micro-ricompensa ogni volta che la loro attestazione individua correttamente la head della chain, ovvero quella che sarà effettivamente adottata come parte della chain canonica. Un validatore che si comporta perfettamente può guadagnare circa il 22% delle proprie ricompense totali da queste reward. Penalità: Slashing Le penalità sono necessarie per scoraggiare comportamenti opportunistici o malevoli. Il meccanismo principale è lo slashing, che comporta la rimozione di una parte del saldo del validatore colpevole e, in alcuni casi, la sua espulsione dall’insieme dei validatori attivi. Proposer Slashing Quando è il turno di un validatore per proporre un blocco in uno specifico slot, esso deve eseguire la fork choice rule per determinare quale blocco esistente rappresenti la head più probabile della chain. Idealmente, il blocco prodotto deve essere costruito su quella head per minimizzare il rischio di reorg. Nel Proof-of-Stake, a differenza del Proof-of-Work, produrre blocchi ha un costo trascurabile. Ne consegue che un validatore disonesto potrebbe proporre blocchi multipli su più rami del fork, garantendosi che almeno uno dei suoi blocchi venga incluso nella chain canonica. In assenza di penalità, questo comportamento sarebbe razionalmente incentivato. Tuttavia, permette la proliferazione dei fork e ostacola la convergenza della rete su una chain unica, esponendola a rischi come il double spending. Per contrastare ciò, il protocollo consente ad attori terzi di costruire e inserire una prova (proposer slashing) all’interno di un blocco successivo. Tale prova consiste semplicemente in due blocchi firmati dallo stesso validatore per lo stesso slot, ma costruiti su rami differenti. Una volta pubblicata la prova, il protocollo punisce il validatore con lo slashing. Attester Slashing Un meccanismo simile è previsto anche per le attestazioni. Quando è il turno di un validatore di pubblicare un’attestazione, egli è tenuto ad applicare la fork choice rule per votare la head che ritiene valida. Un validatore disonesto potrebbe però emettere più attestazioni contraddittorie, ad esempio per: ostacolare il consenso, allungare i tempi di convergenza, o massimizzare le ricompense in scenari borderline, dove è indeciso su quale head votare. Come nel caso dei proposer, il protocollo può rilevare e punire attestazioni contraddittorie, ovvero voti emessi dallo stesso validatore nello stesso slot ma per blocchi differenti. Anche qui, la prova è costituita da due attestazioni firmate e pubblicate in un blocco successivo, che portano all'attivazione dello slashing. Conclusione L’adozione di LMD GHOST da parte di Ethereum rappresenta una scelta architetturale mirata a garantire liveness in un contesto Proof-of-Stake con molti nodi e forte variabilità di latenza di rete. Con liveness si intende la capacità della rete di garantire a nuove transazioni e nuovi blocchi di essere sempre aggiunti alla chain, senza che vi siano interruzioni. A differenza di meccanismi più semplici come la longest-chain rule, LMD GHOST introduce una fork choice rule più robusta, in grado di sfruttare in modo efficace le informazioni parziali e asincrone raccolte dalla rete, grazie all’utilizzo delle attestazioni firmate e propagate dai validatori. Il protocollo combina la struttura ad albero dei blocchi con un sistema di votazione pesata che considera l’ultima attestazione valida di ciascun validatore, determinando il blocco head attraverso l’analisi ricorsiva dei subtree con peso cumulativo massimo, calcolato in funzione del bilancio effettivo dei validatori votanti. Questa architettura consente una selezione dinamica e coerente della chain prevalente, anche in presenza di fork multipli, contribuendo a mitigare i problemi legati alla propagazione non uniforme dei blocchi. Allo stesso tempo, il design di LMD GHOST è compatibile con meccanismi di finalità come Casper FFG, utile a determinare parti della chain come non più modificabili. Infine, il sistema di ricompense e penalità associato a LMD GHOST, basato su accuratezza delle attestazioni e sullo slashing, fornisce un modo coerente per incentivare il comportamento onesto e disincentivare le deviazioni strategiche o malevole. Nel prossimo articolo parleremo di come funziona Casper FFG e della visione globale di Gasper, approfondendo i concetti relativi alla liveness e alla safety di un protocollo di consenso.