Der Newsletter dieser Woche beschreibt, wie der Schwellenwert für die Gefahr von Selfish Mining berechnet werden kann, fasst eine Idee zur Verhinderung des Herausfilterns von Transaktionen mit hoher Gebühr zusammen, bittet um Feedback zu einer vorgeschlagenen Änderung an BIP390-musig()-Deskriptoren und kündigt eine neue Bibliothek zur Verschlüsselung von Deskriptoren an. Ebenfalls enthalten sind unsere regulären Abschnitte mit der Zusammenfassung eines Bitcoin Core PR Review Clubs, Ankündigungen neuer Releases und Release-Kandidaten sowie Beschreibungen aktueller Änderungen an populärer Bitcoin-Infrastruktur.

Nachrichten

  • Berechnung des Schwellenwerts für Selfish Mining: Antoine Poinsot veröffentlichte auf Delving Bitcoin eine Erweiterung der Mathematik aus dem Paper von 2013, das dem Selfish-Mining-Angriff seinen Namen gab (obwohl der Angriff bereits 2010 beschrieben wurde). Er stellte außerdem einen vereinfachten Mining- und Block-Relay-Simulator bereit, mit dem man mit dem Angriff experimentieren kann. Im Fokus steht die Reproduktion einer der Schlussfolgerungen des Papers von 2013: Ein unehrlicher Miner (oder ein Kartell gut vernetzter Miner), der 33 % der gesamten Netzwerk-Hashrate kontrolliert (ohne weitere Vorteile), kann auf lange Sicht marginal profitabler werden als die Miner mit den restlichen 67 % der Hashrate. Dies wird erreicht, indem der 33 %-Miner die Bekanntgabe einiger neu gefundener Blöcke selektiv verzögert. Steigt die Hashrate des unehrlichen Miners über 33 %, wird der Angriff noch profitabler, bis er bei über 50 % die Konkurrenz vollständig vom besten Blockchain-Zweig verdrängen kann.

    Wir haben Poinsots Beitrag nicht im Detail geprüft, sein Ansatz erscheint uns jedoch fundiert. Wir empfehlen ihn allen, die sich für die Mathematik interessieren und sie nachvollziehen oder besser verstehen möchten.

  • Zensurresistenz beim Relay durch Top-Mempool-Set-Abgleichungen: Peter Todd schrieb auf der Bitcoin-Dev-Mailingliste über einen Mechanismus, mit dem Knoten Peers aussortieren könnten, die Transaktionen mit hoher Gebühr herausfiltern. Der Mechanismus basiert auf Cluster Mempool und einem Set-Abgleich (Reconciliation) wie bei Erlay. Ein Knoten würde mit Cluster Mempool die profitabelste Menge unbestätigter Transaktionen berechnen, die z.B. in 8.000.000 Weight Units (maximal 8 MB) passen. Jeder Peer berechnet ebenfalls seine Top-8-MWU unbestätigter Transaktionen. Mit einem effizienten Algorithmus wie minisketch gleicht der Knoten seine Transaktionsmenge mit jedem Peer ab und erfährt so, welche Transaktionen jeder Peer im oberen Bereich seines Mempools hat. Anschließend trennt der Knoten regelmäßig die Verbindung zu dem Peer, dessen Mempool im Durchschnitt am wenigsten profitabel ist.

    Durch das Entfernen der am wenigsten profitablen Verbindungen findet der Knoten schließlich Peers, die am wenigsten dazu neigen, Transaktionen mit hoher Gebühr herauszufiltern. Todd plant, an einer Implementierung zu arbeiten, sobald Cluster Mempool in Bitcoin Core integriert ist. Die Idee stammt von Gregory Maxwell und anderen; Optech erwähnte das Grundprinzip erstmals in Newsletter #9.

  • BIP390-Update: Doppelte Teilnehmer-Schlüssel in musig()-Ausdrücken erlauben: Ava Chow fragte auf der Bitcoin-Dev-Mailingliste, ob es Einwände dagegen gibt, BIP390 so zu ändern, dass musig()-Ausdrücke in Output Script Deskriptoren denselben Teilnehmer-Public-Key mehrfach enthalten dürfen. Das vereinfacht die Implementierung und ist explizit durch die BIP327-Spezifikation von MuSig2 erlaubt. Bis Redaktionsschluss gab es keine Einwände, und Chow hat einen Pull Request zur Änderung der BIP390-Spezifikation eingereicht.

  • Bibliothek zur Verschlüsselung von Deskriptoren: Josh Doman kündigte auf Delving Bitcoin eine Bibliothek an, die sensible Teile eines Output Script Deskriptors oder Miniscripts für die darin enthaltenen Public Keys verschlüsselt.

    Er beschreibt, welche Informationen zum Entschlüsseln benötigt werden:

    • Wenn deine Wallet 2-von-3 Schlüsseln zum Ausgeben verlangt, werden genau 2-von-3 Schlüssel zum Entschlüsseln benötigt.

    • Wenn deine Wallet eine komplexe Miniscript-Policy wie „Entweder 2 Schlüssel ODER (ein Timelock UND ein weiterer Schlüssel)“ verwendet, folgt die Verschlüsselung derselben Struktur, als wären alle Timelocks und Hash-Locks erfüllt.

    Dies unterscheidet sich vom in Newsletter #351 diskutierten Backup-Schema, bei dem jeder Public Key im Deskriptor zur Entschlüsselung genügt. Doman argumentiert, dass sein Ansatz mehr Privatsphäre bietet, wenn der verschlüsselte Deskriptor z.B. öffentlich oder halböffentlich (etwa auf einer Blockchain) gesichert wird.

