国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > P2P網(wǎng)絡(luò)架構(gòu)設(shè)計(jì)及部分細(xì)節(jié)實(shí)現(xiàn)

P2P網(wǎng)絡(luò)架構(gòu)設(shè)計(jì)及部分細(xì)節(jié)實(shí)現(xiàn)

時(shí)間:2023-08-05 17:27:02 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-08-05 17:27:02 來(lái)源:網(wǎng)站運(yùn)營(yíng)

P2P網(wǎng)絡(luò)架構(gòu)設(shè)計(jì)及部分細(xì)節(jié)實(shí)現(xiàn):

一、前言

p2p模塊總是在區(qū)塊鏈的眾多子模塊中優(yōu)先啟動(dòng),它承擔(dān)將本地消息向外發(fā)送,獲取外部消息的職責(zé);獲取與發(fā)送消息之前自身又需要維持一個(gè)最低的鏈接數(shù),維持這個(gè)最低鏈接數(shù)就需要獲取跟多節(jié)點(diǎn)信息。

與區(qū)塊鏈的多個(gè)子模塊交互、消息傳輸?shù)碾[私性與安全性、去中心化等一系列問題,使得設(shè)計(jì)一個(gè)p2p模塊自然會(huì)涉及到很多問題,然而很多優(yōu)秀的公鏈已經(jīng)為我們提供了一些參考的實(shí)例。本文分析主流公鏈的的p2p模塊及實(shí)現(xiàn)的一些細(xì)節(jié)問題,但是限于篇幅的原因僅會(huì)給出部分具體實(shí)例。

二、 架構(gòu)分析及實(shí)現(xiàn)細(xì)節(jié)

從職責(zé)劃分上來(lái)講,p2p模塊可分為兩塊:發(fā)現(xiàn)服務(wù)、消息傳輸服務(wù)。發(fā)現(xiàn)服務(wù)主要用來(lái)獲取更多節(jié)點(diǎn)信息,使得消息傳輸服務(wù)在與其他節(jié)點(diǎn)建立鏈接時(shí)有更多的選擇,節(jié)點(diǎn)信息包括IP、端口、協(xié)議、節(jié)點(diǎn)ID等,鏈接到更多的節(jié)點(diǎn)意味著在以下方面有更大概率:更新的本地狀態(tài)、同等算力下更多的節(jié)點(diǎn)收到本地挖出的block。消息傳輸服務(wù),顧名思義,就是用來(lái)傳輸消息的,比如共識(shí)消息、狀態(tài)同步消息、心跳包、tx/block廣播消息等。消息傳輸服務(wù)從業(yè)務(wù)深度上可劃分為:

1. 發(fā)現(xiàn)服務(wù)

主流公鏈的發(fā)現(xiàn)服務(wù)一般有三個(gè)組成部分:

1.1 節(jié)點(diǎn)信息與鏈接池維護(hù)

節(jié)點(diǎn)信息的應(yīng)該區(qū)分為:

未建立過(guò)鏈接的節(jié)點(diǎn)應(yīng)該額外的保存兩條信息:

重啟后應(yīng)該優(yōu)先嘗試已經(jīng)建立鏈接的節(jié)點(diǎn)。go-ipfs采用bitswap算法,該算法通過(guò)負(fù)債率r調(diào)整消息發(fā)送概率P,負(fù)債率越大消息被丟棄的概率越大。通過(guò)累計(jì)發(fā)送和接受到的消息字節(jié)數(shù)計(jì)算負(fù)債率,進(jìn)一步調(diào)整遠(yuǎn)程節(jié)點(diǎn)的消息被處理的概率,所以我們也建議將這這倆個(gè)指標(biāo)持久化,供消息模塊使用以及嘗試鏈接的優(yōu)先級(jí)。嘗試失敗超過(guò)一定的數(shù)量后,可以認(rèn)為這條信息已經(jīng)失效了。

計(jì)算負(fù)債率、丟棄概率公式如下:

r = bytes_sent / (bytes_recv + 1)P = 1 ? 1 / (1 + exp(6 ? 3r))

1.2 節(jié)點(diǎn)發(fā)現(xiàn)

pex算法本身很簡(jiǎn)單,我們不做的過(guò)多的贅述。kademlia作為目前dht的主流實(shí)現(xiàn),其算法主體思想如下:

  1. A節(jié)點(diǎn)廣播一個(gè)(hash, entry)的鍵值對(duì),一般為(節(jié)點(diǎn)ID, NetworkAddr)
  2. B將(hash, entry)加入本地table
  3. B使用table提供基于距離關(guān)系的查找
table的結(jié)構(gòu)為[距離]list,len(list) < 20(建議),將(hash, entry)加入table的大致過(guò)程如下,可以一定程度的抵抗女巫攻擊:

idx := 計(jì)算與本節(jié)點(diǎn)ID的距離table[idx] = append(table[idx], entry)backup(table[20:]) // 作為備份信息table[idx] = table[idx][:20]計(jì)算距離的算法如下:

func prefixLength(xor uint8) uint { switch { case xor == 1: return 7 case xor >= 2 && xor <= 3: return 6 case xor >= 4 && xor <= 7: return 5 case xor >= 8 && xor <= 15: return 4 case xor >= 16 && xor <= 31: return 3 case xor >= 32 && xor <= 63: return 2 case xor >= 64 && xor <= 127: return 1 case xor >= 128 && xor <= 255: return 0 } return 8}func calcDistance(a, b []byte) uint { c := uint(0) for i := 0; i < len(a) && i < len(b); i++ { x := a[i] ^ b[i] if x == 0 { c += 8 } else { c += prefixLength(x) break } } return uint(len(a))*8 - c}

2. 消息傳輸服務(wù)

2.1 鏈接資源申請(qǐng)管理

p2p的消息傳輸服務(wù)應(yīng)該不僅作為server通過(guò)監(jiān)聽端口處理鏈接請(qǐng)求,還需作為client發(fā)起鏈接,倆個(gè)方向的鏈接都應(yīng)通過(guò)令牌的方式控制連接數(shù)。僅作為server處理鏈接會(huì)降低攻擊難度;僅作為client發(fā)起鏈接會(huì)失去大量鏈接的機(jī)會(huì),因?yàn)槠渌?jié)點(diǎn)發(fā)起與本節(jié)點(diǎn)的鏈接失敗后會(huì)拋棄本節(jié)點(diǎn)信息。此過(guò)程有倆個(gè)細(xì)節(jié)需要說(shuō)明:

