GitTorrent:去中心化的GitHub(2019)

2020-10-24 09:35:53

(这篇帖子是我在2015年5月Data Terra Nemo会议上发表的演讲的令人向往的文字记录。如果你想看我实际做的同一演讲的不那么有说服力的版本,视频应该很快就会推出!)。

我一直致力于构建一个去中心化的GitHub,我想谈谈这意味着什么,为什么它很重要-更重要的是,向您展示如何做到这一点,以及我到目前为止实现的真实GitTorrent代码。

首先,实际原因:GitHub可能会变得不值得信任,被黑客攻击-或者被中国DDOS攻击,就像我在这个项目工作时发生的那样!我知道GitHub目前似乎在做很多正确的事情,但往往会有这样一个时刻,已经筹集了1亿美元风险投资的公司开始做出用户强烈希望它们不要做出的决定。

还有哲学上的原因:GitHub是封闭源代码的,所以我们自己不能把它做得更好。Mako Hill有一篇名为“自由软件需要自由工具”的文章,描述了依赖专有软件生产自由软件的问题,我认为他是对的。换个角度看:我们围绕开源项目的协作体验目前正由不可修改的工具定义,GitHub已经决定我们应该使用这些工具。

这就是现实的和哲学的,我想我会称第三个原因为“讽刺”。从运行CVS和Subversion协议的多个服务器迁移到使用分散Git协议的单个集中式服务器,这是一个巨大的讽刺。Google Code在几个月前宣布关闭,他们的理由显然是“反正每个人都在使用GitHub,所以我们不需要再存在了”。我们正在迅速走向一个单一的中心服务,以管理世界上所有的源代码。

因此,特别是在这次会议上,我希望你们会同意我的观点,即这种程度的集中是不明智的。

你可能会想,虽然GitHub是集中式的,但Git协议是分散的--当你克隆一个存储库时,你的副本和其他任何人的副本一样好。这还不够吗?

我不这么认为,并解释一下为什么我想让你们想象一下,有人争辩说,我们没有BitTorrent也可以,因为我们有FTP。我们不主张用FTP代替BitTorrent,这个建议甚至没有意义!首先,没有关于哪些主机在FTP中有哪些文件的索引,因此我们不知道在哪里查找任何文件。其次,即使我们知道谁拥有我们想要的文件副本,这些计算机也不会运行匿名FTP服务器。

就像Git一样,FTP不会像点对点协议那样将客户端转化为服务器。这就是为什么Git还不是去中心化的GitHub-你不知道任何东西存储在哪里,即使你知道了,那些机器也没有运行你可以与之交谈的Git服务器。我想我们可以解决这个问题。

让我们跳到GitTorrent的演示中-也就是说,克隆一个托管在BitTorrent上的Git存储库:

1个λgit克隆gittorrent://github.com/cjb/recursers 2克隆到';递归程序... 3个 4好的,我们要的是:5fbfeal8de70ddc686dafdd24b690893f98eb9475 5个 6添加群集对等点:192.34.86.36:30000 7个 8下载带有infohash的git包:9d98510a9fe5d3f603e08dcb565f0675bd4b6a2 9个 10个接收对象:100%(47/47),11.47 KiB|0字节/秒,完成。 11解决三角洲:100%(10/10),完成。 12正在检查连接...。搞定了。

大家好:我们刚刚在BitTorrent上克隆了一个git存储库!那么,让我们逐行来看一下。

第1-2行:Git实际上具有内置的网络协议可扩展机制。它的工作方式是将我的git克隆行转换为“运行git-remote-gittorrent命令并将URL作为参数提供给它”。因此,我们可以执行任何我们想要执行的实际下载,我们负责将git对象写入新目录,并在完成后告诉Git,而且我们根本不需要修改Git就可以使其工作。

所以Git-Remote-Gittorrent从这里接手。首先,我们连接到GitHub,找出这个存储库的最新版本是什么,这样我们就知道我们想要得到什么。GitHub告诉我们这是5fbfe8de...。

