# Host、Peer與Node
host即主機,是p2p網絡的參與對象,由于既處理請求和發送請求,所以一個host既是服務器也是客戶端。host概念容易與peer概念混淆,其type是一個interface,包括一系列需要實現的方法,其中ID()方法返回的對象類型為peer.ID(在peer.go)中定義。
我們在啟動一個節點的時候,必然要創建一個host:host是節點Node結構的一個變量。
peer對應于ID,其由創建host時的鍵值對的publickey生成而來,因此,我們可以根據peer.ID與host.ID()比較,判斷本地主機與對等端是否是同一個主機。
加入網絡后的host與peer是相對的,每一個peer都是host,每一個host都是peer。站在某個node的角度,該node即為host,其它node即為peer。我們可以通過PubSub服務的ListPeers,來獲取全網的[]peer.ID。
可以理解,host或peer由ID唯一標識,ID在host創建時候根據同時創建的公鑰生成。
node即節點,更準確的稱呼為網絡節點,我們在實現的時候,直接以network結構體來定義它,其結構包括host在內的多個變量,區塊鏈運行從啟動一個一個節點開始。
host是一個類型對象(type object),實現了作為一個既是服務器也是客戶端的節點的P2P網絡所需的處理方法和參數配置,node是一個結構體(struct),peer等同于ID。
每個peer在加入P2P網絡之前也是一個host,host在創建完畢加入網絡后成為一個peer。
網絡中的每一個peer的功能可能不同(由加入網絡之前創建host確定),host自身知道自己具備什么功能,雖然可以隨時獲取全網的peer,但并不知道其它peer所具備的功能及內容,也就是一個host只知道一個peer的ID,除此之外,一概不知,這也體現了P2P網絡的匿名特性。一個host想要什么,通過通信通道向全網發出命令消息,或者在成功連接到一個peer后,發送命令消息給對方,由該peer給出響應,才能管窺一個peer的部分功能和內容。
我們實際進行編程交互的時候,是以node為對象進行處理的,一切從節點的startnode方法開始(返回一個node對象:*Network):
```
func StartNode(chain?*blockchain.Blockchain,?listenPort,?minerAddress?string,?miner,?fullNode?bool,?callback?func(*Network))
```
# Channel 通信通道
Channel結構體包含一個chan的通道Content(遵循先進先出的規則)。
```
type Channel struct?{
????ctx???context.Context
????pub???*pubsub.PubSub//發布
????topic?*pubsub.Topic
????sub???*pubsub.Subscription//訂閱
????channelName?string
????self????????peer.ID
????Content?????chan?*ChannelContent//有緩沖的非阻塞通道,通道大小ChannelBufSize=128
}
```
在創建host過程中,創建所有的通信通道,并將其加入到pubsub服務中(在join中啟動無限循環,讀取訂閱的消息),當讀到訂閱的消息后,將消息體寫入到自身的通道隊列中。
在啟動一個node的最后:
ui.Run(network)
在Run中,開啟一個協程:
go?ui.handleEvents(net)
在handleEvents中,使用一個無限循環,讀取通道的隊列消息進行處理:
```
case m?:=?<-ui.GeneralChannel.Content:
ui.HandleStream(net,?m)
casem?:=?<-ui.MiningChannel.Content:
????????????ui.HandleStream(net,?m)
casem?:=?<-ui.FullNodesChannel.Content:
????????????ui.HandleStream(net,?m)
```
# pubsub 訂閱發布服務系統
pubsub服務是P2P網絡節點之間交互的關鍵。基于發布/訂閱的模式,將消息的發送和處理分離,使得對等網絡節點間的交互成為可能。
任何一個主機(節點或對端),同時都是一個訂閱發布服務系統。但一個主機可能同時具備訂閱和發布的功能,也可能只有發布的功能而沒有訂閱的功能,這在創建主機時候確定。
libp2p的pubsub是一個基于Gossip協議的消息路由器。
Gossip 過程是由種子節點發起,當一個種子節點有狀態需要更新到網絡中的其他節點時,它會隨機的選擇周圍幾個節點散播消息,收到消息的節點也會重復該過程,直至最終網絡中所有的節點都收到了消息。這個過程可能需要一定的時間,由于不能保證某個時刻所有節點都收到消息,但是理論上最終所有節點都會收到消息,因此它是一個最終一致性協議。
Gossip protocol 也叫 Epidemic Protocol (流行病協議),實際上它還有很多別名,比如:“流言算法”、“疫情傳播算法”等。基于六度分隔理論,任何信息的傳播其實非常迅速,而且網絡交互次數不會很多。比如Facebook在2016年2月4號做了一個實驗:研究了當時已注冊的15.9億使用者資料,發現這個神奇數字的“網絡直徑”是4.57,翻成白話文意味著每個人與其他人間隔為4.57人。
**Gossip 中的通信模式**
在 Gossip 協議下,網絡中兩個節點之間有三種通信方式:
* Push: 節點 A 將數據 (key,value,version) 及對應的版本號推送給 B 節點,B 節點更新 A 中比自己新的數據
* Pull:A 僅將數據 key, version 推送給 B,B 將本地比 A 新的數據(Key, value, version)推送給 A,A 更新本地
* Push/Pull:與 Pull 類似,只是多了一步,A 再將本地比 B 新的數據推送給 B,B 則更新本地
如果把兩個節點數據同步一次定義為一個周期,則在一個周期內,Push 需通信 1 次,Pull 需 2 次,Push/Pull 則需 3 次。雖然消息數增加了,但從效果上來講,Push/Pull 最好,理論上一個周期內可以使兩個節點完全一致。直觀上,Push/Pull 的收斂速度也是最快的。
**Gossip 安全增強**
對于大型區塊鏈用戶來說,重點是穩定性、可擴展性和安全加固。
為此,Gossipsub 協議設計并實現了新版本 v1.1 ([https://blog.ipfs.io/2020-05-20-gossipsub-v1.1/](https://blog.ipfs.io/2020-05-20-gossipsub-v1.1/))。這個新的 P2P PubSub 路由器包含了幾個安全擴展,增加了對 Sybil、eclipse 和垃圾郵件攻擊的保護。
這項工作極為重要,因為大型區塊鏈的采用者(如 Filecoin 和 Ethereum 2.0)需要一個安全的消息層來分發他們的時間敏感和有價值的數據,而不容易受到惡意行為者的攻擊。
- 重要更新說明
- linechain發布
- linechain新版設計
- 引言一
- 引言二
- 引言三
- vs-code設置及開發環境設置
- BoltDB數據庫應用
- 關于Go語言、VS-code的一些Tips
- 區塊鏈的架構
- 網絡通信與區塊鏈
- 單元測試
- 比特幣腳本語言
- 關于區塊鏈的一些概念
- 區塊鏈組件
- 區塊鏈第一版:基本原型
- 區塊鏈第二版:增加工作量證明
- 區塊鏈第三版:持久化
- 區塊鏈第四版:交易
- 區塊鏈第五版:實現錢包
- 區塊鏈第六版:實現UTXO集
- 區塊鏈第七版:網絡
- 階段小結
- 區塊鏈第八版:P2P
- P2P網絡架構
- 區塊鏈網絡層
- P2P區塊鏈最簡體驗
- libp2p建立P2P網絡的關鍵概念
- 區塊鏈結構層設計與實現
- 用戶交互層設計與實現
- 網絡層設計與實現
- 建立節點發現機制
- 向區塊鏈網絡請求區塊信息
- 向區塊鏈網絡發布消息
- 運行區塊鏈
- LineChain
- 系統運行流程
- Multihash
- 區塊鏈網絡的節點發現機制深入探討
- DHT
- Bootstrap
- 連接到所有引導節點
- Advertise
- 搜索其它peers
- 連接到搜到的其它peers
- 區塊鏈網絡的消息訂發布-訂閱機制深入探討
- LineChain:適用于智能合約編程的腳本語言支持
- LineChain:解決分叉問題
- LineChain:多重簽名
- libp2p升級到v0.22版本
- 以太坊基礎
- 重溫以太坊的樹結構
- 世界狀態樹
- (智能合約)賬戶存儲樹
- 交易樹
- 交易收據樹
- 小結
- 以太坊的存儲結構
- 以太坊狀態數據庫
- MPT
- 以太坊POW共識算法
- 智能合約存儲
- Polygon Edge
- block結構
- transaction數據結構
- 數據結構小結
- 關于本區塊鏈的一些說明
- UML工具-PlantUML
- libp2p介紹
- JSON-RPC
- docker制作:啟動多個應用系統
- Dockerfile
- docker-entrypoint.sh
- supervisord.conf
- docker run
- nginx.conf
- docker基礎操作整理
- jupyter計算交互環境
- git技巧一
- git技巧二
- 使用github項目的最佳實踐
- windows下package管理工具