ETH-Pow算法分析

1. Ethash 算法c++

1.1 Ethashgit

Ethash是以太坊1.0中使用的PoW(工做量證實)算法,它是Hashimoto算法結合Dagger以後產生的一個變種。它的特色是計算的效率基本與CPU無關,卻和內存大小和內存帶寬正相關。所以經過共享內存的方式大規模部署的礦機芯片並不能在挖礦效率上有線性或者超線性的增加。github

該算法的通常流程以下:算法

  • 首先根據塊信息計算一個種子(seed, c++代碼中爲seedhash)
  • 使用這個種子,計算出一個16MB的cache數據。輕客戶端須要存儲這份cache.
  • 經過cache,計算出一個1GB(初始大小)的數據集(DAG),DAG能夠理解爲是一個完整的搜索空間,全客戶端和礦工須要存儲完整的DAG,挖礦過程當中須要從DAG中重複的隨機抽取數據拿去和其餘數據計算mixhash,DAG中每一個元素的生成只依賴於cache中的少許數據。每到一個新的紀元DAG會徹底不同,而且它的大小也隨時間線性增加。
  • 因爲僅根據cache就可使用少許內存快速的計算出DAG中指定位置的數據,因此輕客戶端只須要存儲cache就能夠高效的進行校驗。

1.2 內存難解spa

因爲比特幣將hash算法做爲pow工做量證實的重要手段,後續的各類採用pow的數字貨幣也延續了這個設計,以SHA25六、MD5(MD5後來被證實不具有強碰撞性數字貨幣通常不用)爲表明算法。在設計之初都是算力敏感型,意味着計算資源是瓶頸,主頻越高的 CPU 進行 Hash 的速度也越快。這個設計直接致使後來的礦機出現,採用ASIC芯片的礦機更是將這種運算能力成倍提高,更多礦場的出現使得當時的比特幣面臨算力中心化的威脅。爲了限制計算能力的依賴,人們開始尋求新的算法,既然要限制CPU的能力,目光天然投向存儲依賴,也就是內存依賴。設計

​ Hashimoto算法採用IO飽和的策略來對抗ASIC,使內存讀取成爲採礦過程當中的限制因素。3d

​ Dagger算法使用DAG(directed acyclic graphs 有向無環圖)來同時實現內存難解和內存易驗證兩個特色。 主要原理是,計算每一個nonce須要DAG中的一小部分,採礦過程須要存儲完整的DAG,禁止每次計算DAG的相應子集,而驗證過程是容許的。blog

1.3 參數定義內存

  WORD_BYTES  Word的字節數 
  DATASET_BYTES_INIT  2**30 1GB  Dataset的初始大小 |
  DATASET_BYTES_GROWTH  2**23 8MB  每一個紀元dataset的增加量 |
  CACHE_BYTES_INIT  2**24 16MB  Cache的初始大小 |
  CHCHE_BYTES_GROWTH  2**17 128KB  每一個紀元cache的增加量 |
  CACHE_MULTIPLIER  1024  Size of the DAG relative to the cache |
  EPOCH_LENGTH  30000  每一個epoch的塊數 |
  MIX_BYTES  128  Mix的寬度 |
  HASH_BYTES  64  Hash的長度 |
  DATASET_PARENTS  256  每一個數據集元素的parents數量 |
  CACHE_ROUNDS  計算cache時的輪數 |
  ACCESSES  64  Hashimoto循環的次數 |

 

2 DAG資源

DAG是ethash算法中須要頻繁訪問的數據集,這個爲每一個epoch生成的。DAG要花很長時間生成,若是客戶端至少按照須要生成它,那麼在找到新epoch第一個區塊以前,每一個epoch過渡都要等待很長時間。然而,DAG的生成只取決於區塊數量,因此能夠預先計算出DAG來避免在每一個epoch過渡過長的等待時間。

DAG的生成流程以下:

2.1 Dag_size 和Cache_size

每一個epoch的dagsize和cachesize都不一樣,上面已經定義了創世時的初始值,以太坊還提供了一個表來存儲接下來2048個紀元(大約20年)的各個值。詳見官網或源碼cpp-ethereum/libethash/data_sizes.h.

獲取datasize 和cachesize的方法以下:

2.2 Seedhash

算法中須要一個seedhash,由下面程序生成,從程序可見每一個epoch的seed是不變的。

2.3 Cache

使用seedhash計算cache。

2.4 DAG

最後使用cache計算DAG,light參數中保存的是cache數據.

2.5 DAG文件

DAG每次生成都須要很長時間,所以生成時候須要存在文件中,再使用mmap映射到內存中。DAG文件路徑通常以下

Mac/Linux : $HOME/.ethash/full-R–

Windows: $HOME/Appdata/Local/Ethash/full-R–

是ethash算法的版本號,在libethash/ethash.h 中REVISION定義。

是上面計算出來的seedhash

路徑下可能會有多個DAG文件,這取決於用戶或者客戶端是否刪除過期的DAG文件。

格式:

DAG文件以8字節的幻數開頭,值爲0xfee1deadbaddcafe, 以小端格式寫入。接下來是小端格式寫入的dataset數據。

 

3 Ethash實現

3.1 Ethash

圖1 算法流程圖

參數說明:

Header_hash: 是當前塊頭部數據的hash值,在礦機調用get_ethwork時從任務參數中獲取。

Nonce: 是每次計算ethash使用不一樣的數,不能重複。能夠取時間戳或隨機數做爲起始值,而後遞增。

對於礦工來講,若是result的值小於或等於target,那麼就完成了挖礦過程,將當前的nonce和mix_hash做爲工做量證實提交工做;若是result的值大於target,那麼就須要改變nonce的值,再次調用ethash算法.

Ethash算法程序以下:

從圖中看,每次ethash從DAG隨機取64128=8192Bytes, 以GTX1070顯卡爲例,帶寬爲256GB/s, 那麼每秒能承受256102410241024/8192=33554432次ethash運算,即33MH/s的算力。可見,該算法對內存帶寬的要求很高。

3.2 快速驗證

當驗證一個工做提交是否有效時,速度很快。

下面是快速驗證程序:

 

 

原文連接:http://wangxiaoming.com/blog/2018/06/26/HPB-47-ETH-Pow/

相關文章
相關標籤/搜索