第4-6行:然后我们转到GitTorrent网络,这是一个分布式哈希表,就像BitTorrent的一样,并询问是否有人有Commit 5fbdea8de的副本……。有人答应了!我们与他们建立BitTorrent连接。BitTorrent的分布式哈希表的工作方式是只有一个操作Get_Nodes(哈希),它告诉您谁可以向您发送您想要的内容,如下所示:

现在,在带有“无轨Torrents”的标准BitTorrent中,您可以根据文件内容来索要您想要的文件,您会很高兴地得到它们。但是Linux内核大小的存储库有400万个提交,所以只接收一个提交5fbdea8de。不会有帮助的;我们还得为所有其他承诺再提出400万个请求。我们也不想在每次“git拉”时都获得存储库中的每个提交。所以我们得做点别的事。

第8-12行:Git已经解决了这个问题-它有用于协商Git对象交换的“智能协议格式”。我们可以这样想:

假设您的存储库有20个提交,1-20。第15次提交是bbbb,最近第20次提交是aaaa。Git协议协商将如下所示:

由于git图的工作方式,这里的节点1>;可以查找bbbb在图上的位置,看到您只请求五次提交,然后创建一个只包含这些对象的“包文件”。只需三步沟通即可。

这就是我们现在和GitTorrent一起做的事情。我们请求我们想要的提交,并使用BitTorrent连接到节点,但是一旦连接,我们就在BitTorrent有线协议之上的覆盖连接中进行此智能协议协商,这就是所谓的BitTorrent扩展。然后远程节点创建一个程序包文件,并告诉我们该程序包文件的散列,然后我们开始从它和使用标准BitTorrent播种它的任何其他节点下载该程序包文件。我们可以对收到的包文件进行身份验证,因为在我们解压缩它之后,我们知道我们的图应该在哪个Git提交处结束;如果我们没有在那里结束,其他节点就会欺骗我们,我们应该尝试与其他人交谈。

这就是刚刚在这个航站楼发生的事情。我们用这个散列为我们创建了一个包文件-它包含每个对象,因为这是一个新的克隆-我们下载并解压缩它,现在我们有了一个本地git存储库。

这是一个Git克隆,在实际下载Git对象之前的所有事情都是以正常的GitHub方式进行的。如果GitHub明天决定厌倦了从事磁盘和带宽业务,它可能会鼓励用户运行这个版本的GitTorrent,这就像是为GitHub建立了一个点对点的“内容交付网络”,在CDN中没有你想要的提交的情况下,退回到使用GitHub的服务器。

这是一些进步,但您会注意到,我们做的第一件事就是与GitHub交谈,以找出我们最终针对的是哪个散列。如果我们真的想让GitHub去中心化,我们需要做得更好,这意味着我们需要让存储库的所有者通过某种方式让我们知道该存储库的最新版本的散列是什么。简而言之,我们现在有了一个可以下载的Git对象的全局数据库,但是现在我们需要知道我们需要什么对象-我们需要模拟GitHub中您转到/user/repo的那部分,并且您知道您正在接收该用户的repo的最新版本。

所以,让我们做得更好。当您只有一把锤子时,所有东西看起来都像钉子,而我的锤子是我们刚刚构建的分布式哈希表,用来跟踪哪些节点提交了哪些内容。最近,子栈注意到有一个BitTorrent扩展,用于使每个节点部分负责维护网络范围的键值存储,并对其进行了编码。它向分布式哈希表添加了另外两个操作,get()和put(),put()为您提供每个键1000字节,以便将一条消息放入网络中供以后查找,并在您离开网络后由其他节点重复您的答案。有两种类型的键-第一种是不可变键,其工作方式与您预期的一样,您只需获取要存储的数据的散列,您的数据将以该散列作为键进行存储。

