Wäre es möglich, einen RPC-Aufruf hinzuzufügen, um festzustellen, ob ein Knoten vollständig synchronisiert ist?

Nachdem ich diese Antwort gelesen habe , in der Peter Wuille darüber spricht, dass ein Knoten nicht wirklich sagen kann, ob er synchronisiert ist oder nicht, habe ich mich gefragt, ob es einen Weg gibt, wie wir feststellen können, dass ein Knoten so synchronisiert ist, wie es nur möglich ist Peers, mit denen es verbunden ist.

Könnten wir einen solchen RPC-Aufruf hinzufügen getsyncstatus, würde der Knoten seine Peers nach ihren höchsten bekannten Blöcken fragen, und wenn eine Mehrheit (oder ein gewisser Prozentsatz) ihrer Peers sich alle auf die bekannteste Blockhöhe einigen, dann könnte er diese Informationen verwenden, um in der Lage zu sein zu sagen (mit nicht perfekter Zuverlässigkeit), wie synchronisiert der Knoten ist?

Wenn also beispielsweise ein Knoten 8 Peers hat und 7 von ihnen 330448als beste Blockhöhe zurückgeben und der Client Informationen über block 330448hat, könnte er einen Statuscode und eine Meldung ausgeben, die signalisiert, dass er auf dem neuesten Stand ist. Wenn die Peers unterschiedliche Antworten geben (was passieren kann, wenn Sie sich mit einem böswilligen Knoten verbinden, der fälschlicherweise seine bekannteste Höhe meldet, ODER wenn andere Peers nicht vollständig synchronisiert sind), könnte es einen Statuscode und eine Meldung geben, die darauf hinweist, dass die Suche durchgeführt wurde nicht schlüssig und sie sollten es später erneut versuchen. Und schließlich, wenn 87,5 % der Knoten sagen 330448und der Knoten nur bis zu Block synchronisiert ist 1000, dann kann er einen Statuscode und eine Meldung ausgeben, die darauf hinweisen, dass der Knoten wahrscheinlich nicht ausreichend synchronisiert ist.

Ich denke, dies wäre hauptsächlich nützlich, um festzustellen, ob Server ausreichend mit dem Netzwerk synchronisiert sind, um sie für einige Anwendungen zu verwenden. Die Antworten auf diese Frage beschreiben eine Möglichkeit, um festzustellen, ob Knoten auf dem neuesten Stand sind, aber sie scheinen alle irgendwie hackig zu sein, und ich bin mir nicht sicher, ob sie zuverlässig genug wären.

Antworten (4)

Bestehende Methoden

Der Bitcoin-Client hat eine Möglichkeit zu erkennen, ob er nicht ausreichend synchronisiert ist. Meines Wissens ist es jedoch nicht wirklich auf nette Weise RPC ausgesetzt.

Es heißt IsInitialBlockDownload()und betrachtet sich selbst als nicht synchronisiert, wenn einer der folgenden Punkte zutrifft:

  • Der Client importiert aus bootstrap.dat oder indiziert die vorhandenen Blöcke neu.
  • Der Client hat nicht alle seine Block- Checkpoints erreicht .
  • Der Client hat in den letzten 10 Sekunden einen Block empfangen und verifiziert UND dieser Block hat einen Zeitstempel von mehr als 24 Stunden.

Sie können aufrufen getblocktemplate, und wenn IsInitialBlockDownload()wahr ist, wird es mit einem Fehler von RPC_CLIENT_IN_INITIAL_DOWNLOAD(oder -10) zurückkommen.

Nachteile

  • Wenn Ihr Bitcoin-Knoten für weniger als 24 Stunden ausgefallen ist, erkennt dies nichts Falsches, wenn er wieder hochfährt.
  • Es ist ein bisschen hässlich.
  • Wenn Ihr Client innerhalb von 24 Stunden nach dem aktuellen Block kommt, denkt er, dass er auf dem neuesten Stand ist, obwohl er wahrscheinlich ~ 144 Blöcke erhalten muss.
  • Wenn Ihr Client das Herunterladen von Blöcken stoppt, während er noch synchronisiert, wird dadurch kein Fehler erkannt.

Neuer RPC-Aufruf

Nehmen wir an, wir entwerfen einen neuen RPC-Aufruf von Grund auf neu. Wie andere Poster angemerkt haben, ist es nicht möglich, dies in Gegenwart von böswilligen Akteuren perfekt zu bestimmen. Welche Faktoren könnten wir messen, um eine fundierte Vermutung anzustellen?

  • Knotenverfügbarkeit. Ist der Knoten seit mindestens fünf Minuten aktiv?
  • Knotenausfallzeit. War der Knoten in letzter Zeit ausgefallen? Wenn ja, nimm die Zeit, die es unten war, und teile sie durch Tausend. Wenn Ihr Knoten noch nicht mindestens so lange aktiv war, ist er nicht synchronisiert.
  • Zeitstempel blockieren. Das Netzwerk ist ziemlich liberal bei der Durchsetzung dieser Regel, aber meine unwissenschaftliche Vermutung ist, dass es normalerweise innerhalb einer halben Stunde oder so ist. Sie können diese Informationen auf ähnliche Weise wie how IsInitialBlockDownload()does verwenden.
  • Blockhöhe des zentralen Knotens. Dies ist die in der anderen Frage erwähnte Lösung "Blick auf Blockhöhe von Blockexplorer".
  • Ihre Methode würde wahrscheinlich funktionieren. Das einzige Problem, das mir einfällt, ist, dass Sie nicht fehlschlagen würden, wenn Sie eine Verbindung zu einem anderen Knoten herstellen, der noch synchronisiert wird.
