礦池挖礦:如何在不知道塊號的情況下生成 DAG?
這有點類似於:在創建 DAG 以在池上進行探勘時,我是否需要同步到區塊鏈?而這個https://github.com/ethereum/go-ethereum/issues/2333
本質上,池發送用於生成 DAG 的種子雜湊,我不明白這是如何在沒有塊號的情況下完成的。
在https://github.com/ethereum/wiki/wiki/Ethash中,Hashimoto 循環期望知道記憶體大小,我們只能通過塊號獲得。
所以我的問題是:如何僅使用來自 eth_getWork 的參數進行探勘?最好按照 Ethash 規範(https://github.com/ethereum/wiki/wiki/Ethash#defining-the-seed-hash)
eth_getWork
回顧一下,您的礦池將使用以下資訊響應呼叫:DATA, 32 Bytes - current block header pow-hash DATA, 32 Bytes - the seed hash used for the DAG. DATA, 32 Bytes - the boundary condition ("target"), 2^256 / difficulty.
此資訊將用於生成 DAG。
從這裡開始,我參考了黃皮書,而不是 Ethash wiki 頁面。從黃皮書,我們可以確認您查詢的依據:
J.3。數據集生成。為了生成數據集,我們需要記憶體
c
,它是一個字節數組。這取決於記憶體大小csize
和種子雜湊s ∈ B32
。和:
J.2。數據集和記憶體的大小。Ethash 的記憶體
c ∈ B
和數據集的大小d ∈ B
取決於 epoch,而 epoch 又取決於塊數。來自第 J.2 節。在黃皮書中,您會看到記憶體的大小對於給定時期內執行的所有探勘都是恆定的,其中一個時期被定義為 30,000 個塊(約 100 小時)。因此,您不需要知道塊號來計算記憶體大小,只需要知道目前的紀元數。DAG 本身的大小也是如此,這也取決於目前的 epoch 數。
那麼……我們如何在本地找到紀元數?
我們被告知種子雜湊
eth_getWork
,但我們無法反轉雜湊以獲取創建它的塊號。所以我們使用試錯法。從一個我們知道在 epoch 0 中的塊開始 - 因為我們知道 epoch 0 是從塊 0 到塊 30,000 - 我們在本地創建一個種子雜湊並檢查它是否與我們發送的種子雜湊匹配。程式碼中的一個範例如下。
- 在MinerAux.h 中呼叫
getWork
,並返回 3 個變數,包括種子雜湊EthashAux::full()
被呼叫,並getWork
傳入種子雜湊- 動作跳轉到
EthashAux.cpp
定義主要功能的地方- 在
EthashAux::full()
我們呼叫EthashAux::computeFull()
中,再次通過種子雜湊- 在這裡,我們使用計算(近似)塊數
blockNumber = EthashAux::number(_seedHash)
的相關部分
EthashAux::number()
是以下行:
for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {}
…它循環遍歷紀元數,散列以創建種子散列,並根據 . 發送的散列對其進行檢查
getWork
。然後該函式返回一個近似的塊號:
return epoch * ETHASH_EPOCH_LENGTH;
。然後我們稍後使用這個值來計算記憶體大小,這反過來又可以用於生成記憶體。
編輯 - 附錄:
Parity (由 Ethcore 編寫的客戶端)在eth_getWork的實現中確實包含了塊號。