Glossario / Nodi e software
Filtro di Bloom
Noto anche come BIP37.
- Che cos'è un filtro di Bloom?
- Un filtro di Bloom è un insieme probabilistico compatto che i wallet leggeri BIP37 inviavano a un nodo completo, così che il nodo inoltrasse loro solo le transazioni che plausibilmente appartenevano a loro.
Specificato nel BIP-37.
Il progetto barattava la larghezza di banda con quella che i suoi autori speravano fosse privacy, e la privacy non arrivò mai. Bitcoin Core ha smesso di servire questi filtri per impostazione predefinita nella versione 0.19.0, pubblicata a novembre 2019, dopo che anni di ricerca hanno mostrato quanto rivelano. Un wallet che si affida ancora a un filtro sta consegnando alla macchina di uno sconosciuto un elenco utilizzabile dei bitcoin che possiedi.
Come funziona
Stato: il filtro di Bloom di BIP37 è stato disattivato per impostazione predefinita in Bitcoin Core 0.19.0 a novembre 2019, e i filtri compatti dei blocchi di BIP157 e BIP158 hanno assunto il compito dei wallet leggeri.
Un filtro di Bloom è un array di bit più una manciata di funzioni hash. Per inserire un elemento lo si calcola con l'hash in diversi modi, si prende ogni risultato modulo la lunghezza dell'array e si impostano quei bit a uno. Per verificare un elemento lo si calcola con l'hash negli stessi modi e si guardano quei bit. Se uno di quei bit è zero, l'elemento non è stato certamente mai inserito; se sono tutti uno, l'elemento è stato probabilmente inserito, oppure altre inserzioni hanno impostato per caso gli stessi bit. I falsi negativi non possono verificarsi. I falsi positivi sì, e la loro percentuale è il parametro da regolare.
BIP37 ha fissato l'aritmetica. Un filtro è limitato a 36.000 byte e 50 funzioni hash, e l'hash usa la versione 3 della funzione Murmur a 32 bit, inizializzata con il numero di hash moltiplicato per 0xFBA4C795 più un tweak scelto dal client. Tre messaggi lo gestiscono: filterload installa un filtro sulla connessione, filteradd lo estende, filterclear lo rimuove. Una volta impostato un filtro, il peer risponde a una richiesta di blocco con un merkleblock che porta l'intestazione di 80 byte, le transazioni corrispondenti e i rami di Merkle che dimostrano che appartengono a quel blocco. BIP111 ha poi aggiunto il bit di servizio NODE_BLOOM, così che un nodo potesse annunciare se avrebbe collaborato o meno.
La questione della privacy si reggeva interamente su quella percentuale di falsi positivi. Allarga il filtro, cattura le transazioni di sconosciuti insieme alle tue, e secondo la tesi un osservatore non può distinguere quali siano quali. La tesi non regge. Un lavoro accademico pubblicato nel 2014 ha mostrato che un filtro con un numero realistico di indirizzi ne rivela la maggior parte, e che due filtri caricati dallo stesso wallet possono essere intersecati per togliere del tutto il camuffamento. Riconnettersi a un nuovo peer con un nuovo filtro peggiora il problema, non lo migliora.
L'altro difetto era più semplice da spiegare. Servire un filtro significa scansionare i blocchi dal disco su richiesta di uno sconosciuto, quindi qualsiasi peer poteva far svolgere a un nodo con un disco meccanico una quantità enorme di lavoro non retribuito. È quella motivazione legata al denial of service, non la ricerca sulla privacy, ad aprire le note di rilascio della versione 0.19.0.
Dove lo vedi
I filtri di Bloom sopravvivono soprattutto nel software scritto prima del 2019 e nei file di configurazione che aggirano la loro assenza.
I wallet Android costruiti sulla biblioteca software bitcoinj usavano BIP37 come unico backend della catena, e alcuni sono ancora installati. Anche Bisq ne aveva bisogno, ed è per questo che la sua documentazione era solita indicare di aggiungere peerbloomfilters=1 alla configurazione del proprio nodo. Quella riga è l'indizio: quando un programma ti chiede di riattivare il filtro di Bloom su un nodo che gestisci, ti sta chiedendo una tecnica che il client di riferimento ha disattivato per buone ragioni.
Il sostituto moderno funziona al contrario. Con BIP157 e BIP158 il nodo costruisce un filtro per blocco e lo pubblica a tutti, e il wallet confronta sul proprio hardware, così nulla dei tuoi indirizzi lascia il dispositivo.
Filtro di Bloom vs SPV
Un filtro di Bloom era un meccanismo di consegna; la verifica semplificata dei pagamenti è un modello di fiducia, e confondere i due porta a supporre che il modello sia morto con il meccanismo. SPV significa verificare che una transazione stia sotto la radice di Merkle di un'intestazione nella catena con più lavoro, senza validare il resto del contenuto di quella catena. Quel ragionamento è invariato. Ciò che è cambiato è come un wallet leggero trova le transazioni che vale la pena verificare: prima trasmetteva uno schizzo approssimativo dei propri indirizzi e sperava, ora scarica un filtro per blocco e lo verifica in locale.