基于随机代码执行的Monero工作证明算法

2020-06-15 15:35:21

RandomX是一种针对通用CPU进行优化的工作证明(PoW)算法。RandomX使用随机代码执行(因此得名)和几种内存硬技术来最小化专用硬件的效率优势。

RandomX利用虚拟机执行由整数数学、浮点数学和分支组成的特殊指令集中的程序。这些程序可以即时转换为CPU的本机代码(例如:Program.asm)。最后,使用密码散列函数(Blake2b)将执行的程序的输出合并成256位结果。

这两种模式可以互换,因为它们产生相同的结果。快速模式适用于挖掘,而灯光模式预计仅用于证明验证。

第一次审计得到了Arweave的慷慨资助,Arweave是RandomX的早期采用者之一。剩下的三次审计是由莫内罗社区的捐款资助的。所有四项审计均由OSTIF协调。

所有四个审计的最终报告都可以在审计目录中找到。审计没有发现任何严重的漏洞,但是作为审计的直接结果,对算法和代码进行了几次更改。更多细节可以在OSTIF的最终报告中找到。

RandomX是用C++11编写的,它用头文件随机x.h提供的C API构建了一个静态库。api-example1.c中提供了最小API使用示例。参考代码包括用于测试的随机x基准和随机x测试可执行文件。

构建依赖:cmake(最低2.8.7)和GCC(最低4.8版,推荐7+版)。

在Windows上,可以使用MinGW(与Linux上相同的过程)或使用Visual Studio(提供解决方案文件)进行构建。

RandomX最初设计为Monero的PoW算法。推荐用法如下:

密钥K被选择作为区块链中的块的散列-该块被称为密钥块。为了获得最佳挖掘和验证性能,密钥应该每2048个块(~2.8天)更改一次,并且在密钥块和密钥K的更改之间应该有64个块(~2小时)的延迟。这可以通过在block Height%2048==64时更改密钥并选择密钥块以使keyBlockHeight%2048%==0来实现。

如果您希望使用RandomX作为您的加密货币的POW算法,请遵循配置指南。

注意:要实现ASIC阻力,键K必须改变,并且不能是矿工可选的。我们建议使用区块链数据作为密钥,方式与上面的Monero示例类似。如果区块链数据由于某种原因无法使用,请使用预定义的密钥序列。

下表列出了使用最佳线程数(T)和大页面数(如果可能)的选定CPU的性能,单位为每秒哈希数(H/s)。";CNv4";是指使用XMRig v2.14.1测量的CryptoNight变体4(CN/R)哈希率。快速模式和灯光模式是RandomX的两种模式。

请注意,RandomX当前包括用于x86-64和ARM64的JIT编译器。其他体系结构必须使用可移植解释器,这要慢得多。

SChernykh正在为RandomX开发GPU挖掘代码。基准包含在以下存储库中:

仅适用于AMD Vega和AMD Polaris GPU的OpenCL MINer(使用GCN机器代码)。

请注意,GPU在运行RandomX时处于劣势,因为该算法被设计为在CPU上高效。

自2011年以来生产的大多数英特尔和AMD CPU在RandomX上应该都相当高效。更具体地说,高效挖掘需要:

每个挖掘线程16 KiB的L1缓存、256 KiB的L2缓存和2 MiB的L3缓存。

可能需要多个内存通道:DDR3内存限制在每个通道1500-2000小时/秒左右(取决于频率和时序)。

DDR4内存限制为每个通道约4000-6000小时/秒(取决于频率和定时)。

由于算法的工作方式,挖掘恶意软件更容易检测。RandomX Sniffer是一个概念验证工具,可以检测Windows上的非法挖掘活动。

高效的挖掘需要超过2GiB的内存,这也使许多低端机器失去了资格,如物联网设备,这些设备通常是大型僵尸网络的一部分。

Web挖掘是不可行的,因为需要大量的内存,并且在Javascript和WebAssembly中都缺乏对浮点运算的定向舍入支持。

RandomX仅使用IEEE754标准保证能给出正确舍入结果的运算:加法、减法、乘法、除法和平方根。要特别注意避免出现拐角情况,如NaN值或非规格化。

RandomX为每个散列生成多个唯一程序,因此FPGA不能动态重新配置其电路,因为典型的FPGA需要数十秒来加载比特流。由于组合的数量太多(有2512个独特的节目),也不可能预先生成RandomX节目的位流。

足够大的FPGA可以通过模拟CPU在软微处理器配置中挖掘RandomX。在这些情况下,FPGA的效率将远远低于CPU或专用芯片(ASIC)。

如果您想使用RandomX,请考虑捐款以帮助支付算法的开发费用。