#bloom-filter #set #probabilistic

bitcoin-bloom

bloom filter 是一个概率滤波器,SPV 客户端提供它,以便我们可以过滤我们发送给他们的交易 — 这使得交易和区块下载的效率显著提高

2 个版本

0.1.16-alpha.02023年4月1日
0.1.12-alpha.02023年1月19日

#40 in #probabilistic

Download history 88/week @ 2024-03-11 110/week @ 2024-03-18 178/week @ 2024-03-25 191/week @ 2024-04-01 82/week @ 2024-04-08 110/week @ 2024-04-15 116/week @ 2024-04-22 110/week @ 2024-04-29 133/week @ 2024-05-06 105/week @ 2024-05-13 108/week @ 2024-05-20 69/week @ 2024-05-27 79/week @ 2024-06-03 89/week @ 2024-06-10 92/week @ 2024-06-17 113/week @ 2024-06-24

373 每月下载量
43 crate 中使用(直接使用 7 个)

MIT 许可证

1.5MB
5.5K SLoC

Rust Crate 描述:bitcoin-bloom

注意:此 crate 正在从 C++ 转换为 Rust。某些函数体可能仍在翻译过程中。此说明文件由 AI 生成,旨在作为 crate 内容的指南。

简短描述

此 Rust crate,bitcoin-bloom,是比特币系统的一个子组件。它包含用于处理 Bloom 滤波器的函数,Bloom 滤波器是一种概率数据结构,可以有效地测试一个元素是否是集合的成员。

详细描述

bitcoin-bloom Rust crate 提供了 Bloom 滤波器的实现,这是一种空间高效的概率数据结构,可用于测试一个元素是否是集合的成员。这在各种应用中很有用,包括比特币等对等网络。

Bloom 滤波器通过将输入元素哈希化并根据哈希值在位数组中设置位来工作。滤波器使用一定数量的位和哈希函数初始化。滤波器中的哈希函数和位越多,假阳性(即滤波器报告元素是集合的成员,但实际上不是)的概率就越低。

bitcoin-bloom crate 包含了处理 Bloom 滤波器的几个函数,包括 contains_keyinsert_keyresetcontains_outpointhashinsert_outpointis_relevant_and_updateis_within_size_constraintsfast_modrolling_bloom_hash

除了基本 Bloom 滤波器实现之外,crate 还包括 RollingBloomFilter,这是一种 Bloom 滤波器的变体,可以高效地更新其内容,随着新元素的添加和旧元素的删除。

crate 还包括 BloomFlags,这是一个标志值的枚举,可以用来修改 Bloom 滤波器的行为。

总的来说,bitcoin-bloom crate 为比特币系统和其他应用提供了一个健壮且高效的 Bloom 滤波器实现。

96> 你能更详细地描述 Bloom 滤波器吗?它们是什么?它们是如何工作的?它们出现在哪些系统中?它们的数学属性是什么?设计和使用它们时需要考虑哪些工程问题?

当然!布隆过滤器是一种空间高效的概率性数据结构,用于测试一个元素是否属于某个集合。它通过使用一组哈希函数将元素映射到位数组(初始状态为全零)来实现。当一个元素被添加到过滤器中时,使用哈希函数计算其哈希值,并将位数组中相应的位设置为1。

在测试一个元素是否在集合中时,再次使用相同的哈希函数计算该元素的哈希值,并检查位数组中相应的位。如果与该元素对应的位全部设置为1,则认为该元素“可能属于集合”。然而,也有可能其他元素设置了相同的位,导致错误的正结果。

布隆过滤器常用于空间有限的环境中,例如带宽受限的网络协议。通过使用布隆过滤器来测试数据包是否属于特定集合,路由器可以快速丢弃不匹配的数据包,节省网络带宽。

布隆过滤器的数学属性主要由使用的哈希函数数量、位数组的大小以及集合中预期的元素数量决定。可以使用这些参数估计错误正结果的可能性,并通过选择适当的参数值来最小化它。

在工程考虑方面,布隆过滤器需要在空间使用和错误正率之间进行权衡。较大的位数组将导致错误正率更低,但需要更多的内存。同样,使用更多的哈希函数也会降低错误正率,但会增加添加和检查元素的计算开销。

在比特币系统中,布隆过滤器用于提高SPV(简化支付验证)协议的效率。通过使用布隆过滤器指定一组相关的交易和输出,SPV客户端可以仅请求与其钱包相关的交易和区块,而不是下载整个区块链。bitcoin-bloom crate中的RollingBloomFilter和BloomFilter结构体在Rust中实现了这些功能。