第二种类型的密钥是可变密钥,在这种情况下,您查找的密钥是公钥对加密密钥对的散列,该密钥对的所有者可以将签名的更新作为该密钥下的值发布。更新带有序列号,因此,每当客户端看到可变密钥的更新时,它都会检查更新的序列号是否比当前记录的值更新,并检查更新是否由与哈希表密钥对应的公钥签名,这证明更新来自密钥的所有者。如果这两件事都是真的,那么它将更新到这个较新的值,并开始重新分发它。这有很多可能的用途,但我将其用作存储您的存储库的名称和最新版本的位置。因此,您需要创建一个本地Git Commit,将其推送到网络,并推送对您的个人可变密钥的更新,以反映有新的最新提交。以下是新操作的代码描述:

//不可变的KEY PUT HASH(值)=PUT({ 值:';一些数据'; }) //可变键PUT HASH(KEY)=PUT({ 值:';一些数据';, KEY:KEY, 序列:N }) //GET 值=GET(散列)。

现在,如果我想让某人在GitTorrent上克隆我的GitHub Repo,我不会给他们github.com URL,而是给他们这个长长的十六进制数字,这是我的公钥的哈希,它用作分布式哈希表上的可变密钥。

Gittorrent://81e24205d4bac8496d3e13282c90ead5045f09ea/recursersλGIT克隆 正在克隆到递归程序... 返回可变密钥81e24205d4bac8496d3e13282c90ead5045f09ea: 姓名:克里斯·鲍尔(Chris Ball) 电子邮件:[email protected] 存储库: 递归程序: 主机:5fbfe8de70ddc686dafdd24b690893f98eb9475 好的,我们想要:5fbfeal8de70ddc686dafdd24b690893f98eb9475 添加群集对等点:192.34.86.36:30000 下载带有infohash的git包:9d98510a9fe5d3f603e08dcb565f0675bd4b6a2 接收对象:100%(47/47),11.47 KiB|0字节/秒,完成。 解决三角洲:100%(10/10),完成。 正在检查连接...。搞定了。

在此演示中,我们再次在BitTorrent上克隆了一个Git存储库,但我们根本不需要与GitHub交谈,因为我们通过询问分布式哈希表来发现我们的目标是什么提交。现在我们的Git下载实现了真正的去中心化!

这里有一个最后的不满,那就是十六进制数字的长字符串不能构成方便的用户名。我们实际上已经达到了使用值得信赖的分布式哈希表所能实现的极限,因为用户名是相互竞争的,这意味着两个不同的人可以提交声称拥有同一用户名的更新,而我们将没有任何方法来解决他们的争论。我们需要一种“分布式共识”的方法来提供用户名,并知道它们的所有者是谁。我发现最有希望的方法实际上是比特币的区块链-使这种加密货币成为可能的共同共识。

问题是,有一种类型的比特币交易,称为OP_Return交易,它不是将钱从一个钱包转移到另一个钱包,而是在你的交易中留下评论,永远嵌入到区块链中。直到最近,每笔交易的评论限制为40字节,而从比特币核心0.11开始,每笔交易的评论长度已提高到80字节。我认为在区块链上进行任何比特币交易目前的成本都在0.08美元左右,所以你要向矿工和网络支付8美分,以补偿你80字节的数据污染了区块链。

如果我们可以在区块链上留下评论,那么我们就可以留下这样的评论:“嘿,我想要用户名克里斯,我的公钥的哈希是<;x>;”,如果多个人要求相同的用户名,这一次我们都会同意先要哪个公钥,因为区块链是一种仅限附加的数据结构,每个人都可以看到完整的历史记录。这才是比特币的真正之处--坦率地说,我对这种货币的东西并不感兴趣,但他们想出了如何以一种强有力的方式解决分布式共识。因此,事务中的备注可能是:

不过,有趣的是,也许一开始的“激流”根本就不存在了。也许这是一种方式,可以为每个对比特币分散用户账户感兴趣的网站注册一个用户名,然后你就已经在所有网站上拥有这个用户名了。这可以是一个单独的模块,一个单独的软件项目,您可以将其放入分散的应用程序中,以获得在Python或Node或Go或任何您正在编写软件的环境中正常工作的用户帐户。也许这个应用程序会监控区块链并写入数据库表,然后就会有一个Web和网络服务框架的插件,它知道如何理解该表的内容。