Was ist, wenn der Client kürzlich eine Sperre erhalten hat, diese aber noch nicht verarbeitet hat, was wird getblocktemplatein diesem Fall geschehen?
@StephenM347 Es wird untersucht, wann die Validierung der Spitze der besten Blockchain abgeschlossen ist. (Es werden also keine Blöcke berücksichtigt, die nicht validiert wurden.)
Okay danke. Ich wünschte, dies würde in der RPC-Schnittstelle auf weniger hackige Weise offengelegt.
Wird diese Methode also nicht fehlschlagen, wenn der Client über alle Checkpoints hinweg synchronisiert wurde, aber etwa 8 Stunden lang offline war?
@ StephenM347 Nun, es wird nicht fehlschlagen. :) Im Ernst, du hast recht.
Leider löst das das Problem dann nicht wirklich ... :/
Aber es beantwortet meine Frage. Wenn Sie es also aktualisieren, um die Dinge aufzunehmen, die Sie mir in diesem Kommentar gesagt haben, werde ich es als die richtige Antwort markieren. Und das Hinzufügen eines neuen RPC-Aufrufs könnte dies beheben, denken Sie, oder?

Nein, das kann man nicht sagen, weil es keine Definition von „synchronisiert sein“ gibt. Sind Sie in dem Moment, in dem ein Miner einen neuen Block findet, immer noch synchronisiert? Wie würdest du wissen?

Was Sie beschreiben, hat keinen Vorteil gegenüber den bereits implementierten Methoden zum Erkennen, ob der Knoten weit zurückliegt (es ist auch bereits implementiert, wie Pieter Wuille in der von Ihnen verlinkten Antwort erklärt, obwohl es nicht in der API verfügbar ist).

Was genau soll mit diesen Informationen erreicht werden? Warum müssen Sie wissen, ob ein Server ausreichend synchronisiert ist? Sie werden viel früher auf die echten Blöcke stoßen, als ein vernünftiger Angreifer sie erzeugen kann.

Anwendungsbeispiel: Sie haben eine Zahlungsverarbeitungsanwendung und möchten, dass sie sich selbst deaktiviert, wenn der Blockchain-Download nicht auf dem neuesten Stand ist, anstatt dass einige Funktionen auf mysteriöse Weise nicht funktionieren.
Genau wie Nick sagte.
@StephenM347 Wie viele Zahlungsverarbeitungsanwendungen werden nicht kontinuierlich ausgeführt? Selbst dann können Sie immer noch den Zeitstempel im letzten Block überprüfen und mit der Systemzeit vergleichen. Ich sehe den Vorteil nicht.
Diese Zeitstempel in Blöcken sind ziemlich unzuverlässig, daher halte ich das nicht für möglich. Wir haben einen komplizierteren Anwendungsfall im Sinn, aber ich möchte nicht wirklich zu weit darauf eingehen. Was wir wirklich wollen, ist eine Möglichkeit herauszufinden, ob ein Server zu weit zurückliegt, um zuverlässig zu sein.
Und selbst wenn es kontinuierlich läuft, müssen Sie wissen, wann es nach dem ersten Download bereit ist.
@StephenM347 Warum sind sie nicht zuverlässig? Sie sind mindestens genauso zuverlässig wie die Abfrage zufälliger, nicht verifizierbarer Knoten nach ihrer Blockhöhe.
Sie sind nicht zuverlässig, weil Miner sie häufig ändern, um mehr Arbeit zu bekommen, und das Netzwerk eine gewisse Flexibilität bei der Interpretation dieser Blockzeiten zulässt. Ich glaube nicht, dass sie so zuverlässig wären wie die Abfrage der Knoten, mit denen Sie verbunden sind, da Bitcoin nur wirklich funktioniert, wenn die meisten Knoten ehrliche Knoten sind.

Nun, Bitcoin ist Open Source, also ist es durchaus möglich, dass Sie versuchen, so etwas selbst zu integrieren. Anstatt jedoch Änderungen am Basiscode vorzunehmen, können Sie möglicherweise ähnliche Funktionen mit den bereits implementierten RPC-Aufrufen erhalten. Im Wesentlichen macht der Bitcoin-Client bereits etwas, was Sie erklären. Wenn Sie sich mit einem Peer verbinden, teilt ein Teil des Handshake-Prozesses den aktuellen Block des anderen; wenn einer höher ist als der andere und gültig ist, beginnt der andere mit dem Herunterladen von dem aktuelleren Peer. Wenn Sie sich die Datei debug.log ansehen, können Sie sehen, dass dies geschieht, zusammen mit einem laufenden "Fortschritts"-Feld, das protokolliert wird und Ihnen den Prozentsatz anzeigt, den Sie heruntergeladen haben.

Für Ihre Idee, wo Sie Informationen zusammenfassen, können Sie jedoch versuchen, den RPC-Aufruf "getpeerinfo" zu verwenden. Sie können die Informationen von dort nehmen und sie beliebig analysieren, ohne einen nativen RPC-Aufruf durchführen zu müssen.

Kann für Sie von Nutzen sein oder auch nicht, aber nur um manchmal zu überprüfen, habe ich ein kleines Skript / eine Webseite, die die aktuelle Blockhöhe von jedem meiner Bitcoin-Knoten erhält - wenn einer von ihnen niedriger als die Mehrheit ist, sind sie nicht synchron . Offensichtlich benötigen Sie Knoten in verschiedenen Netzwerken und Computern, sonst könnte ein Fehler bedeuten, dass alle Knoten nicht synchron sind. Funktioniert jedoch für mich, es ist einfach und verwendet einen vorhandenen RPC-Aufruf.