在上文的介紹中,出現了多處有關p2p通訊協定的結構類型,比如eth.peer,p2p.Peer,Server等等。這裡不妨對這些p2p通訊協定族的結構一併作個總解。以太坊中用到的p2p通訊協定族的結構類型,大致可分為三層:
第一層處於pkg eth中,可以直接被eth.Ethereum,eth.ProtocolManager等頂層管理模組使用,在型別宣告上也明顯考慮了eth.Ethereum的使用特點。典型的有eth.peer{}, eth.peerSet{},其中peerSet是peer的集合類型,而eth.peer代表了遠端通訊對象和其所有通訊操作,它封裝更底層的p2p.Peer對象以及讀寫通道等。
第二層屬於pkg p2p,可認為是泛化的p2p通訊結構,比較典型的結構類型包括代表遠端通訊對象的p2p.Peer{}, 封裝自更底層連線物件的conn{},通訊用通道對象protoRW{}, 以及啟動監聽、處理新加入串連或中斷連線的Server{}。這一層中,各種資料類型的界限比較清晰,盡量不出現揉雜的情況,這也是泛化結構的需求。值得關注的是p2p.Protocol{},它應該是針對上層應用特意開闢的類型,主要作用包括容納應用程式所要求的回呼函數等,並通過p2p.Server{}在新串連建立後,將其傳遞給通訊對象peer。從這個類型所起的作用來看,命名為Protocol還是比較貼切的,儘管不應將其與TCP/IP協議等既有概念混淆。
第三層處於golang內建的網路程式碼封裝中,也可分為兩部分:第一部分pkg net,包括代表網路連接的<Conn>介面,代表網路地址的<Addr>以及它們的實作類別;第二部分pkg syscall,包括更底層的網路相關係統調用類等,可視為封裝了網路層(IP)和傳輸層(TCP)協議的系統實現。
下列UML圖描繪了上述三層p2p通訊協定族中的一些主要結構,希望對於理解以太坊中p2p通訊相關代碼有所協助。
image.png
小結:
諸如以太坊這種去中心化的數字貨幣運行系統,天生適用p2p通訊架構。不過原理雖然簡單,在系統架構的層面,依然有很多實現細節需要加以關注。
eth.ProtocolManager中,會對每一個遠端peer發起主動傳輸資料的操作,這組操作按照資料類型區分,可分為交易和區塊;而若以發送資料方式來區分,亦可分為廣播單項資料,和同步一組同類型資料。這樣兩兩配對,即可形成4組主動傳輸資料的操作。
ProtocolManager通過在p2p.Protocol{}對象中埋入回呼函數,可以對遠端peer的任何事件及狀態更新作出響應。這些Protocol對象,會由p2p.Server傳遞給每一個新串連上的遠端peer。
以太坊目前實現的p2p通訊協定族的結構類型中,按照功能和作用,可分為三層:頂層pkg eth中的類型直接服務於當前以太坊系統(Ethereum,ProtocolManager等模組),中介層pkg p2p是泛化結構類型,底層包括golang語言套件內建的pkg net, syscall等,封裝了網路層和傳輸層協議的系統實現。