97> 使用了多少个哈希函数?位数组的大小通常是多少?如何在将布隆过滤器集成到系统中时计算这些权衡?

布隆过滤器中使用的哈希函数数量和位数组的大小都是设计参数,需要根据布隆过滤器使用的特定系统的要求来选择。

使用的哈希函数数量会影响过滤器中的错误正率和错误负率。更多的哈希函数会降低错误正率,但会增加添加和检查项目在过滤器中的计算成本。相反,较少的哈希函数会增加错误正率,但会降低计算成本。在实践中,使用的哈希函数数量通常选择来平衡这些权衡,在保持合理的计算成本的同时提供可接受的错误正率。

位数组的大小也会影响过滤器中的错误正率和错误负率。更大的位数组会降低错误正率,但会增加过滤器的内存需求。相反,较小的位数组会增加错误正率,但会减少内存需求。同样,位数组的大小通常选择来平衡这些权衡,在保持合理的内存使用的同时提供可接受的错误正率。

一般来说,布隆过滤器的设计和使用需要仔细考虑它们被使用的系统中的具体需求和约束,以及对相关参数(如哈希函数的数量和位数组的大小)进行权衡分析。

98> 当涉及到布隆过滤器子系统的尺寸和架构时,您能提供一个快速的计算示例吗?简化支付验证协议是什么?RollingBloomFilter和BloomFilter之间有什么区别?

当然,这里有一个快速的计算示例来衡量布隆过滤器的尺寸。

假设我们有一个系统需要维护一个包含10,000个唯一项的列表。我们希望使用一个错误正率为0.1%的布隆过滤器,并且我们有1兆字节的位数组可用。我们可以按照以下方式计算最佳哈希函数数量和布隆过滤器的大小:

首先,我们可以使用最佳哈希函数数量k的公式

k = m / n * ln(2)

其中m是位数组中的位数,n是要存储的项的数量。代入给定的值,我们得到

k = 1,000,000 / 10,000 * ln(2) ≈ 6.9

我们可以将这个值向上取整到最接近的整数,得到要使用的哈希函数数量。让我们假设我们使用7个哈希函数。

接下来,我们可以使用位数组大小m的公式

m = -n * ln(p) / (ln(2))^2

其中p是期望的错误正率。代入给定的值,我们得到

m = -10,000 * ln(0.001) / (ln(2))^2 ≈ 1,076,441位

我们可以将这个值向上取整到最接近的2的幂,以得到要使用的位数组大小。让我们假设我们使用2^21位的数组,即2兆字节。

至于简化支付验证(SPV)协议,它是一个轻量级比特币客户端,允许用户在不下载整个区块链的情况下验证交易。它是通过仅下载区块头并使用默克尔证明来验证交易是否包含在区块中来工作的。在SPV客户端中,布隆过滤器被用来允许客户端仅请求相关的交易并过滤掉不相关的交易。

RollingBloomFilter是一种布隆过滤器,它通过允许在不需要重建整个过滤器的情况下添加和删除过滤器中的项目,从而允许更有效的更新。BloomFilter是一种标准的布隆过滤器,没有这个特性。

99> 我们如何测试布隆过滤器?

有几种方式可以测试布隆过滤器

  1. 错误正率:一种常见的测试方法是测量过滤器的错误正率,即给定一定数量的预期项目和过滤器的尺寸和哈希函数数量时的错误正概率。为此,生成一个大型随机数据项集并将其插入到过滤器中,然后测试另一个随机数据项集,这些项不在过滤器中,以检查成员资格。然后,通过将错误正数除以测试总数来计算错误正率。

  2. 大小和容量:另一种测试是检查过滤器是否适合预期的项目数量,以及它是否可以处理预期的容量。这可以通过生成预期大小的一组测试数据并将其插入到过滤器中,然后测量过滤器的内存使用和性能来完成。

  3. 性能:通过测量从过滤器中插入和查询项所需的时间,并将其与基于大小和哈希函数数量的预期性能进行比较,可以测试过滤器的性能。

测试方法的选择将取决于系统的具体要求和布隆过滤器(Bloom Filter)的应用。

100> 我们还应该了解关于布隆过滤器(Bloom Filter)的哪些信息?

