25. Okt’19
Übersetzung des Blogartikel von Autorin Olivia Saa, IOTA Foundation.
Im letzten Blogbeitrag haben wir Ihnen den Simulator des IOTA Research Teams für das aktuelle Autopeering-Modell sowie einige frühe Ergebnisse vorgestellt. In diesem zweiten Teil der Serie möchten wir Ihnen einen klaren Überblick über den Autopeering-Algorithmus und seine Funktionsweise geben.
Zunächst einmal, warum ist es wichtig, automatisch und mit einem gewissen Grad an Zufälligkeit zu verbinden (peeren)? Grob gesagt, wenn sich ein neuer Node mit anderen verbindet, die von einem Nachbarn dazu geklatscht (Gossip/Klatsch -protokoll) wurden, werden die Informationen, die der erste Node erhält, den für ihn verfügbaren Informationen sehr ähnlich sein. Dadurch entsteht eine Form einer Echokammer. Darüber hinaus kann ein Angreifer bei dieser Art von Netzwerkwachstum eine ausgewählte Region des Netzwerks verdunkeln (Eclipse Angriff), indem er einfach eine große Menge seiner eigenen Nodes an die Neuankömmlinge weiter klatscht (gossiping).
Unser Ziel ist es also, einen Algorithmus zu implementieren, der:
- gute topologische Eigenschaften (d.h. Eigenschaften im Zusammenhang mit der Anordnung der Nodes), um eine gute Konvergenz für den darauf aufbauenden Abstimmungsmechanismus zu ermöglichen.
- eine vernachlässigbare Wahrscheinlichkeit, dass ein Angriff durch einen böswilligen Akteur erfolgreich ist. Um das zu tun, haben wir einen Algorithmus eingeführt, der drei verschiedene Variablen kombiniert; eine überprüfbare, eine unvorhersehbare und eine die mit einer kappen Ressource zusammenhängt.
Der Autopeering-Algorithmus
Hier wird erläutert, wie der Autopeering-Prozess im bereits gemeinsam genutzten Simulator abläuft, nachdem die Erkennung der Nodes bereits abgeschlossen ist,
Jeder der Nodes hat:
- eine öffentliche Node ID (eine 32 Byte lange Zeichenkette)
- eine öffentliche Salt (eine 20 Byte Zeichenkette)
- eine private Salt (eine 20 Byte lange Zeichenkette)
Wir definieren die angeforderte Entfernung zwischen Node A und B wie folgt:
d_req(A,B) = hash(node_id(A)) XOR hash(node_id(B)+pub_salt(A))
Um eine neue Verbindung anzufordern, berechnet der Node A für alle ihm bekannten Node d_req(A,B) und ordnet die Nodes nach diesen Abstand. Danach beginnt der Node, von der nächstgelegenen zur entferntesten anzufordern, bis k Verbindungen von den anderen Nodes akzeptiert und infolgedessen aufgebaut werden.
Wir definieren auch den Akzeptanzabstand zwischen Node A und B wie folgt:
d_acc(A,B) = hash(node_id(A)) XOR hash(node_id(B)+priv_salt(A))
Ein Node A nimmt eine Anforderung von einem Node B entgegen, wenn
1) er hat weniger als k Anfragen angenommen hat
oder
2) d_acc(A,B) kleiner ist, als die Akzeptanzabstände zu einem seiner akzeptierten Verbindungspartner (peer). In diesem Fall wird der Node A die Verbindung zu seinem am weitesten entfernten akzeptierten Node trennen.
In regelmäßigen Abständen ändern die Nodes ihre Salt’s und aktualisieren alle Entfernungen. Beachten Sie, dass für jeden Node 2k Verbindungen angestrebt werden, k wird durch die Anforderung anderer Nodes aufgebaut und k wird auch durch die Akzeptierung der Anfragen anderer Nodes aufgebaut.
Wie verhindert dieser Algorithmus Angriffe?
Zuerst wollen wir uns auf das öffentliche und private Salt-Schema konzentrieren. Die geforderten Entfernungen hängen nur von der öffentlichen Information ab. Auf diese Weise können die Nodes überprüfen, ob eine bestimmte Anforderung wahrscheinlich legitim ist oder nicht, indem sie bewerten, ob die Entfernung eine angemessene Größenordnung hat. Das macht die Arbeit für den Eclipse-Angreifer bereits etwas schwieriger, denn jetzt muss er eine öffentlichee Salt “minen”, das ihn nahe genug an den Node bringt, den er verdecken (eclipsen) will. Des Weiteren, wenn die Salts mit Hilfe von Hash-Ketten erzeugt werden, verpflichten sich die Nodes zu einer langen Folge von Salts, was es praktisch unmöglich macht, dass ein erfolgreicher Angriff über einen längeren Zeitraum aufrechterhalten werden kann.
Nun, da die Akzeptanz von einer nur dem Ziel bekannten Variablen (dem privaten Salt) abhängt, ist für den Angreifer völlig unvorhersehbar, ob ein Angreifer eine Verbindung zu einem Ziel herstellen wird oder nicht. Dadurch werden die möglichen Strategien der bösartigen Akteure noch weiter eingegrenzt, so dass Trial-and-Error mit mehreren verschiedenen Nodes die einzig mögliche Strategie in der Praxis ist. Dies führt uns zur letzten Komponente des Systems: Mana (noch nicht im Simulator implementiert). Wenn wir die oben definierten Entfernungen mit Manadifferenzen gewichten, stellt der Algorithmus Verbindungen zwischen Nodes mit ähnlichen Mengen an Mana her. Da Mana als knappe Ressource konzipiert ist, wird kein Angreifer genug davon haben, um diese Art von Trial-and-Error-Angriff auf teilnehmende (nicht Null-Mana-) Nodes durchzuführen.
Dies macht unser Autopeering zum vielversprechendsten, zufallsgesteuerten, automatisierten, nicht leicht zu manipulierenden Peering-Algorithmus unter den großen DLT’s.
Wir hoffen, dass Ihnen diese kleine Serie über das Autopeering-Modell gefallen hat! Wie immer sind alle Fragen und Kommentare willkommen, entweder hier oder auf unserem Discord-Server.
Quellen
https://blog.iota.org/coordicide-update-autopeering-part-2-4e462ba68bd