Bitcoin verwendet TCP für P2P, aber warum wird UDP nicht verwendet? Das moderne Internet hat eine relativ niedrige Paketverlustrate, sodass UDP zuverlässig ist. Selbst wenn einige Pakete verworfen werden, können die Peers immer die Blöcke anfordern. Bei TCP ist das Netzwerk eher statisch aufgebaut, während Sie bei UDP jedes Mal, wenn ein Block propagiert wird, einen zufälligen Graphen erstellen können, da UDP verbindungslos ist.
NANO verwendet UDP und ich denke, es ist ein guter Ansatz. Ich bin nur neugierig, ob ich etwas vermisse. Bootstrapping kann offensichtlich mit TCP durchgeführt werden.
Das Bitcoin-System hat nicht nur ein Netzwerkprotokoll: Jeder Weg, um die Blöcke zu erhalten, ist gleichermaßen gültig – Blöcke über Freenet, über Satellitenübertragung, über das P2P-Netzwerk, alle funktionieren genauso gut und werden in der Praxis verwendet. UDP wird auch mit Bitcoin vom Fiber-Protokoll verwendet .
Soweit das gängige Bitcoin P2P-Protokoll geht, ist UDP für die meisten Operationen, die es ausführt, nicht besonders gut geeignet. Bitcoin muss zuverlässig Nachrichten senden, die viel größer als ein IP-Paket sind, wie Transaktionen und Blöcke. Obwohl das Internet "zuverlässig" ist, sind Paketverlustraten von 1-3% üblich. Das bedeutet, dass jede Anwendung, die große Nachrichten mit UDP übertragen muss, Paketierung, Neuübertragung, Neuordnung usw. implementieren muss – dieselben Dinge, die TCP bereits für uns implementiert. Viele Anwendungen, die im Userspace 'ihr eigenes TCP gerollt' haben, haben am Ende ausnutzbare Bugs in sich, also sollte dies nicht ohne guten Grund getan werden.
UDP hat auch das Problem des NAT-Traversal: Bidirektionale Kommunikation über ein NAT mit UDP zu erhalten, ist keine einfache Angelegenheit. Das Überqueren von etwas Komplizierterem als einem Full-Cone-Nat erfordert beträchtliche Mengen an speziellem Code, aber ohne ihn wird es viele Hosts geben, die einfach nicht mit anderen Peers mit UDP kommunizieren können.
Sie erwähnen die Verbindungslosigkeit, die es Ihnen ermöglicht, zu einem zufälligen Host im Netzwerk zu wechseln, aber in Bitcoin P2P nutzen wir die konsistente Beziehung zwischen Knoten, um das Netzwerk zuverlässiger und effizienter zu machen. Knoten haben eine Vorstellung davon, was ihre Kollegen bereits wissen, und können es vermeiden, ihnen redundante Daten zu senden. Knoten wissen auch, welche Peers ihnen in der Vergangenheit am schnellsten Blöcke gesendet haben, und behandeln sie speziell. Auch wenn das Protokoll verbindungslos ist, entstehen Kosten für die Verarbeitung von Nachrichten von Peers, indem die Verarbeitung von Nachrichten von vorhandenen Peers priorisiert wird. Bitcoin reduziert die Auswirkungen einiger Arten von DOS-Angriffen. Die Handhabung von Nachrichten, die größer als ein Paket sind, Neuübertragungen usw. bedeutet auch, dass selbst bei einem verbindungslosen Transport immer noch eine Art dauerhafter Zustand vorhanden sein muss.
Aber eine if-Implementierung wollte zufällig eine Verbindung herstellen, um eine Nachricht zu senden, die es könnte, gegen Aufpreis sind ein paar Hin- und Rückfahrten für den Handshake. Oder nicht einmal das: Es gibt nur etwa 10.000 erreichbare Knoten im P2P-Netzwerk, es wäre keine große Herausforderung, eine meist inaktive TCP-Verbindung zu jedem einzelnen von ihnen offen zu halten, wenn der gesamte beibehaltene Zustand nur das TCP wäre Zustand. An dieser Stelle wäre die Verwendung von UDP bestenfalls nur eine Optimierung für etwas, das bereits getan werden könnte, aber nicht getan wird. Ich denke, es wäre interessanter, zuerst die Nützlichkeit all dieser Verbindungen zu demonstrieren, bevor Sie sich Gedanken über die Optimierung machen.
Warum also könnte der UDP-Transport für das Bitcoin P2P-Protokoll nützlich sein?
Um eine Blockübertragung mit niedrigster Latenz zu erzielen, darf es selbst bei Paketverlusten keine Roundtrips geben, was TCP ausschließt, und aus diesem Grund verwendet Fiber UDP. Um jedoch keine Roundtrips zu erhalten, muss das Protokoll in der Lage sein, Verluste ohne erneute Übertragung zu verarbeiten, und um eine niedrige Latenz zu erzielen, muss ein Block mit einer minimalen Menge an empfangenen Daten dekodierbar sein. Dies erfordert sehr ausgefeilte Fehlerkorrekturtechniken, die sich in einem sich entwickelnden Bereich befinden und noch nicht ausgereift genug sind, um sie in Betracht zu ziehen. Die Latenzvorteile von Glasfaser bestehen auch, solange eine kleine Anzahl von Hosts sie verwendet, da sie die schwere Arbeit übernimmt, Blöcke auf der ganzen Welt zu nehmen. Roundtrips richten bei Verbindungen mit geringer Latenz keinen großen Schaden an. Und diese Latenzbedenken gelten nur für Block-Relay.
Im Gegensatz zu TCP erfordert UDP ein gewisses Maß an NAT-Traversal-Handhabung, um einfach die bidirektionale Kommunikation zum Laufen zu bringen. In Kombination mit der vollständigen Behandlung von NAT-Traversal ist UDP jedoch häufig in der Lage, eine Kommunikation zwischen Hosts herzustellen, die sich beide hinter verschiedenen NATs befinden. Dies könnte für das Bitcoin P2P-Netzwerk hilfreich sein, da die meisten Hosts hinter einem nat nicht erreichbar sind. Ironischerweise ist also eine der Herausforderungen von UDP auch eine seiner Verwendungen. Um jedoch Hosts zu verbinden, die sich beide hinter einem Netz befinden, ist die Unterstützung eines nicht-natted Hosts eines Drittanbieters zusammen mit noch mehr NAT-Traversalcode erforderlich. In Anbetracht der Komplexität der Traversierung wäre eine Verbesserung der Unterstützung von Bitcoin für TCP-Port-Mapping (z. B. Implementierung von NAT-PMP) derzeit wahrscheinlich eine bessere Kapitalrendite.
Die Verwendung von UDP würde eine "schlechteste als die beste Anstrengung"-Verkehrsabwicklung ermöglichen. Für "Massenverkehr" mit niedriger Priorität wie das Synchronisieren der Blockchain wäre es schön, wenn sich der Verkehr sorgfältig selbst gestalten würde, um eine Störung des anderen Verkehrs im Netzwerk zu vermeiden. Alternative Überlastungskontrollalgorithmen wie LEDBAT machen es möglich, Daten mit niedriger Priorität mit minimalen Auswirkungen zu übertragen. Da TCP-Stacks diese Überlastungskontrollansätze jedoch noch nicht allgemein unterstützen, müssen Anwendungen, die sie benötigen, derzeit ihre eigenen Transporte implementieren. Für Bitcoin wäre es ideal, wenn wir einfach eine Socket-Option umdrehen und LEDBAT bei bestehenden Verbindungen ein- und ausschalten könnten (z. B. wenn der Peer historische Blöcke anfordert oder in Zukunft, wenn etwas wie Fiber vom Knoten verwendet wird, um neue Blöcke weiterzuleiten ) aber das ist '
[Diese letzten beiden Gründe sind die Gründe, warum Bittorrent normalerweise UDP verwendet]
NANO verwendet UDP einfach für Blöcke, die normalerweise (sicherlich meistens, aber immer??) kleiner als die theoretische Größenbeschränkung eines UDP-Pakets von 65 KB sind. Im Fall von Bitcoin sind Transaktionen ≠ Blöcke. Es ist sicherlich ineffizient, lange Daten (Bitcoin-Blöcke können bis zu 4 Megabyte groß sein – theoretisch) mit UDP zu übertragen, und so wählen auch andere Dienste zwischen ihnen. Außerdem, selbst wenn Blöcke ein paar Kilobyte groß sind, wird der Paketverlust dazu führen, dass Bergleute VIEL verlieren, da eine Verzögerung von wenigen Sekunden erheblich ist.
Wenn die Daten klein sind, können Sie nur ein Paket senden (das normalerweise viel kleiner als 65 KB ist). Ansonsten sind die Dinge mit TCP, Handshake und Keepalive nicht teuer.
Wissenswertes: In Satoshis Client gab es keine zusätzlichen Fehlerkorrekturcodes im Protokoll. Satoshi Trusted TCP-Fehlerkorrektur.
UDP ist in Bitcoin nicht sehr nützlich. Es ist weitgehend eine unidirektionale Kommunikationsstruktur, während Bitcoin auf bidirektionale Kommunikation angewiesen ist. Wenn sich ein Knoten mit einem anderen Knoten verbindet, gibt es einen gespeicherten Zustand für diese Knoten (Knoten verfolgen Dinge, die sie an andere Knoten gesendet haben, und Dinge, die sie von anderen Knoten empfangen haben) und es gibt eine Hin- und Her-Kommunikation (z. B. senden inv
, empfangen getdata
Antwort und senden Sie die Daten). UDP ist dafür nicht geeignet, aber TCP schon.
Darüber hinaus setzt UDP die Knoten der Unzuverlässigkeit der Netzwerke aus. Die Paketverlustrate ist nicht 0 (und kann nicht 0 sein), daher führt die Verwendung von UDP dazu, dass aufgrund von Paketverlusten viele zusätzliche Daten gesendet werden. Dies liegt daran, dass Blöcken und Transaktionen keinerlei Bytes fehlen dürfen. Andernfalls werden sie ungültig. Wenn bei TCP ein Paket verworfen wird, übernimmt TCP das erneute Senden der Daten. Bei UDP muss dies jedoch auf der Anwendungsebene gehandhabt werden, und es wird nur kompliziert, da das Herausfinden, was gelöscht wurde, eine bidirektionale Kommunikation erfordert, die mit UDP nicht einfach zu bewerkstelligen ist.
Insgesamt ist UDP also für Bitcoin nicht sinnvoll. Es unterstützt keine bidirektionale Kommunikation und garantiert keine Paketzustellung. Beides ist notwendig, damit das P2P-Protokoll von Bitcoin funktioniert, daher kann UDP nicht verwendet werden. TCP erledigt beides auf Protokollebene, also wird es verwendet.
Mittlerweile sind mehrere Reliable UDP-Implementierungen verfügbar, sodass Anforderungen wie die Wiederherstellung nach Paketverlust und Statefulness erfüllt werden können. Ein Beispiel ist die von der University of Chicago entwickelte UDT-Bibliothek: http://udt.sourceforge.net/
Wir haben ein Protokoll namens SRT (Secure Reliable Transport) entwickelt, das ursprünglich auf UDT basierte und um bidirektionale Datenübertragung und Verschlüsselung erweitert wurde. Obwohl es für Echtzeitdaten wie Video optimiert ist, ist es inhaltsunabhängig konzipiert: https://github.com/Haivision/srt
In Video-Anwendungsfällen sehen wir dramatisch erhöhte Bandbreitennutzungszahlen mit UDP über TCP (z. B. RTMP), besonders relevant für die Kommunikation über größere Entfernungen. Ich halte es für sinnvoll, UDP-basierte Alternativen für die Datenübertragung zwischen Knoten zu evaluieren, um die Netzwerkeffizienz zu erhöhen.
Benutzer2584960
Pieter Wuille
Benutzer2584960
G. Maxwell
Benutzer2584960