Vai al contenuto
buybitcoinsmart

Glossario / Riferimento per sviluppatori

MSG_CMPCT_BLOCK

Che cos'è MSG_CMPCT_BLOCK?
MSG_CMPCT_BLOCK, tipo di inventario 4, è un codice riservato alle richieste: non compare mai in un annuncio ed è valido solo all'interno di un messaggio getdata inviato a un peer che lo ha prima accettato.

Specificato nel BIP-152.

I blocchi compatti si negoziano, non si annunciano. Un peer invia sendcmpct una volta per dire che li accetterà, e solo allora l'altra parte può rispondere a un nuovo blocco con il tipo 4 invece del tipo 2. BIP152 è arrivato con Bitcoin Core 0.13.0 ad agosto 2016, e il risparmio è proprio il punto: sei byte per indicare una transazione che il destinatario possiede già, invece dei duecento o più necessari per inviarla due volte.

Come funziona

MSG_CMPCT_BLOCK richiede una descrizione di un blocco invece del blocco, e la descrizione vale la pena solo quando i due nodi hanno mempool simili.

Prima viene la negoziazione. Il messaggio sendcmpct porta un flag e un numero di versione: la versione 1 identifica le transazioni tramite txid, la versione 2 tramite witness txid ed è l'unica in uso dal segregated witness. Un nodo non deve mai mettere il tipo 4 in un getdata destinato a un peer che non ha inviato sendcmpct, perché quel peer non ha alcun obbligo di comprenderlo.

La risposta è un messaggio cmpctblock che contiene l'intestazione di 80 byte, un nonce di otto byte, un identificatore corto di sei byte per transazione e alcune transazioni fornite per intero, tra cui sempre la coinbase, che il destinatario non può in alcun modo aver già visto. Gli identificatori corti sono prodotti con SipHash con chiave derivata dall'intestazione e da quel nonce, quindi cambiano per ogni blocco e per ogni richiesta. La casualizzazione è una difesa: uno schema fisso permetterebbe a un attaccante di precalcolare due transazioni che collidono e di bloccare la ricostruzione in tutta la rete in una volta.

Il destinatario confronta gli identificatori con la propria mempool, chiede ciò che manca con getblocktxn e ricostruisce il blocco localmente. La validazione successiva è quella ordinaria e nessuna regola di consenso viene toccata.

La profondità è limitata. Bitcoin Core serve un blocco compatto solo per i cinque blocchi più recenti e risponde a una richiesta per qualsiasi blocco più vecchio con un blocco completo, perché un destinatario così indietro non ha una mempool utile e finirebbe per chiedere ogni transazione che contiene.

Dove lo vedi

La visione più chiara di MSG_CMPCT_BLOCK è nei log di Bitcoin Core, che riportano come è andata ogni ricostruzione.

Avvia il nodo con -debug=cmpctblock e ogni nuovo blocco produce una riga che indica quante transazioni erano precompilate, quante sono state trovate nella mempool e quante è stato necessario scaricare. Su una macchina in funzione da ore il conteggio delle transazioni scaricate è di solito zero, e il blocco arriva come decine di kilobyte invece di un megabyte e mezzo. Un blocco con 3.000 transazioni richiede 18.000 byte di identificatori corti più l'intestazione e la coinbase.

Quell'aritmetica crolla su un nodo appena avviato. Una mempool vuota significa che ogni identificatore non trova corrispondenze, la richiesta successiva chiede l'intero blocco e il viaggio di andata e ritorno in più rende il percorso compatto più lento del semplice chiedere il blocco direttamente. Per questo il codice appartiene ai nodi che stanno sulla punta della catena e non compare mai durante una sincronizzazione iniziale.

Per chi gestisce un nodo a casa, questa è la funzione che decide se una connessione ordinaria tiene il passo della rete o resta indietro ogni volta che viene trovato un blocco.

Da non confondere con

Domande frequenti

Perché questo tipo di inventario può comparire solo in un messaggio getdata?

Perché un blocco compatto può essere decodificato solo da un peer che lo ha richiesto e ha prima concordato una versione. Annunciarlo non avrebbe senso, quindi BIP152 limita il codice alle richieste ed esige prima un messaggio sendcmpct.

I blocchi compatti cambiano ciò che conta come blocco valido?

No. Cambiano solo il modo in cui un blocco viene trasmesso. Il destinatario ricostruisce esattamente gli stessi byte dalla propria mempool e poi li valida secondo le regole di consenso nel modo abituale.

Termini correlati

Altro in Riferimento per sviluppatori

Leggi questa pagina in inglese