Bitcoin Core PR Review Club

In diesem monatlichen Abschnitt fassen wir ein aktuelles Bitcoin Core PR Review Club-Meeting zusammen und heben wichtige Fragen und Antworten hervor. Ein Klick auf eine Frage zeigt die Zusammenfassung der Antwort aus dem Meeting.

Separate UTXO set access from validation functions ist ein PR von TheCharlatan, der es ermöglicht, Validierungsfunktionen aufzurufen, indem nur die benötigten UTXOs übergeben werden, statt das komplette UTXO-Set vorauszusetzen. Dies ist Teil des bitcoinkernel-Projekts und ein wichtiger Schritt, um die Bibliothek für Full-Node-Implementierungen nutzbar zu machen, die kein UTXO-Set implementieren, wie z.B. Utreexo oder SwiftSync Knoten (siehe Newsletter #349).

In den ersten vier Commits reduziert dieser PR die Kopplung zwischen Transaktionsvalidierungsfunktionen und dem UTXO-Set, indem der Aufrufer die benötigten Coins oder CTxOuts selbst holen und an die Validierungsfunktion übergeben muss, statt dass diese direkt auf das UTXO-Set zugreift.

In späteren Commits wird die Abhängigkeit von ConnectBlock() zum UTXO-Set vollständig entfernt, indem die verbleibende Logik, die UTXO-Set-Interaktion benötigt, in eine eigene Methode SpendBlock() ausgelagert wird.

  • Warum ist das Auslagern der neuen SpendBlock()-Funktion aus ConnectBlock() für diesen PR hilfreich? Wie würdest du den Zweck der beiden Funktionen vergleichen?

    Die Funktion ConnectBlock() führte ursprünglich sowohl die Blockvalidierung als auch die Modifikation des UTXO-Sets durch. Dieses Refactoring trennt diese Verantwortlichkeiten: ConnectBlock() ist jetzt nur noch für die Validierungslogik zuständig, die kein UTXO-Set benötigt, während die neue Funktion SpendBlock() alle Interaktionen mit dem UTXO-Set übernimmt. Dadurch kann ein Aufrufer ConnectBlock() zur Blockvalidierung verwenden, ohne ein UTXO-Set zu benötigen. 

  • Siehst du einen weiteren Vorteil dieser Entkopplung, außer der Ermöglichung der Kernel-Nutzung ohne UTXO-Set?

    Neben der Ermöglichung der Kernel-Nutzung für Projekte ohne UTXO-Set erleichtert diese Entkopplung das Testen des Codes in Isolation und vereinfacht die Wartung. Ein Reviewer merkt auch an, dass die Beseitigung der Notwendigkeit für den Zugriff auf das UTXO-Set die parallele Validierung von Blöcken ermöglicht, was ein wichtiges Merkmal von SwiftSync ist. 

  • SpendBlock() benötigt einen CBlock block, CBlockIndex pindex und uint256 block_hash Parameter, die alle auf den ausgegebenen Block verweisen. Warum benötigen wir 3 Parameter dafür?

    Validierungscode ist leistungskritisch, er beeinflusst wichtige Parameter wie die Blockverbreitungsgeschwindigkeit. Den Blockhash aus einem CBlock oder CBlockIndex zu berechnen, ist nicht umsonst, da der Wert nicht zwischengespeichert wird. Aus diesem Grund hat der Autor beschlossen, die Leistung zu priorisieren, indem er einen bereits berechneten block_hash als separaten Parameter übergibt. Ebenso könnte pindex aus dem Blockindex abgerufen werden, dies würde jedoch eine zusätzliche Map-Abfrage erfordern, der nicht unbedingt notwendig ist.
    Hinweis: Der Autor hat später den Ansatz geändert, indem er die block_hash-Leistungsoptimierung entfernt hat. 

  • Die ersten Commits in diesem PR refaktorisieren CCoinsViewCache aus der Funktionssignatur einiger Validierungsfunktionen. Hält CCoinsViewCache das gesamte UTXO-Set? Warum ist das (nicht) ein Problem? Ändert sich durch diesen PR dieses Verhalten?

    CCoinsViewCache hält nicht das gesamte UTXO-Set; es ist ein Zwischenspeicher im Speicher, der vor CCoinsViewDB sitzt, welche das vollständige UTXO-Set auf der Festplatte speichert. Wenn ein angeforderter Coin nicht im Cache ist, muss sie von der Festplatte abgerufen werden. Dieser PR ändert nicht das Caching Verhalten selbst. Durch das Entfernen von CCoinsViewCache aus den Funktionssignaturen wird die UTXO-Abhängigkeit explizit, was den Aufrufer verpflichtet, die Coins vor dem Aufruf der Validierungsfunktion abzurufen. 

Releases und Release-Kandidaten

Neue Releases und Release-Kandidaten für populäre Bitcoin-Infrastrukturprojekte. Bitte erwäge, auf neue Releases zu aktualisieren oder Release-Kandidaten zu testen.

Wichtige Code- und Dokumentationsänderungen

Bemerkenswerte aktuelle Änderungen in Bitcoin Core, Core Lightning, Eclair, LDK, LND, libsecp256k1, Hardware Wallet Interface (HWI), Rust Bitcoin, BTCPay Server, BDK, Bitcoin Improvement Proposals (BIPs), Lightning BOLTs, Lightning BLIPs, Bitcoin Inquisition und BINANAs.

  • Bitcoin Core #32406 hebt das Größenlimit für OP_RETURN-Outputs (Standardness-Regel) auf, indem die Standardeinstellung für -datacarriersize von 83 auf 100.000 Bytes (das maximale Transaktionsgrößenlimit) erhöht wird. Die Optionen -datacarrier und -datacarriersize bleiben erhalten, sind aber als veraltet markiert und werden in einer zukünftigen Version entfernt. Außerdem wird die Beschränkung auf ein OP_RETURN pro Transaktion aufgehoben; das Größenlimit gilt nun für alle OP_RETURN-Outputs einer Transaktion zusammen. Siehe Newsletter #352 für weitere Hintergründe.

  • LDK #3793 fügt eine neue Nachricht start_batch hinzu, die Peers signalisiert, die nächsten n (batch_size) Nachrichten als eine logische Einheit zu behandeln. Außerdem wird PeerManager so angepasst, dass dies für commitment_signed-Nachrichten beim Splicing genutzt wird, statt für jede Nachricht ein TLV- und batch_size-Feld zu verwenden. Ziel ist es, auch weitere LN-Protokollnachrichten zu bündeln, nicht nur commitment_signed, wie es die LN-Spezifikation vorsieht.

  • LDK #3792 führt erste Unterstützung für v3 Commitment-Transaktionen (siehe Newsletter #325) ein, die auf TRUC-Transaktionen und ephemeralen Anchors basieren (hinter einem Test-Flag). Ein Knoten lehnt jetzt open_channel-Vorschläge mit nicht-null Feerate ab, initiiert selbst keine solchen Channels mehr und akzeptiert v3-Channels erst, nachdem ein UTXO für spätere Fee-Bumps reserviert wurde. Außerdem wird das pro-Channel- HTLC-Limit von 483 auf 114 gesenkt, da TRUC-Transaktionen unter 10 kB bleiben müssen.

  • LND #9127 fügt der Option lncli addinvoice den Parameter --blinded_path_incoming_channel_list hinzu, mit dem ein Empfänger eine oder mehrere bevorzugte Channel-IDs für den Zahler angeben kann, die beim Routing über einen Blinded Path bevorzugt werden sollen.

  • LND #9858 beginnt, das Produktions-Feature-Bit 61 für den RBF- Cooperative-Close-Flow (siehe Newsletter #347) zu signalisieren, um die Interoperabilität mit Eclair zu ermöglichen. Das Staging-Bit 161 bleibt erhalten, um die Interoperabilität mit Test-Knoten sicherzustellen.

  • BOLTs #1243 aktualisiert die BOLT11-Spezifikation dahingehend, dass ein Reader (Sender) eine Rechnung nicht bezahlen darf, wenn ein Pflichtfeld wie p (Payment Hash), h (Description Hash) oder s (Secret) die falsche Länge hat. Zuvor konnten Knoten dieses Problem ignorieren. Außerdem wird im Examples-Abschnitt ergänzt, dass Low-R-Signaturen, auch wenn sie ein Byte sparen, nicht vorgeschrieben sind.