Was ist die Standardreihenfolge von Transaktionen während des Minings?

Ich weiß, dass das gelbe Papier nicht festlegt, wie Transaktionen in einem Block angeordnet werden sollen, und dies dem Miner überlassen bleibt. Aber ich interessiere mich dafür, wie dies praktisch gehandhabt wird (ich gehe davon aus, dass keine Randfunktion aufgerufen wird, um eine Bestellung zu erhalten). Diese Antwort auf eine verwandte Frage legt nahe, dass der Gaspreis eine Rolle spielt. Wie bestellt zB geth Transaktionen während des Mining-Prozesses?

Tolle Frage! Es wäre interessant, wenn dies eine Antwort von einer Vielzahl von Kunden erhält.

Antworten (3)

Edit: 23. Juni 2017 - Paritätsdetails hinzugefügt (siehe unten)


Geth

Für die Vanilla-Geth-Implementierung ordnet die commitNewWork()Funktion in worker.go folgendermaßen an:

//approach 2
transactions := self.eth.TxPool().GetTransactions() <--- fetch from pool
types.SortByPriceAndNonce(transactions)      <---------- order

dh Sortiert nach Gaspreis und Nonce-Wert (und nach Eigentümerkonto - siehe unten).

Es gibt zwei weitere Ansätze im Code, die beide auskommentiert sind, aber möglicherweise einen Hinweis auf frühere Ideen geben (oder Minern, die ihre eigene Implementierung verwenden möchten, Beispiele geben). Sie sind:

  • Ansatz 1: nur nach Nonce sortieren
  • Ansatz 3: Sortieren Sie nach Besitzer (Einzel- und Mehrbesitzertransaktionen werden unterschiedlich behandelt), dann nach Preis und Nonce

SortByPriceAndNonce()ist in transaction.go definiert :

// This method first sorts the separates the list of transactions into individual
// sender accounts and sorts them by nonce. After the account nonce ordering is
// satisfied, the results are merged back together by price, always comparing only
// the head transaction from each account. This is done via a heap to keep it fast

Nach dem Sortieren werden die Transaktionen weiter überprüft commitTransactions(), um alle mit „niedrigem Gas“ zu entfernen.


Parität

Für Parity sind die Dinge etwas einfacher: Es gibt eine CLI-Option. Dies wird es zumindest ermöglichen, die Reihenfolge auf einige grundlegende Arten zu ändern.

 --tx-queue-strategy S          Prioritization strategy used to order transactions
                                 in the queue. S may be:
                                 gas - Prioritize txs with low gas limit;
                                 gas_price - Prioritize txs with high gas price;
                                 gas_factor - Prioritize txs using gas price
                                 and gas limit ratio (default: gas_price).
Nur zur Verdeutlichung, SortByPriceAndNoncesortiert zuerst nach Preis und dann (für den gleichen Preis) nach Nonce: github.com/ethereum/go-ethereum/blob/master/core/types/…
Gemäß der folgenden Antwort werden die Transaktionen zuerst nach Nonce sortiert: ethereum.stackexchange.com/a/13402/7132
Ich denke, es ist ein bisschen komplizierter, dass nur "x vor y" - es wird im Grunde nach beiden gleichzeitig sortiert. "SortByPriceAndNonce sortiert die Transaktionen nach Preis so, dass die Nonce-Bestellungen innerhalb eines einzigen Kontos beibehalten werden."
Beispielsweise werden die Top-5-Transaktionen mit den höchsten Gaspreisen ausgewählt, bei denen alle 6 Millionen Gaskosten haben. Wenn zwei davon ausgewählt werden, wird das aktuelle Transaktionsgaslimit von 10 Millionen überschritten. Wie gehen Bergleute mit diesem Fall um? @RichardHorrocks

Um die ausgezeichnete Antwort von Richard Horrocks hinzuzufügen:

Ich habe die letzten 1000 Blöcke studiert:

  • ~85 % der Blöcke scheinen zuerst nach dem hohen Gaspreis geordnet zu werden (unter Berücksichtigung der Nonce-Reihenfolge für eine einzelne Absenderadresse) (Die Standardeinstellung für Parity und Geth)
  • ~9% der Blöcke scheinen zuerst nach Low Gas Limit geordnet zu werden (Paritys "gas" tx-queue-Strategie)
  • Ich konnte die Reihenfolge der letzten 6% nicht herausfinden. Ich vermute, sie könnten einfach in der Reihenfolge sein, in der der Minenarbeiter davon gehört hat.
  • Keine Blöcke scheinen nur von Nonce bestellt zu werden.

Parität

Den Quellcode für die verschiedenen Transaktionsordnungsstrategien finden Sie hier .

Hier ist die standardmäßige Bestelllogik:

  1. Transaktionen, deren Ausführung länger als eine bestimmte Zeit dauert, werden bestraft und an das Ende der Liste gesetzt. Wenn ein Absender 16 anstößige Transaktionen sendet, wird er gesperrt.
  2. Transaktionen, die vom Miner-Knoten stammen, werden zuerst gestellt.
  3. Die "Nonce-Höhe" wird überprüft. Ich gehe davon aus, dass dies garantiert, dass Nonces für einen bestimmten Benutzer in der richtigen Reihenfolge sind.
  4. Dann wird die gewählte Strategie angewendet.
  5. Wenn alle gleich sind, werden sie in der Reihenfolge geordnet, in der sie eingegangen sind.

TL;DR

Denken Sie am Ende daran, dass dies Open-Source-Software ist und es keine Regeln gibt, wie Transaktionen bestellt werden müssen. Jedem Miner steht es frei, Transaktionen in der von ihm gewünschten Reihenfolge zu senden, daher gibt es keine Möglichkeit, die Transaktionsreihenfolge zu garantieren, aber es sieht so aus, als ob ein hoher Gaspreis und ein angemessenes Gaslimit Ihnen in den meisten Fällen einen guten Platz sichern sollten.

Ich denke, Horrocks Antwort ist etwas schwer zu verstehen, und das "Sortieren" ist eine seltsame Art des Sortierens, die etwas näher erklärt werden muss.

Angenommen, Sie sind der Miner und müssen 100 Transaktionen sortieren. Angenommen, 80 einzelne Personen haben 80 eindeutige Transaktionen gesendet. Nehmen wir dann an, dass 10 eindeutige Personen jeweils 2 Transaktionen gesendet haben. Das sind 10 "erste" Transaktionen und 10 "zweite" Transaktionen für diese 10 Personen. 100 insgesamt.

Die Idee ist, die 80 eindeutigen Transaktionen und die 10 "ersten" Transaktionen in eine Gruppe G zu gruppieren.

while gasLimitNotReached:
   T = highestGasPrice(G)
   G.remove(T)
   if T was some Account."first":
      G.append(Account."second")
   Commit(T)

Ich denke, Sie können sehen, wie sich dies auf einige Konten mit drei oder vier Transaktionen erstreckt. Die Idee ist, dass G nur Transaktionen von eindeutigen Konten haben kann. Wenn dasselbe Konto viele txs hat, dann betrachten Sie nur die kleinsten Nonces, unabhängig vom Gaspreis dieser größeren Nonces. Schleife dann über G und platziere in der Reihenfolge des Gaspreises. Überprüfen Sie jedes Mal, wenn Sie eine Transaktion loswerden, ob dieses Konto noch Transaktionen mit höherer Nonce hat, und fügen Sie dann diesen tx wieder in G hinzu, falls er existiert.

Quelle: https://github.com/ethereum/go-ethereum/blob/290e851f57f5d27a1d5f0f7ad784c836e017c337/core/types/transaction.go#L372 , aus Horricks Antwort.