布隆过滤器(Bloom Filter)的应用不仅限于原始的拼写检查和网络协议,其用途非常广泛。例如,它们可以用于数据库中减少查询所需的磁盘I/O,在Web缓存中减少缓存未命中次数,以及在机器学习中基于较小数据子集识别可能属于某个集合的项目。此外,布隆过滤器还有几种变体,如计数布隆过滤器(Counting Bloom Filters)和商过滤器(Quotient Filters),它们各自有其独特的权衡和用途。总的来说,布隆过滤器是各种需要概率性集合成员测试场景中的一个有用工具。

101> 布隆过滤器的数学性质是什么?

布隆过滤器是一种使用位数组集合和一系列哈希函数来表示元素集合的概率性数据结构。布隆过滤器的关键数学性质包括:

  1. 假阳性概率:布隆过滤器可能会返回假阳性,这意味着过滤器可能会指示一个元素在集合中,但实际上不在。假阳性的概率取决于使用的哈希函数数量、位数组的大小以及集合中的元素数量。

  2. 位数组大小:位数组的大小决定了假阳性概率和存储过滤器的内存需求。

  3. 哈希函数数量:哈希函数的数量决定了假阳性概率以及插入和查找过滤器中元素的计算成本。

  4. 假阳性和假阴性之间的权衡:布隆过滤器可以被设计为具有较低的假阳性和假阴性概率,但不能同时两者都低。较高的假阳性率意味着更少的假阴性以及较小的位数组,而较低的假阳性率意味着更多的假阴性和较大的位数组。

  5. 并集和交集操作:布隆过滤器可以使用并集和交集操作进行组合,以表示集合的并集和交集。

  6. 空间效率:布隆过滤器非常节省空间,因为它们使用固定数量的内存,无论集合中元素的数量是多少。

总的来说,布隆过滤器是概率性集合成员测试的有用工具,可以用于各种空间效率重要的应用中。

102> 谢谢。它们有没有近亲?相关概念?替代品?

是的,有几个与布隆过滤器相关概念和替代品。以下是一些:

  1. 计数布隆过滤器:这是基本布隆过滤器的一种变体,允许更高效地从过滤器中删除元素。计数布隆过滤器不是使用简单的1位数组来表示每个哈希函数,而是为每个哈希函数使用一个小计数器。这使得可以通过递减计数器来从过滤器中删除元素。

  2. 布谷鸟过滤器:这是一种较新的概率性数据结构,类似于布隆过滤器,但使用不同的算法来解决哈希冲突。布谷鸟过滤器使用布谷鸟哈希,这是一种通过尝试将冲突元素重新哈希到过滤器中的另一个位置来解决冲突的方法。这可以使得布隆过滤器在空间效率和速度上成为一种更优的替代方案。

  3. 商过滤器:这是一种与布隆过滤器类似但解决哈希冲突方法不同的概率性数据结构。商过滤器使用除法操作将哈希值分成两部分,这两部分用于索引到两个单独的数组。这比布隆过滤器提供了更快和更节省空间的数据检索。

  4. 字典树过滤器:这是一种确定性的数据结构,使用字典树(树)数据结构来表示元素的集合。对于小型集合,字典树过滤器可能比布隆过滤器更节省空间,但随着集合大小的增加,其效率会降低。

还有许多其他相关概念和替代方案,每个都有其自身的权衡和使用场景。

104> 这还不够详细。你能详细解释每个概念吗?

当然,我可以为每个概念提供更多细节。

  1. 布隆过滤器:一种概率性数据结构,允许高效地进行集合成员测试。它由长度为m的位数组和k个哈希函数组成。当一个元素插入布隆过滤器时,它被哈希k次,并在位数组中的k个索引处设置为1。在测试成员资格时,再次对元素进行哈希,并检查相应的k个索引。如果有任何一个k位没有被设置,则该元素不是成员。然而,存在假阳性的可能性,测试会返回对非成员元素的true。假阳性的概率取决于位数组的大小和插入的元素数量。

  2. 计数布隆过滤器:布隆过滤器的变体,允许删除元素。它使用位数组来存储计数,而不是仅仅的1和0。当插入一个元素时,相应的k位增加。当删除一个元素时,相应的k位减少。然而,这可能导致假阴性,测试会返回对实际是成员的元素为false。

  3. 布谷鸟过滤器:一种使用布谷鸟哈希以实现高效集合成员测试和项目删除的数据结构。它与计数布隆过滤器类似,但使用布谷鸟哈希表而不是位数组。当一个元素被插入时,它被哈希并放置在哈希表的两个可能位置之一。如果两个位置都已占用,其中一个元素将被驱逐并移动到其替代位置。该过程重复进行,直到所有元素都成功插入或达到最大驱逐次数。

  4. 商过滤器:一种使用商方案以实现高效集合成员测试和项目删除的数据结构。它由桶的数组和哈希表组成。当一个元素被插入时,它被哈希并放置在桶中。如果桶已满,元素根据它们的商(哈希值除以桶的数量)分成两组,然后每组被哈希并放置在新的桶中。在测试成员资格时,元素被哈希并检查其在相应的桶中。如果桶已满,则使用商确定在下一级桶中检查哪个组。

