Glossaire / Référence pour développeurs
MSG_CMPCT_BLOCK
- Qu'est-ce que MSG_CMPCT_BLOCK ?
- MSG_CMPCT_BLOCK, type d'inventaire 4, est un code réservé aux requêtes : il n'apparaît jamais dans une annonce et n'est légal qu'à l'intérieur d'un message getdata envoyé à un pair qui l'a accepté au préalable.
Spécifié dans BIP-152.
Les blocs compacts se négocient, ils ne s'annoncent pas. Un pair envoie sendcmpct une fois pour dire qu'il les acceptera, et c'est seulement alors que l'autre partie peut répondre à un nouveau bloc avec le type 4 plutôt que le type 2. Le BIP152 est arrivé avec Bitcoin Core 0.13.0 en août 2016, et l'économie est tout l'intérêt : six octets pour désigner une transaction que le destinataire détient déjà, au lieu des deux cents octets ou plus nécessaires pour la lui envoyer deux fois.
Comment cela fonctionne
MSG_CMPCT_BLOCK demande une description d'un bloc au lieu du bloc, et cette description ne vaut la peine que lorsque les deux nœuds détiennent des mempools similaires.
La négociation vient d'abord. Le message sendcmpct porte un indicateur et un numéro de version : la version 1 identifie les transactions par txid, la version 2 par witness txid et c'est la seule utilisée depuis segregated witness. Un nœud ne doit jamais mettre le type 4 dans un getdata destiné à un pair qui n'a pas envoyé sendcmpct, car ce pair n'a aucune obligation de le comprendre.
La réponse est un message cmpctblock contenant l'en-tête de 80 octets, un nonce de huit octets, un identifiant court de six octets par transaction, et quelques transactions fournies en entier, dont toujours la coinbase, que le destinataire n'a pas pu voir auparavant. Les identifiants courts sont produits avec SipHash, dont la clé dérive de l'en-tête et de ce nonce, de sorte qu'ils diffèrent pour chaque bloc et chaque requête. Cette randomisation est une défense : un schéma fixe permettrait à un attaquant de précalculer deux transactions qui entrent en collision et de bloquer la reconstruction sur tout le réseau d'un seul coup.
Le destinataire compare les identifiants à sa mempool, demande ce qui manque avec getblocktxn et reconstruit le bloc localement. La validation qui suit est ordinaire, et aucune règle de consensus n'est touchée.
La profondeur est limitée. Bitcoin Core ne sert un bloc compact que pour les cinq blocs les plus récents et répond à toute demande plus ancienne par un bloc complet, car un destinataire aussi en retard n'a pas de mempool utile et finirait par demander chaque transaction qu'il contient.
Où le voir
La vue la plus claire de MSG_CMPCT_BLOCK est la journalisation de Bitcoin Core elle-même, qui indique la qualité de chaque reconstruction.
Lancez le nœud avec -debug=cmpctblock et chaque nouveau bloc produit une ligne indiquant combien de transactions ont été préremplies, combien ont été trouvées dans la mempool et combien ont dû être récupérées. Sur une machine qui tourne depuis des heures, le nombre de transactions récupérées est généralement nul, et le bloc arrive en dizaines de kilo-octets plutôt qu'en un mégaoctet et demi. Un bloc contenant 3 000 transactions nécessite 18 000 octets d'identifiants courts, plus l'en-tête et la coinbase.
Ce calcul s'effondre sur un nœud fraîchement démarré. Une mempool vide signifie que chaque identifiant rate, que la requête de suivi demande le bloc entier, et que l'aller-retour supplémentaire rend le chemin compact plus lent que la simple demande du bloc. C'est pourquoi ce code appartient aux nœuds situés à la pointe de la chaîne et n'apparaît jamais pendant une synchronisation initiale.
Pour quiconque exploite un nœud chez soi, c'est la fonctionnalité qui décide si une connexion ordinaire suit le rythme du réseau ou prend du retard chaque fois qu'un bloc est trouvé.