扣块攻击:矿池无法从单个份额发现的攻击
一个矿工提交真实的份额,却藏起本该成为区块的那一个。了解它的代价、由谁承担、为什么有人这样做,以及如何发现它。
什么是区块扣留攻击?
这是一个矿工提交所有普通份额,却藏起那个本该成为区块的份额。矿池为这些份额付钱,而区块永远不会到来。
您发给矿池的每个份额,都是一个没达到区块目标的真实解。区块目标是哈希要成为区块必须通过的更高门槛。偶尔会有一个解也通过了它,这个份额就是一整个区块。
在矿池检查之前,这样的份额和其他份额看起来一模一样。
攻击者老老实实地做工作,提交每一个普通份额。它悄悄扔掉那个本该成为区块的份额。矿池统计份额并为之付钱。矿池本该收到的区块永远不会到来。
为什么单个份额暴露不了它?
从任何单个份额来看,攻击者都没有异常。硬件是真的,算力也是真的。份额有效,到达速度也正常。矿池检查一个份额,什么也看不出来。
缺少的是一种“不存在”,而“不存在”只能随时间显现。一个占矿池算力某个比例的矿工,大致也应该找到同样比例的区块。
在一小时内,这说明不了什么。找到区块是随机的,安静的时段很平常。在足够长的时间窗口里,它能说明很多。
代价是什么,由谁承担?
矿池失去了本该得到的区块奖励。但损失其实并不落在矿池身上。无论在哪个矿池,这一点都值得弄明白。
- 在按比例方式下,这一轮会一直持续到别人找到区块为止。这一轮里的每个人都在一个比正常更长的轮次上工作。所以每个人每单位工作的收益都略有减少。代价分摊到了诚实的矿工身上。
- 在按份额支付的方式下,对运营者更糟。矿池已经自掏腰包为每个份额付了钱,靠区块到来回本。持续的攻击会直接掏空运营者。历史上,人们最担心的就是这种情况。
为什么有人会这样做?
攻击者也扔掉了区块奖励。乍一看,这纯粹是自损。只有当攻击者在矿池看不到的地方获益时,这才说得通。
常见的动机是竞争。经营自己矿池的人可以租来或调来算力,指向竞争对手,压低它的成绩。这样他自己的矿池相比之下就显得运气更好。攻击者仍能拿到的份额收入,为这场破坏买了单。
在一种更隐蔽的变体中,攻击者不扔掉区块,而是把它留在手里。它在这个区块之上私下继续挖矿,然后在对自己有利的时机再提交。这更难得手,需要占有很大比例的算力才值得一试。
怎样检测它?
检测只能靠统计,因为没有别的信号。把某个参与者实际找到的区块,与按其份额数应该找到的区块进行比较。比较的时间窗口要足够长,让运气能够平均掉。
难点在于时间窗口。
- 窗口太短,普通的坏运气看起来就像攻击。诚实的矿工会不断被指控。
- 窗口太长,真正的攻击者在数字说话之前就能活动一段时间。
这种取舍没有巧妙的解法。它来自随机性,而不是软件。
所以一个靠谱的检测器会把问题交给人来判断,而不是自己动手。由统计数字驱动的自动封禁,总有一天会封掉一个只是运气不好的人。让一个正当的矿工下线,比攻击本身更糟。
这对诚实的矿工意味着什么?
几乎没有影响,这一点值得直说。
无论如何,您的份额都照样被统计和支付。运气不好不是过错,也不可能是过错。在任何短时间窗口里,大多数矿工都运气不好。
连续几轮您贡献了很多而矿池什么都没找到,这是正常的波动。矿池统计中的运气数值会告诉您这有多正常。
这种攻击是矿池在意谁把算力指向自己的原因之一。这也是为什么一个如实公布区块和运气的矿池更值得信任。核查矿池所需的一切都在区块页面上。