用户把交易发到比特币网络上,节点收到交易后把他们打包到区块里,然后把区块发到比特币网络上。那么新发布的交易和区块在网络上是如何传输的?
比特币网络的工作原理
比特币工作在应用层(application layer),他的底层是一个P2P的Overlay network
比特币的P2P网络非常简单,所有节点都是对等的,不像有些P2P有所谓的超级节点(Super Node)或者主节点(Master Node)。你要加入这个网络,首先至少得知道一个种子节点(Seed Node),然后你和种子节点联系,它会告诉你它所知道的网络中的其它节点。节点之间是通过TCP通信的,这样有利于穿透防火墙,然后你离开的时候不需要通知其它节点,退出应用程序即可,别的节点没有听到你的消息,过一段时间就会把你删掉。
比特币网络的设计原则
简单、鲁棒而不是高效。每个节点维护一个邻居节点的集合,消息传播在网络中采取的是flooding方式,节点第一次听到某个消息的时候,把它传播给所有的邻居节点,同时记录一下这个消息我已经收到过,下次再收到这个消息就不再转发。邻居节点的选择是随机的,没有考虑底层的拓扑结构,比如加利福尼亚的节点选的邻居节点可能在阿根廷,这样设计的好处是增强鲁棒性,但是牺牲的是效率,你向身边的人转账和美国的人转账速度是差不多的。比特币系统中,每个节点要维护一个等待上链的交易的集合,第一次听到某个交易的时候,把这个交易加入集合,并且转发这个交易给邻居节点,以后再收到这个交易就不转发,这样避免交易在网络中无效传播,转发的前提是交易是合法的。这里有一个risk condition(风险状况),有可能两个有冲突的交易同时被广播到网络上,比如有一个交易是A→B,另外一个交易是A→C,它们用的是同一个输出,每个节点根据在网络中的位置的不同,有的可能先收到前者,有的可能先收到后者,收到后加入等待上链的交易的集合,下次收到另外一个交易的时候就认定是非法的,就不管了。集合中的交易如果被写到区块链中就要被删掉,比如说有个节点听到新发布的区块里面包含了A→B这个交易,这个交易在自己的等待上链的交易的集合中,就会被集合删掉,如果它听到的新发布的区块是A→C这个交易,也会把A→B给删掉,因为它是非法的。新发布的区块在网络中传播的方式和新发布的交易类似,每个节点除了要检查区块的内容的合法性,还要检查是不是在最长合法链上,越是大的区块在网络上传播的速度越慢,比特币协议对区块大小有一个1M的限制。
比特币网络的传播是属于best effort,一个交易被发布到比特币网络上,不一定所有节点都能收到,而且不同节点收到这个交易的顺序也不一定一样,网络传播存在延迟,可能会很长,而且有的节点可能不会按比特币协议的要求进行转发,比如有的该转发不转发,导致别的节点收不到合法交易;有的转发不该转发的,像不合法交易,这个是面临的实际问题。