Wie kann man Transaktionen sofort in Blöcke aufnehmen, wenn noch Platz ist?

  • Geth-Version: 1.8.12 – stabil
  • Betriebssystem & Version: Linux/OSX

Erwartetes Verhalten

Transaktionen werden direkt an der gesendeten Blocknummer an das Netzwerk verteilt und innerhalb dieser bereitgestellt.


Tatsächliches Verhalten

Transaktionen werden um eine Blockzeit verzögert, um über das Netzwerk verteilt zu werden, und folglich um eine Blockzeit zu spät bereitgestellt.


Erläuterung

Ich habe einen kleinen Cluster, der mit einer privaten Ethereum-Kette verbunden ist, die eine POABlockzeit von 15 Sekunden verwendet. Der Cluster hat vier Knoten, die alle Knoten miteinander verbunden sind. Bitte beachten Sie, dass es in meinem Cluster drei Unterzeichnerknoten gibt.

Wenn ich eine Transaktion von einem Knoten einreiche; Die Transaktion erreicht nicht alle Unterzeichnerknoten im aktuellen Block, sondern wird auf den nächsten Block übertragen. Ich beobachte jedoch, dass die gesendete Transaktion direkt nach dem Senden vom Nicht-Signer-Knoten empfangen wurde.

Zum Beispiel; Wenn ich eine Transaktion innerhalb des aktuellen Blocks gesendet habe, wird sie nicht im aktuellen Block, sondern im kommenden Block bereitgestellt. Dies zwingt das Netzwerk also dazu, eine Transaktion in 2-Block-Zeit bereitzustellen, die zwischen 15 Sekunden und 30 Sekunden liegt.

Wenn ich also meine Transaktion in der ersten Sekunde des Blocks gesendet habe, muss ich zuerst 14 Sekunden warten, bis der nächste Block kommt. Und warten Sie im nächsten Block weitere 15 Sekunden, bis diese Transaktion bereitgestellt wird, also muss ich insgesamt 29 Sekunden warten.


Beispielfall: alper@home ist ein Nicht-Unterzeichner-Knoten und andere Knoten sind Unterzeichner-Knoten.

Ich habe eine Transaktion innerhalb der Blocknummer 869,334vom benannten Knoten eBloc@netlab(Unterzeichner-Knoten) gesendet und die Transaktion wird direkt danach am alper@homebenannten Knoten (Nicht-Unterzeichner-Knoten) auf der Blocknummer angezeigt 869,334 , aber sie wird nicht auf den Unterzeichnerknoten angezeigt, nicht einmal auf dem von mir gesendeten Knoten es aus.

Geben Sie hier die Bildbeschreibung ein

Beim nächsten Block ( 869,335) beobachte ich, dass alle Knoten die Transaktionen erhalten.

Geben Sie hier die Bildbeschreibung ein

Und schließlich wird die Transaktion auf Blocknummer ( 869,336) bereitgestellt.

Geben Sie hier die Bildbeschreibung ein

=> Wenn die Transaktion direkt nach dem Senden an alle Cluster verteilt wurde, sollte sie auf der Blocknummer ( 869,334) bereitgestellt werden, aber dafür wurde 1 zusätzliche Blockzeit benötigt.

[Q1] Warum wird die gesendete Transaktion direkt nach dem Senden von den Nicht-Signer-Knoten empfangen, aber nicht von den Signer-Knoten?

[F2] Ist es normal, dass die gesendete Transaktion nicht direkt nach dem Senden an das gesamte Netzwerk übertragen wird, sondern dass es zusätzlich 1 Blockzeit dauert, selbst wenn alle Knoten miteinander verbunden sind? Gibt es eine Möglichkeit zu erzwingen, dass eine Transaktion direkt nach dem Senden an alle meine Unterzeichnerknoten übertragen wird?

Hinweis: Weitere Diskussionen finden Sie in einem offenen Thema auf go-ethereum.

Hätte aber gerne das Kopfgeld bekommen :/
Wie ich aus den Kommentaren des Entwicklers verstehe, ist mein Beispielfall ein normaler Fall für das Mainnet, wo Unterzeichnerknoten Transaktionen erhalten und signieren, die 1 Block verzögert sind, das System erzwingt dies. Aber diese Implementierung deckt auch Testnetze ab, so dass unabhängig davon, welches System Transaktionen zur Verteilung an Unterzeichnerknoten erzwingt, 1 Block verzögert wird, selbst wenn der Block vollständig leer ist. Bei meiner Frage habe ich nach einer Lösung für dieses Problem gesucht, aber ich denke, ich bin von der Entscheidung / Implementierung des Entwicklers für eine Lösung abhängig. @NikitaFuchs

Antworten (2)

Dieses Problem wurde vom go-ethereumTeam gelöst.

@karalabe:

