BlockTrain网络
【BlockTrain网络】
1、每个节点都参与全⽹络的路由功能,同时也可能包含其他功能。每个节点都参与验证并传播交易及区块信息,发现并维持与对等节点的连接。在图6-1所⽰的全节点⽤例中,名为“⽹络路由节点”的橙⾊圆圈即表⽰该路由功能。
2、⼀些节点保有⼀份完整的、最新的区块链拷⻉,这样的节点被称为“全节点”。全节点能够独⽴⾃主地校验所有交易,⽽不需借由任何外部参照。另外还有⼀些节点只保留了区块链的⼀部分,它们通过⼀种名为“简易⽀付验证(SPV)”的⽅式来完成交易验证。这样的节点被称为“SPV节点”,⼜叫“轻量级节点”。
在如上图所⽰的全节点⽤例中,名为完整区块链的蓝⾊圆圈即表⽰了全节点区块链数据库功能。上图中,SPV节点没有此蓝⾊圆圈,以⽰它们没有区块链的完整拷⻉。
3、挖矿节点通过运⾏在特殊硬件设备上的⼯作量证明(proof-of-work)算法,以相互竞争的⽅式创建新的区块。⼀些挖矿节点同时也是全节点,保有区块链的完整拷⻉;还有⼀些参与矿池挖矿的节点是轻量级节点,它们必须依赖矿池服务器维护的全节点进⾏⼯作。在全节点⽤例中,挖矿功能如图中名为“矿⼯”的⿊⾊圆圈所⽰。
4、当前,越来越多的⽤⼾钱包都是SPV节点,尤其是运⾏于诸如智能⼿机等资源受限设备上的⽐特币钱包应⽤;⽽这正变得越来越普遍。在图6-1中,名为“钱包”的绿⾊圆圈代表钱包功能。
【常见节点类型】
Stratum协议就被应⽤于挖矿、以及轻量级或移动端⽐特币钱包之中。
Stratum服务器通过Stratum协议将所有的Stratum挖矿节点连接⾄⽐特币主⽹络、并将Stratum协议桥接(bridge)⾄⽐特币P2P协议之上。
SPV轻量钱包 vs SPV轻量Stratum钱包:
核心客户端:
BitCoin网络架构:
【网络发现】
节点通常采⽤TCP协议、使⽤8333端⼝(该端⼝号通常是⽐特币所使⽤的,除8333端⼝外也可以指定使⽤其他端⼝)与已知的对等节点建⽴连接。
在建⽴连接时,该节点会通过发送⼀条包含基本认证内容的version消息开始“握⼿”通信过程(如下图)。这⼀过程包括如下内容:
1)PROTOCOL_VERSION
2)nLocalServices:⼀组该节点⽀持的本地服务列表,当前仅⽀持NODE_NETWORK
3)nTIme:当前时间。
4)addrYou:当前节点可见的远程节点的IP地址。
5)addrMe:本地节点所发现的本机IP地址。
6)subver:指⽰当前节点运⾏的软件类型的⼦版本号(例如:”/Satoshi:0.9.2.1/”)
7)BaseHeight:当前节点区块链的区块⾼度。
⽹络中的对等节点通过对verack消息的响应进⾏确认并建⽴连接;有时候,如果接收节点需要互换连接并连回起始节点,也会传回该对等节点的version消息。
新节点是如何发现⽹络中的对等节点的呢?
1、客⼾端会维持⼀个列表,那⾥列出了那些⻓期稳定运⾏的节点。这样的节点被称为“种⼦节点(seed nodes)”。
在⽐特币核⼼客⼾端中,是否使⽤种⼦节点是通过 “-dnsseed” 控制的。默认情况下,该选项设为1,即意味着使⽤种⼦节点。
2、另⼀种⽅式是,起始时将⾄少⼀个⽐特币节点的IP地址提供给正在启动的节点。在这之后,启动节点可以通过后续指令建⽴新的连接。⽤⼾可以使⽤命令⾏参数“-seednode”把启动节点“引荐”并连接到⼀个节点,并将该节点⽤作DNS种⼦。在初始种⼦节点被⽤于形成“引荐”信息之后,客⼾端会断开与它的连接、并与新发现的对等节点进⾏通信。
当建⽴⼀个或多个连接后,新节点将⼀条包含⾃⾝IP地址的addr消息发送给其相邻节点。相邻节点再将此条addr消息依次转发给它们各⾃的相邻节点,从⽽保证新节点信息被多个节点所接收、保证连接更稳定。
另外,新接⼊的节点可以向它的相邻节点发送getaddr消息,要求它们返回其已知对等节点的IP地址列表。通过这种⽅式,节点可以找到需连接到的对等节点,并向⽹络发布它的消息以便其他节点查找。
由于节点可以随时加⼊和离开,通讯路径是不可靠的。因此,节点必须持续进⾏两项⼯作:
1)在失去已有连接时发现新节点。
2)并在其他节点启动时为其提供帮助。
在启动完成后,节点会记住它最近成功连接的对等节点;因此,当重新启动后它可以迅速与先前的对等节点⽹络重新建⽴连接。如果先前的⽹络的对等节点对连接请求⽆应答,该节点可以使⽤种⼦节点进⾏重启动。
在运⾏⽐特币核⼼客⼾端的节点上,您可以使⽤ getpeerinfo 命令列出对等节点连接信息:
⽤⼾可以通过提供 -connect=<IP地址> 选项来指定⼀个或多个IP地址,从⽽达到复写⾃动节点管理功能并指定IP地址列表的⽬的。如果采⽤此选项,节点只连接到这些选定的节点IP地址,⽽不会⾃动发现并维护对等节点之间的连接。
如果已建⽴的连接没有数据通信,所在的节点会定期发送信息以维持连接。如果节点持续某个连接⻓达90分钟没有任何通信,它会被认为已经从⽹络中断开,⽹络将开始查找⼀个新的对等节点。
【全节点】
辨别您是否在运⾏全节点是⼗分容易的:只需要查看您的永久性存储设备(如硬盘)是否有超过20GB的空间被⽤来存储完整区块链即可。如果您需要很⼤的磁盘空间、并且同步⽐特币⽹络耗时2⾄3天,那么您使⽤的正是全节点。这就是摆脱中⼼化管理、获得完全的独⽴⾃由所要付出的代价。
尽管⽬前还有⼀些使⽤不同编程语⾔及软件架构的其他的完整区块链客⼾端存在,但是最常⽤的仍然是⽐特币核⼼客⼾端,它也被称为“Satoshi客⼾端”。⽐特币⽹络中超过90%的节点运⾏着各个版本的⽐特币核⼼客⼾端。如前⽂所述,它可以通过节点间发送的version消息或通过getpeerinfo命令所得到的⼦版本字符串“Satoshi”加以辨识,例如 /Satoshi: 0.8.6/。
⼀个全节点连接到对等节点之后,第⼀件要做的事情就是构建完整的区块链。如果该节点是⼀个全新节点,那么它就不包含任何区块链信息,它只知道⼀个区块——静态植⼊在客⼾端软件中的创世区块。新节点需要下载从0号区块(创世区块)开始的数⼗万区块的全部内容,才能跟⽹络同步、并重建全区块链。
同步区块链的过程从发送version消息开始,这是因为该消息中含有的BestHeight字段标⽰了⼀个节点当前的区块链⾼度(区块数量)。节点可以从它的对等节点中得到版本消息,了解双⽅各⾃有多少区块,从⽽可以与其⾃⾝区块链所拥有的区块数量进⾏⽐较。
对等节点们会交换⼀个getblocks消息,其中包含他们本地区块链的顶端区块哈希值。如果某个对等节点识别出它接收到的哈希值并不属于顶端区块,⽽是属于⼀个⾮顶端区块的旧区块,那么它就能推断出:其⾃⾝的本地区块链⽐其他对等节点的区块链更⻓。
它会识别出第⼀批可供分享的500个区块,通过使⽤inv(inventory)消息把这些区块的哈希值传播出去。缺少这些区块的节点便可以通过各⾃发送的getdata消息来请求得到全区块信息,⽤包含在inv消息中的哈希值来确认是否为正确的被请求的区块,从⽽读取这些缺失的区块。
于是它开始向所有与之相连的对等节点请求区块,并通过分摊⼯作量的⽅式防⽌单⼀对等节点被批量请求所压垮。该节点会追踪记录其每个对等节点连接上“正在传输”(指那些它已经发出了请求但还没有接收到)的区块数量,并且检查该数量有没有超过上限( MAX_BLOCKS_IN_TRANSIT_PER_PEER )。⽤这种办法,如果⼀个节点需要更新⼤量区块,它会在上⼀请求完成后才发送对新区块的请求,从⽽允许对等节点控制更新速度,不⾄于压垮⽹络。
每当⼀个节点离线,不管离线时间有多⻓,这个与对等节点⽐较本地区块链并恢复缺失区块的过程就会被触发。如果⼀个节点只离线⼏分钟,可能只会缺失⼏个区块;当它离线⻓达⼀个⽉,可能会缺失上千个区块。但⽆论哪种情况,它都会从发送 getblocks 消息开始,收到⼀个inv响应。
【简易支付验证结点】
随着⽐特币的使⽤热潮,SPV节点逐渐变成⽐特币节点(尤其是⽐特币钱包)所采⽤的最常⻅的形式。
SPV节点只需下载区块头,⽽不⽤下载包含在每个区块中的交易信息。由此产⽣的不含交易信息的区块链,⼤⼩只有完整区块链的 1/1000。
SPV节点不能构建所有可⽤于消费的UTXO的全貌,这是由于它们并不知道⽹络上所有交易的完整信息。
SPV节点验证交易时所使⽤的⽅法略有不同,这个⽅法需依赖对等节点“按需”提供区块链相关部分的局部视图。
例如:
1)对于全节点。
⼀个全节点要检查第300,000号区块中的某个交易,它会把从该区块开始⼀直回溯到创世区块的300,000个区块全部都链接起来,并建⽴⼀个完整的UTXO数据库,通过确认该UTXO是否还未被⽀付来证实交易的有效性。
2)对于SPV节点。
SPV节点则不能验证UTXO是否还未被⽀付。相反地,SPV节点会在该交易信息和它所在区块之间⽤merkle路径(⻅“7.7 Merkle 树”)建⽴⼀条链接。然后SPV节点⼀直等待,直到序号从300,001到300,006的六个区块堆叠在该交易所在的区块之上,并通过确⽴交易的深度是在第300,006区块~第300,001区块之下来验证交易的有效性。事实上,如果⽹络中的其他节点都接受了第300,000区块,并通过⾜够的⼯作在该块之上⼜⽣成了六个区块,根据代理⽹关协议,就可以证明该交易不是双重⽀付。
SPV节点毫⽆疑问可以证实某个交易的存在性,但它不能验证某个交易(譬如同⼀个UTXO的双重⽀付)不存在。SPV节点也容易受到⽹络分区攻击或Sybil攻击。在后者情况中,SPV节点被连接到虚假节点或虚假⽹络中,没有通向可靠节点或真正的⽐特币⽹络的连接。
SPV节点使⽤的是⼀条getheaders消息,⽽不是getblocks消息来获得区块头。发出响应的对等节点将⽤⼀条headers消息发送多达2000个区块头。这⼀过程和全节点获取所有区块的过程没什么区别。SPV节点还在与对等节点的连接上设置了过滤器,⽤以过滤从对等节点发来的未来区块和交易数据流。任何⽬标交易都是通过⼀条getdata的请求来读取的。对等节点⽣成⼀条包含交易信息的tx消息作为响应。
监控⽹络的第三⽅可以跟踪某个SPV节点上的钱包所请求的全部交易信息,并且利⽤这些交易信息把⽐特币地址和钱包的⽤⼾关联起来,从⽽损害了⽤⼾的隐私。
【Bloom过滤器】
在引⼊SPV节点/轻量级节点后不久,⽐特币开发⼈员就添加了⼀个新功能:Bloom过滤器,⽤以解决SPV节点的隐私⻛险问题。Bloom过滤器通过⼀个采⽤概率⽽不是固定模式的过滤机制,允许SPV节点只接收交易信息的⼦集,同时不会精确泄露哪些是它们感兴趣的地址。
⽤我们之前的例⼦,⼀位⼿中没有地图的游客需要询问去特定地⽅的路线。如果他向陌⽣⼈询问“教堂街23号在哪⾥”,不经意之间,他就暴露了⾃⼰的⽬的地。Bloom过滤器则会这样问,附近有带‘堂’字的街道吗?”这样的问法包含了⽐之前略少的关键词。
【交易池】
被称为内存池或交易池。节点们利⽤这个池来追踪记录那些被⽹络所知晓、但还未被区块链所包含的交易。
当⼀个交易被添加到交易池中,会同时检查孤⽴交易池,看是否有某个孤⽴交易引⽤了此交易的输出(⼦交易)。任何匹配的孤⽴交易会被进⾏验证。如果验证有效,它们会从孤⽴交易池中删除,并添加到交易池中,使以其⽗交易开始的链变得完整。对新加⼊交易池的交易来说,它不再是孤⽴交易。前述过程重复递归寻找进⼀步的后代,直⾄所有的后代都被找到。通过这⼀过程,⼀个⽗交易的到达把整条链中的孤⽴交易和它们的⽗级交易重新结合在⼀起,从⽽触发了整条独⽴交易链进⾏
级联重构。
交易池和孤⽴交易池(如有实施)都是存储在本地内存中,并不是存储在永久性存储设备(如硬盘)⾥。更准确的说,它们是随⽹络传⼊的消息动态填充的。节点启动时,两个池都是空闲的;随着⽹络中新交易不断被接收,两个池逐渐被填充。
有些⽐特币客⼾端的实现还维护⼀个UTXO数据库,也称UTXO池,是区块链中所有未⽀付交易输出的集合。“UTXO池”的名字听上去与交易池相似,但它代表了不同的数据集。UTXO池不同于交易池和孤⽴交易池的地⽅在于,它在初始化时不为空,⽽是包含了数以百万计的未⽀付交易输出条⽬,有些条⽬的历史甚⾄可以追溯⾄2009年。UTXO池可能会被安置在本地内存,或者作为⼀个包含索引的数据库表安置在永久性存储设备中。
【警告消息】
警告消息并不经常使⽤,但在⼤多数节点上都有此功能。警告消息是⽐特币的“紧急⼴播系统”,⽐特币核⼼开发⼈员可以借此功能给所有⽐特币节点发送紧急⽂本消息。
收到警告消息的节点会验证该消息,检查是否过期,并传播给其所有对等节点,从⽽保证了整个⽹络中的快速传播。
BlockTrain网络的更多相关文章
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- Android请求网络共通类——Hi_博客 Android App 开发笔记
今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...
- 网络原因导致 npm 软件包 node-sass / gulp-sass 安装失败的处理办法
如果你正在构建一个基于 gulp 的前端自动化开发环境,那么极有可能会用到 gulp-sass ,由于网络原因你可能会安装失败,因为安装过程中部分细节会到亚马逊云服务器上获取文件.本文主要讨论在不变更 ...
- Virtual Box配置CentOS7网络(图文教程)
之前很多次安装CentOS7虚拟机,每次配置网络在网上找教程,今天总结一下,全图文配置,方便以后查看. Virtual Box可选的网络接入方式包括: NAT 网络地址转换模式(NAT,Network ...
- 前端网络、JavaScript优化以及开发小技巧
一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...
- 猫哥网络编程系列:HTTP PEM 万能调试法
注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...
- C# 利用性能计数器监控网络状态
本例是利用C#中的性能计数器(PerformanceCounter)监控网络的状态.并能够直观的展现出来 涉及到的知识点: PerformanceCounter,表示 Windows NT 性能计数器 ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化
KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...
随机推荐
- ViewpagerHandler
import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.su ...
- SSL&TLS渗透测试
什么是TLS&SSL? 安全套接字层(SSL)和传输层安全(TLS)加密通过提供通信安全(传输加密)和为应用程序如网络.邮件.即时消息和某些虚拟私有网络(VPN)提供隐私的方式来确保互联网和网 ...
- Hystrix 学习使用
说明: 每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中 执行execute()/queue做同步或异步调用 请求接收后,会先看是否存在缓存数据,如果存在,则不会继续 ...
- java volatile
volatile可以保证变量的可见性 当一个变量定义为volatile后,此变量对所有的线程具有可见性.这里的可见性是指当一个线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的. 每次使用v ...
- DSP2812 启动详解
百度文库转载 1. 从0X3F FFC0处复位→执行0X3F FC00地址处的初始化引导函数(Initboot) →根据GPIO选择引导模式→确定用户程序入口地址→从入口处开始执行用户程序. 输入外部 ...
- Linux 释放cache化缓存
Linux 释放cache化缓存 free -g查看空余内存以及已使用内存 原文 https://blog.csdn.net/tomspcc/article/details/78131468 机械硬 ...
- tomcat的 tomcat-user.xml
http://blog.csdn.net/asdeak/article/details/1879284 很多个tomcat因为在缺少 " <role rolename="m ...
- pytorch下的lib库 源码阅读笔记(2)
2017年11月22日00:25:54 对lib下面的TH的大致结构基本上理解了,我阅读pytorch底层代码的目的是为了知道 python层面那个_C模块是个什么东西,底层完全黑箱的话对于理解pyt ...
- Linux 入侵检测小结
Linux 入侵检测小结 0x00 审计命令 在linux中有5个用于审计的命令: last:这个命令可用于查看我们系统的成功登录.关机.重启等情况:这个命令就是将/var/log/wtmp文件格式 ...
- 轻松制作X86 OPENWRT USB启动盘
本文介绍了一个x86 live USBi启动盘的制作方法. 该方法有如下特点: 1. 可在winXP/win 7/win vista上制作, U盘采用fat格式, 即使对于linux经验较少者, 也 ...