Die schnellste Methode, um neue Blöcke zu erhalten

Bitte entschuldigen Sie meinen Mangel an Wissen über einige Aspekte der Funktionsweise von Ethereum.

Ich erstelle eine DAPP, die web3 verwendet, um mit der Blockchain zu kommunizieren. Ich muss Ereignisse aus einem bestimmten Vertrag erhalten, sobald sie eintreten. Was ist die beste Methode? Was ist insbesondere die zuverlässigste Methode, mit der das Ereignis so nah wie möglich an dem Zeitpunkt verarbeitet werden kann, an dem es gesendet wurde?

Ich habe bisher Infura-Knoten verwendet, aber sie unterstützen keine Ereignisaufrufe. Meine Alternative ist jetzt, einen lokalen Ethereum-Knoten (geth) zu betreiben. Ist dies der optimale Ansatz, um Ereignisse schnell zu erhalten?

Welche wichtigen Überlegungen würden hier ins Spiel kommen? Hat Netzwerkgeschwindigkeit, Anzahl der Peers etc. einen großen Einfluss?

Antworten (2)

Diese Antwort beantwortet Ihre Frage nur teilweise.

Ihre logische Position im Ethereum-Netzwerk (d. h. welche Peers Sie haben) wirkt sich an jedem beliebigen Punkt auf das aus, was Sie als die kanonische Kette ansehen. Aufgrund der Möglichkeit einer vorübergehenden Gabelung sollten Sie, wenn Sie sofort auf eine Blockierung reagieren, bereit sein, damit umzugehen, dass die Blockierung „rückgängig gemacht“ wird, wenn sie Teil einer verlorenen Gabelung ist.

Abhängig von Ihrer Anwendung möchten Sie möglicherweise auch viele unabhängige Knoten ausführen und Ihre Software in der Lage haben, schließlich konsistent zu werden, sodass Sie gleichzeitig auf mehreren Gabeln sein können. Dadurch können Sie schneller auf Änderungen reagieren, unabhängig davon, welche Gabel Sie treffen. Die Kette, die (für jeden Moment) als kanonisch betrachtet wird, hängt davon ab, welche Blöcke Sie zuerst erhalten. Dies bedeutet, dass nicht nur Ihre Peers wichtig sind (weil verschiedene Peers unterschiedliche Ketten als kanonisch ansehen), sondern auch Ihre Latenz zu den Peers beeinflusst, welcher Knoten gethals kanonisch gilt. Bei nur wenigen Peers ist die Bandbreite weniger wichtig als die Fähigkeit Ihrer Latenz/des Betriebssystems, Pakete zu verarbeiten (1). Somit sehen Sie nur eine Version der Blockchain mit einer SinglegethBeispiel, wenn tatsächlich zu einem bestimmten Zeitpunkt mehrere Versionen vorhanden sein könnten. Infolgedessen könnten Sie tatsächlich einige Blöcke "langsam" im Verhältnis zur Gewinnkette ausführen, wenn Sie nur eine Instanz verwendet haben. Wenn Sie zum Beispiel bei einem Block, der eine Transaktion enthält, in einer Kette Asind und darauf reagieren und dann bei einem Block x, der eine Transaktion enthält, aeine Kette gewinnt B( ebenfalls bei blockx + 1bx), dann sind Sie bei der Bearbeitung der Transaktion einen Block zu spät. Da mehr Peers einen Einfluss ungleich null auf die Leistung Ihres Knotens haben, ist es tatsächlich vorzuziehen, mehr physische Knoten mit jeweils weniger Peers zu betreiben, wenn Ihr Ziel die schnellste Reaktionszeit ist. Wenn es andererseits Ihr Ziel ist, etwas schnell zu verbreiten, ist es wahrscheinlich hilfreich, viele Peers pro Knoten zu haben.

Mehrere Knoten ermöglichen es Ihnen also, auf verschiedene Versionen der Blockchain zu reagieren, sobald sie erscheinen. Die Wahrscheinlichkeit des Forkens nimmt mit langsameren Blockzeiten ab, ist aber immer noch ungleich Null.