Die Transaktion sollte sich gleichzeitig über das Netzwerk ausbreiten.

Es ist jedoch nicht im aktuellen Block enthalten, da der aktuell abgebaute Block bereits abgeschlossen ist. Es ist teuer, jedes Mal einen neuen Block neu zu erstellen, wenn eine neue Transaktion auftaucht. Und im Fall von Mainnet sind die Blöcke so oder so voll, also macht es nicht viel Sinn. Aus diesem Grund gibt es immer eine Verzögerung von 1 Block zwischen dem Senden und Mining.

Für Testnetze haben wir jedoch Code, der den Miner überarbeitet, und wir möchten unter anderem auch Funktionen haben, um Transaktionen sofort in Blöcke aufzunehmen, wenn noch Platz ist.


Wir haben den Miner auf dem Master-Branch überarbeitet. Der aktuelle Code regeneriert während des Minings alle 3 Sekunden Blöcke. Wenn es also mehr/bessere Transaktionen zum Anfeuern gibt, wählt der Knoten diese aus.

In einem öffentlichen Netzwerk (Proof-of-Work-Blockchain) ist es nicht im Interesse der Miner, Transaktionen einzubeziehen, sobald sie ihnen mitgeteilt werden. Ein Grund dafür lässt sich aus folgendem Auszug aus dem Yellow Paper (Seite 7, EIP 150 überarbeitete Version) ableiten:

Da die Nonce [die Anforderungen der Blockvalidierung] erfüllen muss und da ihre Erfüllung vom Inhalt des Blocks und wiederum von seinen zusammengesetzten Transaktionen abhängt , ist das Erstellen neuer, gültiger Blöcke schwierig ...

Mit anderen Worten, wenn der Miner versucht, den Nonce-Block zu finden, muss er bereits eine Merkle-Root aller Transaktionen haben, die in den Block aufgenommen werden sollen. Würde er ständig neue Transaktionen hinzufügen, würde sich der Root-Hash ändern und er müsste von vorne anfangen zu minen.

Ich weiß nicht genau über die Zwei-Block-Verzögerung zwischen Broadcasting und Mining Bescheid, aber hier ist, was ich vermute: Wenn Block n der Block ist, in dem Ihre Transaktion abgebaut wird, dann

Block n-2: Transaktionen werden in den Mempool des Miners übertragen.

Block n-1: Der Miner wählt Transaktionen so schnell wie möglich aus und führt sie aus/validiert sie, um „alles bereit“ zu haben, um um den nächsten gültigen Block zu konkurrieren, und wartet nur darauf, den Hash des übergeordneten Blocks zu erhalten.

Block n: Der Miner hat den übergeordneten Block-Hash erhalten, sonst ändert sich nichts an seinem Blockkandidaten, er schürft die richtige Nonce und versiegelt den Block.

Man könnte dieses Verhalten natürlich im Mining-Node-Client ändern, dies würde natürlich einige Fähigkeiten in Go oder Rust erfordern ;)

Siehe ( github.com/ethereum/go-ethereum/issues/… ); Ich vermute, dass dies ( functionality to immediately include transactions into blocks if there is still space) in Zukunft für die Testnetze .@Nikita Fuchs implementiert werden soll
Es gibt keinen Miner-Knoten auf Proof-of-Authority, daher gibt es nur wenige Unterzeichnerknoten. Das Problem ist, dass ich beobachte, dass Transaktionen direkt nach dem Senden an Nicht-Signer-Knoten verteilt werden können, aber egal, welche Transaktionen in einer Verzögerungszeit von 1 Block an den Signer-Knoten verteilt werden, selbst der Block ist leer. @ Nikita Fuchs
Es gibt keinen Unterzeichner in einem PoA-Netzwerk und keine erzwungene Transaktionsübertragungsverzögerung. Bei PoA ist es nur so, dass nur die autorisierten Nodes einen Block schürfen dürfen, und ab da ist alles gemäß meiner obigen Antwort: Jede Transaktion wird sofort gesendet, Miner müssen nur vorher alles bereit haben, um nicht anfangen zu müssen wieder über Mining.
Es gibt diese Funktion clique.getSigners(), siehe ( ethereum.stackexchange.com/a/15779/4575 ). Wie ich auf meiner Frage gezeigt habe, als ich eine Transaktion gesendet habe, wird sie nicht auf dem aktuellen Block angezeigt, der sofort auf dem gesendeten Block abgebaut würde, selbst wenn keine andere Transaktion auf dem Block vorhanden ist. Wenn ich also meine Transaktion in der ersten Sekunde des Blocks gesendet habe, muss ich zuerst 14 Sekunden warten, bis der nächste Block kommt. Und warten Sie weitere 15 Sekunden, bis diese Transaktion bereitgestellt wird, also muss ich insgesamt 29 Sekunden warten.