这篇「以太坊矿池构建指南」来自DragonflyCapital研究合伙人IvanBogatyy构建MiningDAO.io矿池的第一手经验,并概述了如何将叔块率降低的方法。矿池是以太坊生态系统中的主要力量。随着矿工可提取价值(MEV)呈指数级增长,EIP-1559升级以及即将到来的合并,矿池已成为生态系统中更重要、更有发言权的参与者。给萌新解释一下:矿池是软件提供商,使许多矿机能够汇聚其挖矿能力并分享奖励。从两个层面上看,矿池在基于工作量证明(PoW)共识机制的挖矿中是必不可少的:首先,因为个体矿工的收入波动会很大;其次,因为围绕挖矿构建软件基础设施的难度越来越高。通过资源的集中,个体矿工可以降低收入变动,因此拥有可预测性更强的业务运营。但是这种权力也伴随着巨大的责任,矿池拥有很大的权力,这是因为矿池最终决定了其矿机处理哪些区块,以及这些区块中可以包含哪些交易。矿池决定提取哪些MEV以及谁可以提取它,他们对Gaslimit进行投票,并参与重大的政治斗争。因此对于以太坊文化来说,矿池的入场门槛尽可能低、以最大限度地去中心化是至关重要的。所以当我决定构建一个矿池时,我惊讶地发现它是一项非常有挑战性的工作!关于如何运行具有高响应性、低叔块率的竞争性矿池,很少有公开的知识分享。所以我想:好吧,让我们解决这个问题。构建一个矿池包含两部分工作:设置一个具有良好对等网络和快速处理速度的全节点客户端;将全节点连接到矿池软件,该软件管理哈希率并在所有矿工之间分配工作负载。在本文中,这两者都会谈到。这篇「以太坊矿池构建指南」来自我们构建MiningDAO.io矿池的第一手经验,并概述了我们如何将叔块率从10%-14%降低到大约4%-5%,与前10名矿池中的部分组织保持持平,甚至更佳。设置以太坊全节点客户端运行矿池需要运行以太坊全节点客户端。该客户端将负责接收新块和待处理的交易,以及生成自己的区块并将它们广播到其他节点。本节介绍如何正确设置一个全节点客户端。服务器硬件要求运行一个完全同步的节点需要相当好的硬件。我们建议至少32GB内存(RAM)和至少2TBSSD存储(永远需要将以太坊链与HDD同步)。带宽也很重要。最好尽可能靠近其他节点,以尽快接收新块。我们建议采用其他矿池普遍采用的云服务上使用云托管专用机器:在欧洲是和,亚洲则是阿里云和亚马逊云AWS。
Geth还是OpenEthereum?Geth!下一个决定是使用哪个以太坊客户端。最受欢迎和经过充分测试的选择是Geth和OpenEthereum(原名Parity)。Geth在协议开发方面处于领先地位,并且始终保持最新状态。为了进行比较,我们利用Parity-2.7.2(OpenEthereum重构之前的最新稳定分支)和OpenEthereum进行了一些小规模实验,但两者在区块导入时间和区块生产时间方面的测试结果都很糟糕,导致叔块率高到令人无法接受。我们欢迎任何人进行更彻底的A/B测试,并与我们联系,为我们提供更多数据,但在当前阶段,我们只推荐Geth。以下是我们使用的命令行:geth--datadir=/ssd/gethdata--syncmode=fast--cache=21000--maxpeers=250--txpool.globalslots=1000--http--http.api=eth--miner.etherbase='0xADDRESS'--mine--miner.threads=0--miner.extradata='MiningDAO'--miner.notify=''&>>~/geth-log.txt这里--cache=21000表示分配21GB用于内存状态存储(这是Geth可以处理的峰值),命令行其余部分将在下文予以解释。更重要的是,我们下文描述的对Geth代码的修改可以在找到,作为可供下载的存储库,或者在,作为要应用的补丁。将空块产生频率降至最低有两件事会破坏矿工所获取的价值回报:挖出叔块和挖出空块。这两者几乎同样糟糕:叔块奖励为1.75ETH,空块奖励为2ETH,两种情况下都没有交易费盈余。相比之下,带有交易费用的完整区块的总奖励通常达到3-4ETH,有时甚至更多。为什么矿池有时会,以及如何将其产出频率降至最低?当另一个矿池挖出一个新区块(比如高度N)时,高度N的任何其他区块都可能成为叔块。因此每当发现新区块时,Geth会立即切换矿工的工作,在N+1高度挖出一个空区块。这个空块中不包含交易费用,但这还是比挖出注定要成为叔块的区块要好。随后,Geth在高度N+1处构建了一个「真正的」区块,并再次切换矿工的工作。构建这样一个「真实」的区块需要时间(0.1-0.3秒),因此需要两步过程。但在这段0.1到0.3秒的过渡期间,其他矿工们则正在挖一个空块。收集所有待处理的交易,以实现费用收益最大化,可能很诱人,但像txpool.globalslots这样贪婪,会大大增加Geth构建「真实」区块所需的处理量(要耗时多达1秒或更长时间)。我们的推荐值不大于1000或2000。要了解这方面的更多详细信息,请查看将叔块产生频率降至最低解决了空块,我们就可以开始困难的部分了。要尽量降低叔块率,有两件事是关键:当其他矿池生产出新区块时,尽快掌握消息;当您的矿池产生一个新区块时,尽可能广泛地传播它(这样其他人开始在它后面开始挖矿)。
如前所述,实现良好对等网络(p2p)的第一步是在临近其他节点的云服务器上运行您的全节点,并配备良好的带宽。其次,良好的带宽允许节点处理更多的直接对等点,从而减少接收新信息所需的p2p中继段(hop)数量。Geth命令行中对等点数的标志是--maxpeers。下面我们将解释一些更细微和强大的技巧,以最大限度地提高区块导入速度和区块广播速度。使用bloXroute是一项致力于改善矿工之间连接并降低其叔块率的服务。大多数矿池都连接到bloXroute,甚至主要的成熟矿池都,使用bloXroute会带来显著改进。KeeperDAO进行的进一步证实了bloXroute相比同类服务具有巨大优势。我们的实验也体现出显著的改进。在具有默认对等设置的新同步节点上,大约90%的所有新区块首先来自bloXroute(只有10%来自所有其他对等节点)。即使在我们的节点经过微调以连接到顶级对等点之后,仍有40%-60%的新区块首先来自bloXroute。按照bloXroute设置教程进行操作后,不要忘记,稍后会用到它。是Geth将始终连接到的预设节点,无论对等点如何随机初始化。受信任的对等点也不计入连接数限制。将bloXroute网关添加到受信任的对等点,可确保Geth的这一连接不会意外断开。我们进一步建议连接到太极网络。太极网络项目是星火矿池开发的区块广播网络。可以通过将太极网络添加到同一个受信任的对等文件中,来保持与太极网络的连接。积极广播您的区块每当Geth成功挖出一个新区块时,它就会发送该区块以在网络上广播。默认情况下,Geth只将其广播到大小为sqrt(n_peers)的随机子集,后者将区块广播到它们的部分对等点,依此类推。即使所有对等点都同样有效,这种机制也不是很理想,但是当某些对等点比其他对等点更强大,而这些对等点最终没有被包含在子集中时,这种机制的缺点尤其明显。特别是,在挖出新区块时要做的第一件事是将其发送到bloXroute,以便将其转发到所有参与的矿池。如果bloXroute网关最终没有出现在那个随机的sqrt(n_peers)子集中,那么您获得叔块的机率就会大大增加!接下来,您会希望将该区块发送给质量最高的对等点,然后再发送给所有其余的对等点。
我们已将开源,建议将其应用于您的客户端。它将所有新挖出的区块广播到所有受信任的节点(包括bloXroute),然后广播到所有剩余的对等点。培养人脉最广的对等点VanillaGeth旨在实现最大程度的去中心化和网络结构扁平化。这种选择非常适合爱好者,并支持由个节点组成的强大生态系统。然而,正如我们在上一节中看到的那样,对于执行关键职责、或一旦故障会造成高昂成本的节点而言,这些默认参数的效果不佳。实际上,并非所有对等点都同样有效。有些节点连接速度较慢,既不会提供新区块,也不会帮助您的区块进行广播。其他人,尤其是其他矿池的节点,则会产生源源不断的新区块数据。根据星火矿池的建议,我们,以记录哪些节点最先向我们发送新区块。经过几个月收集这些数据,使我们能够找出始终保持连接的最佳对等点(通过Geth中的「静态」/「受信任」节点设置)。是一个Python脚本,我们用来处理上述数据,并将其转换为Geth可以摄取的trusted_nodes.json列表。由于MiningDAO矿池存在于每个地理区域(北美、欧洲、亚洲)中,我们对每个地理区域的顶级对等点列表进行了数据挖掘。不幸的是,我们不能公开分享这些节点的IP,避免这些节点遭遇DDoS攻击。对于有充分理由的严肃询问者,我们可以私下分享。也很乐于分享我们自己在每个地理区域的节点,以供其他矿池连接!设置矿池软件正确设置全节点后,下一步是设置矿池软件本身。该软件将负责处理来自所有单个矿机的连接、跟踪工人的份额并管理支出。挑选矿池软件我们简要分析了以下4个选项:、、和。我们后来了解到,但未对其进行实验。出于两个原因,我们对于Miningcore获得了丰富的经验。首先,它将所有过去的数据保存在SQL数据库的磁盘上,这与open-ethereum-pool不同,后者通过Redis仅将数据保存在RAM中。磁盘存储提供了抗重启的稳定性和分析历史数据的能力。其次,我们喜欢Miningcore高度可读、面向对象的代码。
最终,MiningDAO采用了我们自己的矿池软件,以Miningcore为模型,用Go语言编写以提高速度。我们希望尽快开源我们的软件,但同时我们推荐使用Miningcore。修补矿池软件的延迟问题我们在使用Miningcore时遇到的一个主要问题是它处理工作更新的方式。默认情况下,Miningcore每0.5秒ping全节点远程过程调用(RPC),以查看最新作业是否已更改。这一设置可能适用于其他具有区块生产时间较长的加密货币(对于区块生产时间为10分钟的比特币来说,这是一个可以忽略不计的问题),但对于以太坊而言,这种设置会导致无法接受的高叔块率。做个背景知识介绍,有一种简单的方法可以计算任何处理延迟所带来的叔块率增加数值。出块时间是的,意味着无论距离上一个挖出的区块已经过去多久,在下一秒(或毫秒或其他时间单位)内找到下一个区块的概率总是相同的。例如,以太坊的目标是13秒出块时间,意味着下一秒出块的概率始终为1秒/13秒≈7.7%。因此,如果您的矿池因任何原因在管道中的任何地方有0.1秒的延迟,则由于该延迟,将有0.1秒/13秒≈0.77%的额外叔块。叔块将来自您的矿机处理过时工作的0.1秒时间段。回到Miningcore。使用上面的公式,矿工作业更新如果出现0.5秒延迟,将导致0.5秒/13秒≈4%额外的叔块(绝对比例,而不是相对百分比)。当然,如此高的非受迫性失误率是不可接受的。我们已经广泛尝试将更新频率从0.5秒降低到50毫秒及以下,但发现这一设置相当不可靠:工作更新仍然明显延迟。更好的解决方案是利用Geth的notifyWork功能,以便Geth在作业更新出现时主动将其发送到矿池软件。我们对Miningcore打了补丁,以支持这一选项,并发布了。过渡到notifyWork后,我们发现Geth和Miningcore之间的通信延迟几乎可以忽略不计,因此我们的叔块率显著降低。总结希望这篇文章有用,并引导更多人运营以太坊矿池;自制矿池的文化对于保持以太坊的开放性和去中心化至关重要。简单总结一下,我们最初采用vanillaMiningcore的默认参数和vanillaMiningcore软件。这种默认设置的叔块率约为10%-14%。我们在逐步采用了本文概述的种种修改后,使我们的叔块率降至,与当前现有的前10名矿池的水准持平甚至更好(Etherscan中显示的叔块率略高,因为我们有时会在生产中进行实验)。我们的Geth修改方案可以在这里作为repo,也可以在这里作为找到。可以在找到我们的Miningcore修改方案,且可以在找到相应的矿池配置文件。如果您对如何改进这一参数设置有进一步的想法,请向我们发送pull请求或!鸣谢:Miningcore加速由开发。感谢这些朋友提供建议和想法:()、、()、()、YangZe()、Chris()和()。