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?
Edit: 23. Juni 2017 - Paritätsdetails hinzugefügt (siehe unten)
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:
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.
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).
SortByPriceAndNonce
sortiert zuerst nach Preis und dann (für den gleichen Preis) nach Nonce: github.com/ethereum/go-ethereum/blob/master/core/types/…Um die ausgezeichnete Antwort von Richard Horrocks hinzuzufügen:
Den Quellcode für die verschiedenen Transaktionsordnungsstrategien finden Sie hier .
Hier ist die standardmäßige Bestelllogik:
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.
eth