# 前言
節點之間要組成一個P2P網絡,又沒有中心化節點,這些節點之間在P2P網絡中進行信息傳播,涉及到節點之間的連接管理、
地址管理、Peer節點的管理和Peer之間同步區塊的協議等,參考比特幣區塊鏈的網絡設計:
* btcd/peer:實現了P2P網絡中Peer之間維持連接及收發wire協議消息的機制。
* btcd/wire:實現Bitcoin網絡協議,定義理論Peers之間的協議消息,消息格式及包的封裝和解析等。
* btcd/connmgr:管理Peer節點之間的TCP連接,包括監聽本地端口等待其他節點連接和主動連接Peer節點等。
* btcd/addrmgr:收集、存儲Bitcoin網絡上的節點的地址,隨機從地址集中選擇路由可達的地址建立Peer連接,這些地址包括IPv4,IPv6及洋蔥地址(onion address)等。
* netsync:同步管理器,用于統一處理各個節點發送和接收到的數據,以便同步區塊鏈和同步交易。
* btcd/server.go:btcd節點啟動后執行的主要入口,定義了server及serverPeer類型,負責初始化和啟動connmgr,addrmgr,以及響應Peer的協議消息等。
與比特幣區塊鏈不同,我們不使用洋蔥網絡協議,而是使用libp2p作為網絡協議。另外,本項目會先基于libp2p進行基本功能實現,并考慮DDOS攻擊和釣魚攻擊的風險規避。
暫時不考慮實現SPV節點,而假定每一個節點都是全節點,關注點在三個區塊鏈網絡核心功能上:
1. 發現節點;
2. 同步區塊;
2. 發布交易;
3. 挖礦(交易上鏈)
# 發現節點
比特幣通過dns seed幫助節點發現其它節點,dns seed數據是硬編碼到項目中的。
為了能夠加入到比特幣網絡,區塊鏈客戶端會做一下幾件事情:
a、節點會記住它最近成功連接的網絡節點,當重新啟動后它可以迅速與先前的對等節點網絡重新建立連接。
b、節點會在失去已有連接時嘗試發現新節點。
c、當建立一個或多個連接后,節點將一條包含自身IP地址消息發送給其相鄰節點。相鄰節點再將此消息依次轉發給它們各自的相鄰節點,從而保證節點信息被多個節點所接收、保證連接更穩定。
d、新接入的節點可以向它的相鄰節點發送獲取地址getaddr消息,要求它們返回其已知對等節點的IP地址列表。節點可以找到需連接到的對等節點。
e、在節點啟動時,可以給節點指定一個正活躍節點IP, 如果沒有,客戶端也維持一個列表,列出了那些長期穩定運行的節點。這樣的節點也被稱為種子節點(其實和BT下載的種子文件道理是一樣的),就可以通過種子節點來快速發現網絡中的其他節點。
1、新節點自舉,連接到區塊鏈網絡
區塊鏈的核心部分維護一個在啟動時可以連接的對等節點列表,并被硬編碼到項目中。當一個新的節點第一次啟動時,它必須被自舉(bootstrapped)到網絡。使用選項-dnsseed定義這種自舉行為,默認的設置是1。**dns**請求命令返回一個可連接的IP地址列表。任何一個節點均可從那里可以連接到整個區塊鏈網絡。
自舉過程完成后,節點向其對等節點發送一個包含其自身IP地址的**addr**消息。其對等的每個節點向它們自己的對等節點轉發這個信息,以便進一步擴大連接池。
通過**getpeerinfo**命令可以查看某個節點所連接的對等節點及相關的數據。
小結:
這里涉及到3個命令需要實現:
(1)dns -dnsseed,默認值為1
(2)addr
(3)getpeerinfo -address 節點地址
# 連接到對等節點
節點通過發送version消息連接到一個對等節點。消息version 包含了節點的版本信息、塊信息和距離遠程節點的時間。一旦這個消息被對等節點收到,它必須回復一個verack。如果它愿意建立對等關系,它將發送自己的version消息。
一旦建立對等關系,節點可以向遠程節點發送getaddr和addr消息來獲得其它的對等節點信息。為了維持與對等節點的連接,節點默認情況下每30分鐘內會給對等節點至少發送一次信息。如果超過90分鐘沒有收到回復,節點會認為連接已經斷開。
這里需要實現1個新命令:
(1)version
# 塊廣播
在與對等節點建立連接后,雙方互發包含最新塊哈希值的getblocks消息。如果某個節點堅信其擁有最新的塊信息或者有更長的鏈,它將發送一個inv消息,其中包含至多500個最新塊的哈希值,以此來表明它的鏈更長。收到的節點使用getdata來請求塊的詳細信息,而遠程的節點通過命令block來發送這些信息。在500個塊的信息被處理完之后,節點可以通過getblocks請求更多的塊信息。這些塊在被接收節點認證之后得到確認。
新塊的確認也可通過礦工挖到并發布的塊來發現。其擴散過程和上述類似。通過之前的連接,新塊以inv消息發布出去,而接收節點可以通過getdata請求這些塊的詳細信息。
需要實現的新命令:
(1)getblocks
(2)block
(3)inv
(4)getdata
# 交易的廣播
和對等節點的交易通過inv消息來實現。如果收到了getdata信息,那么交易通過發送tx實現。對等節點收到有效的交易的信息后會通過類似的方式將其擴散。如果交易的信息在一段時間內沒有被放進塊中,那么交易將被從內存池中清除,而原節點將重新發送交易信息。
需要實現的新命令1個:
(1)tx
# 處罰行為不端的節點
對于所有的廣播,那些行為不端的節點(占用帶寬和通過發布錯誤信息來浪費計算資源)將收到懲罰。如果一個節點懲罰分數超過門限值-banscore=,它將被禁止加入網絡若干秒。這個時間由參數-bantime=定義,默認值是86400秒,即24小時。(暫不實現)
# 警告
為了應對可能出現的bug和攻擊,提供了比特幣警告服務RSS。比特幣用戶通過命令getinfo可以查看針對其特定客戶端版本的錯誤信息。這些信息通過allert消息盡可能多擴散出去給每一個連接的對等節點。錯誤信息采用特定的ECDSA私有密鑰簽名,只被極少數的開發者控制。(暫不實現)
# 四個類
## peer
實現P2P網絡中Peer之間維持連接及收發wire協議消息的機制。
## wire
實現libp2p網絡協議,定義理論Peers之間的協議消息,消息格式及包的封裝和解析等。
## connmgr
管理Peer節點之間的TCP連接,包括監聽本地端口等待其他節點連接和主動連接Peer節點等。
## addrmgr
收集、存儲Bitcoin網絡上的節點的地址,隨機從地址集中選擇路由可達的地址建立Peer連接,這些地址包括IPv4,IPv6及libp2p地址等。
## server
節點啟動后執行的主要入口,定義了server及serverPeer類型,負責初始化和啟動connmgr,addrmgr,以及響應Peer的協議消息等。
模塊之間通信關系如下:

- 重要更新說明
- 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管理工具