Wie gehen Pool-Betreiber mit Hashing um?

Für jedes vom Pool bediente „Getwork“ muss eine Merkle-Wurzel für einen Block berechnet werden. Die Laufzeit von SHA-256 ist proportional zur Anzahl der „Chunks“ von 256 Bit, und ein typischer Block wird Tausende dieser Chunks haben (ein Block-Header hat nach der Vorverarbeitung nur drei). Der Poolbetreiber benötigt also ungefähr Hashing-Leistung im Mhash/sec-Bereich. Habe ich soweit recht?

Die einzelnen Miner benötigen viel mehr Hashing-Leistung, aber in einer einfacheren Form: Hier ist ein vorverarbeiteter Block-Header mit drei Chunks; hash es mit jedem von 0000_0000x bis FFFF_FFFFx im Nonce-Feld. Wenn sich Hash-Engines auf diese Einfachheit spezialisieren, um sie billiger und/oder schneller zu machen, dann funktionieren sie für die Pool-Betreiber nicht so gut.

Wenn ich also ein Pool-Betreiber oder ein Solo-Miner bin und Millionen von Merkle-Wurzeln generieren muss, welche Möglichkeiten habe ich? Haben die Hashing-Engines (CPU/GPU/FPGA/ASIC) eine API, die ich verwenden kann?

Verwandte: Getwork ist nur ein Ansatz zur Verteilung der Arbeit für das Pool-Mining.

Antworten (2)

Ein Pool erstellt im Allgemeinen einen eindeutigen Merkle-Root für jede Getwork-Anfrage eines Miners. Wenn es Anteile der Schwierigkeit 1 akzeptiert, kann der Miner durchschnittlich etwa 4.000 Mega-Hashes für diesen Block ausgeben (und verdient durchschnittlich 1 Anteil pro Getwork).

Um einen Block-Header für jeden Miner zu erstellen, ändert der Pool-Operator einige eindeutige Informationen in der ersten (Generierungs-)Transaktion des Blocks und hasht dann den Block erneut, um die Merkle-Root zu erstellen. Wenn dies naiv gemacht wird, benötigt dies O(N log N) sha256-Hashes (wobei N die Anzahl der Transaktionen in dem abgebauten Block ist). Indem Sie einige Informationen aus der Berechnung der letzten Merkle-Root speichern, können Sie eine Änderung in der Generierungstransaktion mit nur O(log N) Hashes neu berechnen.

Bei Hunderten von Transaktionen pro Block liegt das Verhältnis der vom Poolbetreiber und den Minern durchgeführten Hashes bei über 100 Millionen zu 1.

Für noch größere Einsparungen können Pools eine getblocktemplate-API-Anforderung anstelle einer getwork-Anforderung akzeptieren. Dieser Modus ermöglicht es dem Miner, seine eigenen Blockheader zu generieren und durchschnittlich 10 Minuten lang zu minen, bevor er vom Pool aufgefrischt werden muss.

Ein rechenintensiver Teil der Serverarbeit ist das Erstellen neuer Merkle-Roots. Wie Mckoss erwähnt, wird dies viel schneller, wenn Sie nur den Merkle-Zweig neu berechnen, der durch die Transaktion der neuen Generation geändert wird, anstatt den gesamten Merkle-Baum neu zu berechnen.

Der andere rechenintensive Teil der Arbeit des Servers ist die Überprüfung der später eingesandten Arbeitsnachweise. Im Allgemeinen bedeutet dies, zwei SHA-256-Chunks zu hashen und das Ergebnis gegen die Schwierigkeit zu überprüfen. Aber wenn es mehrere Proofs of Work mit demselben Merkle-Stamm gibt, dann könnten Sie den Midstate einmal berechnen und dann einfach einen SHA-256-Chunk für jeden Proof of Work hashen, den Sie verifizieren möchten. Genau wie Kunden es mit rollntime tun.

Jede neue Merkle-Wurzel ist also Arbeit, um sie zu erzeugen, und schafft auch später mehr Arbeit, da ein neuer Mittelzustand berechnet werden muss.

BitMinter nutzt das Rollen des ntime-Felds sowohl auf dem Server als auch auf dem Client. Jedes Mal, wenn die Wanduhr eine Sekunde vorwärts tickt, aktualisieren Sie das ntime-Feld der Blockdaten mit einem neuen Zeitstempel. Dann können Sie alle Merkle-Wurzeln und Mittelzustände wiederverwenden, die Sie aus der vorherigen Sekunde haben.

Dies spart enorm viel Arbeit auf dem Server, und so konnte BitMinter mit geringer Last auf einem einzelnen Server mit 2-3 TH/s Hashpower laufen, während einige (nicht gut optimierte) Pools für alle 300 GH einen neuen Server benötigten /s Hashpower.

Seitdem haben solche Optimierungen an Bedeutung verloren. Mehr Kunden begannen, rollntime zu unterstützen. Server und Clients begannen mit der Arbeitsschwierigkeit über 1, was bedeutet, dass viel weniger Arbeit auf dem Server verifiziert werden musste. Und dann gibt es die neuen Protokolle, die getwork ersetzen: Stratum und GBT (getblocktemplate). Bei diesen Protokollen generiert der Server einfach eine Vorlage, die sehr billig zu generieren ist, dann erledigen die Clients den schwereren Teil der Erstellungsarbeit auf der Grundlage der Vorlage.

Ich denke immer noch, dass es für Clients eine gute Idee ist, den ntime-Trick zu verwenden, um Merkle-Roots und Midstates wiederzuverwenden, was die Wiederverwendung von Midstates auch auf der Serverseite ermöglicht, obwohl dies keine große Sache mehr ist.