Zum Inhalt springen
buybitcoinsmart

Glossar / Entwicklerreferenz

MSG_CMPCT_BLOCK

Was ist MSG_CMPCT_BLOCK?
MSG_CMPCT_BLOCK, der Inventartyp 4, ist ein reiner Anforderungscode: Er erscheint nie in einer Ankündigung und ist nur innerhalb einer getdata-Nachricht zulässig, die an einen Peer gesendet wird, der zuvor zugestimmt hat.

Spezifiziert im BIP-152.

Kompakte Blöcke werden ausgehandelt, nicht angekündigt. Ein Peer sendet einmal sendcmpct, um zu erklären, dass er sie annimmt, und erst dann darf die andere Seite einen neuen Block mit Typ 4 statt mit Typ 2 beantworten. BIP152 kam mit Bitcoin Core 0.13.0 im August 2016, und die Ersparnis ist der ganze Sinn der Sache: sechs Bytes, um eine Transaktion zu benennen, die der Empfänger bereits hat, statt der zweihundert oder mehr Bytes, die nötig sind, um sie zweimal zu übertragen.

So funktioniert es

MSG_CMPCT_BLOCK fordert eine Beschreibung eines Blocks statt des Blocks an, und diese Beschreibung lohnt sich nur, wenn beide Nodes ähnliche Mempools haben.

Zuerst kommt die Aushandlung. Die Nachricht sendcmpct trägt ein Flag und eine Versionsnummer: Version 1 identifiziert Transaktionen über die txid, Version 2 über die Witness-txid und ist seit Segregated Witness die einzige, die verwendet wird. Ein Node darf Typ 4 niemals in eine getdata-Nachricht an einen Peer setzen, der kein sendcmpct gesendet hat, denn dieser Peer ist nicht verpflichtet, ihn zu verstehen.

Die Antwort ist eine cmpctblock-Nachricht mit dem 80 Byte großen Header, einem acht Byte großen Nonce, einem sechs Byte großen kurzen Identifikator pro Transaktion und einigen vollständig mitgelieferten Transaktionen, darunter immer die Coinbase, die der Empfänger unmöglich schon gesehen haben kann. Kurze Identifikatoren werden mit SipHash erzeugt, dessen Schlüssel sich aus dem Header und diesem Nonce ableitet, sodass sie für jeden Block und jede Anfrage anders ausfallen. Die Randomisierung ist eine Verteidigung: Ein festes Verfahren würde es einem Angreifer erlauben, zwei kollidierende Transaktionen vorab zu berechnen und die Rekonstruktion im gesamten Netzwerk auf einmal lahmzulegen.

Der Empfänger gleicht die Identifikatoren mit seinem Mempool ab, fordert Fehlendes mit getblocktxn an und baut den Block lokal wieder zusammen. Die anschließende Validierung ist gewöhnlich, und keine Konsensregel wird berührt.

Die Tiefe ist begrenzt. Bitcoin Core bedient einen kompakten Block nur für die fünf jüngsten Blöcke und beantwortet eine Anfrage für alles Ältere mit einem vollständigen Block, weil ein so weit zurückliegender Empfänger keinen brauchbaren Mempool hat und am Ende jede Transaktion darin anfordern würde.

Wo er auftritt

Am deutlichsten ist MSG_CMPCT_BLOCK in der eigenen Protokollierung von Bitcoin Core zu sehen, die meldet, wie gut jede Rekonstruktion verlief.

Starten Sie den Node mit -debug=cmpctblock, und jeder neue Block erzeugt eine Zeile, die angibt, wie viele Transaktionen vorab mitgeliefert wurden, wie viele im Mempool gefunden wurden und wie viele abgerufen werden mussten. Auf einem Rechner, der seit Stunden läuft, ist die Zahl der abgerufenen Transaktionen meist null, und der Block kommt als einige zehn Kilobyte statt als anderthalb Megabyte an. Ein Block mit 3.000 Transaktionen benötigt 18.000 Bytes an kurzen Identifikatoren plus den Header und die Coinbase.

Diese Rechnung bricht auf einem frisch gestarteten Node zusammen. Ein leerer Mempool bedeutet, dass kein Identifikator passt, die Nachfolgeanfrage den gesamten Block anfordert und der zusätzliche Roundtrip den kompakten Weg langsamer macht, als es das direkte Anfordern des Blocks wäre. Deshalb gehört der Code zu Nodes an der Spitze der Kette und erscheint nie während einer initialen Synchronisierung.

Für alle, die zu Hause einen Node betreiben, ist dies die Funktion, die entscheidet, ob eine gewöhnliche Verbindung mit dem Netzwerk Schritt hält oder jedes Mal zurückfällt, wenn ein Block gefunden wird.

Nicht zu verwechseln mit

Häufig gestellte Fragen

Warum kann dieser Inventartyp nur in einer getdata-Nachricht erscheinen?

Weil ein kompakter Block nur von einem Peer dekodiert werden kann, der ihn angefordert und zuvor eine Version ausgehandelt hat. Eine Ankündigung wäre bedeutungslos, deshalb beschränkt BIP152 den Code auf Anfragen und verlangt vorher eine sendcmpct-Nachricht.

Ändern kompakte Blöcke, was als gültiger Block gilt?

Nein. Sie ändern nur, wie ein Block übertragen wird. Der Empfänger baut aus seinem Mempool exakt dieselben Bytes wieder zusammen und validiert sie anschließend wie gewohnt anhand der Konsensregeln.

Verwandte Begriffe

Mehr zum Thema Entwicklerreferenz

Diese Seite auf Englisch lesen