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/

相关文章
相关标签/搜索