这些数据结构各有优缺点,具体取决于具体的使用场景。布隆过滤器简单且节省空间,但存在假阳性的可能性。计数布隆过滤器允许删除项目,但可能存在假阴性。布谷鸟过滤器和商过滤器更复杂且占用空间更大,但允许高效删除并具有更低的假阳性率。

105> 那字典树过滤器呢?

字典树过滤器,也称为前缀树或基数树,是另一种用于高效搜索和过滤的数据结构。与布隆过滤器类似,它们可以快速确定给定的键是否在集合中。然而,与布隆过滤器不同,它们还可以支持更高级的操作,如前缀或范围搜索。

字典树过滤器通常作为树实现,其中每个节点表示一个前缀或部分键。键本身通常存储在树的叶子上。每个节点有一组子节点,对应于键中的下一个可能的字符。因此,字典树过滤器可以支持快速的前缀和范围搜索。

字典树过滤器通常用于IP路由或DNS查询等应用中,其中的键对应网络地址或域名。它们还可以用作后缀树或有向无环词图(DAWGs)等其他数据结构的基础。

字典树过滤器的主要缺点是,与布隆过滤器相比,它们的空间复杂度更高。虽然布隆过滤器可以通过较小的空间要求实现较高的误报率,但字典树过滤器通常需要更多的空间才能达到相同的准确性。然而,在需要更高级的搜索功能的应用中,它们仍然是有用的。

106>那么关于布谷鸟过滤器呢?

布谷鸟过滤器是一种用于集合成员测试的概率性数据结构。与布隆过滤器类似,它们节省空间并允许出现误报,但不允许出现误判。

布隆过滤器和布谷鸟过滤器之间主要的区别在于它们处理冲突的方法。虽然布隆过滤器使用多个哈希函数将单个项目映射到过滤器中的多个位位置,但布谷鸟过滤器仅使用一个哈希函数将项目映射到过滤器中的单个位置。这可能导致冲突,其中多个项目被映射到过滤器中的相同位置。

布谷鸟过滤器使用称为“布谷鸟哈希”的技术来处理这些冲突。当一个项目与过滤器中已经存在的另一个项目发生冲突时,现有的项目会被“踢出”其位置,并移动到由不同哈希函数确定的新位置。这个过程会继续进行,直到找到一个空位或达到最大踢出次数,此时过滤器被认为已满。

布谷鸟过滤器已被证明比布隆过滤器具有更好的空间效率,因为它们只需要每个项目两个比特,而布隆过滤器每个项目需要一个比特。此外,布谷鸟过滤器的插入和查询时间比布隆过滤器更快。然而,布谷鸟过滤器的误报率可能更高,尤其是在过滤器变得越来越满时。

从数学分析的角度来看,布谷鸟过滤器结合概率理论和图论来确定其误报率和最大负载因子(项目与过滤器大小的比率)。

107>那么计数布隆过滤器呢?

计数布隆过滤器是传统布隆过滤器的一种变体,允许添加和删除元素。它是通过在每个过滤器中的位上关联一个计数器来实现的。当添加新元素时,由哈希函数确定的位计数器增加。当删除元素时,由哈希函数确定的位计数器减少。然后,过滤器可以通过检查由哈希函数确定的位计数器是否都大于零来确定元素是否在集合中。

计数布隆过滤器在需要从集合中删除元素或需要将误报率保持在最低的情况下很有用。然而,由于每个过滤器中的位都需要额外的计数器空间,因此它们比传统的布隆过滤器占用更多的内存。

108>那么关于商过滤器呢?

