比特币矿池挖矿的奖励系统分析(二)

8 minute read Published: 2019-11-24

来自论文:Analysis of Bitcoin Pooled Mining Reward Systems

这一篇介绍打分法中用得最多的 PPLNS 及其变体 UPPLNS。另外还介绍了几种对 PPS 改良的尝试手段,想让矿池支持 PPS 的风险变得更低,但效果并不是很完美。

基于打分的方法

PPLNS(Pay per last N shares)

PPLNS 抛弃了轮的概念,奖励不再分给一轮中的所有矿工,而是出块前一段时间内的矿工。这样矿工不能预先确定某个时间段是否能出块,就不能决定是否要切走算力对自己有利,所以 PPLNS 能防止 pool-hopping。

最简单的是选固定的 N,出块前的 N 个 shares 平分 \(\dfrac{\lparen 1-f \rparen B}{N}\)。只要 D 和 B 是常数,每个 share 的收益期望就是 \( \lparen 1-f \rparen pB \),方差为 \(\dfrac{{\lparen 1-f \rparen}^2 pB^2 }{N} \approx \dfrac{pB^2}{N} \),这个方差比单独挖矿是小了 N 倍。每 share 收益期望推导如下:

式中 L 是这个 share 之后的 N 个 share 中出现块的数目,它同样服从 \(\lambda = pN\) 的泊松分布,p 是 share 能出块的概率,\(p = \dfrac{1}{D}\),L 的期望和方差都是 \(pN\)。

某个 share 之后再过 N share 才能知道它有没有奖励,而且这 N 个 share 是块的概率是等可能的,所以支付 share 的时间是 \(0 \sim N\) 的均匀分布,平均支付时间是 \(\dfrac{N}{2}\) 个 share。换成块就是说某个 share 提交之后,平均再出 \(\dfrac{pN}{2}\) 个块就能确定是否有奖励。\(\dfrac{pN}{2}\) 就是成熟时间。

增大 N,可以降低方差,但也会增大成熟时间。方差和成熟时间的乘积是定值 \(\dfrac{p^2B^2}{2}\)。

如果 D 和 B 不是固定的,那上面这种固定 N 的方法是不能完全抗 pool-hopping 的。矿工预先知道难度调整,可在难度往下调的时候加入矿池,往上调的时候离开。另一种 \(N = 挖块的难度 * 固定的值、) 同理也是不能完全抵挡。

能完全抗 pool-hopping 的 Unit-PPLNS

算法步骤:

  1. 选定 f 和 X

  2. 当 share 提交时,记录 2 个属性:单元值,它数值上等于当 share 是块的概率 p;放大倍数,值等于当时的收益 B

  3. 发现块时,令 \(u_1= 出块 share 的单元值、)。对于它之前非块 share (这个出块的 share 不会在这次出块中获得奖励,它要算在下一次)令它的单元值为 \(u_i\),放大倍数为 \(a_i\),\(U_i\) 为这个 share 到出块 share(包括它)的单元值之和,这个非块 share 的奖励为 \(\dfrac{\lparen 1-f \rparen a_i u_i \max \lbrace \min \lbrace \dfrac{X-U_i+u_1}{u_1}, 1 \rbrace, 0 \rbrace }{X}\)。

在实现时,用数组保存 \(U^T\),也就是这个 share 提交之前的单元值之和。出块 share 找到时,\(U^T\) 数组新增元素 M,那上面公式里的 \(U_i = M - U^t \lbrack i \rbrack\),所以只有 \(U^T \lbrack i \rbrack > M - X - u_1\) 的元素对应的 share 有奖励。

在这种方案中,每个 share 的奖励是 \(\dfrac{\lparen 1-f \rparen pBL }{X}\),L 为接下来单元值之和为 X 的 share 中出块的个数。因为每个 share 是块的概率等于单元值,L 又服从 \(\lambda = X \) 的泊松分布,所以每个 share 的期望收益仍然是 \( \lparen 1-f \rparen pB \),方差变为 \(\dfrac{p^2B^2}{X}\),为单独挖矿时的 \(\dfrac{X}{p} \) 倍。成熟时间为 \(\dfrac{X}{2}\)。每个 share 被延迟的收益的期望是 \(\dfrac{\lparen 1-f \rparen a_i u_i \max \lbrace X-U_i, 0 \rbrace }{X}\)。

修改 f 和 X 参数时,必须把所有 share 都调整,让它们在调整前后的延迟收益期望不变。改变 f,每个 share 的放大倍数乘以 \(\dfrac{1-f_1}{1-f_2}\);改变 X,每个 share 的单元值乘以 \(\dfrac{X_2}{X_1}\),放大倍数乘以 \(\dfrac{X_1}{X_2}\),这样保证 \(a_i u_i\) 和 \(\max \lbrace X-U_i \rbrace \) 不变。有时候没法做到让延迟收益期望不变,比如缩小 X 时,有些 share 的 \(U_i > X\),这种 share 就要立即支付这它的收益期望,这反映了实际上相当于矿池一开始就欠矿工 X 的收益。

几种让 PPS 无风险的方案

MPPS(Maximum pay per share)

这种方法为每个矿工记录 2 个属性:PPS 余额,在他提交 share 是增大;比例余额,在出块时增大。支付给矿工的是这两者中的较小值。

缺点:

矿工收益期望比期望值小。假如某个时间段内矿池共出了 n 个块,则矿工的收益比期望值小 \(\dfrac{1}{\sqrt{2\pi n}}\)。另外也不防 pool-hopping(矿池有币时就是 0 手续费的 PPS,有更大的吸引力)。

SMPPS(shared maximum pay per share)

这种方法为每个矿池按照 PPS 记录一个应得收入,然后矿池记录冗余 R,它是矿池总收入减去矿工应得收入之和。当 \(R<0\) 时,矿工按应得收入的比例分掉出块奖励 B。

缺点:

  1. \(R<0\) 时,成熟时间(share 的收益得到支付)太长,几乎为 \(\dfrac{-R}{B}\) 个块

  2. 只要时间足够,R 肯定会在某个时间点到达 \(\lparen 0, -\infin \rparen \) 中的任意一个值,类似一维布朗运动。这时成熟时间太长,矿工就会离开,算力下降,出块时间变长,进入恶性循环。并且由于 stale share、invalid block、攻击等,让实际收益比期望低,这个过程所需的时间比想象中的短。

  3. 不能抗 pool-hopping

ESMPPS(Equalized SMPPS)

基于 SMPPS,只是每个 share 有一个最小需要立即支付的值。它的成熟时间是无穷大,SMPPS 的缺点也没有解决,只是让新 share 更有可能被支付,保留矿工的可能性更大一点而已。