开源矿工的备用矿池设计与实现
本文基于内核自有的备用矿池功能实现开源矿工的备用矿池,以后可能会脱离具体内核实现备用矿池。
设计和实现备用矿池的功能时充分体现了为什么开源矿工会有10多万行代码。
备用矿池分两种:
一种像Claymore通过写一个Claymore指定的文件实现;
一种像更合理的NBMiner通过正常的命令行参数实现,-o是主矿池-o1是备用矿池;
这两种的不同只是外部系统向内核内部系统传送信息的方式不同,claymore通过文件传送信息的方式对直接使用claymore原版挺方便但对像开源矿工这样的第三方程序来说导致引入了除命令行参数外的第二种向内核输入数据的方式。
通过硬编码功能完备的编程语言是可以实现特定于Claymore的备用矿池的,但开源矿工想做的通用,想一次性解决所有像Claymore这样的内核,为此需要抽象出其中的模式写出更多的代码,但如果掌握了规则会发现开源矿工10万行的代码如同1万行,因为所有地方都一致。
面向类Claymore内核的文件书写器
为了写内核的备用矿池文件,我们需要一个文件书写器,比如对应Claymore的内核配置会引用一个文件书写器,文件书写器需要知道往哪个位置写以及写什么内容。
向什么位置书写
文件书写器向小编给定的位置书写(小编作为一个外部系统向开源矿工系统输入信息的唯一途径是开源矿工启动时从阿里云下载的server.json,这个server.json会在界面上发生用户活动时检测到更新时刷新),要写向的这个位置应是一个相对位置,最终的完整位置应由运行时根据当时的上下文信息计算得到。
书写什么内容
书写小编指定的内容,但小编指定的内容中会有变量,这些变量需要在写之前根据当前的上下文信息赋值。以Claymore为例,小编给定的内容会是POOL: {pool1}, WALLET: {wallet1}/{worker1}, PSW: x, ESM: 0, ALLPOOLS: 0这样的内容,里面的大括号括住的是变量,这些变量需要运行时在写文件之前填充上,其中任何一个大括号括住的位置从环境中得不到值则表示不匹配(如同计算机语言的函数调用和函数签名不匹配),不匹配的书写器将被忽略。 是不是很熟悉?文件书写器像什么?是不是像个函数?向什么位置书写和写什么内容是它的入参,而书写的内容中又有大括号括住的如同{pool1}这样的东西,{pool1}这是函数体中用到的父级作用域中的变量,对于开源矿工来说它依然是一个纯函数因为它只从上下文中读取变量的值而并没有写,对于开源矿工来说这个函数没有输出,因为它输出到外部文件系统中去了。
这个设计是可以支持钱包地址形式和用户名密码形式的备用矿池的,只需给内核关联两条文件书写器记录,一条书写器中有{wallet1}这样的变量导致它只会在上下文中有钱包地址时执行,另一条书写器中有{userName1}变量导致它只会在上下文中有用户名时执行。值得指出的是{wallet1}、{userName1}虽然和{wallet}、{userName}不同,但{wallet1}的值和{wallet}相同因为{wallet1}直接只是{wallet}的别名,而{userName1}和{userName}很可能不同,因为用户名密码形式的备用矿池会在界面上拥有对应{userName1}的输入框。
类NBMiner的备用矿池同理,但不需要文件书写器。
当我们说开源矿工是一个完备的系统时我们指的是它内部具有和外部环境足够多的映射信息,完备的系统可以通过调整自己的内部空间排布和行为方式节能高效的应对环境的变量从而让生命周期更长。
开源矿工官网:https://ntminer.com/