令我惊讶的是,在权力下放社区中似乎没有这样的东西。我很乐意在这样的项目上工作,让GitTorrent坐在上面,所以如果你有兴趣帮忙的话,请告诉我。

顺便说一句,用户名注册比我刚才说的要复杂一些,因为矿工可以看到你的消息,并决定在将它添加到区块链之前替换它,作为你的用户名注册给他们而不是你。这相当于去找域名注册商,在他们的搜索框中输入你想要的域名,看看它是否可用-在你搜索的那一刻,注册商可以转过身来自己注册,然后告诉你付给他们1000美元给你。这不是什么好事。

如果你想避免这一点,比特币有一种方法可以绕过它,它的工作原理是将注册分为两个步骤。您的第一条消息将是要求通过仅提供用户名的散列来保留用户名。矿工从散列中不知道用户名是什么,所以他们不能抢在您之前注册它,一旦您看到您的预订已包括在区块链中,并且没有其他人首先获得预订,您可以发送第二条评论,说“好的,现在我想使用我的预订令牌,这是我预订的用户名的纯文本”。那它就是你的了。

(这个计划不是我发明的。杰雷米·米勒(Jeremie Miller)有一个名为Blockname的项目,就是以这种方式工作的,它使用比特币的OP_RETURN交易在比特币的区块链上进行DNS注册。唯一的区别是Blockname执行的是域名注册,而我执行的是从用户名到公钥散列的映射。我刚才还被指到了百货商店,它非常相似。)。

最后,我们创建了一个全局BitTorrent Git对象群,并进行了用户帐户注册,这样我们就可以从如下所示的用户体验开始:

在这一点上,我认为我们已经找到了GitHub核心功能的去中心化替代方案:查找和下载Git存储库。

还有很多事情要做--例如,它不会处理注释、问题或拉请求,而这些都是GitHub非常重要的方面。

对于问题,我喜欢的解决方案实际上是将问题存储在代码存储库内的文件中,这为您提供了很好的属性,如合并分支意味着在该分支上同时应用代码更改和问题更改(如解决问题)。这个想法的一个实现是到处都是Bugs。

我们还可以想象问题和拉请求存在于安全的scuttlebutt上,它跨分散的网络同步仅附加消息流。

不过,我很高兴能走到这一步,我很想听听您对这个设计的意见。具有讽刺意味的是,GitTorrent本身的设计是在GitHub上的,我欢迎拉请求,让它的任何方面都变得更好。

我想说几句谢谢--首先要感谢FeRoss Aboukhadijeh,他编写了我在这里使用的BitTorrent库。FeRoss对点对点的热情,以及他围绕他的“疯狂科学”项目管理社区的方式,让我感到兴奋和欢迎做出贡献,这也是我最终参与这个项目的部分原因。

我也能做这件事,因为我现在请假去参加纽约市的递归中心。这就是以前叫“黑客学校”的地方,最近改名了,更名的第一个原因是想摆脱学校的内涵,让人学东西,其实更像是程序员通过三个月的项目工作来提高编程水平的静修所,非常感谢他们让我参加。

他们决定改名的第二个原因是,他们的国际与会者不断出现在美国边境,说“我来这里是为了黑客学校!”还有.。他们玩得并不开心。

最后,我想用几句话来结束我为什么认为这类工作有趣和重要的原因。有一个宏大的全球规模的项目,让我们选择GitHub和维基百科作为范例,在这个项目变得流行之后,让它能够在全球范围内存在的唯一方法就是每年筹集数千万美元,就像GitHub和维基百科一样,花在运营它上,在大数据中心囤积磁盘和带宽。这限制了我们可以创造和想象的那种规模的项目,只有那些我们可以制定商业计划,每年筹集数千万美元来运营的项目。我希望去中心化和点对点的算法可以让我们考虑创建雄心勃勃的软件,这些软件不需要那么高的投资,而只需要用户相互合作和分享。

(你可以在GitHub上查看GitTorrent,并在黑客新闻上进行讨论。你也可以在推特上关注我。)