高级方法
双几何法
所有抗 pool-hopping 的方法都需要维护一个平稳状态,这时每个矿工都能看到相同的相关历史,而不管他何时提交 share。
-
几何法通过使用一个可变费用来做到这一点,它有轮的概念。经营者吸收风险时,吸收得越多(c 越大),那么基于 share 的方差(提交 share 断断续续引起的)就越小,基于 pool 的方差(矿池算力太小引起的)也会减小。基于 share 的方差和基于 pool 的方差都是对于矿工而言的。
-
PPLNS 通过完全抛弃轮的概念做到这一点,share 得到的奖励和它到出块 share 之间的 share 完全独立。增大 X,会降低基于 share 的方差,但基于 pool 的方差不变,经营者的风险也不变,只是成熟时间变长了。但是这种方法不能减小基于 pool 的方差。
双几何法介于几何法和 PPLNS 之间。在双几何法中,轮可以跨过,而不是像几何法那样找到块后完全开始新的一轮,可以调控平均手续费、基于 pool 的方差、基于 share 的方差、经营者的方差和成熟时间。
算法步骤:
-
设定 f 为固定费用(可以为负数),c 是平均可变手续费,平均总手续费每个块为 \(\lparen c+f-cf \rparen B\)。增大 c 会减小矿工方差,增大经营者方差
-
矿池初始时,令 \(s=1\),对每个矿工有一个分数 \(s_k = 0\)
-
令 \(r = 1 + \dfrac{p \lparen 1-c \rparen \lparen 1-\theta \rparen}{c}\),\(\theta\) 为跨轮系数,\(\theta\) 增大会减少矿工基于 share 的方差,增大成熟时间。\(\theta = 0\) 即为几何法,\(\theta = 1\) 时即为 PPLNS 的一个变种(就是 share 有没有奖励是按指数函数衰减而不是阶跃函数),此时 c 必须为 0,r 也不按这个公式算,可自由选择
-
提交 share 时,令 \(s_k += \lparen 1-f \rparen \lparen 1-c \rparen spB\),\(s *= r\)
-
share 是块时,支付给矿工 \(\dfrac{\lparen 1-\theta \rparen s_k}{cs}\),再令 \(s_k *= \theta\)
上面步骤中的参数在任何时间点都可以修改,而不会影响已有 share 的收益期望。
找到块时,在 PPLNS 中会不修改分数而继续,在几何法中会把分数清算支付再清零,而在双几何法介于两者之间,保留一部分分数,剩余部分清算支付。
双几何法同样有对数版本:
-
初始化令 \(s = 0\),每个矿工的分数是 \(s_k = -\infin\)
-
令 \( r = 1 + \dfrac{p \lparen 1-c \rparen \lparen 1-\theta \rparen}{c}\),\(r_l = \ln{r}\)
-
提交 share 时,\(s_k = s + \ln \lbrace \exp \lbrace s_k - s \rbrace + \lparen 1-f \rparen \lparen 1-c \rparen p B \rbrace \),\(s += r_l\)
-
出块时,支付 \(\dfrac{\lparen 1-\theta \rparen \exp \lbrace s_k - s \rbrace }{c}\),再令 \(s_k += \ln{\theta}\)
双几何法中,每个矿工的延迟收益的期望为 \(\dfrac{s_k}{s}\),对数版本为 \(\exp \lbrace s_k - s \rbrace\)。
PPLNS 的各种变体
下面再大致介绍几种 PPLNS 的变体方法。
一种变体是换另一种衰减函数,由原来的阶跃函数(只有出块前的 N 个 share 有奖励,再往前的就没有奖励,这是阶跃函数)换成指数衰减函数、线性衰减函数等。
pay once PPLNS,就是每个 share 最多支付一次,支付过的 share 被去掉(部分支付过则只保留未支付的比例),让更早的 share 有机会得到奖励。若 share 都支付完则剩余的奖励先暂存,有了 share 之后再继续拿出来分。这种 PPLNS 的 X 必须小于 1.
shift PPLNS,它和标准的 PPLNS 很相似,只是实现上是流式的,它不需要保存 share。
General unit-based framework:最复杂的方法,它是这篇论文里面介绍的最一般的方法,PPLNS、几何法都是它的特例。
攻击向量
pool-hopping 攻击,这个在之前的各种方法里面已经介绍过。
block withholding:
-
sabotage,也就是常说的扣块攻击,矿工不提交出块的那个 share。在 PPLNS 中,攻击者自己也有损失,他的每个 share 的期望收益变为 \(\lparen 1-f \rparen \lparen 1-\dfrac{h}{H} \rparen pB \)。在 PPS 中,损失全部由矿池经营者承担,矿池每个 share 的收益期望变为 \(\lparen f - \dfrac{h}{H} \rparen pB \),这甚至能是负数。
-
lie in wait,攻击者在多个 PPLNS 矿池中都进行挖矿,一旦在某个时间点找到了出块 share,其它算力就会切到这个矿池挖一段时间 T,再提交之前的块。在这期间,其他人可能会出块,那就把算力恢复成原样,再找机会。
解决扣块攻击的方法是修改共识协议,让矿工算出 share 时不知道它是否能够出块,只能提交给矿池再做验证。