比特币网络节点发现

[TOC]

0x0 概述

比特币节点发现,指节点寻找其他节点的地址(IP和PORT)的方法。主要有以下几种:

  • 节点发现本节点的外部IP
  • 节点接收远程连接节点的回调地址
  • 节点使用DNS服务发现地址
  • 节点使用软件本身硬编码的地址列表
  • 节点与其他节点交换地址列表
  • 节点把地址列表存储到数据库,在启动时从数据库中读取
  • 节点在启动时从配置文件中读取地址列表

为每个地址保留时间戳,以跟踪节点地址上次被查看的时间。当从节点收到消息(message)时,该时间戳被更新。时间戳仅在地址上更新,并且在时间戳超过20分钟时保存到数据库。

0x1 getaddr消息

当一个节点收到一个“getaddr”请求时,它首先计算出它在最近3个小时内有多少个地址有时间戳。如果地址数量超过2500个,它随机选择2500个最新的地址。

0x01 发现方法

本地节点的外网地址

本地节点发现自己的外网地址需要使用到公共服务。比特币网络(中本聪版本)中的过程如下:

  • 节点尝试连接91.198.22.70:80 #checkip.dyndns.org
  • 若上述操作失败,尝试连接74.208.43.192:80
  • 如果连接成功,则发送HTTP请求,解决http response数据,获取IP地址。该地址作为该节点的外部地址广播给周边的其他节点

IRC地址

不再支持

DNS地址

节点在启动时,发布dns解析请求,请求种子节点的地址。截至到2017年,种子节点的域名列表如下:

  • seed.bitcoin.sipa.be
  • dnsseed.bluematt.me
  • dnsseed.bitcoin.dashjr.org
  • seed.bitcoinstats.com
  • seed.bitcoin.jonasschnelli.ch
  • seed.btc.petertodd.org

硬编码种子地址

这些地址仅用作最后的手段。

地址广播(addr消息)

节点在发送“getaddr”请求之后可以在“addr”消息中接收地址,或者“addr”消息可能未经请求而到达,因为节点在中继地址时会无条件地通告地址(见下文) 或建立连接时。

如果地址来自真正的旧版本,则会被忽略; 如果来自不太旧的版本,如果我们已经有1000个地址,它将被忽略。

如果发件人发送超过1000个地址,则全部被忽略。

从“addr”消息收到的地址有一个时间戳,但时间戳不一定是可信的。

对于消息中的每个地址:

如果时间戳太低或太高,则设置为5天前。

我们从时间戳中减去2小时并添加地址。

如果地址在过去24小时内出现过,而时间戳现在已超过60分钟,那么它会更新到60分钟前。

如果在过去24小时内没有看到地址,并且时间戳目前已超过24小时,则会更新到24小时前。

地址中继

一旦地址从“addr”消息中被添加(见上文),则它们可以被中继到其他节点。 首先,必须设定以下标准[9]:

  • 处理后的地址时间戳在当前时间的60分钟内
  • “addr”消息包含10个地址或更少
  • 并且fGetAddr未在节点上设置。 当我们从节点请求地址时,fGetAddr开始为false,设置为true,当我们从一个节点接收少于1000个地址时,它被清除。
  • 地址必须可路由

对于符合上述条件的每个地址,节点都会对地址,当天(以整数形式)和随机256位值(在客户端启动时生成)进行hash。 该节点获取散列值最低的两个地址,并向它们中继“addr”消息。 这确保了每个节点只在任何给定时间将“addr”消息中继给另外两个客户端,另外两个客户端是随机选择的,并且随机选择至少每24小时开始一次。

自广播

每24小时,节点将自己的地址通告给所有连接的节点。

它还会清除我们认为远程节点具有的地址列表,这将触发发送到节点的刷新。

地址入库

地址入库操作大概每0.1秒调用执行一次。

文本文件提供的地址

客户端将自动读取比特币数据目录中名为“addr.txt”的文件,并将其中找到的任何地址添加为节点地址。 这些节点没有特别优先于其他地址。 他们只是添加到地址池中。

从文本文件加载的地址最初被赋予零时间戳,因此它们不会响应“getaddr”请求而被公布。

你可能感兴趣的:(比特币网络节点发现)