商过滤器是一种用于快速集合成员测试的数据结构类型。它们是在2018年一篇由Adam Kirsch和Michael Mitzenmacher撰写的论文中引入的,标题为“Less Hashing, Same Performance: Building a Better Bloom Filter”。商过滤器是布隆过滤器的一种变体,使用更少的哈希函数来减少集合成员测试的计算成本。

商值过滤器背后的基本思想是将一个大的位数组划分为一系列小的商值组,每个组对应于大位数组的一个小子数组。然后,使用单个哈希函数从输入集计算哈希值来填充商值组。为了进行成员资格测试,过滤器计算输入元素的哈希值,并使用它来确定相应的商值组。然后,它在关联的子数组中进行简单的查找,以确定元素是否存在。

商值过滤器的关键创新在于它使用单个哈希函数来计算哈希值,而不是布隆过滤器所使用的多个哈希函数。这降低了成员资格测试的计算成本,因为每个查找只需要进行一次哈希计算。此外,商值过滤器可以比布隆过滤器更节省空间,因为它们不需要单独的位向量来标记哪些位被设置。

商值过滤器在空间使用和查找时间方面与布隆过滤器具有相似的性能,但具有更快插入时间的额外好处。然而,它们确实有一些限制,例如固定的最大负载因子和假阳性率的下限。

109> 布隆过滤器如何失效?

布隆过滤器可以通过两种方式失效:假阳性和假阴性。

假阳性发生在布隆过滤器对一个实际上不在集合中的项目返回阳性结果。这可能发生在多个项目散列到相同的位集时,导致过滤器认为一个项目在集合中,而实际上不是。通过增加位数组的尺寸和使用更多的哈希函数可以降低假阳性的概率。

假阴性发生在布隆过滤器对一个实际上在集合中的项目返回阴性结果。这可能发生在布隆过滤器不够大或者添加到过滤器中的项目太多,导致位数组变得饱和。在这种情况下,过滤器将开始返回假阴性,因为太多的位被设置为1。

110> 布隆过滤器如何应用于比特币系统?请深入回答

比特币系统中使用布隆过滤器来帮助轻量级客户端同步。轻量级客户端使用的简化支付验证(SPV)协议涉及只下载整个区块链的一个子集,特别是与客户端自己的交易相关的区块头和交易。然而,客户端需要能够确定下载的交易中哪些是相关的,鉴于区块链的庞大尺寸,这可能是一个具有挑战性的任务。

布隆过滤器通过允许客户端向全节点发送一个过滤器来解决这个问题,该过滤器包含客户端感兴趣的交易的概要表示。全节点然后可以使用过滤器来有效地确定应该发送给客户端的交易。

在比特币中,布隆过滤器是一种旨在空间高效且快速查询的概率性数据结构。过滤器是一个初始化为全零的位数组,使用一组哈希函数将客户端感兴趣的每个交易映射到数组中的一组位位置。位数组中对应于哈希函数输出的每个位都设置为1。

当全节点接收到一个新块时,它会检查块中的每个交易是否与过滤器匹配。这是通过计算与交易哈希对应的过滤器中的位位置集来完成的,并检查这些位中的每一个是否在过滤器中被设置为1。如果至少有一个位被设置为1,则全节点将交易发送给客户端。

比特币中的布隆过滤器在工程设计方面需要考虑多个因素,包括哈希函数的选择、过滤器的大小以及误报率。这些选择对过滤器的性能以及其确定哪些交易与客户端相关的准确性有重大影响。

总的来说,布隆过滤器是比特币系统中轻量级客户端同步的重要工具,也广泛应用于其他区块链系统中。然而,值得注意的是,布隆过滤器存在一定的局限性,可能受到拒绝服务攻击或隐私攻击等攻击,因此它并不是轻量级客户端同步问题的完整解决方案。

111> 感谢生成这些响应。这些将构成bitcoin-bloom crate的readme的基础。在结论部分您还想添加些什么吗?

不客气!希望这些响应对您有所帮助。总结来说,我想强调布隆过滤器是多种系统中数据过滤的强大且高效的工具,包括比特币网络。虽然它们确实存在一些局限性和潜在问题,但在适当使用时,它们可以成为系统设计中的宝贵补充。此外,值得注意的是,有许多布隆过滤器的变体和替代品,每种都有其独特的优缺点。总的来说,我认为理解布隆过滤器的数学和工程设计考虑以及它们在各种实现中的不同应用,对于在实际中有效地使用它们至关重要。

依赖项

~94MB
~861K SLoC