注册
关闭
区块链大帝

区块链大帝

发布于 5天前 阅读数 2940

技术向:交易转发中的带宽优化(上)

技术向:交易转发中的带宽优化(上)

早期的区块链系统往往吞吐量很低,相应的对带宽要求也不高,共识协议本身才是它们性能的瓶颈。例如比特币网络平均每 10 分钟只产生 1MB 大小的区块,在如今的宽带网络环境下几乎是可以忽略不计的。

近年来,随着 Conflux 等新一代区块链的发展和成熟,区块链的吞吐量有了质的飞跃,网络带宽越来越成为限制区块链性能进一步提高的瓶颈。这次,就让我们来聊一聊 Conflux 是如何优化带宽的使用效率的。

交易广播是在区块链上达成共识的第一步。每当用户发起一笔交易时,这笔交易从客户端程序出发,被发往一个或几个全节点。之后,全节点之间通过点对点网络将交易转发给各自的邻居节点,直到最终所有的全节点都收到这笔交易。

区块链的吞吐量越大则每个节点需要转发的交易数量也就越多。因此,在区块链的吞吐量和网络带宽处于相同的数量级时,交易转发过程的带宽利用率将直接影响了整个区块链系统最终的吞吐性能。

我们首先来看一个最简单的方案:每当一个全节点收到一笔新的交易时,该全节点就将这笔交易发送给它的所有邻居节点。

按照上述方案,每个节点将多次从不同的邻居节点收到同一笔交易,这意味着无论是交易的发送还是交易的接收,都有着成倍的冗余,网络带宽的利用率自然也非常低。以一笔 200 字节大小的交易为例,如果每个节点有 8 个邻居,那么这笔交易就要为每个全节点带来约 1.6kB 的发送量和 1.6kB 的接收量——而其中大部分流量是被浪费掉的。

即使是比特币,作为一个吞吐率只有 7 笔/秒、交易转发的带宽利用率完全不构成性能瓶颈的系统,也不再使用上面这种毫无优化的方案了。

比特币的方案是,当一个比特币节点 A 第一次收到这笔交易时,它将这笔交易的哈希值(32字节)发送给所有的邻居节点(除了发给它交易的节点)。邻居节点 B 收到哈希值后查看自己已经收到的交易中有没有哈希值一样的。如果有,就说明 B 已经收到过这笔交易,不需要再接收一次;如果没有,B 就向 A 请求这笔交易的完整内容。

上述过程中,发送交易哈希值的环节称为 announcement,对于交易哈希值的检测可以保证每个节点只需要接收一次完整的交易内容,避免重复传送完整交易带来的带宽浪费。

但是 announcement 本身也需要使用网络带宽。粗略地计算可知上述方案中每个节点在announcement 环节约发送 250 字节,虽然比 1.6kB 少了很多,但仍超过了转发一笔交易的数据量。

我们的目标,是在比特币交易转发方案的基础上,将 announcement 环节产生的数据发送量压缩至八分之一。

为了实现这一点,最简单的方法是缩短 announcement 环节广播的交易哈希值长度。本文中,为了将这个哈希值与应用层面(钱包/智能合约)所使用的 32 字节交易哈希值区分,我们将应用层面交易的哈希值称为交易的 ID, 转发中 announcement 环节用到的短哈希值称为交易的 FID (Forwarding ID).

在比特币的方案中,FID 与 ID 相等,长达 32 个字节。如果我们将 FID 设为 ID 值的前 4 个字节,就可以达到降低数据发送量的目标。

然而,更短的交易 FID 在节省带宽的同时也会带来安全性上的隐患。如果两笔不同的交易 Tx1 和 Tx2 有相同的交易 FID ,一个节点收到第一笔交易 Tx1 后,在邻居节点发来第二笔交易 Tx2 的 FID 时,会因为 FID 冲突误认为自己已经收到了这笔交易,从而不再请求 Tx2 的完整内容。这样将阻塞第二笔交易 Tx2 在网络中的广播。

技术向:交易转发中的带宽优化(上)

我们可以具体来算一下交易的 FID 冲突发生的概率:

假设交易的生成速率是每秒 6000 笔交易,每个全节点收到一笔交易 FID 时,会将它和过去 5 分钟内收到的 FID 对比,来判断是否请求这笔交易的完整内容。这样,一笔交易的 FID 和已经存在的交易 FID 冲突的概率是 6000 * 300 / 232,大约是 0.04 %。这意味着每秒平均有 2.4 笔交易会因为 FID 值冲突而无法广播。

虽然 0.04% 的冲突概率看似不是很高,但这只是没有攻击的正常情况。利用特定的攻击策略,一个攻击者可以阻塞任意一笔交易的广播,从而实现阻止特定交易的目的。

攻击的策略也并不复杂:4 字节的 FID 一共只有 232 个可能的取值,也就是大概 42 亿个。攻击者只要为每一个 FID 取值预先构造一笔交易并存起来,然后就可以根据受害者广播的交易的 FID 值,从自己预先存的 42 亿笔交易中找到 FID 值相同的交易,并抢在受害者前面发送到尽可能多的节点,则先接收到攻击者发送的交易的节点就会因为 FID 冲突而忽略受害者的交易。即使受害者重发了另一笔交易,攻击者也有能力重复这个过程。

根据概率上的计算,攻击者要挑选 42 亿个 FID 不同的交易,需要尝试构造约 1000 亿笔交易。对于服务器级的 CPU 来说,构造约 1000 亿笔交易只需花一个星期的时间。计算所需的存储空间在优化后也只需要 32GB。

从整体来说,实施上述攻击的成本并不算很高。但是在特定的情景下(如 Fomo3D 等合约),交易被阻塞可能为受害者带来不小的损失。所以这种风险必须从一开始就被排除掉。

在下一篇文章中,我们将介绍如何通过将静态 FID 转为动态 FID 的方式解决交易被恶意阻塞的风险。

  • 0
区块链大帝
区块链大帝

0 条评论