Neben der Zeit, um eine Sperre zu erhalten, müssen Sie, wenn Sie so schnell wie möglich reagieren möchten, auch die neue Sperre bearbeiten; das bedeutet eine schnelle CPU, wahrscheinlich mit AES-Beschleunigung, und ein möglichst schnelles Speichervolumen. Ich vermute, viel RAM für das Caching wird auch nicht schaden, basierend auf einer Strategie zur Abschwächung der Auswirkungen des Angriffs, der EIP150 erforderlich machte. Die CPU-Geschwindigkeit und die Speichergeschwindigkeit sind für Parity definitiv von Bedeutung (wie in der Protokollausgabe von Parity angegeben), und RAM-Verknappung hat negative Auswirkungen. Ich kann Ihnen jedoch nicht sagen, ob eine hohe Anzahl von Kernen einer höheren Single-Thread-Ausführungsfrequenz vorzuziehen ist. Vielleicht werde ich das hier als Frage posten, aber es hängt möglicherweise von Dingen wie dem Inhalt der eingehenden Blöcke ab.

(1) Bei 100 KiB/Block dauert die Übertragung eines Blocks auf einer relativ bescheidenen 100-Mbit/s-Leitung 8 ms (Geben oder Nehmen). Das ist etwa so lange, wie ein Paket braucht, um die kurze Strecke von London nach Paris auf direktem Weg zurückzulegen.

Infura-Knoten unterstützen Ereignisaufrufe; Es gibt einige Einschränkungen und Leistungsprobleme beim Versuch, Protokolle aus der Vergangenheit über einen weiten Bereich abzurufen, aber wenn Sie nur Ereignisse aus einem bestimmten Vertrag abhören, sollte das funktionieren. Sehen Sie sich dieses Beispiel an, wie Sie dies mit Web3 + JavaScript tun würden. Es gibt auch Python-Bibliotheken mit ähnlicher Funktionalität.

Wenn Sie nicht von Infura abhängig sein möchten, können Sie es vorziehen, Ihren eigenen Knoten zu betreiben. Sinnvoll kann es auch sein, dies parallel zu Infura zu machen, damit Ihr Dienst noch läuft, wenn das eine oder andere umfällt. Dieselbe Logik deutet darauf hin, dass sowohl ein Geth- als auch ein Paritätsknoten ausgeführt werden.

Theoretisch werden Blöcke an Orten mit geringerer Latenz zu den Servern, auf denen sie abgebaut wurden, etwas schneller angezeigt. Wenn Sie also wirklich die Blöcke am schnellsten erhalten möchten, können Sie davon profitieren, dass Knoten auf der ganzen Welt verteilt sind. Wenn möglich, möchten Sie direkt mit den größeren Minern zusammenarbeiten, aber ich bin mir nicht sicher, wie Sie ihre Knoten finden und sich mit ihnen verbinden würden.

Sie sollten Ereignisse auch schneller erhalten, wenn Ihr Knoten sie schneller validieren kann, was eine gute CPU und E/A impliziert, aber YMMV; Es kann sich lohnen, VMs mit unterschiedlichen Spezifikationen auszuprobieren und zu messen, ob es einen erkennbaren Unterschied gibt.

Beachten Sie schließlich, dass bei der Erstellung einer DApp die übliche Annahme darin besteht, dass sich der Client direkt mit einem Knoten verbindet, ohne eine andere Partei zu durchlaufen. Wenn sie MetaMask verwenden, ist dies standardmäßig Infura, aber der Benutzer könnte seinen lokalen Knoten ersetzen. Nach diesem Muster würden Sie normalerweise nicht einmal kontrollieren, mit welchem ​​Knoten sie sich verbinden, obwohl Sie Ihren Benutzern selbst einen Knoten zur Verfügung stellen und ihn in Ihrer DApp fest codieren könnten.

Ich habe es gerade noch einmal mit Events versucht und es funktioniert einwandfrei. Hatte irgendwo gelesen, dass das nicht möglich sei.
Ich denke, das Beobachten von Dingen, die in neuen Blöcken passieren, hat immer funktioniert, aber sie unterstützten das Abrufen von Daten aus früheren Protokollen nicht.