¶ Intro
Herzlich willkommen bei Nodesignal, deine Bitcoin-Frequenz. Ich habe heute mal wieder
¶ Begrüßung und Blockzeit
den Thorsten dabei. Hi Thorsten. Hallo, guten Abend. Genau, ich bin der Jan-Paul und wir haben zum, wir haben gerade noch überlegt, ist es das dritte oder das vierte Mal, ich glaube es ist das vierte Mal, wir haben den Merch zu Gast. Hallo Merch. Servus, schönen Nachmittag. Ja, für dich Nachmittag, genau, für uns schon spät am Abend. Genau, aber das bringt uns doch zum guten Thema, hast du die Blockzeit für uns, Merch? Oh, das ist natürlich ein Moment. Das ist so überraschend
immer. Die Blockzeit ist zurzeit 869.016. Sehr schön, haben wir alle zusammen, sehr gut. Merch,
¶ Murch's neues Projekt
also ich glaube wir müssen dich nicht weiter einführen, aber du hast ein paar News mitgebracht oder eine News, vielleicht magst du mal erzählen, da hat sich was Neues für dich beruflich ergeben.
Was kommt? Ja genau, also wir haben jetzt auf TabConf letzte, nein vor zwei Wochen inzwischen angekündigt, ein Freund von mir und ich, wir gründen eine neue gemeinnützige Organisation, also noch nicht gemeinnützige Organisation, aber wir werden das versuchen zu erreichen und zwar werden wir ein Bitcoin-Entwicklerbüro öffnen im Bay Area, also bei San Francisco und das wird
Anfang nächsten Jahres anlaufen. Magst du uns den Namen verraten? Ah ja, die Organisation nennt sich Local Host Research, ihr könnt uns finden unter ltlhost.org, also Local Host, aber ohne O und A und ja, da ist noch nicht so viel, wir existieren zwar als Organisation, wir haben uns incorporated, wie auch immer gegründet, aber wir haben eben noch Papierkrieg gerade, damit wir auch gemeinnützig sind und so fort und wirklich anfangen wollen wir Anfang nächsten Jahres, also im Januar.
Wir haben bisher mich und meinen Mitgründer und dann haben wir Ewa Chao und einen weiteren Entwickler,
der unser Angebot angenommen hat, also drei Entwickler haben wir dann vom Start. Wir werden unterstützt von Vences Casares und Mark Casey, die beide großzügige Spenden gemacht haben, die uns ermöglichen, dass wir da anfangen und wir wollen uns konzentrieren auf Bitcoin Core, vor allem die Bitcoin Core Wallet am Anfang mal und dann müssen wir mal gucken, wir wollen vielleicht noch mal ein, zwei andere Leute anheuern, vielleicht Leute, die auch gerade erst anfangen, an Bitcoin Core mitzuarbeiten,
dass wir mit unserer etwas größeren Erfahrung denen helfen können, sich zurechtzufinden und ja, dann ist es vielleicht auch einfach schön, im Bay Area zu sein, wo es eben eine sehr große Zahl Entwickler gibt, wo man vielleicht dann auch mal irgendwie einen Meetup machen kann oder Leute dafür interessieren, selbst beizutragen oder auch einfach die Präsenz im Bay Area von von Bitcoin und Open-Source-Bitcoin-Entwicklern war ein bisschen reduziert seit der Pandemie, das heißt, da einfach
ein bisschen mehr Präsenz zeigen ist auch irgendwie Teilziel. Das heißt, ich werde dann Anfang nächsten Jahres wieder in Kalifornien sein statt New York und nicht mehr bei Chaincode Labs, aber das entwickelt sich alles noch. Also wanderst du von der Ost- zur Westküste von den USA? Ja, also ich kam ja gerade erst von der Westküste wieder und jetzt geht es zurück. Es dürfte schwieriger
werden, die Termine zu koordinieren zu unseren Aufnahmen. Das müsste machbar sein, ich bin ja dann nur neun Stunden hinterher, wenn ihr abends aufnehmen wollt, dann ist es halt bei mir um Mittagszeitraum. Aber das müsste eigentlich machbar sein. Also da legen wir uns keine großen Steine in den Weg, glaube ich. Sehr gut. Aber die Idee ist tatsächlich, dass ihr in einem Büro dann auch zusammensitzt. Oder das ist auch eine der Kernideen, dass ihr wirklich auch mal physisch
quasi sich in einem Raum trifft und zusammenarbeitet. Ja, genau. Also für viele Bitcoin-Entwickler, gerade Leute, die an Bitcoin Core mitarbeiten, ist es ja so, entweder machen sie es eh nur Teilzeit in ihrer Freizeit oder wenn sie Vollzeit daran arbeiten, dann haben sie häufig ein Grant, also quasi ein Stipendium. Sie arbeiten dann meistens von zu Hause und haben eben nur Online-
Kontakt zu anderen Entwicklern. Und das ist schon ein bisschen... Also erstens in den USA ist das mit der Gesundheitsversorgung immer schwierig, weil Gesundheitsversicherung dann gekoppelt ist an deinen Arbeitgeber. Das heißt, wenn du ein Grant hast, musst du dich da auch selber für aufkommen und so weiter. Du bist quasi selbstständig. Das kann hier relativ teuer sein. Was wir eben jetzt leisten wollen, ist, dass wir Anstellungen, Stellen schaffen, wo Leute Vollzeit
arbeiten können, in einem Büro, wo wir dann auch als Team an Projekten arbeiten können. Also nicht nur jeder zwei im Büro sitzt, aber an seinem eigenen Zeug arbeitet, sondern wir eben auch ein paar Sachen gemeinsam als Gruppe angehen wollen, um halt voneinander zu lernen und
vielleicht auch mehr Fortschritt zu machen in Projekten. Und eben anders als die Grants, dass man nicht jedes Jahr ein neues Grant finden muss und diesen ganzen bürokratischen Overhead hat, dass man selbstständig ist, dass man selbst sich um alle Gesundheitsversicherungen und sonst alles Mögliche kümmern muss. Das ist einfach ein bisschen einfacher, wenn man angestellt ist. Aber das Büro selber soll sich dann trotzdem überwiegend aus langfristigen Spenden dann
finanzieren? Oder habt ihr andere Finanzierungsdinge im Kopf? Ja, wir haben jetzt eben diese zwei großen Spender. Es ist vielleicht auch ein bisschen ein Anliegen. Ich weiß nicht, wie bekannt das ist, aber Jack Dorsey ist natürlich der Spender hinter sehr, sehr vielen von den Grants und auch anderer Organisationen. Also zum Beispiel Spiral Komplett. Er ist auch ein großer Spender bei Brink. Er ist der Hauptspender für OpenSats
und auch HRF ist ein großer Spender. Das heißt, ich glaube, es ist gut, dass wir noch mal ein paar andere Leute haben, die auch Entwickler finanzieren. Nicht, dass er jetzt viel Einfluss nehmen würde, aber wenn er sich irgendwann mal eines Tages überlegt, dass er was anderes machen möchte und daran nicht mehr interessiert ist, dann hätten wir da ein bisschen, müssten wir eben neue Quellen auftun. Ja, super. Das klingt auf jeden Fall sehr spannend. Wir packen auf jeden Fall
einen Link zu localhost.org in die Shownotes. Dann könnt ihr gerne mal draufklicken. Es ist noch nicht so viel zu sehen, aber es ist zumindest mal ein Pfad, auf dem man euch weiter beobachten kann oder verfolgen kann. Ja, hoffentlich hört man dann nächstes Jahr mehr davon. Aber es läuft nur ganz langsam an gerade. Gut, dann lasst uns doch mal zum Thema des Abends oder dieser Sendung
¶ Einführung in den Bitcoin Mempool
kommen. Wir wollten über den Mempool sprechen, insbesondere über das Thema Cluster-Mempool. Aber ich denke, da wir, glaube ich, hier bei Noten Signal noch nie eine eigene Sendung zu Mempool gemacht haben, wäre es vielleicht ganz gut, wenn wir einmal so ein bisschen high-level darüberfliegen über das ganze Thema. Also was ist eigentlich dieser Mempool? Was ist das Problem, das sich uns stellt? Und was zumindest auf einer hohen Abstraktionsebene, was dieser Vorschlag des
Cluster-Mempools eigentlich darstellt. Und dann werden wir noch mal ein bisschen tiefer einsteigen. Meine Hoffnung ist, dass wir so wenigstens die ersten 10, 15 Minuten des Gesprächs die Leute, die jetzt noch nicht so tief in dem Thema drin sind, einmal abholen können. Und dann für die Leute, die das tiefer interessiert, dass sie dann einfach weiterhören können und dann uns tiefer reinfolgen können. Ist das okay so, Thorsten? Denkst du, das kriegen wir hin? Ja, ich denke,
das ist auf jeden Fall ein guter Punkt. Wir werden das Ganze auch wieder wie üblich mit Kapitelmarken versehen. Vielleicht auch schon mal hier so wieder Hinweis vorab. Wir haben ein paar Folien, die Merch benutzt hat, auch glaube ich auf der TabConf, wo er eine Präsentation auch zu dem Thema gehalten hat. Und wir werden die auch in den Kapitelmarken versuchen zu verlinken. Und wenn das bei euch im Player auch unterstützt wird, werden wir auch mal gucken, ob wir diese Folien
vielleicht sogar als Bilder in die Show Nodes importieren können. Dass sie dann, wenn ihr durch die Show Nodes scrollt, auch Bilder habt. Ich weiß nicht, ob das auch welcher Player das unterstützt, aber dann habt ihr zumindest schon mal alle Optionen zur Hand. Und die Präsentation selber verlinken wir auch noch mal. Die ist ja, glaube ich, auf YouTube, meine ich. Oder, ich glaube, wir haben sie hier als Präsentation selber verlinkt. Und dann können wir die vielleicht
dann auch noch mal reinstellen. Ich glaube, meine ist noch nicht veröffentlicht. Es gibt eine andere Präsentation von Peter Welle von Ende letzten Jahres. Also er spricht über eine deutlich frühere Variante. Das Proposal hat sich sehr entwickelt seitdem. Aber es gibt diesen Vortrag von dem Bitcoin Research Day eben letzten Jahres. Den packen wir auf jeden Fall auch in die Show Nodes. Die Frage wäre, ob wir die Folien, die du auf der Tabcom benutzt hast, ob wir die auch mit
den Zuhörern teilen können. Ja, super. Genau. Dann habt ihr das auch als Unterlage. Könnt ihr da mal reingucken. Cool. Also rein in die Luzi. Was ist eigentlich der Mempool? Ich denke, es ist ein Begriff, der sehr häufig genannt wird. Es gibt eine sehr bekannte Webseite im Bitcoin Space, mem.mempool.space. Aber was ist eigentlich dieser Mempool-Merge? Vielleicht kannst du da ein paar Worte zu verlieren. Ja, also abstrakt. Der Mempool beschreibt alle unbestätigten Transaktionen,
die darauf warten, in einen Block gewählt zu werden. Konkret hat jeder einzelne Node seinen eigenen Mempool. Die Mempools der verschiedenen Nodes überdecken sich meist zum größten Teil. Also vielleicht hat einer eine Transaktion, die der nächste noch nicht erhalten hat. Oder vielleicht hat jemand einen Mempool kleiner konfiguriert und deswegen weniger Transaktionen. Aber generell ist der Inhalt aller Mempools sehr ähnlich. Oder das wäre zumindest unser Wunsch. Also wir möchten,
dass Nodes generell hoffentlich alle Transaktionen sehen, bevor sie in Blöcken landen. Manchmal ist das natürlich nicht der Fall. Zum Beispiel, wenn ein Miner direkt eine Transaktion in den Block wählt, aber die nie veröffentlicht hat, der vorher unbestätigt. Oder manchmal haben wir auch ein - wir hatten glaube ich Anfang letzten Jahres eine Zeit, wo so viele Transaktionen veröffentlicht wurden, also in den Mempool abgesondert wurden, dass teilweise die Synchronisation über die
verschiedenen Nodes nicht nachkam. Und dann sind die auch ein bisschen auseinandergelaufen. Aber generell, wir wollen eben, dass jeder Miner, jeder potenzielle neue Miner, also alle Fullnodes generell, alle guten Transaktionen sehen, damit sie die besten Blöcke bauen können. Das ist sehr wichtig für uns, damit die Miner eben so fair wie möglich in Konkurrenz stehen können. Das heißt, wir haben den Anspruch, dass Transaktionen so gut wie möglich, so schnell wie möglich an alle
Nodes verteilt werden. Das hilft uns dann auch, wenn der Block gefunden wird. Also wenn jemand einen neuen Block veröffentlicht, verwenden wir seit 2015 oder so Compact Blocks Relay. Vorher hatten wir die Transaktion unbestätigt rumgeschickt und dann, wenn der Block gefunden wurde, wurde der komplette Block verschickt, so dass wir eigentlich alle Transaktionen meistens
zweimal erhalten haben. Und mit dem Compact Block Relay schicken wir nicht mehr den ganzen Block mit allen Transaktionen, sondern wir schicken den Block Header und ein Rezept, wie man sich den Block aus seinem eigenen Mempool zusammenbauen kann. Also quasi nur eine Liste von den Transaktionen in der Reihenfolge, in der sie im Block auftauchen. Und dann, wenn man so ein Compact Block Announcement erhält, schaut man eben die Liste durch, fängt an, seinen Block selbst zusammenzubauen.
Also der Node. Natürlich muss man nichts manuell machen. Und der Node fragt dann eben denjenigen Peer, der ihm den Block gegeben hat, "Hey, diese Transaktionen fehlen mir noch, kannst du mir die schicken?" Und dann hoffentlich weniger als fünf oder so Transaktionen hat er dann den kompletten Block und kann eben den Block selbst validieren und weiterschicken. Und je mehr Transaktionen ihm dann noch fehlen, desto länger würde dann die Blockvalidierung entsprechend dauern und die
Propagation wahrscheinlich dann durch das Netzwerk an der Stelle? Ja, genau. Also die Transaktionen, die wir selbst im Mempool haben, da haben wir die Skripte schon geprüft. Wir haben die Transaktion selbst validiert. Wir wissen, die Transaktion wird valide sein, sofern die Inputs existieren, wenn wir sie versuchen zu bestätigen. Aber selbst in sich ist sie valide. Und für Transaktionen, die wir noch nicht gesehen haben, können wir natürlich diese Überprüfung nicht gespeichert
haben. Das heißt, wir müssen die dann erst noch durchführen, nachdem die Transaktion kommt. Das ist insbesondere für sehr große Transaktionen vielleicht langsamer. Vor allem für Legacy- Transaktionen, also nicht-Segwit-Transaktionen, gibt es das Quadratic-Hashing-Problem, das dazu führen kann, dass Transaktionen sehr lange brauchen, um sie zu überprüfen. Aber eben, falls wir die Transaktion schon im Mempool haben, dann haben wir diese Überprüfung schon
durchgeführt und dann ist das extrem schnell. Je mehr Transaktionen wir erst holen müssen, das gibt, sofern überhaupt nur eine fehlt, dann gibt es einen extra Roundtrip. Wir müssen noch mal zurückfragen, "Hey Nachbar, du hast mir den Block gegeben, hier diese Transaktionen fehlen mir." Da wurde jetzt auch gerade diese Woche ein neuer Bitcoin Core Disclosure, also Security
Disclosure, veröffentlicht. Es gab da ein Problem, wenn nämlich der Nachbar jetzt einfach dir die Transaktionen, wenn der Nachbar dir einen Block ankündigt, aber den Block dann gar nicht gibt, kann er dich bis zu zehn Minuten verzögern, bis du versuchst, den anderweitig zu beschaffen. Das konnte dazu führen, dass man eben Nodes etwas verlangsamt und falls das viele Nodes getan hätten, dann hätte das auch das Weitersenden von Blöcken generell im Netzwerk verlangsamen
können und die Zeit, bis sich alle auf die neue Chain-Tip einigen, verzögern können. Also, das kam gerade erst vor ein paar Tagen. Oder das ist vielleicht noch gar nicht groß. Vielleicht arbeiten wir an dem Pull-Request gerade. Es ist schon öffentlich, weil das Pull-Request sichtbar ist, aber vielleicht ist es noch gar nicht veröffentlicht. Okay, lass uns gerne noch mal
¶ Kapazitätsprobleme im lokalen Mempool
einen Schritt zurücktreten. Ich glaube, wir haben jetzt einen ganz guten Punkt, wo wir den Übergang noch mal schaffen. Und zwar, wir haben jetzt ja gerade darüber gesprochen, dass die Nodes, wenn sie Transaktionen in einem neuen Block, den sie bekommen, nicht kennen, dann müssen sie diese ganze Validierung durchführen. Das bringt mich jetzt dazu, noch mal zurück auf den Mempool zu kehren. Du hattest ja gesagt, dass wir auf unserer lokalen Node ja nur eine begrenzte Anzahl oder
einen begrenzten Raum für den Mempool bereitstellen. Vielleicht können wir einmal noch mal erklären, was heißt das eigentlich, dass dieser Platz begrenzt ist? Also, wo sind denn jetzt diese ganzen Transaktionen im Mempool? Wo sind die auf meiner Node? Und dann würde ich ganz gerne dazu hinkommen, dass wir noch mal beschreiben, okay, was ist denn jetzt die Herausforderung, wenn ich
jetzt einen Mempool habe? Also, wenn mehr Transaktionen auf einmal auf meiner Node ankommen, als ich an Speicher zur Verfügung gestellt habe, dann können wir vielleicht den Übergang zu der Problemstellung schaffen. Ja, also die Standardkonfiguration von Bitcoin Core Nodes ist, dass wir bis zu 300 Megabyte Arbeitsspeicher verwenden für die Mempool-Datenstruktur. Und zwar, das sind nicht 300 Megabyte Block-Daten, sondern 300 Megabyte RAM-Arbeitsspeicher. Und
wenn die voll sind, dann ist unser Mempool voll. Und dann müssen wir anfangen zu überlegen, was wir behalten und was wir wegwerfen. Das ist verwandt, aber nicht ganz genau die Security Disclosure von ein paar Monaten, die ich vorhin angeschnitten hatte. Da ging es hauptsächlich darum, was wir weiterschicken. Und die Liste unserer Relay, der Dinge, die wir Relayen wollten, konnte zu dem Zeitpunkt noch schneller wachsen, als wir die abarbeiten konnten. Und das war das
Problem damals. Hier reden wir einfach nur darüber, dass ein Mempool voll sein kann, weil eben diese Arbeitsspeicherbegrenzung erreicht wird. Und dann wollen wir natürlich die Transaktionen wegschmeißen, die wir am spätesten wieder brauchen. Das heißt, generell würden wir gerne die Transaktionen wegschmeißen, die als letztes gemeint werden. Und da gibt es eben jetzt mit dem, wie der Mempool heute funktioniert, sollen wir da schon
reintauchen oder bleiben wir beim Überblick? Also versuchen wir, wir bringen es gerade noch zu Ende und dann gehen wir noch einen Schritt zurück. Also das wäre nicht ganz so tief. Wir wollen das wegwerfen, was am spätesten wieder nützlich ist, also was wir am längsten nicht brauchen werden. Und das ist das Ziel und das ist nicht ganz einfach. Ja, da würde ich jetzt so ganz laienhaft ja mal vermuten, dass das ungefähr dem entspricht,
¶ Auswahlverfahren der Miner: Ancestor Set Feerate
was die Miner wahrscheinlich auch bei der Erstellung der Blocks priorisieren werden. Und da ganz naiv gesagt, das ist wahrscheinlich das, wo sie am meisten Transaktionsgebühren bei kassieren können. Deswegen würden wahrscheinlich die Transaktionen mit den höchsten Gebühren tendenziell nicht weggeschmissen werden, aber die mit den niedrigen Transaktionen. Das ist ein guter Instinkt. Also ja, reden wir doch einfach mal ein bisschen darüber oder? Osterjan Paul möchte noch mal zurückrudern.
Ja, gerne. Das ist eins der Hauptziele. Wie wir vorhin schon gesagt haben, jeder Node hat ein Mempool und schickt alles so gut wie möglich weiter, damit Miner eben Zugang haben zu den besten Transaktionen, um Blöcke zu bauen. Damit Mining so fair wie möglich ist. Weil wir wollen
natürlich, dass das so dezentralisiert wie möglich ist. Es gibt sowieso schon Vorteile für größere Miner, einfach dadurch, dass sie natürlich sich selbst nicht überzeugen müssen, dass ihr Block valide ist und sie so immer ein bisschen Vorsprung kriegen auf den nächsten Block, wenn sie selbst einminen. Und das passiert natürlich häufiger, wenn du selbst schon viel
Hashrate hast. Aber sonst wollen wir das so fair wie möglich machen. Das heißt, jeder sollte die besten Transaktionen in seinem Mempool haben und damit die besten Blöcke bauen können. Und was heißt es denn eigentlich, einen guten Block zu bauen? Blöcke sind limitiert im Gewicht. Wir können maximal vier Millionen Weight Units an Blöcken haben. Und vielleicht hat der eine
oder andere schon mal das Rucksackproblem gehört, also ein NP-schweres Problem. Wie genau nutze ich optimal einen limitierten Platz aus, um verschiedene Dinge, die verschieden groß und verschieden wertvoll sind, zu packen? Und wenn du sehr, sehr viele potenzielle Gegenstände hast, die du reinpacken kannst, dann ist das ein NP-schweres Problem. Es ist eine Weile her, dass ich das alles auf Deutsch erklärt habe. Ist das soweit klar?
Also es ist sehr schwierig, also nur um es vielleicht mal vereinfacht auszudrücken. Wenn ich ganz viele Gegenstände habe, die unterschiedlich groß sind und unterschiedlich wertvoll sind und die Herausforderung habe, ich soll sie alle in einen Rucksack stecken, der zum Beispiel vier Liter fasst, dann muss ich, also je mehr von diesen wertvollen oder weniger wertvollen und unterschiedlich großen Gegenständen ich habe, die ich in den Rucksack packen muss,
desto größer ist das Problem zu lösen, da den idealen Rucksack zu bauen, der wirklich das volle Gesicht ausschöpft und den maximalen Wert ausschöpft. Das ist das Problem im Grunde. Genau. Es gibt verschiedene andere Varianten von diesen NP-schweren Problemen. Das bezieht sich generell auf eine Komplexitätsklasse von Problemen, die nicht mit polynomischen Algorithmen zu lösen ist. Das heißt, je mehr Optionen du hast, die Zeit wächst exponentiell und es wird
relativ schnell unmöglich, alle Möglichkeiten erschöpfend zu berechnen. Es gibt häufig greedy Verfahren, die einfach nur punktuell optimale Entscheidungen machen, die zu sehr guten Lösungen führen, aber es ist schwierig oder sogar unmöglich, das optimale Ergebnis zu berechnen. Und einen Block zu bauen ist tatsächlich ein NP-schweres Problem. Nämlich, also vielleicht wenn man sich überlegt, wie man kennt natürlich das Schachspiel,
zu jedem Zeitpunkt hat man mit jeder Figur, die sich bewegen kann, hat man eine Möglichkeit. Und dann von jedem dieser Züge gibt es jede mögliche Antwort vom Gegner und so weiter und so fort, sodass die Möglichkeit aller potenziellen Schachspiele, die man spielen kann, unendlich, ja nicht ganz unendlich groß ist, aber sehr, sehr riesig. So ähnlich ist das eben mit einem Block und das wird insbesondere problematischer, wenn man sehr große Unterschiede zwischen den Gewichten
von Transaktionen hat. Wenn man sehr, sehr riesige Transaktionen hat und sehr kleine Transaktionen. Es ist relativ einfach, wenn man fast nur kleine Transaktionen hat, dann tut man vielleicht die eine kleine Transaktion nicht nehmen, aber eine andere kleine Transaktion und dann kommt man genau
ans Ende des Blocks. Aber wenn man zum Beispiel halt eine Transaktion hat, die fast den ganzen Block einnimmt und sonst alle möglichen Kombinationen von kleineren Transaktionen ausprobieren muss, um zu prüfen, was das bessere Ergebnis hätte, dann ist das ein ziemlich komplexes Problem. Entschuldigung, da bin ich wieder vom S-Planner-Stecklein gekommen. Alles gut, alles gut. Ja, passt schon. Wir lassen es einfach, wir lassen es ein bisschen
laufen. Ich versuche uns ab und zu ein bisschen zurückzuholen. Genau, jetzt haben wir über die Fragestellung gesprochen, wie schwierig ist es eigentlich einen Block zu bauen. Das ist schon sehr schwierig, aber wir haben ja noch ein zweites Problem, worauf ich jetzt gerne noch ein bisschen hinaus möchte, nämlich welche Probleme treten möglicherweise dabei auf, wenn ich die Speichergrenze meines Mempools erreicht habe und jetzt Transaktionen wegschmeißen muss. Das ist ein bisschen komplexer,
aber vielleicht können wir trotzdem mal versuchen, das zu erklären. Es geht hier vor allem darum, vielleicht um das vorne wegzuschicken, es geht darum, dass manche Transaktionen oder beziehungsweise es ist zulässig in Bitcoin, dass ich Transaktionen baue, die einen Input verwenden, der noch nicht in einem anderen Block oder in einem Block gemeint wurde. Das heißt, ich kann also Transaktionen konstruieren, die darauf verweisen auf eine andere Transaktion,
die im Mempool ist und die eben diesen Output generiert erst noch. Zum Beispiel Child Pays for Parent, das ist so das gängige Beispiel. Also man kann unbestätigte Transaktionen aneinandergliedern oder verketten und dann ist es natürlich relevant zu wissen, man kann einen
Output einer Transaktion erst ausgeben, wenn er existiert. Das heißt, damit man eine Kind Transaktion, also eine Transaktion, die einen unbestätigten Input ausgibt, überhaupt erst in einem Block verwenden darf, muss man die Elterntransaktion eben auch vorher schon im Block haben. Ich würde sagen, vielleicht wir sollten darüber reden, wie der Block denn gebaut wird, weil wir verwenden eben nicht die optimale Lösung, wir verwenden ein Greedy-Verfahren.
Wir schauen uns nämlich alle Transaktionen eben in dem Kontext ihrer Vorfahren an. Also, wenn eine Transaktion zum Beispiel eine Elterntransaktion hat oder mehrere Eltern oder Großeltern sogar, dann müssen ja alle diese Vorfahren vor der Transaktion im Block stehen. Das heißt, es ist relevant nicht nur die Fee, die die Gebühr, die die Transaktion selbst bezahlt, sondern das Gewicht und die Gebühren aller Vorfahren und das Gewicht und die Gebühr der
eigentlichen Transaktion. Wir nennen das ein Vorfahren-Set oder ein Ancestor-Set im Englischen. Ich werde wahrscheinlich beides verwenden. Entschuldigung schon. Also jedenfalls die Vorfahren-Sets. Wir speichern uns für jede einzelne Transaktion im Mempool, wie viel das Vorfahren-Set an Gebühren bringt und wie viel es wiegt. Und wir verwenden diese Fee-Rate, also die Gebühren geteilt durch das Gewicht, als die Metrik, welches Paket von Transaktionen wir
als nächstes in den Block wählen. Und das geht relativ schnell, weil wir uns eben für jede Transaktion zumindest spontan jetzt eine gute Entscheidung machen können, welches ist das nächste, was wir reinwählen wollen. Und zwar, wenn wir jetzt zum Beispiel die Child-Pays-for-Parent, also Kind bezahlt für Eltern, für das Eltern, dann, wenn wir so eine Situation hätten, dann hat die Elterntransaktion eben eine niedrigere Gebühr oder Fee-Rate. Wie sagt ihr das auf
Deutsch? Gebühr. Wir bleiben erstmal weg von Gebühr. Fee und Fee-Rate sind ja komplett verschiedene Größen. Ja, also genau. Es gibt eine Gebühr, das wäre die Gesamtgebühr, die man für eine Transaktion bezahlt, weil die Gebühr ja davon abhängt, wie viel man bereit ist, für die Größe der Transaktion, also die Länge ausgerügt in V-Bytes, zu bezahlen. Und das ist eben diese Transaktionsgebühr, die man entrichtet, oder eher die Gebührenrate, die man entrichtet.
Wir sagen jetzt zum Beispiel, wir sind bereit, drei Satz pro V-Byte für diese Transaktion zu bezahlen. Das wäre quasi die Gebührenrate. Okay, Gebühr und Gebührenrate, wunderbar. Also, wir wissen jetzt also für jede einzelne Transaktion in unserem Mempool, was die Gebührenrate des Ancestor-Sets sein würde und die Gesamtgröße des Ancestor-Sets. Das heißt, wie viel plus Satz unseres Blocks müssen wir verwenden, um dieses Vorfahren-Set in den Block zu wählen,
und wie viel werden wir erlösen an Gebührenrate pro Ancestor-Set. Und jetzt sortieren wir die einfach alle und wir wählen immer das Vorfahren-Set mit der höchsten Gebührenrate als nächstes in den Block. Und da kommt das erste Problem ins Spiel. Wenn wir Transaktionen haben, deren Vorfahren in den Block gewählt werden, dann müssen wir ihr Vorfahren-Set neu berechnen. Und das betrifft alle
Nachfahren von Transaktionen, die in den Block gewählt werden. Das heißt, während wir den Block bauen, müssen wir alle Nachfahren immer wieder updaten, sobald irgendwelche Vorfahren von ihnen in den Block gepackt werden. Und das ist kompliziert und teuer und macht das Block bauen etwas langsamer. Und diese Vorfahren-Sets führen nicht zu einem optimalen Ergebnis. Wir finden nur ein gutes Ergebnis. Das ist ein greedy Verfahren, also nicht eine optimale Lösung,
sondern eine Annäherung an die optimale Lösung. Vielleicht, ich weiß nicht, ob das jetzt ein bisschen dazwischen greift, aber wir hatten uns vorgestern bei Vorbereitung auf die Folge, Jan-Paul und ich, gefragt, wie häufig denn so auf die Gesamtmenge der Transaktionen denn so eine Abhängigkeit zwischen Transaktionen vorkommt. Also wie groß ist dieses Problem, was du gerade beschrieben hast, dass das neu berechnet werden müsste? Also die meisten Transaktionen sind
tatsächlich eigenständig im Mempool. Also es gibt wahrscheinlich über 90 Prozent, vielleicht sogar 95 Prozent der Transaktionen sind ohne Verwandten im Mempool. Und die sind trivial zu betrachten, entweder man wählt sie oder nicht. Und die sind genauso viel wert wie die Transaktion eben selbst. Das Problem ist, dass sonst aber gerade zum Beispiel Geschäfte, also Exchanges und so weiter, machen diese Transaktionen, wo sie ganz viele Kunden gleichzeitig ihr Geld auszahlen und die
teilweise 300 verschiedene Leute in einer Transaktion bezahlen. Dann verwenden sie vielleicht schon 10, 20 Inputs und ganz viele ihrer Kunden wollen dann vielleicht das Geld schnell ausgeben und bauen weitere unbestätigte Transaktionen, wo sie diese große Transaktion als Elterntransaktion verwenden. Und manche Exchanges tun zum Beispiel auch selbst ihre Auszahlungen aneinanderketten, so dass, als ich vor, ich glaube inzwischen zwei Jahren,
hatte ich ein Projekt, wo ich mich mit Research für Blockbuilding beschäftigt habe. Da haben wir ein Cluster gesehen zum Beispiel, das hatte über 500 Transaktionen. Also alles, was verwandt war über Eltern- und Kindbeziehungen und dann transitiv, war ein riesiges Paket von 500 Transaktionen, die alle aneinanderhängen. Das heißt meistens ist es kein Problem. Es gibt
wenig Transaktionen, die davon betroffen sind. Aber wenn man dann eben in so einem Riesencluster ist und da irgendwas in den Block wählt, dann kann es sein, dass brutal viele, also es gibt ein Limit, wie viel Nachfahren eine einzelne Transaktion haben kann. Es können also bis zu 25 Transaktionen direkt betroffen sein. Aber natürlich wählt man ja ein ganzes Vorfahren-Set
zusammen in den Block. Also wenn es vielleicht fünf Transaktionen hat, könnten das so um die 100 oder so vielleicht sogar mehr als 100 Transaktionen sein, die alle neu berechnet werden müssen. Okay, was die nächste Frage wäre? Du hattest eigentlich ja nach rauswerfen gefragt
¶ Auswahlverfahren zum Cleanup: Descendant Set Feerate
und ich hatte das umgekehrt und habe gesagt, wir sollten erst über Blockbauen reden. Jetzt wollen wir ja eigentlich, dass es rauswerfen, wenn unser Mempool überläuft. Genau das Gegenteil ist vom Blockbauen. Wir würden gerne die Transaktionen rauswerfen, die als allerletztes in einen Block gewählt werden würden. Aber um rauszufinden, was die Transaktionen wären, die als letztes in den Block gewählt werden würden, müssten wir eigentlich einen Block bauen, der so groß ist wie der ganze
Mempool. Nur dann, durch die ganzen Neuberechnungen von den Nachfahren usw., wüssten wir wirklich, was das allerletzte ist, was in den Block gewählt wird. Mit 300 MB im Mempool ist das natürlich ein bisschen viel Arbeit. Vor allem, wenn wir nur sagen, unser Mempool ist gerade ein paar Kilobyte zu groß und wenn dann die nächsten paar Transaktionen kommen, wollen wir das gerade wieder machen. Dann berechnen wir dauernd, was eigentlich das allerletzte wäre, was im Mempool
rausgeworfen würde. Dann würden wir extrem viel Rechenzeit darauf verwenden. Für etwas, wo wir eigentlich nicht so ganz super genau, ist uns wahrscheinlich relativ egal, ob wir die letzte oder eine vom letzten Dutzend rausschmeißen. Darf ich da noch mal einhacken, nur da ich das richtig verstanden habe. Im Grunde haben wir einen Sortierungsalgorithmus für den nächsten Block.
Also dieses Verfahren haben wir jetzt im ersten Schritt beschrieben gehabt. Und der Punkt jetzt ist, wenn wir dieses Verfahren, nämlich Sortierung der optimalen Transaktionen auf die nächsten Blocke über den gesamten Mempool anwenden würden, dann wäre das sehr rechenintensiv, weil ich quasi jedes Mal den kompletten Mempool durchrechnen müsste. Das ist das Problem, dass wir im Grunde. Es braucht viel Rechenkapazität auf meiner Node. Ist das das Problem?
Genau. Wenn der Mempool voll ist mit 300 Megabyte, dann haben wir 75 bis 110 Blöcke an Transaktionen in unserem Mempool. Kommt darauf an, ob das Segwit oder nicht Segwit Transaktionen sind und so weiter. Einen Block bauen ist nicht super schnell, aber auch nicht so langsam. Aber 110 Blöcke bauen ist halt ungefähr 100 Mal langsamer. Das ist dann schon uncool. Okay, aber das heißt, das ist keine gute Lösung, wie ich jetzt entscheide oder wie ich derzeit
entscheide, wie ich Transaktionen aus meinem Mempool rausgehe. Wie macht es denn zurzeit der Mempool auf meiner Node? Genau, also wir haben stattdessen ein anderes Greedy-Verfahren und zwar, wir haben ein Multi-Index auf unserem Mempool, wo wir uns zum Beispiel alle Transaktionen nachgucken können nach der TX-ID. Wir können alle Transaktionen nachgucken nach
ihrer Ancestor-Set-Fee-Rate, also dem Vorfahren-Set, der Gebührenrate des Vorfahren-Sets. Und wir haben noch einen weiteren Index, wo wir die Transaktionen im Kontext ihrer Nachfahren speichern, also ein Descendant-Set. Und wir verwenden eben dieses Descendant-Set als einen Indikator dafür, wie unattraktiv die Transaktion ist. Und zwar, das Descendant-Set ist das Gegenstück zum Ancestor-Set, also die Nachfahren werden alle aufaddiert, sowohl in Gebühren als auch in ihrem
Gewicht. Und dann erhält man damit eine Gebührenrate für das Nachfahren-Set. Und wir schmeißen eben nicht die letzte Transaktion, die wir meinen würden, raus, sondern wir schmeißen das Descendant-Set raus, dass das Nachfahren enthält und die Transaktion selbst mit der niedrigsten Gebührenrate eines Nachfahren-Sets. Das ist ein Mundvoll. Vielleicht noch mal, um es nochmal für die
Zuhörer klar zu machen, das ganz einfache Beispiel. Wir haben zwei Transaktionen, A und B, und jetzt ist das Ascendant-Set, also das Vorgänger-Set, ich schaue mir die Transaktion B an, die ein Output der Transaktion aus A ausgibt. Das ist das Vorgänger-Set. Also A und B in dem Fall? Ja, das Set besteht aus A und B, aber der Ausgangspunkt ist B. Ich schaue von B aus auf
seine Vorfahren. Und das Nachfolger-Set ist genau andersrum. Ich habe die Transaktion A, schaue, welche Transaktionen hängen denn noch da dran, welche geben also aus diesem Output dieser Transaktion wiederum diese Outputs als Inputs aus und habe dann quasi von A ausgehend, blicke ich auf B. Das ist das ganz einfache, die zwei Sichtweisen auf zwei Transaktionen. Lass uns dieses Beispiel noch vervollständigen. Also wir haben die zwei Transaktionen A und B.
A ist die Eltern-Transaktion, B ist die Kind-Transaktion. Das heißt, das Vorfahren-Set von A ist A alleine. Das Vorfahren-Set von B ist A und B. Das Nachfahren-Set von A ist A und B. Und das Nachfahren-Set von B ist nur B. Wenn jetzt also B eine niedrigere Transaktionsgebührenrate hat als A, dann würden wir B alleine rausschmeißen. Wenn A aber eine niedrigere Gebührenrate, also unser Mempo ist nur A und B und er ist voll. Wir müssen was rausschmeißen. Abstrus, aber lass uns
das mal so durchspielen. Also wir würden das Ernstheste-Set, das Vorfahren-Set, oder der hat es noch anders genannt, aber Vorfahren-Set mit der höchsten Gebührenrate in den Block wählen. Das heißt, wenn wir zum Beispiel eine Child-Pays-for-Parents-Situation haben und die Transaktion A zahlt eine Gebührenrate von einem Satoshi pro vByte und die Transaktion B zahlt zehn Sats pro vByte, also die Transaktion B repriorisiert A, dann wäre das Ernstheste-Set A, B die höchste
Fee-Rate. Wenn die gleich groß sind, 11 geteilt durch 2 ist 5,5, wählen wir in den Block. Aber das Descendent-Set mit der niedrigsten Gebührenrate wäre A und B, weil A selbst hat nur eine Fee-Rate von 1 und selbst mit B hat es eine niedrigere Gebührenrate im Descendent-Set als B alleine. B hat 10 im Descendent-Set, weil es ja nur alleine im Descendent-Set steht, aber A und B hat 5,5 und
damit ist es das niedrigste Descendent-Set im Mempool. Das ist natürlich ein bisschen ein konstruiertes Beispiel, weil wir so einen kleinen Mempool haben, aber tatsächlich kann man auch ein komplexeres Beispiel bauen. Ich habe das in meinen Folien, wenn ihr da reinguckt später, wo viele Transaktionen auftauchen, aber es trotzdem der Fall ist, dass die Transaktionen, die als nächstes in den Block gewählt werden würden, die Transaktion enthalten, die als erstes rausgeschmissen wird.
Und das ist ein Missstand. Wir wollen natürlich nicht die Dinge wegschmeißen, die wir als nächstes verwenden wollen, um einen Block zu bauen. Und dass das überhaupt passieren kann, ist eben ein Indikator dafür, dass das, was im Eigen liegt. Also nur noch mal, um das klarzustellen, das Problem
¶ Mögliche Zielkonflikte: Folien von Peter Wuile
ist, dass halt Widersprüche auftreten können zwischen einer Transaktion wäre quasi ein idealer Kandidat für den nächsten Block, ist aber gleichzeitig auch ein idealer Kandidat, um aus dem Mempool rausgeworfen zu werden. Also ich denke, Thorsten, da können wir nochmal vielleicht ein Screenshot jetzt in die Show Nodes packen, dass man sich das mal angucken kann. In dem Vortrag von Peter Willey, den er Ende 2023 zu dem Thema mal gehalten hat, da gibt es eine ganz schöne Slide,
da steht das einfach mal drin. Da kann man sich das mal angucken. Das sind, ich glaube, fünf Transaktionen insgesamt. Da hat das dann mal so eingekringelt. Was ist das Ancestor Set und was ist das Descendant Set? Und dann wird einem, glaube ich, mit der Erklärung von Merch sehr schnell klar, ah, guck mal, da ist der Widerspruch. Es würde sowohl aufgenommen werden, als auch rausgeschmissen werden aus dem, also aufgenommen werden in den nächsten Block, aber auch rausgeschmissen werden
aus dem Mempool. Und damit hätten wir das Problem, dass diese Transaktion dann ein Mempool, also ein Node, der nur einen sehr kleinen Mempool hat, in dem nächsten Block, in dem A dann drin ist, A neu validieren muss. Und jetzt gucken wir uns doch nochmal genau dieses Beispiel mit A und B an. Da A vor B stehen muss in einem Block, wenn wir wirklich nur eine Transaktion rausschmeißen wollen und wir die letzte Transaktion rausschmeißen wollen, die in den Block gewählt werden würden,
dann würden wir nur B rausschmeißen, weil A muss vor B stehen. Und das ist im Grunde genommen, was das Gegenteil von in den Block wählen wäre. Aber das Descendant Set, während das natürlich viel einfacher zu berechnen ist und das meistens auch noch einigermaßen gut funktioniert, das ist halt eben nicht das exakte Gegenteil. Gut, also ich glaube, wir haben das Problem,
¶ Lösungsvorschlag: Cluster Mempool
haben wir glaube ich herausgearbeitet. Ich denke auch, wir haben auch kurz darüber gesprochen, dass diese offensichtliche Lösung, dass wir einfach nur den Block-Sortierungsalgorithmus einmal über unseren ganzen Mempool laufen lassen, dass das halt sehr rechenaufwendig wäre, etwas ist, was wir nicht machen wollen. Es gibt Widersprüche da drin. Jetzt gibt es einen Lösungsvorschlag, das muss man jetzt sagen, es ist ein Vorschlag, der noch in Arbeit ist,
nämlich Cluster-Mempool. Vielleicht können wir einfach mal zwei Dinge ganz kurz einmal versuchen, uns vom Merge erklären zu lassen. Erstens, was ist ein Cluster? Und dann glaube ich, können wir gleich auch anschließen, was ist dann eben dieser Chunk, dass wir erstmal nur diese Begriffe klarkriegen, worüber wir uns jetzt unterhalten, wenn wir über den Cluster-Mempool sprechen. Okay, da können wir vielleicht auch, bevor du startest, ganz kurz, vielleicht auch
nochmal den Verweis auf die Bilder, die wir hier haben. Ich glaube, das macht es wesentlich einfacher, weil es jetzt halt super schwierig ist, das rein auf der Audiospur nachzuvollziehen. Deswegen, ich inspiriere mich jetzt mal von einem anderen Podcast, der auch immer sagt, die Folien benutzen. Wenn ihr im Auto seid, fahrt rechts ran und guckt euch die Folien an, und dann könnt ihr sicher weiterfahren. Aber Merge. Genau, vielleicht fangen wir einfach mal
¶ Was sind Cluster?
ganz oben an. Was ist denn jetzt dann in diesem neuen Kontext als Cluster zu verstehen, was ja dann der Namensgeber für diesen neuen Proposal an der Stelle ist? Genau, in dem Cluster-Mempool-Proposal bezeichnen wir als ein Cluster einen zusammenhängenden Subgraph im Mempool. Und zusammenhängend heißt alles, was irgendwie über Kind-Eltern-Beziehungen miteinander verbunden ist. Also im Grunde genommen die ganze Familie. Im vorherigen Beispiel mit A und B wäre A und B
eben ein Cluster. Aber wenn eine dritte Transaktion im Mempool wäre, die nicht verwandt ist, also weder an A noch an B hängt, dann wäre das ein getrenntes Cluster C mit der Transaktion C. Also alles, was irgendwie über diese Verbindungen zwischen Eltern und Kindern zusammenhängt, transitiv. Also du kannst hoch, runter, hoch, runter, hoch, runter. Alles, was eben irgendwie verbunden ist. Das ist ein Cluster. Also ich finde die Erklärung eigentlich schon völlig ausreichend. Also es ist
die Gruppe aller irgendwie miteinander zusammenhängenden Transaktionen. Und das kann natürlich beliebig komplex werden. Also wenn wir jetzt die Kette aufbauen. Ich habe das Eltern A, das hat ein Kind B. B gibt also ein Input aus A aus. Aber B gibt auch ein Input aus einer Transaktion C aus. Dann gehört C auch mit zu diesem Cluster, weil es halt über B alle diese Transaktionen miteinander zusammenhängt. Das ist also die größtmögliche Menge an zusammenhängenden
Transaktionen, die wir bilden können im Mempool. Genau. Im Grunde genommen, man fängt bei einer beliebigen Transaktion an und dann fügt man alle Eltern und Kinder von allen Transaktionen, die man schon gesammelt hat, wieder hinzu, bis nichts mehr hinzugefügt wird. Gut, also das ist quasi jetzt der erste Vorschlag. Wir sortieren uns das Ganze erstmal als Cluster. So gucken wir uns das an. Aber es sollte, glaube ich, klar sein, dass wir nicht immer alle Cluster als Ganze in
¶ Was sind Chunks?
einem Block aufnehmen wollen und werden. Also zum einen können diese Cluster so groß sein, dass sie gar nicht in einen Block passen. Zum zweiten könnte das auch suboptimal bezüglich der Gebühren sein. Das heißt, Miner würden da sicherlich sich ein Stück rausschneiden wollen. Und da sind wir schon, glaube ich, beim nächsten Begriff. Wie macht man das denn jetzt? Was sind Chunks im Grunde? Das ist die Frage. Genau. Also wenn wir in diesen Clustern, ich würde eigentlich
gern noch was zwischendrin einfügen und das werde ich mir jetzt einfach ausnehmen. Also die Idee ist, wenn wir uns ein Cluster angucken, dann ist die Reihenfolge, in welcher wir diese Transaktionen in Blöcken verwenden werden, nur abhängig von anderen Transaktionen in diesem selben Cluster. Transaktionen, die in anderen Clustern sind, beeinflussen dieses Cluster überhaupt nicht in
der Reihenfolge. Die Reihenfolge hängt nur von sich selbst im Cluster ab. Es heißt, wenn wir uns im Cluster überlegen, in welcher Reihenfolge wir alle Transaktionen im Cluster verwenden würden, kriegen wir quasi eine lineare List, also eine Linearisierung, eine Liste, in welcher Reihenfolge wir alle Transaktionen wählen würden. Und von dieser Liste, die können wir stückeln in die
Dinge, in die Pakete, die zusammenverwendet werden würden. Und diese Pakete, die zusammenverwendet werden würden, sind zum Beispiel das Child-Parent-Pay-for-Parents-Konstellation, wo das Kind mehr bezahlt als das Ältere und dementsprechend die beiden zusammen attraktiv sind, als Gruppe gewählt zu werden. Wir überlegen uns die Reihenfolge im Cluster und dann schneiden wir das Cluster in Stücke, die zusammen in Blöcke gewählt werden. Und diese Stücke nennen wir
Chunks. Das Attraktive an diesen Chunks ist, dass die Chunk-Gebührenrate gleich bleibt. Auch wenn Chunks früher im Cluster in den Block gewählt werden, bleibt die Chunk-Fee-Rate für das Chunk, das nächste Chunk, die gleiche wie die, die wir zuerst berechnet hatten. Und ich hatte vorher gesagt, es ist quasi rechnerisch zu teuer, jedes Mal, wenn wir was aus dem Mempool werfen wollen, auszurechnen, was das Letzte wäre, was im Mempool ist, weil wir den ganzen Mempool sortieren
müssten. Der Trick ist, warum merken wir uns nicht den ganzen Mempool sortiert? Wir tun also den Mempool in diese Cluster aufteilen. Wir suchen für jede Transaktion, zu welchem Clusters gehört. Und diese Cluster in sich sind nur von sich selbst abhängig, um die Reihenfolge festzulegen. Und dann merken wir uns die Reihenfolge, in welcher wir die Transaktionen in jedem Cluster meinen würden. Und auf diesen Linearisierungen überlegen wir uns, welche
Pakete sind attraktiv zusammenverwendet zu werden. Also Pakete von Transaktionen, die zusammenverwendet werden. Und jetzt wissen wir die Fee Rate, also Gebührenrate, zu welcher jede Transaktion in den Mempool gewählt werden wird. Was wir vorher immer erst zwischenzeitlich neu berechnen mussten, während frühere Transaktionen in Clustern in den Block gewählt
wurden, wissen wir jetzt immer, welche Fee Rate ein Chunk hat. Und die Chunk Fee Rate ist die Fee Rate von allen Transaktionen in diesem Chunk, zu welchen sie später in den Block gewählt werden. Das liegt dann aber daran, dass die Chunks in dem Sinne sich nicht mehr verändern,
wenn wir sie einmal gebildet haben. Weil wenn neue Transaktionen dann dazukommen, die vielleicht dann auch zu diesem Cluster gehören in irgendeiner Form, landen die aber nicht mehr in diesem schon bereits gebildeten Chunk, den wir vor fünf Minuten gebaut haben. Genau. Wir können das alles vorberechnen, weil solange sich das Cluster nicht verändert, wissen wir immer, in welcher Reihenfolge das Cluster verarbeitet wird. Und wir wissen genau,
welche Gebühren, also Transaktionen ändern sich ja nicht. Solange sich das Cluster nicht ändert, müssen wir nichts neu berechnen. Wir können das vorberechnen. Wir speichern uns für jedes Cluster einfach die Reihenfolge. Und natürlich, wenn dann später neue Transaktionen hinzugefügt werden, muss man vielleicht das Cluster neu sortieren. Zum Beispiel, wenn ein weiteres Kind hinzugefügt wird,
dann könnte das ja alle Vorfahren verschieben, weil es mehr Gebühren mitbringt. Dann müsste man sich vielleicht neu überlegen, in welcher Reihenfolge werden wir dieses neue Cluster eben verändern durch das Hinzufügen des weiteren Kindes. Wie würde man das wieder sortieren? Aber es ist eben immer limitiert auf dieses einzelne Cluster. Wir müssen immer nur ein Cluster sortieren und wir können uns einfach für jedes andere unbetroffene Cluster weitermerken,
wie es vorher war. Okay, also der Vorteil dabei ist, dass wir den Rechenaufwand auf quasi nur noch die Cluster, die sich vielleicht dann durch neue Transaktionen verändern, aber wir berechnen nicht den gesamten Mempool ständig neu oder müssten ihn nicht komplett neu berechnen, was jetzt die Herausforderung wäre, die Stand jetzt dann ohne dieses Cluster Mempooling dann wäre. Genau. Also während wir vorher ... Entschuldigung, fahre fort.
Nee, fertig. Das war eine Erkenntnis. Darf ich noch mal grade ... Also, weil's mir grade ein bisschen schwergefallen ist, euch beiden zu folgen. Wenn ich einmal diese Sortierung gemacht habe, ohne da ins Detail zu gehen, wir haben diese Cluster gebildet, dann haben
wir sie irgendwie geordnet, Fee Rate uns ausgerechnet, die Chunks gebildet und so weiter. Die Frage, die sich jetzt mir auftat, war, wenn jetzt also eine neue Transaktion auf meine Node kommt, das heißt, ich empfange jetzt zum Beispiel vom Thorsten eine neue Transaktion, wie auch immer die herkommt, dann muss ich mir erst mal nur anschauen, welches Cluster betrifft diese neue Transaktion. Und für dieses Cluster, das sich dann neu bildet, da habe ich dann noch
ein bisschen Rechenaufwand. Soweit bin ich. Aber alle anderen Cluster sind davon ja unbetroffen. Genau. Also es kann natürlich eins oder mehrere Cluster betreffen oder gar keins. Also wenn du eine eigenständige Transaktion hinzufügst, dann erzeugt diese Transaktion ein neues Cluster, das nur sich selbst enthält. Die Transaktion selbst enthält. Es könnte aber zum Beispiel auch eine Transaktion hinzugefügt werden, die Outputs von drei anderen Transaktionen ausgibt
und die dann natürlich drei Cluster verbindet dadurch, dass sie hinzugefügt wird. Also drei einzelne Transaktionen werden alle mit einem Kind verbunden. Dann hat man ein neues Cluster mit diesen vier Transaktionen. Und jetzt wissen wir natürlich in dem Moment nicht, in welcher Reihenfolge diese
vier Transaktionen sein würden. Also gucken wir uns die an. Und im naivsten Ansatz können wir einfach wieder den Ancestor Set V-Rate Algorithmus verwenden, den wir schon im alten Mempool verwenden, um die Reihenfolge zu finden, in der wir diese vier Transaktionen in den Block wählen würden. Und dann haben wir eine Reihenfolge im Cluster. Und jetzt schauen wir uns diese Reihenfolge im Cluster an. Also natürlich müssen Transaktionen, die vorfahren sind, vor ihrem Nachfahren stehen.
Also das fügt schon mal die ersten Einschränkungen an die Sortierreihenfolge hinzu. Also Vorfahren müssen vor Nachfahren stehen. Und dann müssen, dann wählen wir aber sonst Transaktionen, die auf der
gleichen Ebene stehen. Da wählen wir natürlich die mit der höchsten Gebührenrate zuerst. Also wenn wir bei dem Beispiel bleiben, wo A, B, C drei einzelne Cluster waren und nun eine neue Transaktion D hinzugefügt wird, die diese drei Cluster verbindet, indem sie jeweils einen Output von ihnen ausgibt, würden wir vielleicht, vielleicht ist A eine Transaktion mit einer hohen Gebührenrate, höher als D, dann wäre das vielleicht das erste Chunk, weil es die höchste
Feerate im ganzen Cluster hat. Und B und C haben beide niedrigere Feerates als D und werden von D repriorisiert, gebumped, dann würden die drei Transaktionen ein zweites Chunk bilden. Vielleicht können wir noch mal in dieses konkrete Beispiel von den Folien gehen,
damit wir das vielleicht daran noch mal nachvollziehen können. Also ich bin jetzt auf dieser Folie, wo jetzt Cluster Chunks steht und da haben wir das Beispiel mit C, E und D. Also quasi die mittlere Zeile hier an der Stelle, wo man sich natürlich jetzt fragen würde, warum ist D nicht Teil des Chunks an der Stelle? Und meine logische Erklärung wäre hier, wir sehen jetzt hier C hat einen Satz pro wie weit fünf und E hat sieben, was natürlich in Summe dann zwölf
durch zwei wäre jetzt dann sechs Satz pro wie weit, wenn wir dann halt nehmen. Und würden wir D jetzt noch mit der Reihe nehmen, die nur mit drei angegeben sind, wären wir ja bei 15 und 15 durch drei wäre ja fünf, was schlechter wäre, als wenn wir den Chunk nur mit den ersten beiden Transaktionen bauen würden, jetzt in dem Fall dann mit sechs Satz pro wie weit und deswegen fällt D jetzt an der Stelle als eigener Chunk raus. So würde ich das jetzt an der Stelle in
diesem Beispiel verstehen. Vollzügig, genau richtig. Sehr gut. Das heißt für euch, liebe Zuhörer, schaut euch diese Folie an und gerade bei dieser mittleren, da erkennt man das wirklich sehr, sehr gut, dass dann, wenn man diese drei Transaktionen, also C, D und E zusammennehmen würde, wäre es halt schlechter für die Minor, weil wir jetzt ja aus Chunks Sicht wieder auf
diese Perspektive suchen, wie können wir optimale, oder viel optimierte Blöcke bauen. An der Stelle würde das dann halt, wenn wir die drei zusammennehmen würden, nicht optimal sein, aber jetzt so wäre es dann, dass D dann in quasi später erfolgen würde an der Stelle. Ich bin mir nicht
¶ Cluster und Chunks
ganz sicher, ob du es gesagt hattest, aber C ist eine Elterntransaktion von D und E. D und E sind beide Kinder parallel zueinander, Kinder von C. Und E mit C, weil E mehr bezahlt, ist eben eine Child Pays for Parents Situation, wo wir erkennen, dass E mit C zusammen eine höhere Set Fee Rate hat als C alleine. D mit C aber, D hat eine niedrigere Fee Rate als C und dementsprechend ist es nicht
attraktiv, D mit C zu verbinden, weil C alleine schon besser wäre. Und in diesem Fall, C und E hat sogar noch eine höhere, weil ja E eben ein Child Pays for Parents darstellt und dementsprechend wählen wir aus diesem Cluster von drei Transaktionen C und E zuerst in den Block, bei einer Set Fee Rate von 6 Set per Rebate und D bleibt alleine und wird eben bei drei dann erst in einen Block gewählt. Und ja, wir würden eben C und E in diesem Cluster als einen Chunk bezeichnen und D als ein
weiteres Chunk alleine bezeichnen. Und das interessante ist jetzt, wenn wir C und E in den Block gewählt haben, ändert sich die Fee Rate von D nicht. D hat als Chunk, also das Chunk mit D, hat immer noch eine Fee Rate, Chunk Fee Rate von 3, weil es unabhängig davon ist. Vorher mit dem ernstesten Set Fee Rate hätten wir aber ausgerechnet, dass D und C zusammen 4 Sets per Rebate haben und
würden das eben für D uns gemerkt haben. Und dann nachdem C und E in den Block gewählt werden, müssten wir D neu berechnen und feststellen, ach, eigentlich geht es erst bei drei rein. Das ist ein guter Punkt, stimmt das. Das ist vielleicht auch nochmal der Hinweis darauf, auf der Folie davor, die nur die Cluster beinhaltet, da sieht man dann auch wirklich erst so richtig, wie die Abhängigkeit eigentlich ursprünglich war, dann und wo dann dieser Chunk
dann an der Stelle davon rausgeschnitten. Also genau, die Abhängigkeit hier ist, glaube ich, sehr wichtig. Das hatte ich eben nicht gesagt. Guter Punkt auf jeden Fall. Super. Ja, ich hatte mir schon überlegt in der Vorbereitung, das wird alles ein bisschen schwierig zu erklären ohne visuelle Hilfe. Absolut. Ja, ist es auch. Genau, ich überlege jetzt gerade, ob wir unsere Zuhörer nochmal abholen müssen. Also ich habe es jetzt mit den Folien vor Augen, habe es eigentlich ganz gut verstanden.
So spontan fällt mir jetzt aber auch kein gutes Beispiel ein, wie wir das den Zuhörern
¶ Zwischenzusammenfassung
erklären können. Thorsten, hast du vielleicht eine Idee, was wir noch machen könnten? Ja, guckt euch die Folien an. Also ich glaube, das hilft wirklich. Warum sollte man sich jetzt irgendein Beispiel konstruieren, was jetzt vielleicht einfacher sein könnte, als wenn wir das jetzt schon versucht haben, an diesen Folien zu erklären. Ich meine, das ist ja schon noch recht überschaubar, wenn man nur drei Transaktionen hat, die irgendwie voneinander
abhängig sind. Okay, pass auf, dann versuche ich es vielleicht nochmal einigermaßen high-level zusammenzufassen und Merch springt dann einfach ein, wenn ich total Blödsinn erzähle. Also was wir machen ist, wir bilden erstmal Cluster über den Mempool, den ich auf meiner Node habe. In meinem Mempool sind alle Transaktionen, von denen ich bereits gehört habe. Und jetzt sage ich, ich möchte alle Transaktionen, die miteinander in irgendeiner Weise zusammenhängen, also vor
allem Vorfahren, Nachfahren, die baue ich zusammen in ein sogenanntes Cluster. Das ist der erste Schritt, den ich mache. Der zweite Schritt ist, dass ich dieses Cluster, wie sagt man das denn jetzt, in eine Reihenfolge bringe. Also weil ich ja sehen kann, genau, linearisiere. Ich wollte diesen Ausdruck nicht verwenden, sondern ich bringe es in eine Reihenfolge, weil ich ja sehen kann, okay, welche Transaktion hat denn welches Kind, beziehungsweise welches Kind hat welchen
Elternteil oder mehrere Elternteile. So kann ich das quasi in eine Reihenfolge bringen. Und das Schöne ist, dass ich jetzt einmal, muss ich doch jetzt den Rechner aufmachen, dass ich mir nämlich jetzt anschaue, wenn ich zwei oder mehrere Transaktionen davon zusammenfasse, welche Fee-Rate sie haben oder welchen Gebührenrate sie haben. Das ist die Aufgabe, die quasi jetzt mein Mempool oder meine Node bei mir zu Hause dann durchführen würde. Die würde das einmal durchrechnen.
Ja, welche Gebührenrate kommt eigentlich zustande, wenn ich Transaktionen jetzt zusammenfassen würde, in diese sogenannten Chunks. Okay, Merge nickt, dann sollte das soweit passen. Ja, ich mache es jetzt mal noch ein bisschen komplizierter, wodurch es hoffentlich einfacher wird. Wichtig ist, dass die Sortierung erlaubt ist. Und erlaubt ist alles, wo die Vorfahren vor den Nachfahren stehen. Wir können am Anfang erstmal Fee-Rates, Gebührenraten komplett ignorieren.
Hauptsache die Topologie ist valide, also Vorfahren vor Nachfahren. Und wenn wir jetzt, also im Grunde genommen könnten wir eine beliebige Reihenfolge haben, solange das der Fall ist. Und dann können wir immer durch unsere Cluster durchlaufen und von vorne in den Block wählen. Und das wird immer einen gültigen Block ergeben. Weil wir eben dieses Kriterium, dass Outputs erst erzeugt werden müssen,
bevor sie ausgegeben werden, ist erfüllt. Wenn wir jetzt also die Reihenfolge der Transaktionen oder die Liste der Transaktionen ablaufen, wann immer eine Transaktion eine höhere Fee-Rate hat, als die vorherige Transaktion, zeigt uns das an, dass die zusammen in einem Chunk stehen sollten. Und nachdem zum Beispiel jetzt wir haben fünf Transaktionen und die zweite hat eine niedrigere Fee-Rate als die dritte. Und dann fassen wir zwei und drei zusammen zu einem Chunk. Da haben wir
also die erste Transaktion, zwei, drei zusammen, vier, fünf. Wenn jetzt dieses Chunk zwei, drei immer noch als Chunk eine höhere Fee-Rate hat als eins, dann zeigt uns das an, dass das auch ein Chunk sein sollte. Dann haben wir das Chunk eins, zwei, drei. Falls das nicht der Fall ist, bleibt eins alleine. Das hat eine höhere Fee-Rate. Das wird alleine gewählt. Dann wird zwei, drei gewählt. Und wir würden uns vier angucken. Wenn vier eine niedrigere Gebühr hat als zwei, drei,
wird es nicht zusammengefasst. Wenn es eine höhere hat, gehört es auch zum Chunk zwei, drei. Und so können wir also mit einer beliebigen gültigen Reihenfolge des Clusters das einfach ablaufen. Immer wenn es einen Sprung gibt von niedrig nach hoch, wird das nach vorne reingefaltet. So kommen wir zu den Chunks. Jetzt ist natürlich eine beliebige Reihenfolge nicht die optimale Reihenfolge. Und da kommt eben ein Spiel. Wir müssen weiterhin dieses Kriterium, dass die
Vorfahren vor den Nachfahren stehen, beibehalten. Aber sonst wollen wir immer, indem die prinzipiell an der gleichen Position stehen könnten, also die in Konkurrenz stehen für eine bestimmte Position, wählen wir immer das mit der höchsten Fee-Rate zuerst. Und dadurch, also das ist sehr vereinfacht. Peter hat, ich glaube, fünf Blogposts auf Delving Bitcoin geschrieben darüber, wie man am besten und am rechnerisch effizientesten alle möglichen Cluster
Satirungsalgorithmen verwendet, um das so schnell wie möglich zu machen. Aber generell, die Idee ist einfach, wann immer mehrere Transaktionen an einer bestimmten Position stehen können, wählen wir zuerst die Transaktion mit der höchsten Fee-Rate. Und dadurch bilden sich die besten Chunks vorne im Cluster. Und generell hat man dann eben möglichst kleine Chunks mit den höchsten Fee-Rates vorne und es wird immer die Chunks in einem Cluster sind dann immer hohe Fee-Rate zu
niedriger Fee-Rate sortiert. Zwangsläufig. Egal mit welcher Sortierung man anfängt, aber insbesondere wenn man mit der optimalen Sortierung ans Werk geht, hoch nach niedrig. Und ja, hat das geholfen? Cool. Also ich glaube, ich habe ein ganz gutes Bild davon. Ich hoffe, nur unsere Zuhörer kriegen das auch. Ich würde ganz gerne nochmal darauf kommen,
¶ Was kann der Enduser damit anfangen?
was bedeutet das jetzt eigentlich für den User, der jetzt Cluster Mempool irgendwann bald mal, vielleicht auch noch kurz darüber sprechen, wie da der Stand der Dinge ist. Aber viel wichtiger ist für mich, was ändert sich jetzt eigentlich für den Betreiber eines Mempools oder was bedeutet das für ihn? Nicht, was ändert sich für ihn das natürlich auch, aber was bedeutet das für
ihn? Vielleicht sogar auch, was bringt das für das Bitcoin-Netzwerk an sich? Also jetzt auch nicht nur für den Notbetreiber, sondern auch generell für andere Teilnehmer, die halt auch irgendwie im Netzwerk unterwegs sind. Ja, also die Hoffnung wäre, dass die Endnutzer möglichst, wahrscheinlich sehr wenig davon mitkriegen. Also es ist ein Infrastruktur-Upgrade, das ist weniger ein
End-User-UX oder sonst irgendwie Upgrade. Leute, die zum Beispiel Lightning oder andere Contracting Protocols wie ARK oder Timeout-Trees und so fort verwenden, werden hoffentlich es leichter haben, irgendwelche zeitsensitiven Transaktionen schnell bestätigt zu kriegen, weil wir eben besser darin sind, CPFP zu erkennen oder sogar Children Pays for Parent, also mehrere Kinder zahlen mehr als das Ältere und unterstützen sich nun gegenseitig, statt in Konkurrenz zu stehen. Also zeitsensitive
Transaktionen gehen hoffentlich leichter und schneller durch. Es wird schneller, Blöcke zu bauen, weil der Mempool schon vorsortiert ist und der neue Algorithmus, mit dem man jetzt Blöcke baut, ist, man stellt alle Cluster parallel nebeneinander und dann wählt man vorne vom Cluster mit der höchsten Chunk-V-Rate das Chunk mit der höchsten Chunk-V-Rate in allen Clustern. Und das ist das erste, was man in den Block wählt. Und jetzt laufen wir einfach nur auf allen Clustern
von vorne nach hinten und wählen jeweils das beste verbleibende Chunk über alle Cluster. Das ist super schnell. Das ist im Grunde genommen wie ein Merge Sort für die Leute, die Informatik Hintergrund haben. Und sehr hübsch ist auch, wir wissen genau, was das Letzte ist, was wir in den Mempool, sorry, in den Block wählen würden, nämlich das Chunk mit der niedrigsten Chunk-V-Rate über alle Cluster ist das, was wir wegwerfen wollen. Also von hinten wegschneiden, von vorne
reinwählen in den Block. Und das ist jetzt tatsächlich exakt das Gegenteil. Vielleicht schmeißen dann Leute weniger Transaktionen weg, die sie gerne haben wollen, um irgendwelche Blöcke zu validieren. Also es könnte sein, dass minimal, wahrscheinlich nur Blöcke sich schneller auf dem Netzwerk verteilen. Und vor allem, da sind wir jetzt noch gar nicht so weit eingegangen, aber es wird viel einfacher in diesem Clustermempool zu beurteilen, ob ein Paket von Transaktionen besser
ist als etwas, was wir versuchen zu ersetzen. Also wenn wir zum Beispiel ein RBF-Situation haben oder sogar eine Package-RBF-Situation haben, wo mehrere Transaktionen etwas anderes ersetzen wollen, haben wir jetzt Werkzeug an der Hand, mit dem man besser vergleichen kann, ob mehrere Transaktionen ein Cluster verbessern oder nicht. Was meinst du mit verbessern an der Stelle? Dass man da höhere Gebühren für bekommt oder es effizienter ist? Oder was sind die Faktoren dafür? Also generell wollen
wir ja Blöcke bauen, die so viel Gebühren wie möglich sammeln. Und wie wir festgestellt haben, ist das ein NP-schweres Problem und das ist nicht optimal zu lösen. Aber wir können das sehr gut in Annäherung lösen, indem wir einfach nur die Transaktion mit den höchsten Gebührenraten wählen. Aber insbesondere gegen Ende des Blocks hat man dann wenig Platz übrig und muss dann entscheiden, welche Kombination von Transaktionen insgesamt die höchsten Gebühren erlösen, während wir mit
Gebührenraten argumentieren, was wir wählen wollen. Und das macht es eben so schwer. Mit Cluster Mempool, dadurch dass wir jetzt die exakte Reihenfolge wissen von allen Transaktionen in Clustern und wir das über Cluster zusammensetzen können, so dass wir quasi eine Gesamtreihenfolge im ganzen Mempool kennen, wissen wir relativ genau, was wegfallen würde, wenn wir eine Ersetzung haben
und was hinzukommt. Und wir können das eben dann klarer vergleichen und können uns überlegen, ob dann insgesamt mehr Gebühren für weniger Gewicht im Grunde genommen zur Verfügung stehen im Mempool. Das ist unser Kriterium. Mehr Gebühren und/oder weniger Gewicht. Haben wir jetzt die Frage schon vollständig beantwortet? Ich merke gerade, dass ich ein bisschen abbaue. Die Frage war für Endnutzer. Hoffentlich sehr transparent. Der Mempool ist ein zentraler Teil
vom Bitcoin-Node. Es verwaltet ja die unbestätigten Transaktionen, ist involviert in Blockvalidierung und so fort. Das Cluster-Mempool-Proposal, also der Vorschlag, wäre, den alten Mempool zu ersetzen mit dem neuen Mempool. Von außen sieht es einigermaßen genau gleich aus. Hoffentlich merken die meisten Nutzer nicht mal, dass irgendwas passiert ist. Aber es wird eben für uns einfacher, darüber zu argumentieren, was genau passieren soll mit Package-RBF,
also Paketersetzungen. Oder es wird schneller, Blöcke zu bauen. Es wird sauber, was wir rauswerfen wollen. Und es wird hoffentlich schneller, dadurch, dass wir viel der Berechnung jederzeit machen können im Voraus, statt wenn wir einen Block bauen und Block validieren. Es ist eher Infrastruktur und für Mining fairer machen als für End-User. Ein großer Unterschied, hoffentlich.
Wir hatten im Vorgespräch, Jan-Paulo und ich, uns auch noch darüber gefragt, ob es dadurch nicht auch dazu führt, dass, wenn ich einen Child-Pay-as-for-Parent machen möchte, dass ich da eine effizientere Fee-Prediction habe, dadurch, dass ich einfach weiß, was als nächstes an der Stelle kommt, dass ich da nicht im Zweifelsfall überbezahle zu viel, weil das vielleicht
effizienter an der Stelle jetzt gebildet wurde. Dann ist das dann auch ein Vorteil, der Endanwender irgendwie dem dann doch zugute kommen könnte hinten raus, weil ich dann statt, weiß ich nicht, 10 Satz pro Viva nur 8 zahle, weil ich genau weiß, okay, das ist einfach an der Stelle, Stand jetzt, besser. Genau, also wenn du einen Fullnode hast, auf den du zugreifen kannst,
kannst du genau sehen, wo deine Transaktion in der Reihenfolge auftauchen wird. Und wir könnten dann auf Seite von Transaktionsbauern und Wallets und so weiter einbauen, dass wir eben sehr genau zielen, wo wir uns in den Mempool einsortieren wollen. Und wenn eben mehrere Child-Pays-for-Parents sich auf das gleiche Parent beziehen, dann bilden die einen Chunk. Das heißt, wenn wir dann hintereinander stehen, dann werden wir quasi Eltern, Kind, dass wir dann Eltern, Kind, Enkel
dann haben. Oder Eltern, Kind 1, Kind 2. Und vorher hatten wir eben dann Ancestorsets Kind 1 und Eltern und Kind 2 und Eltern. Und die würden, also Kind 2 ist ja kein Vorfahre von Kind 1, sondern das ist so unser Beispiel von CDE vorhin. Wenn jetzt die Kinder beide mehr bezahlen als die Elterntransaktion, dann wurde vorher im alten Mempool, werden die in Konkurrenz stehen. Also das eine Kind mit den Eltern bildet ein Vorfahrens-Set und das andere Kind mit der Elterntransaktion
bildet auch ein Vorfahrens-Set. Und je nachdem welches von den beiden die höhere Vorfahrens-Set Gebührenrate hat, wird das zuerst in den Block gewählt. Und plötzlich, das andere Kind hat dann eine riesige Fee-Rate, weil es natürlich nicht mehr für die Elterntransaktion bezahlen muss, nach der Neuberechnung. Und wird dann gleich als nächstes reingewählt in den Block. Aber erst
nachdem das erste Vorfahrens-Set gewählt ist. Und unter Clustermempool bilden die drei Transaktionen jetzt ein Chunk mit einer höheren Set-Fee-Rate als jedes der beiden Vorfahrens-Sets. Also solche Konstellationen mit mehreren Nachfahren, die einen Vorfahren repriorisieren, die werden eben jetzt als Zusammenarbeit betrachtet statt als Konkurrenz zueinander. Carsten, was wolltest du sagen?
¶ Was verbessert sich noch?
Die Heuristiken, die jetzt ja verwendet werden, stand jetzt für die Blockbildung in dem Sinne, was wir besprochen hatten. Die haben sich ja jetzt nicht wirklich verändert dadurch. Also, dass die effizienter werden, die Heuristiken, dass wir einen besseren Block entbauen. Doch, wir kriegen bessere Blöcke. Also, die ernsteste Set-Heuristik ist zum Beispiel suboptimal,
wenn wir zwei Kinder haben, die beide die Eltern-Transaktion priorisieren. Dann würden wir ja erst eins der Kinder mit der Eltern-Transaktion wählen, wenn das ernsteste Set eine gut genoge Fee-Rate hat. Aber mit dem Clustermempool würden wir eben entdecken, dass dieses Chunk besser ist und es früher in den Block wählen, was heißt, dass für das gleiche Gewicht mehr Gebühren in den Block früher auftauchen, was dazu führt, dass der Block potenziell insgesamt mehr Gebühren
erlöst. Wir haben das ein bisschen simuliert. Ich glaube, in Sohas Simulation hat er einfach den Mempool wieder abgespult und hat statt die herkömmlichen Blöcke zu bauen, hat er Clustermempool Blöcke gebaut. Und er wollte insbesondere wissen, führt das zum Beispiel dazu, dass manche Transaktionen deutlich später in Blöcke gewählt werden oder werden mehr Gebühren gesammelt mit Blöcken oder solche Dinge. Und seine Ergebnisse waren, dass für die meisten Situationen sich sehr wenig ändert,
aber alle Blöcke sind praktisch mindestens so gut wie vorher. Weil wir halt wahrscheinlich dann die wenig Transaktionen haben, die Abhängigkeiten zueinander haben, die sich dazu eigentlich zuvor wenig ändern. Ja, also es ist immer so gut wie das alte Verfahren. Es ist manchmal auch besser. Und das war halt wichtig, dass man nichts schlechter macht für irgendjemanden. Und das scheint zumindest gegeben zu sein. Und dann war halt einfach zum Beispiel Gloria Zhao
hat seit vier Jahren an Package Relay gearbeitet. Und davon sind ja die ersten Teile jetzt endlich im letzten Release verschifft worden. Aber es war immer noch unklar, wie wir eigentlich überhaupt über Pakete nachdenken können, die mehr als zwei Transaktionen haben. Und jetzt mit Package Relay und dem Fee Rate Diagramm, das wir noch nicht so sehr beleuchtet hatten, kann man das eben sehr schön visuell durchdenken, was jetzt bevorzugt werden sollte. Also das Original oder die Ersetzung.
Und das ermutigt uns, dass wir vielleicht Package Relay mit mehr Transaktionen machen können, was wir definitiv zurzeit mit dem alten Mempool schlicht und einfach überhaupt nicht machen können. Die alten RBF-Regeln sind suboptimal. Die führen nicht immer zum besten Mempool. Die führen nicht immer zu den Blöcken mit den meisten Gebühren. Und wir haben die Hoffnung, dass zumindest im Cluster-Mempool mit diesen neuen Ersetzungsregeln basierend auf dem Fee Rate Diagramm, dass wir
immer nur Ersetzungen akzeptieren, die tatsächlich den Mempool besser machen. Wir werden vielleicht nicht alles akzeptieren, was potenziell den Mempool besser machen könnte. Aber alles, was wir akzeptieren, macht den Mempool besser. Und das ist schon mal eine große Verbesserung gegenüber dem alten Mempool. Also wahrscheinlich nicht eine, die die Endnutzer erkennen werden. Aber wir können tatsächlich jetzt einfach evaluieren, ob Dinge besser funktionieren oder
nicht und darüber nachdenken. Dieses ganze Framework, wie die Abstraktionen zusammenhängen und so weiter, verbessert sich. Und das ist, glaube ich, der große Meilenstein. Der alte Mempool war auch 2015 zusammengeschraubt worden. Und seitdem haben wir viel gelernt über zum
Beispiel Pakete. Und wir hatten auch kein Lightning damals. Also diese Problematik, dass wir Transaktionen, die innerhalb von einer bestimmten Zahl von Blöcken bestätigt werden müssen, so dringlich durchbringen müssen und eben Pinning und solche Sachen überhaupt erst auftreten. All das war überhaupt nicht in Betracht gezogen worden, als dieser alte Mempool und auch die alten Replace-by-Fee-Regeln gemacht wurden. Da hatte man darüber noch gar nicht drüber
nachgedacht oder hatte noch keine Lösung dafür. Das ist jetzt einfach ein großes Update, um viele der Dinge, die wir jetzt besser verstehen und gelernt haben seitdem, einzuflechten. Gut. Cool. Ich denke, wir machen das Thema jetzt mal inhaltlich zu. Wir haben jetzt schon echt
¶ Wann soll Cluster Mempool kommen?
eine gute Stunde gesprochen. Das wurde teilweise doch sehr intensiv. Ich hoffe, wir haben es einigermaßen geschafft, unsere Zuhörer abzuholen mit den Hinweisen auf die Folien, die wir einblenden oder die wir auch verlinken in den Shownotes. Also könnt ihr euch das noch mal anschauen. Aber Mörtsch, bevor wir dich entlassen, vielleicht kannst du noch einmal kurz darüber sprechen, was ist der aktuelle Status von Cluster Mempool und wann erwartet ihr,
dass das tatsächlich dann auch ausgerollt wird? Also wie man sich vielleicht vorstellen kann, wenn man alle Transaktionen im Mempool neu verwalten möchte und die ganze Datenstruktur anders aufziehen muss. Da fließt gerade viel Arbeit da rein, diese ganzen Klassen und Interfaces zu designen. Die Linearisierung ist schon extrem schnell und fortgeschritten. Die Tankberechnung ist trivial. Cluster finden ist auch sehr einfach. Muss man ja nur immer alle
Verwandten weiter ins Boot holen. Und was eben jetzt noch an Arbeit aussteht, ist dieses Pull Request, also die Codeänderung in Bitcoin Core einzupflegen, die den alten Mempool mit dem neuen Mempool ersetzt. Und daran schreitet Arbeit voran. Die Idee ist jedenfalls, also die Hoffnung wäre, das im nächsten Release schon drin zu haben. Aber es könnte auch der übernächste sein, also Bitcoin Core 30 oder 29 hoffentlich. Generell, gerade zum Beispiel die Leute,
die an anderen Mempool-Projekten wie Package Relay und so weiter arbeiten, sind sehr begeistert. Es macht vielleicht auch manche Fragen in Richtung Mining einfacher, also mit Stratum V2 und so, könnte das potenziell interessant sein. Ja, die Arbeit schreitet voran. Es ist noch nicht ganz klar, wann genau es fertig sein wird, aber vielleicht hoffentlich gegen Ende des Jahres. Aber vielleicht auch später. Gut, aber also die Arbeit, nur ganz kurz,
also es wird noch daran gearbeitet. Die Überlegung ist entweder Ende dieses Jahres oder im Laufe des nächsten Jahres, im nächsten oder übernächsten Release, könnte es dann drin sein. Genau, okay. Ja, also es ist fertig, wenn es fertig ist. Und bisher scheinen alle Bitcoin Core Contributors sehr angetan. Aber es ist natürlich ein Vorschlag und dann muss es reviewed werden und so fort. Aber ja, ich könnte mir vorstellen, dass es schon im April Release sein wird, vielleicht sonst im
Oktober Release. Also kann man eher sagen, es ist nicht eine Frage ob, sondern eher eine Frage des wann an der Stelle. Zumindest nicht, dass das jetzt, wenn du sagst, dass die viele Contributor davon positiv angetan sind, dass ja schon dann ein breiter Konsens, in Anführungszeichen, wenn man das so sagen darf, dafür eher ist, dass das umgesetzt wird an der Stelle. Ich will nur ganz klarstellen, es ist überhaupt nicht eine Protokollveränderung. Von außen
gesehen verändert sich der Node nicht. Ja, also der Node verhält sich, vielleicht tut er ab und zu eine andere Transaktion vorschlagen als ein alter Node. Aber sonst von außen ist es nicht sichtbar für andere Nodes, was unter der Haube passiert. Es ist also wirklich nur eine Optimierung und Veränderung innerhalb von einem einzelnen Bitcoin Core Node. Aber es ist kein Softwork oder irgendwas in der Art. Es ist einfach nur eine Verbesserung, wie Bitcoin Core selbst funktioniert.
Naja, ist glaube ich gut, dass du das nochmal gesagt hast. Hatten wir uns auch im Vorfeld überlegt, wollen wir dich das fragen. Ich glaube für viele ist das selbstverständlich, aber es ist glaube ich trotzdem die Leute, die nicht so tief sind, trotzdem nochmal wichtig, dass das ja an der Stelle gesagt ist, dass es einfach nur ein Feature ist in Bitcoin Core und jetzt nicht irgendwie, weiß ich nicht, wir die Regeln von Bitcoin jetzt komplett auf den Kopf
stellen damit oder ihr an der Stelle? Vielleicht die eine Sache, die nach außen ein bisschen sichtbarer sein wird, vielleicht für Leute, die lange Transaktionsketten bauen. Im Moment ist natürlich das Ancestor und Descendant Limit 25, wie vermutlich die meisten wissen. Man kann also keine Transaktion, kann mehr als 24 vorfahren haben. Ancestor Set ist inklusive sich selbst,
also 25 ist mit sich selbst. Und mit Cluster Mempool werden wir eben auch ein Limit haben müssen, aber wir können sowohl das Ancestor Set Limit als auch das Descendant Set Limit wegwerfen und stattdessen haben wir ein Cluster Limit und wir werden wahrscheinlich Cluster auf 64
Transaktionen limitieren, ist die Idee soweit. Wir können wahrscheinlich Cluster von bis 15 oder sogar 20 Transaktionen immer optimal sortieren und für größere Cluster können wir immer mindestens so gut sein wie der aktuelle Blockbuilding Algorithmus, der auf den Vorfahren basiert. Und ja, das heißt, wenn man Ketten baut, dann könnte man zum Beispiel weniger häufig in dieses
25 Limit rennen, weil man 64 Transaktionen aneinanderketten kann. Aber generell würde ich sagen, wenn das ein Problem ist, dann hat man vielleicht auch andere Wege, wie man das verbessern kann, weil das ist vielleicht nicht der optimale Weg, wie man Transaktionen bauen sollte.
Ohne jetzt unseren Hörern zu nahe zu treten, glaube ich jetzt nicht, dass das unbedingt im Alltag bei unseren Hörern regelmäßig vorkommt, dass die an dieses Transaktionslimit kommen, aber wenn es so sein sollte, dann ist da auf jeden Fall jetzt eine Perspektive. Ja. Super. Dann würde ich sagen, haben wir eine schöne Folge über den Mempool, insbesondere
¶ Verabschiedung und Outro
über den Cluster-Mempool aufgenommen. Vielen Dank, Mörsch, dass du da warst. Thorsten, danke, dass du dabei warst. Ich würde sagen, Mörsch, letzte Worte nochmal, nochmal Tschüss sagen. Ja, danke, dass ihr mich wieder erzählen lasst hier. Ich hoffe, dass wir ein bisschen beleuchten konnten, woran wir gearbeitet haben hier, also hauptsächlich meine Kollegen Suhas und Peter.
Aber ja, das ist super spannend für mich persönlich. Ich weiß nicht, wie viele von euch das direkt betreffen wird, aber vielleicht kriegen wir zum Beispiel dann Package-Relay mit größeren Transaktionen bald und das könnte zum Beispiel helfen mit coolen neuen Contracting-Protokollen. Und ja, das wird gut. Also danke, bis bald. Sehr schön, danke dir. Dann würde ich sagen, focus on the signal, not on the noise. Ciao, ciao, macht's gut. Ciao. [Musik]
Nodesignal. Focus on the signal, not on the noise. [Musik]