為了保證消息的完整性,ethereum使用如下的消息報(bào)文格式來(lái)拆解包

| length | msgHash | msg |

2.2 協(xié)議/代碼版本檢測(cè)

在具體的業(yè)務(wù)邏輯開始前進(jìn)行本代碼版本檢測(cè)可以實(shí)現(xiàn)控制代碼升級(jí)、分叉,進(jìn)行協(xié)議檢測(cè)可以避免大量無(wú)效鏈接。目前ethereum的節(jié)點(diǎn)分為倆種full node、light node, 即將到來(lái)的sharding版本又增加了更多的節(jié)點(diǎn)角色類型,light node僅同步header信息以及向full node請(qǐng)求merkel proof,而full node是否支持為light node提供服務(wù)就需要在這一步確認(rèn)。

2.3 隱私保護(hù)

區(qū)塊鏈建立在非對(duì)稱加密算法ECC上,非對(duì)稱加密算法做加解密效率很低,此外ECC是無(wú)法用來(lái)加解密信息只是用來(lái)’驗(yàn)證‘ ,所以提供消息隱私性功能需要借助對(duì)稱加密算法比如AES算法。一般使用STS實(shí)現(xiàn)AES密鑰同步,算法如下:

concat := func(a, b uint) uint { v, _ := strconv.Atoi(fmt.Spintf("%d%d", a, b)) return uint(v)}mod := func(x, y uint) uint { return x % y}pow := func(x, y uint) uint { return uint(math.Pow(x, y))}算法:

A, B : set p = 23, g = 5A : generate a = 6, set va=mod(concat(g, a), p)=8 , sendTo(B, 8) // 56 % 23 == 8B : generate b = 15, set vb=mod(concat(g, b), p)=19 , sendTo(A, 19) // 515 % 23 == 19A : set secret=mod(pow(vb, a), p)=2 // 47045881 % 23=19B : set secret=mod(pow(va, b), p)=2 // 35184372088832% 23 = 2密鑰安全性保證證明如下:

節(jié)點(diǎn)A節(jié)點(diǎn)B惡意節(jié)點(diǎn)已知 信息a, p, g, concat, modb, p, g, concat, modp, g, concat, mod已知 信息vb, a, p, pow, modva, b, p, pow, modva, vb, p, pow, mod已知 信息secretsecret-

2.4 消息路由

主流的公鏈包括若干個(gè)模塊比如:共識(shí)、交易池、賬本、P2P等。共識(shí)模塊需要通過(guò)P2P 廣播投票信息、收集投票出塊;交易池將驗(yàn)證tx通過(guò)p2p 廣播給周圍節(jié)點(diǎn),通過(guò)p2p收集tx驗(yàn)證后加入本地交易池;賬本通過(guò)p2p同步賬本信息,比如我們可以在心跳包中加入賬本高度,賬本模塊對(duì)比本地高度請(qǐng)求block。 ethereum的交易池模塊業(yè)務(wù)流程如下:

  1. 接收tx (來(lái)源包括rpc調(diào)用、p2p轉(zhuǎn)發(fā)等)
  2. tx驗(yàn)證(包括nonce,value、gas、signature)后加入本地交易池,并依據(jù)tx中的nonce刪除老舊tx
  3. 通過(guò)gasprice對(duì)交易池里的tx排序
  4. 為出塊模塊(挖礦、共識(shí))提供tx list
  5. 調(diào)用p2p廣播驗(yàn)證過(guò)的tx
  6. 監(jiān)聽eventhub的“挖礦”主題,刪除本地交易池中已經(jīng)被出塊模塊打包進(jìn)入block的tx
  7. 監(jiān)聽eventhub的”新塊“主題,刪除本地交易池中已經(jīng)其他節(jié)點(diǎn)打包進(jìn)入block的tx
我們可以清晰的看到p2p與交易池的交互發(fā)生:1、5。交易池與p2p調(diào)用實(shí)現(xiàn)大致如下:

type Message struct { topic string // 消息主題,此處是 txpool code uint payload []byte // 消息體,解析方式需由各模塊自定義 推薦google/proto.Marshal/Unmarshal}type Context interface { Send(uint32, []byte) // 模塊調(diào)用p2p向遠(yuǎn)程節(jié)點(diǎn)發(fā)送消息 ID() string // 節(jié)點(diǎn)標(biāo)識(shí)符 Topic()string ...}type PeerHandler interface { NewPeer(Context)TopicHandler ...}type TopicHandler interface { Setup()error Handle(uint32, []byte) error // 遠(yuǎn)程節(jié)點(diǎn)向本節(jié)點(diǎn)發(fā)消息 Treardown()}func readLoop(conn Conn) { for { data := conn.Read() // 消息完整性檢測(cè)、數(shù)據(jù)加解密在conn封裝層完成 go disptath(data) ... }}var mTopicHandler map[string]TopicHandlerfunc dispatch(data []byte) { topic, code, payload := decode(data) h, exists := mTopicHandler[topic] // 依據(jù) topic做路由 if exists{ h.Handle(code, payload) } ...}type TxPoolServer server { txHandlers map[string]txHandler}func (self *TxPoolServer)NewPeer(ctx context) TxPoolHandler { h := txHandler{...} self.txHandlers[ctx.ID()] = h ... return h}func (self TxPoolServer)broadcastTx(tx Transaction, except func(string)bool){ // 廣播交易 payload = encode(tx) for id, h := range self.txHandlers{ if except!=nil && except(id){ // 哪些節(jié)點(diǎn)不能發(fā) continue } h.Send(1, payload) }}func (self txHandler)Handle(code uint, msg []byte) error { switch code { case 1: // new tx ... } return nil}p2p模塊應(yīng)該對(duì)外只承擔(dān)消息發(fā)送與接受、對(duì)內(nèi)實(shí)現(xiàn)節(jié)點(diǎn)發(fā)現(xiàn)的功能,具體的業(yè)務(wù)邏輯不應(yīng)該交由p2p處理,事實(shí)上主流公鏈也都采用如下的架構(gòu)來(lái)解耦具體業(yè)務(wù):

2.5 鏈接資源釋放管理

鏈接的client端應(yīng)該負(fù)責(zé)發(fā)送心跳包維持鏈接,server端釋放不活躍、異常的client; 釋放鏈接的同時(shí)應(yīng)該同步通知與該節(jié)點(diǎn)交互的各個(gè)子模塊。注意前文提到需要“歸還不同的令牌。

三、總結(jié)

以上只是簡(jiǎn)單描述了設(shè)計(jì)幾個(gè)核心模塊時(shí)需要主要注意的問題以及幾條建議,當(dāng)然還有一些其他問題比如:流量控制、節(jié)點(diǎn)管理、ssl transport、Conn封裝、消息去重等,這些問題之所以沒有展開是因?yàn)樗鼈儾粎⑴c核心流程,但是如果設(shè)計(jì)的時(shí)候沒有考慮到,那么這個(gè)p2p模塊也只能算是基本可用。






關(guān)鍵詞:部分,細(xì)節(jié),實(shí)現(xiàn),設(shè)計(jì),網(wǎng)絡(luò)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