# P2P缃戠粶 ## Libp2p ### 姒傝堪 缃戠粶妯″潡涓昏璐熻矗濡備笅鍔熻兘瀹炵幇锛� - 鑺傜偣缁勭綉 - 鍏锋湁瀹夊叏淇濋殰鐨勮妭鐐归棿鏁版嵁閫氳 - 鑺傜偣缃戠粶韬唤璁よ瘉 - 娑堟伅骞挎挱鍙婅闃咃紙Pubsub锛� - 鎵╁睍鏀寔鑺傜偣鑷姩鍙戠幇銆佽嚜鍔ㄧ粍缃� - 澶氶摼闂寸綉缁滄秷鎭暟鎹殧绂� - 澶嶆潅缃戠粶鐜鍦烘櫙瑙e喅鏂规鐨勬敮鎸� 闀垮畨閾�2.0鐗堟湰鐨勭綉缁滄ā鍧楁槸鍩轰簬[libp2p](https://libp2p.io)鐨剉0.6.4鐗堟湰瀹炵幇骞舵敼杩涚殑銆傝妭鐐圭殑缃戠粶鍦板潃閬靛惊libp2p鍦板潃鏍煎紡鍗忚锛涗负浜嗘弧瓒抽暱瀹夐摼缃戠粶娑堟伅鍦ㄥ閾惧満鏅笅鐨勬暟鎹殧绂婚渶姹傦紝鎴戜滑淇敼浜唋ibp2p-gossip-pubsub妯″潡婧愮爜锛屽姞鍏ヨ妭鐐圭櫧鍚嶅崟鏈哄埗锛岀簿纭帶鍒惰矾鐢辫〃锛屽苟璁╄妭鐐逛笂鐨勬瘡鏉¢摼閮界嫭浜竴涓嫭绔嬬殑Pubsub鏈嶅姟锛屼繚璇佷簡骞挎挱鏁版嵁鍙細鍦ㄩ摼鍐呯殑鑺傜偣浼犳挱鐨勭‘瀹氭€э紱涓轰簡婊¤冻鍥藉瘑鍔犲瘑绠楁硶鐨勬敮鎸侊紝鎴戜滑杩樹慨鏀逛簡libp2p-core鏍稿績鍖咃紝澧炲姞浜嗗鍥藉瘑TLS璇佷功鐨勬敮鎸併€� 浜嗚В缃戠粶妯″潡鐨勪娇鐢ㄧず渚嬶紝璇风偣鍑诲涓嬮摼鎺ワ細 [P2P浣跨敤鏂囨。](../manage/P2P缃戠粶绠$悊.md) **鍩轰簬libp2p鐨勬敼杩�:**manage - 鏍稿績鍖呭鍔犲鍥藉瘑SM绠楁硶鐨勬敮鎸侊紱 - libp2p-gossip-pubsub鍔熻兘妯″潡澧炲姞鐧藉悕鍗曞姛鑳斤紝瀹炵幇瀵笹ossip璺敱琛ㄧ殑鎺у埗锛岃揪鍒板箍鎾秷鎭殧绂绘晥鏋滐紱 - 寮曞叆StreamPool锛屽疄鐜皊tream澶嶇敤鎻愰珮鎬ц兘銆佺綉缁滃悶鍚愯兘鍔涜嚜鍔ㄦ墿瀹圭瓑鐗规€с€� P2P缃戠粶鐩稿叧鐗规€э紝鍙敤涓嬪浘涓€鍥炬眹鎬伙紝鍖呮嫭锛� - 澶ц妯¤妭鐐圭粍缃戯紱 - 鍔ㄦ€佽妭鐐瑰拰杩炴帴绠$悊锛� - 涓撴湁缃戠粶绌块€忚繛鎺ワ紱 - 澶氶摼缃戠粶闅旂銆� <img loading="lazy" src="../images/P2P-schematic.png" style="width:900px;" /> ### 缁勭綉鏂瑰紡 闀垮畨閾炬敮鎸佽嚜鍔ㄥ彂鐜般€佽嚜鍔ㄨ繛鎺ョ殑缁勭綉鏂瑰紡锛岄粯璁ゅ湪绾跨殑姣忎釜鑺傜偣閮藉彲浠ヤ綔涓虹瀛愯妭鐐逛负鍏朵粬鑺傜偣鎻愪緵缃戠粶鍙戠幇鏈嶅姟锛屾瘡涓瀛愯妭鐐归兘浼氳褰曠綉鍐呰妭鐐瑰湴鍧€淇℃伅銆傚綋鏈夋柊鑺傜偣杩炴帴鍒版煇涓瀛愯妭鐐规椂锛屾柊鑺傜偣浼氬悜璇ョ瀛愯妭鐐规煡璇㈢綉鍐呭叾浠栧彲杩炴帴鑺傜偣鐨勫湴鍧€锛屾嬁鍒板叾浠栬妭鐐瑰湴鍧€鍚庯紝鏂拌妭鐐逛細涓诲姩灏濊瘯涓庤繖浜涜妭鐐瑰缓绔嬭繛鎺ワ紱鍙﹀锛岀瀛愯妭鐐瑰湪鎺ュ彈浜嗘柊鑺傜偣閾炬帴鍚庯紝浼氶€氳繃缃戠粶鍙戠幇鏈嶅姟灏嗚鏂拌妭鐐圭殑鍦板潃閫氱煡缁欏叾浠栧湪绾跨殑绉嶅瓙鑺傜偣锛屽叾浠栬妭鐐瑰湪鑾峰緱璇ユ柊鑺傜偣鍦板潃鍚庯紝涔熶細涓诲姩灏濊瘯涓庤鏂拌妭鐐瑰缓绔嬭繛鎺ャ€� 闀垮畨閾剧悊璁轰笂鍙疄鐜颁笂涓囩敋鑷虫洿澶氳妭鐐瑰悓鏃跺湪绾跨粍缃戙€� #### 澶嶆潅缃戠粶鐜鍦烘櫙鏀寔 闀垮畨閾惧彲浠ラ拡瀵瑰鏉傜綉缁滅幆澧冨満鏅彁渚涚粍缃戦€氳瑙e喅鏂规锛屽寘鎷絾涓嶉檺浜嶯AT绌块€忋€佷唬鐞嗚妭鐐硅浆鍙戠瓑銆� ### 鑺傜偣韬唤楠岃瘉 - 鑺傜偣韬唤鏄敱缁勭粐CA绛惧彂鐨凾LS璇佷功纭畾锛屽湪鑺傜偣鍏ョ綉鏃讹紝浼氶€氳繃TLS鎻℃墜鍗忚鏍¢獙TLS璇佷功鐨勫悎娉曟€с€� - 姣忎釜鑺傜偣浣跨敤鐨凾LS璇佷功鐨勫繀椤讳繚璇佸敮涓€鎬э紝涓嶅彲澶氳妭鐐瑰叡鐢ㄤ竴涓猅LS璇佷功銆� - 姣忎釜TLS璇佷功閮藉彲瀵瑰簲鐢熸垚涓€涓狽odeId鍞竴鏍囪瘑锛岃鏍囪瘑鏄妭鐐圭綉缁滃湴鍧€鐨勭粍鎴愰儴鍒嗭紝鏄綉缁滈€氳鐜妭閲嶈鐨勬爣璇嗐€� ### 涓庡叾浠栨ā鍧椾氦浜� 褰撳墠鐗堟湰缃戠粶妯″潡涓庡叾浠栨ā鍧椾氦浜掗兘鏄紓姝ョ殑锛岄兘鏄€氳繃MsgBus鏉ヨ繘琛屾暟鎹簰浼狅紝浜や簰鍥惧涓嬶細 <img loading="lazy" src="../images/P2P-interaction.png" style="zoom:90%;"/> ### 鎺ュ彛璇存槑 ```go package protocol type ChainNodeInfo struct { NodeUid string NodeAddress []string NodeTlsCert []byte } type MsgHandler func(from string, msg []byte, msgType net.NetMsg_MsgType) error // ChainNodesInfoProvider provide base node info list of chain. type ChainNodesInfoProvider interface { // GetChainNodesInfo return base node info list of chain. GetChainNodesInfo() ([]*ChainNodeInfo, error) } // NetService type NetService interface { // BroadcastMsg broadcast a msg to the net. BroadcastMsg(msg []byte, msgType net.NetMsg_MsgType) error // Subscribe register a MsgHandler for subscribe. Subscribe(msgType net.NetMsg_MsgType, handler MsgHandler) error // CancelSubscribe cancel subscribe. CancelSubscribe(msgType net.NetMsg_MsgType) error // ConsensusBroadcastMsg broadcast a msg to the consensus nodes. ConsensusBroadcastMsg(msg []byte, msgType net.NetMsg_MsgType) error // ConsensusSubscribe register a MsgHandler handle the msg from consensus nodes for subscribe. ConsensusSubscribe(msgType net.NetMsg_MsgType, handler MsgHandler) error // CancelConsensusSubscribe cancel subscribe. CancelConsensusSubscribe(msgType net.NetMsg_MsgType) error // SendMsg send msg to any nodes. SendMsg(msg []byte, msgType net.NetMsg_MsgType, to ...string) error // ReceiveMsg register a MsgHandler to handle the msg received from other node. ReceiveMsg(msgType net.NetMsg_MsgType, handler MsgHandler) error // Start the net service. Start() error // Stop the net service. Stop() error // GetNodeUidByCertId return node uid which mapped to the given cert id. If unmapped return error. GetNodeUidByCertId(certId string) (string, error) // GetChainNodesInfoProvider return a implementation of ChainNodesInfoProvider. GetChainNodesInfoProvider() ChainNodesInfoProvider } ``` - `ChainNodeInfo` 鏄摼涓婅妭鐐逛俊鎭粨鏋勪綋锛屼富瑕佸瓨鍌ㄦ煇涓摼涓婁笌鏈湴鑺傜偣寤虹珛杩炴帴鐨勮妭鐐筃odeID銆佺綉缁滃湴鍧€銆乀LS璇佷功绛変俊鎭€� - `MsgHandler` 鏄綉缁滄秷鎭鐞嗗櫒锛屽綋缃戠粶妯″潡鏀跺埌鏉ヨ嚜鍏朵粬鑺傜偣鎴栬闃呯殑娑堟伅鏃讹紝浼氭牴鎹秷鎭被鍨嬪洖璋冪粰涓嶅悓鐨勬秷鎭鐞嗗櫒鍘诲鐞嗘帴鏀跺埌鐨勬秷鎭€� - `ChainNodesInfoProvider` 鏄摼涓婅妭鐐逛俊鎭疨rovider鎺ュ彛瀹氫箟锛屼富瑕佺敤浜庣粰rpcServer鎴朧M鎻愪緵鏌ヨ褰撳墠閾惧凡杩炴帴鑺傜偣淇℃伅鍔熻兘銆� - `NetService` 鏄綉缁滄湇鍔℃帴鍙e畾涔夛紝涓昏鐢ㄤ簬涓哄叾浠栨ā鍧楁彁渚涚綉缁滄湇鍔℃敮鎸併€� - `BroadcastMsg`鏂规硶锛屽悜閾惧唴骞挎挱涓€鏉℃秷鎭紝闇€瑕佹寚瀹氭秷鎭被鍨嬨€� - `Subscribe`鏂规硶锛屾敞鍐屼竴涓敤浜庡鐞嗘寚瀹氭秷鎭被鍨嬬殑璁㈤槄娑堟伅澶勭悊鍣紝涓巂BroadcastMsg`閰嶅悎浣跨敤銆� - `CancelSubscribe`鏂规硶锛屾敞閿€涓€涓敤浜庡鐞嗘寚瀹氭秷鎭被鍨嬬殑璁㈤槄娑堟伅澶勭悊鍣ㄣ€� - `ConsensusBroadcastMsg`鏂规硶锛屽悜閾惧唴鍏辫瘑鑺傜偣骞挎挱涓€鏉℃秷鎭紝闇€瑕佹寚瀹氭秷鎭被鍨嬨€傝鏂规硶鍙細鎶婃秷鎭彂缁欏叡璇嗚妭鐐癸紝闈炲叡璇嗚妭鐐规敹涓嶅埌璇ユ柟娉曞箍鎾殑娑堟伅銆� - `ConsensusSubscribe`鏂规硶锛屾敞鍐屼竴涓敤浜庡鐞嗘寚瀹氭秷鎭被鍨嬬殑鍙彂缁欏叡璇嗚妭鐐圭殑璁㈤槄娑堟伅澶勭悊鍣紝涓巂ConsensusBroadcastMsg`閰嶅悎浣跨敤銆� - `CancelConsensusSubscribe`鏂规硶锛屾敞閿€涓€涓敤浜庡鐞嗘寚瀹氭秷鎭被鍨嬬殑鍙彂缁欏叡璇嗚妭鐐圭殑璁㈤槄娑堟伅澶勭悊鍣ㄣ€� - `SendMsg`鏂规硶锛屽悜鎸囧畾鑺傜偣鐩存帴鍙戦€佺綉缁滄秷鎭€� - `ReceiveMsg`鏂规硶锛屾敞鍐屼竴涓敤浜庡鐞嗗叾浠栬妭鐐圭洿鎺ュ彂閫佽繃鏉ョ殑娑堟伅澶勭悊鍣ㄣ€� - `Start`鏂规硶锛屽惎鍔ㄧ綉缁滄湇鍔°€� - `Stop`鏂规硶锛屽仠姝㈢綉缁滄湇鍔°€� - `GetNodeUidByCertId`鏂规硶锛屾牴鎹瘉涔D鏌ヨ浣跨敤璇ヨ瘉涔D瀵瑰簲鐨凾LS璇佷功鑺傜偣鐨凬odeID銆� - `GetChainNodesInfoProvider`鏂规硶锛岃繑鍥瀈ChainNodesInfoProvider`鎺ュ彛瀹炵幇銆� ### 鑺傜偣鍦板潃鏍煎紡璇存槑 闀垮畨閾捐妭鐐瑰湴鍧€閬靛惊libp2p缃戠粶鍦板潃鏍煎紡鍗忓畾锛屼娇鐢╩ultaddr缁勪欢瑙f瀽鍦板潃锛屼緥濡傦細 ```text /ip4/127.0.0.1/tcp/6666/p2p/QmQZn3pZCcuEf34FSvucqkvVJEvfzpNjQTk17HS6CYMR35 ``` 鎴栬€� ```text /dns4/chainmaker.org/tcp/6666/p2p/QmQZn3pZCcuEf34FSvucqkvVJEvfzpNjQTk17HS6CYMR35 ``` 鍦板潃浠�"/"寮€濮嬶紝骞朵互"/"鍒嗘锛屽ぇ澶氭暟鎯呭喌涓嬶紝鍚勬璇存槑濡備笅锛� - 绗竴娈碉細IP鍗忚鐗堟湰鎴朌NS瑙f瀽鍗忚鐗堟湰銆俰p4浠h〃IPv4锛宨p6浠h〃IPv6锛沝ns4瀵瑰簲IPv4鐗堟湰DNS鏈嶅姟锛宒ns6瀵瑰簲IPv6鐗堟湰DNS鏈嶅姟 - 绗簩娈碉細IP鍦板潃鎴栧煙鍚嶏紝闇€瑕佷笌绗竴娈靛搴� - 绗笁娈碉細閫氳缃戠粶鍗忚锛岄粯璁や娇鐢╰cp - 绗洓娈碉細鐩戝惉绔彛 - 绗簲娈碉細鍥哄畾鍗忚锛岃鍕挎敼鍔紝鍥哄畾涓�"p2p" - 绗叚娈碉細鑺傜偣NodeId锛屼笌TLS璇佷功閰嶅锛屾牴鎹甌LS璇佷功閫氳繃鐗瑰畾绠楁硶璁$畻鑰屾潵 浠ヤ笂鍙槸鏈€鏅€氬父鐢ㄥ満鏅笅鑺傜偣鍦板潃涓句緥锛屽湪澶嶆潅缃戠粶鍦烘櫙涓嬶紙姣斿闇€瑕佷娇鐢ㄨ妭鐐逛腑缁с€丯AT绌块€忕瓑锛夊湴鍧€鏍煎紡浼氱◢鏈変笉鍚屻€� ### 缃戠粶娑堟伅鏁版嵁鏍煎紡璇存槑锛堝姞瀵嗗墠锛� 鍔犲瘑鍓嶇殑娑堟伅鏁版嵁鏄敱 `8浣峛yte琛ㄧず鏁版嵁闀垮害 + 1浣峛yte鏁版嵁鍘嬬缉鏍囪瘑 + 瀹為檯鏁版嵁` 鏉ョ粍鎴愩€� 涓轰簡鏂逛究璇存槑锛屾垜浠娇鐢ㄥ涓嬩緥瀛愶細 ```text [0 0 0 0 0 0 0 78 0 10 57 10 5 ...... 80 85 83 72] ``` 鍋囪杩欐槸涓€鏉″緟鍙戦€佺殑缃戠粶娑堟伅鏁版嵁锛屽叾涓細 - 鍓�8浣嶏紝[0 0 0 0 0 0 0 78] 琛ㄧず瑕佸彂閫佹暟鎹殑闀垮害锛屽湪鎺ユ敹鏂规帴鏀舵暟鎹椂锛岃嫢鎺ユ敹鍒扮殑鏁版嵁闀垮害涓嶈冻璇ュ€硷紝鍒欎細灏濊瘯缁х画璇诲彇鏁版嵁锛岀洿鑷虫帴鏀跺叏閮ㄩ暱搴︾殑鏁版嵁鎴栨帴鏀跺け璐ャ€� - 绗�9浣嶏紝[0] 鎴� [1] 鏄暟鎹帇缂╂爣璁颁綅锛岃嫢鏄�1锛屾帴鏀舵柟鍦ㄦ帴鏀跺埌瀹屾暣鏁版嵁鍚庯紝浼氬皢鎺ユ敹鍒扮殑鏁版嵁杩涜瑙e帇缂╋紝寰楀埌鏈€缁堢殑鏁版嵁缁撴灉銆� - 鍓╀綑浣嶏紝[10 57 10 5 ...... 80 85 83 72] 涓鸿鍙戦€佺殑鍘熷鏁版嵁鎴栬鍘嬬缉鍚庣殑鍘熷鏁版嵁锛屾槸鍚﹀帇缂╄涓庣9浣嶅帇缂╂爣璇嗙浉瀵瑰簲銆傚帇缂�/瑙e帇缂╀娇鐢℅Zip宸ュ叿鍖呭畬鎴愩€� ## Liquid ### 姒傝堪 闀垮畨閾緑1.x鐗堟湰鐨凱2P缃戠粶鏄熀浜巐ibp2p鏉ュ疄鐜扮殑锛屼絾鏄痩ibp2p鍦ㄨ璁′笂鏈夊緢澶氬湴鏂瑰苟涓嶅畬鍏ㄧ鍚坈hainmaker鐨勭綉缁滃簲鐢ㄩ渶姹傦紝鍦ㄨ繖鏍风殑鎯呭涓嬶紝鑷爺缃戠粶璁″垝璇炵敓浜嗐€傚湪浜嗚В鑷爺缃戠粶涔嬪墠锛屾垜浠厛鏉ヨ涓媍hainmaker瀵圭綉缁滄ā鍧楁彁鍑虹殑闇€姹傘€� 缃戠粶妯″潡瑕佸叿澶囧涓嬪姛鑳藉強鐗规€э細 - 鑺傜偣缃戠粶韬唤璁よ瘉 - 鍏锋湁瀹夊叏淇濋殰鐨勮妭鐐归棿鏁版嵁閫氳 - 鑺傜偣缁勭綉 - 鍩轰簬閾惧眰鐨勬秷鎭彂甯冨強璁㈤槄锛圥ubSub) - 澶氶摼鍏辩敤缃戠粶涓旈摼闂寸綉缁滄秷鎭暟鎹殧绂� - 鍥藉瘑鍔犲瘑绠楁硶鏀寔 - 鎵╁睍鏀寔鑺傜偣鑷姩鍙戠幇銆佽嚜鍔ㄧ粍缃� - 澶嶆潅缃戠粶鐜鍦烘櫙鐨勮В鍐虫柟妗堟敮鎸� 鍦ㄨ嚜鐮旂綉缁滀唬鐮佹灦鏋勮璁¢樁娈碉紝鎴戜滑鐫€閲嶈€冭檻浜嗕互涓婇渶姹傦紝纭繚鏂扮綉缁滃疄鐜板彲鏈€澶ч檺搴﹁创鍚坈hainmaker鐨勮璁$悊蹇点€� 鍦ㄨ嚜鐮旂綉缁滃紑鍙戦樁娈碉紝鎴戜滑鎬荤粨浜嗕娇鐢╨ibp2p浣滀负缃戠粶瀹炵幇鏃堕亣鍒扮殑涓€浜涢棶棰樺苟瀵瑰簲鐨勭粰鍑鸿В鍐虫柟妗堬紝鍦ㄥ紑鍙戣嚜鐮旂綉缁滄椂锛屼細鐩存帴灏嗚В鍐虫柟妗堝簲鐢ㄥ湪鏂颁唬鐮佷腑銆傛垜浠篃瀵筶ibp2p缃戠粶瀹炵幇鐨勪唬鐮佸仛浜嗛儴鍒嗚皟鏁达紝璁╂暣涓綉缁滄ā鍧椾唬鐮佺粨鏋勬洿鍚堢悊楂樻晥锛屽悓鏃朵篃瑙e喅浜嗕竴浜涘巻鍙查仐鐣欓棶棰樸€� 鎴戜滑缁欒嚜鐮擯2P缃戠粶璧嬩簣浜嗕竴涓柊鍚嶅瓧鈥斺€擫iquid銆傚湪涓嬫枃涓垜浠細浣跨敤Liquid鏉ヤ唬琛ㄨ嚜鐮旂綉缁溿€� 浜嗚В缃戠粶妯″潡鐨勪娇鐢ㄧず渚嬶紝璇风偣鍑诲涓嬮摼鎺ワ細 [P2P浣跨敤鏂囨。](../manage/P2P缃戠粶绠$悊.md) ### 鏋舵瀯璁捐 #### Liquid鏁翠綋鏋舵瀯 Liquid鏋舵瀯鍦ㄥ姛鑳藉眰闈㈢敱涓婅嚦涓嬫€诲叡鍒掑垎涓轰笁涓眰绾э紝鍒嗗埆鏄細缃戠粶搴旂敤灞傘€佺綉缁滅鐞嗗眰銆佸畨鍏ㄤ紶杈撳眰銆� 鍔熻兘鏋舵瀯鍥惧涓嬶細 <img loading="lazy" src="../images/Liquid-structure.png" style="width:900px;" /> - 缃戠粶搴旂敤灞傦細鏄寚浣跨敤Liquid鏉ュ疄鐜扮綉缁滈€氳鐨勪笂灞傚簲鐢ㄩ泦鍚堬紝Liquid鏄娇鐢ㄥ簲鐢ㄥ崗璁紙protocol.ID)鏉ュ尯鍒嗘爣璇嗕笂灞傚簲鐢ㄧ殑锛屾瘡涓簲鐢ㄦā鍧楅兘搴旇鏈変竴涓叏灞€鍞竴鐨勫簲鐢ㄥ崗璁€傚簲鐢ㄥ崗璁弿杩拌瑙�4.1銆傛秷鎭彂甯冨強璁㈤槄妯″潡锛圥ubSub锛夋槸Liquid鍐呯疆鐨勪竴涓簲鐢ㄣ€� - 缃戠粶绠$悊灞傦細璐熻矗Liquid缃戠粶鑺傜偣闂磋繛鎺ョ姸鎬佺鐞嗭紝鐢卞涓鐞嗙粍浠剁粍鎴愶紝瀹冧滑鍖呮嫭浣嗕笉闄愪簬锛氬簲鐢ㄥ崗璁鐞嗭紙鍖呭惈搴旂敤鍗忚浜ゆ崲鏈猴級銆佽妭鐐逛俊鎭鐞嗭紙PeerStore锛夈€佽繛鎺ョ鐞嗭紙ConnMgr锛夈€佹暟鎹祦绠$悊锛圫endStreamPool/SendStreamMgr/ReceiveStreamMgr锛夈€侀粦鍚嶅崟绠$悊銆佺粍鎾粍浠躲€佽繛鎺ョ姸鎬佺淮鎶ょ粍浠讹紙ConnSupervisor锛夈€佽妭鐐瑰彂鐜帮紙Discovery锛夈€佽妭鐐硅矾鐢憋紙PeerRouting锛夈€佽妭鐐逛腑缁с€丯AT绌块€忕瓑銆傚叾涓簲鐢ㄥ崗璁氦鎹€€佽妭鐐瑰彂鐜颁篃鏄熀浜庡簲鐢ㄥ崗璁敮鎸佸疄鐜扮殑锛屽畠浠睘浜庣鐞嗗眰鍐呯疆鐨勫簲鐢ㄦā鍧椼€� - 瀹夊叏浼犺緭灞傦細璐熻矗搴曞眰缃戠粶鍗忚鏀寔鍙婁紶杈撳姞瀵嗭紝鐩墠宸插疄鐜癟CP/TLS銆丵UIC涓ょ鍗忚鏀寔锛屾湭鏉ヤ細鏈夋洿澶氾紙姣斿WebSocket銆丼CTP绛夛級鍗忚鏀寔銆� #### Liquid鏍稿績鍖� Liquid缃戠粶鏍稿績鍖呴噷鍖呭惈浜嗘鏋舵牳蹇冩帴鍙e畾涔夈€侀€氱敤绫诲瀷瀹氫箟鍙婃蹇垫娊璞″畾涔夈€� 鏍稿績鍖呭唴姣忎釜瀛愬寘璇存槑濡備笅锛� - core/basic 鍩虹鎺ュ彛鍖咃紝鍖呭惈Starter銆丼topper浠ュ強涓よ€呯粍鍚堝皝瑁呮帴鍙witcher銆� - core/blacklist 榛戝悕鍗曟帴鍙e畾涔夈€� - core/broadcast PubSub娑堟伅鍙戝竷/璁㈤槄鍔熻兘鎺ュ彛瀹氫箟銆� - core/discovery 鑺傜偣鍙戠幇鐩稿叧鎺ュ彛瀹氫箟锛屽寘鍚獳nnouncer銆丏iscoverer浠ュ強涓よ€呯粍鍚堝皝瑁呮帴鍙iscovery銆� - core/groupmulticast 缁勬挱缁勪欢鎺ュ彛瀹氫箟銆� - core/handler 鐢ㄤ簬鍥炶皟鐨勫鐞嗗櫒鍑芥暟绫诲瀷瀹氫箟銆� - core/host 缃戠粶Host鎺ュ彛瀹氫箟銆佺綉缁滄椿鍔ㄤ簨浠堕€氱煡鎺ュ彛瀹氫箟銆� - core/mgr 绠$悊缁勪欢鎺ュ彛瀹氫箟锛屽寘鍚繛鎺ョ鐞嗭紙ConnMgr锛夈€佽繛鎺ョ姸鎬佺淮鎶わ紙ConnSupervisor锛夈€佸簲鐢ㄥ崗璁鐞嗗櫒锛圥rotocolManager锛夈€佸簲鐢ㄥ崗璁氦鎹㈡満锛圥rotocolExchanger锛夈€佸彂閫佹祦姹狅紙SendStreamPool锛夈€佸彂閫佹祦姹犵鐞嗭紙SendStreamPoolManager锛夈€佹帴鏀舵祦绠$悊锛圧eceiveStreamManager锛夌瓑鎺ュ彛瀹氫箟銆� - core/network 浼犺緭灞傜綉缁滅姸鎬佹満鐩稿叧鎺ュ彛瀹氫箟锛屽寘鍚彂閫佹祦锛圫endStream锛夈€佹帴鏀舵祦锛圧eceiveStream锛夈€佸弻鍚戞祦锛圫tream锛夈€佽繛鎺ワ紙Conn锛夈€佺姸鎬侊紙Stat锛夈€佹嫧鍙峰櫒锛圖ialer锛夈€佺洃鍚櫒锛圠istener锛夈€佺綉缁滅姸鎬佹満锛坣etwork锛夌瓑浠ュ強鐩稿叧鐨勫叾浠栫殑鎺ュ彛鎴栫被鍨嬪畾涔夈€� - core/peer 鑺傜偣鐩稿叧姒傚康鎺ュ彛瀹氫箟锛屼富瑕佸寘鎷妭鐐笽D锛坧eer.ID锛夌被鍨嬪畾涔夈€� - core/protocol 鍗忚鐩稿叧瀹氫箟锛屼富瑕佸寘鎷簲鐢ㄥ崗璁紙protocol.ID锛夌被鍨嬪畾涔夊強缃戠粶鏁版嵁鍖呯粨鏋勪綋瀹氫箟銆� - core/reuse 绔彛澶嶇敤鐩稿叧銆� - core/routing 鑺傜偣璺敱鐩稿叧鎺ュ彛瀹氫箟銆� - core/store 鑺傜偣淇℃伅瀛樺偍鐩稿叧姒傚康鎺ュ彛瀹氫箟锛屼富瑕佸寘鎷妭鐐瑰湴鍧€绨匡紙AddrBook锛夈€佽妭鐐瑰崗璁翱锛圥rotocolBook锛変互鍙婁袱鑰呯粍鍚堝皝瑁呮帴鍙o紙PeerStore锛夊畾涔夈€� - core/types 閫氱敤绫诲瀷鎴栫粨鏋勪綋锛屽寘鎷厛杩涘厛鍑虹紦瀛橈紙FIFOCache锛夈€佸浐瀹氬ぇ灏忚秴鏃舵帶鍒剁紦瀛橈紙FixedCapDurationCache锛夈€佽繛缁暟瀛楄褰曢泦锛圛ntervalSet锛夈€侀€氱敤闆嗭紙Set锛夌瓑銆� - core/util 閫氱敤宸ュ叿闆嗗悎銆� #### Liquid瀹炵幇浠g爜缁撴瀯 鍦↙iquid寮€鍙戞椂锛屾垜浠敖鍙兘鐨勪繚璇佷簡瀹冪殑閫氱敤鎬с€侺iquid铏界劧鏄负浜哻hainmaker鑰岀敓锛屼絾鎴戜滑骞朵笉闄愪簬瀹冨彧鑳借chainmaker闆嗘垚浣跨敤銆傛垜浠篃灏藉彲鑳藉皢涓嶉渶瑕佷娇鐢ㄨ€呭叧蹇冪殑缁勪欢鍙婇厤缃繘琛屼簡闅愯棌锛堥潪瀵煎嚭澶勭悊锛夛紝涓轰簡鑳借寮€鍙戣€呮洿瀹规槗璇绘噦鎴戜滑鐨勪唬鐮佺粨鏋勶紝鎵€浠iquid瀹炵幇浠g爜骞舵病鏈変弗鏍兼寜鐓�2.1涓弿杩扮殑妗嗘灦璁捐銆備互涓嬪唴瀹归兘鏄弿杩癓iquid鍐呴儴榛樿瀹炵幇锛屽紑鍙戣€呭彲浠ユ牴鎹牳蹇冨寘瀹氫箟鎺ュ彛鑷缂栧啓瀹炵幇鏉ユ浛鎹iquid鍐呯疆榛樿瀹炵幇銆� BasicHost锛堝湪net/liquid/host/host.go涓級鏄疞iquid鍐呯疆榛樿Host瀹炵幇锛屼篃鏄綉缁滃垵濮嬪寲鐨勬€诲叆鍙c€傛垜浠熀浜嶣asicHost鏁寸悊浜嗕竴寮燣iquid榛樿瀹炵幇鐨勪唬鐮佺粨鏋勫浘锛� <img loading="lazy" src="../images/Liquid-BasicHost-structure.png" style="width:900px;" /> 鍏蜂綋鍚勭粍浠堕棿鐨勮仈绯诲強璋冪敤鍏崇郴浼氬湪鎴戜滑鍙戝竷姝e紡绋冲畾鐗堜箣鍚庤ˉ鍏呭湪鍔熻兘閫昏緫娴佺▼鍥句腑锛屾暚璇锋湡寰呫€� ##### Liquid Host鍩烘湰浣跨敤 浠ヤ笅浠g爜鍙槸鐢ㄤ簬涓句緥灞曠ず锛屽苟闈炲疄闄呭彲杩愯绋嬪簭锛� ```go import ( "chainmaker.org/chainmaker/chainmaker-net-liquid/core/handler" coreHost "chainmaker.org/chainmaker/chainmaker-net-liquid/core/host" "chainmaker.org/chainmaker/chainmaker-net-liquid/core/peer" "chainmaker.org/chainmaker/chainmaker-net-liquid/core/protocol" "chainmaker.org/chainmaker/chainmaker-net-liquid/discovery/protocoldiscovery" "chainmaker.org/chainmaker/chainmaker-net-liquid/host" "chainmaker.org/chainmaker/chainmaker-net-liquid/logger" "chainmaker.org/chainmaker/chainmaker-net-liquid/pubsub" "chainmaker.org/chainmaker/chainmaker-net-liquid/tlssupport" "chainmaker.org/chainmaker/common/crypto" "chainmaker.org/chainmaker/common/crypto/asym" "context" "fmt" ma "github.com/multiformats/go-multiaddr" ) func main() { ctx := context.Background() // 1. 濡備綍鍒濆鍖栦竴涓狶iquid Host瀹炰緥 // 棣栧厛鍒涘缓涓€涓狧ostConfig hostCfg := &host.HostConfig{} // 鍑嗗鍔犲瘑瀵嗛挜(闈炲浗瀵�) sk, err := asym.GenerateKeyPair(crypto.ECC_NISTP256) if err != nil { // do something panic(err) } hostCfg.PrivateKey = sk // 浣跨敤瀵嗛挜鍒涘缓TLS config鍙奓oadPidFunc tlsCfg, pidFunc, err := tlssupport.MakeTlsConfigAndLoadPeerIdFuncWithPrivateKey(sk) if err != nil { // do something panic(err) } hostCfg.TlsCfg, hostCfg.LoadPidFunc = tlsCfg, pidFunc // 璁剧疆鍙戦€佹祦姹犲ぇ灏忥紝鍙€夛紝榛樿100 hostCfg.SendStreamPoolCap = 100 // 璁剧疆涓庢瘡涓妭鐐瑰缓绔嬬殑鏈€澶ц繛鎺ユ暟锛屽彲閫夛紝璇ュ弬鏁扮洿鎺ュ奖鍝嶅苟鍙戝彂閫佹暟鎹€ц兘锛岄粯璁ゆ槸1锛岃嫢涓�1鏃讹紝鍒欎笉浼氬惎鐢ㄥ苟鍙� hostCfg.MaxConnCountEachPeerAllowed = 5 // 璁剧疆涓庢瘡涓妭鐐归棿鎺ユ敹娴佹渶澶ф暟閲� hostCfg.PeerReceiveStreamMaxCount = hostCfg.SendStreamPoolCap * int32(hostCfg.MaxConnCountEachPeerAllowed) // 璁剧疆鍙缓绔嬭繛鎺ヨ妭鐐规暟閲忥紝鍙€夛紝榛樿涓�20 hostCfg.MaxPeerCountAllowed = 20 // 璁剧疆鏈湴鐩戝惉鍦板潃 lAddr := ma.StringCast("/ip4/0.0.0.0/tcp/8001") hostCfg.ListenAddresses = []ma.Multiaddr{lAddr} // 璁剧疆瑕佽繛鎺ョ殑鍏朵粬鑺傜偣鍦板潃锛屽彲閫� hostCfg.AddDirectPeer("/ip4/127.0.0.1/tcp/8002/p2p/QmeyNRs2DwWjcHTpcVHoUSaDAAif4VQZ2wQDQAUNDP33gH") hostCfg.AddDirectPeer("/ip4/127.0.0.1/tcp/8003/p2p/QmXf6mnQDBR9aHauRmViKzSuZgpumkn7x6rNxw1oqqRr45") // 鏂板缓涓€涓狧ost瀹炰緥 log := logger.NewLogPrinter("TEST") h, err := hostCfg.NewHost(host.TcpNetwork, ctx, log) if err != nil { // do something panic(err) } // 2. 鍚慔ost娉ㄥ唽涓€涓狽otifee锛屾柟渚挎垜浠劅鐭ュ埌鍝簺鑺傜偣宸茶繛鎺ユ垨鏂紑杩炴帴锛屼互鍙婂摢浜涜妭鐐规柊鏀寔浜嗗摢浜涘簲鐢ㄥ崗璁� notifyBundle := &coreHost.NotifieeBundle{ PeerConnectedFunc: func(id peer.ID) { fmt.Printf("鑺傜偣宸茶繛鎺ワ紝鑺傜偣ID锛�%s\n", id) }, PeerDisconnectedFunc: func(id peer.ID) { fmt.Printf("鑺傜偣宸叉柇寮€锛岃妭鐐笽D锛�%s\n", id) }, PeerProtocolSupportedFunc: func(protocolID protocol.ID, pid peer.ID) { fmt.Printf("鑺傜偣%s鏂版敮鎸佸崗璁�%s\n", pid, protocolID) }, PeerProtocolUnsupportedFunc: func(protocolID protocol.ID, pid peer.ID) { fmt.Printf("鑺傜偣%s鍙栨秷鏀寔鍗忚%s\n", pid, protocolID) }, } h.Notify(notifyBundle) // 3. 鍚慔ost娉ㄥ唽涓€涓秷鎭鐞嗗櫒 testProtocol := protocol.ID("TEST") var msgHandler handler.MsgPayloadHandler = func(senderPID peer.ID, msgPayload []byte) { fmt.Printf("鏀跺埌鏉ヨ嚜鑺傜偣%s鐨勬秷鎭細%s\n", senderPID, string(msgPayload)) } err = h.RegisterMsgPayloadHandler(testProtocol, msgHandler) if err != nil { // do something panic(err) } // 4. 鍚姩Host瀹炰緥 err = h.Start() if err != nil { // do something panic(err) } // 5. 浣跨敤Host灏濊瘯涓庡叾浠栬妭鐐瑰缓绔嬭繛鎺� remoteAddr := ma.StringCast("/ip4/127.0.0.1/tcp/8002/p2p/QmeyNRs2DwWjcHTpcVHoUSaDAAif4VQZ2wQDQAUNDP33gH") _, err = h.Dial(remoteAddr) if err != nil { // do something panic(err) } // 6. 浣跨敤Host鍚戝叾浠栧凡杩炴帴鑺傜偣鍙戦€佹暟鎹� data := []byte("Hello!") receiverPid := peer.ID("QmeyNRs2DwWjcHTpcVHoUSaDAAif4VQZ2wQDQAUNDP33gH") err = h.SendMsg(testProtocol, receiverPid, data) if err != nil { // do something panic(err) } // 娑堟伅鍙戝竷鍙婅闃� // 7. 鍒濆鍖朇hainPubSub鏈嶅姟 ps := pubsub.NewChainPubSub("test_chain", log) err = ps.AttachHost(h) if err != nil { // do something panic(err) } // 8. 鍚慍hainPubSub娉ㄥ唽璁㈤槄娑堟伅澶勭悊鍣� testTopic := "test_topic" var subHandler handler.SubMsgHandler = func(publisher peer.ID, topic string, msg []byte) { fmt.Printf("鏀跺埌鑺傜偣%s鍚戦閬�%s鍙戝竷鐨勬秷鎭細%s\n", publisher, topic, string(msg)) } ps.Subscribe(testTopic, subHandler) // 9. 浣跨敤ChainPubSub鍙戝竷娑堟伅 ps.Publish(testTopic, data) // 鑺傜偣鍙戠幇鏈嶅姟 // 10. 寮€鍚妭鐐瑰彂鐜版湇鍔� discoveryService, err := protocoldiscovery.NewProtocolBasedDiscovery(h, protocoldiscovery.WithLogger(log)) if err != nil { // do something panic(err) } // 11. 瀹e竷鑷繁鏀寔鐨勬湇鍔� err = discoveryService.Announce(ctx, "test_chain") if err != nil { // do something panic(err) } // 12. 鎼滃鍏朵粬鑺傜偣 findC, err := discoveryService.FindPeers(ctx, "test_chain") if err != nil { // do something panic(err) } newPeerAddr := <- findC fmt.Printf("鍙戠幇鏂拌妭鐐癸紝鍦板潃锛�%s\n", newPeerAddr.String()) } ``` ### 瀹夊叏浼犺緭灞� #### TCP锛圱LS锛変紶杈� TCP浼犺緭鏄互TCP浣滀负搴曞眰浼犺緭鍗忚鐨勪竴绉嶄紶杈撳眰瀹炵幇锛岄粯璁ゅ疄鐜板湪liquid/host/tcp鍖呭唴銆傚簳灞備娇鐢╣olang瀹樻柟net搴撳疄鐜般€� TCP浼犺緭鏀寔鏄庢枃銆乀LS鍔犲瘑銆丟MTLS锛堝浗瀵嗙畻娉曟敮鎸侊級鍔犲瘑浼犺緭涓夌妯″紡銆� 鐢变簬瀹樻柟net搴撶殑tcp杩炴帴娌℃湁娴佺殑姒傚康锛屾墍浠CP浼犺緭鐨勬暟鎹祦锛圫tream锛夌洰鍓嶆槸鍩轰簬yamux寮€婧愮粍浠跺疄鐜帮紝鎸夌収鏁版嵁娴佸悜鍙垎涓烘帴鏀舵祦銆佸彂閫佹祦銆佸弻鍚戞祦涓夌銆� #### SNI鎵╁睍 liquid鏀寔SNI鎵╁睍銆俵iquid鍦ㄨ幏寰椾竴涓妭鐐圭殑缃戠粶鍦板潃鐨勬椂鍊欙紝浼氳嚜鍔ㄨ瘑鍒綉缁滃湴鍧€涓璬ns鍏抽敭瀛楀悗闈㈢殑鍩熷悕锛屽皢鍏朵綔涓篢LS鎻℃墜涓殑servername锛孴LS鐨勬湇鍔$鍙互鏍规嵁servername鎵ц鐩稿簲鐨勯€昏緫锛屾瘮濡傚皢缃戠粶閾炬帴杞彂鍒版煇涓壒鐐圭殑鑺傜偣銆� #### QUIC浼犺緭 QUIC浼犺緭鏄互Quic浣滀负搴曞眰浼犺緭鍗忚鐨勪竴绉嶄紶杈撳眰瀹炵幇锛岄粯璁ゅ疄鐜板湪liquid/host/quic鍖呭唴銆傚簳灞備娇鐢ㄦ垜浠慨鏀硅繃鐨剄uic-go寮€婧愬簱瀹炵幇銆傛垜浠湪quic-go鐨勫疄鐜板熀纭€涓婂姞鍏ヤ簡瀵瑰浗瀵嗙畻娉旼MTLS鐨勬敮鎸併€� QUIC浼犺緭涓嶆敮鎸佹槑鏂囦紶杈擄紝瑕佹眰浣跨敤TLS鍔犲瘑浼犺緭銆傛垜浠慨鏀瑰悗鍚屾椂鏀寔鍥藉瘑TLS銆� Quic鍗忚鏈韩灏辨湁鏁版嵁娴佺殑姒傚康瀹氫箟锛屾墍浠UIC浼犺緭鐨勬暟鎹祦鐩存帴浣跨敤quic-go鐨凷tream灏佽瀹炵幇銆� **娉細缁忚繃鎴戜滑娴嬭瘯锛岀洰鍓嶅湪Linux绯荤粺涓嬶紝UDP鎶ユ枃鎺ユ敹鏁堢巼浼氭瘮杈冧綆涓嬶紙Linux鍐呮牳闀挎湡娌℃湁瀵筓DP浼樺寲锛夛紝浣跨敤QUIC鏃犳硶灏嗙綉缁滃甫瀹藉厖鍒嗗埄鐢紙鍗冨厗鍙婁互涓婏級銆傝嫢浣跨敤鍗冨厗/涓囧厗缃戠粶锛屽缓璁綋鍓嶉樁娈典娇鐢═CP銆�** #### 鐢勫埆鎭舵剰娑堟伅 liquid涓嶄粎鏀寔鏍囧噯TLS銆佸浗瀵嗗姞瀵嗕紶杈擄紝鍚屾椂瀵规瘡涓€涓秷鎭兘浼氬崟鐙獙璇侊紝閬垮厤鎭舵剰鏀诲嚮銆� liquid鍦ㄦ敹鍒颁换鎰忎竴鏉℃秷鎭椂锛屼細閫氳繃涓嬮潰涓や釜姝ラ璇嗗埆鎭舵剰娑堟伅锛� 鈶犻鍏堥€氳繃鍏挜璁$畻鍑哄鏂圭殑鑺傜偣id锛屽苟鍜屾秷鎭殑鏉ユ簮id锛堝嵆sender id锛夎繘琛屽姣斻€傚鏋滀袱涓猧d涓€鑷达紝鍒欒瘉鏄庤繖涓猻ender鍜屽叕閽ユ槸鍑鸿嚜鍚屼竴涓妭鐐广€傚鏋滀笉涓€鑷达紝璇佹槑杩欎釜娑堟伅鏉ユ簮鏈夐棶棰橈紒瑕佷箞鏄秷鎭潵婧愬嵆sender琚鏀癸紝瑕佷箞鏄叾鍏挜琚鏀癸紝杩欐椂liquid浼氱珛鍒诲垹闄よ娑堟伅銆� 鈶$劧鍚庨€氳繃娑堟伅鎼哄甫鐨勭鍚嶅拰鍏挜杩涜楠岀锛岃瘉鏄庢秷鎭殑鍐呭鐨勭‘鏄鑺傜偣缂栬緫鐨勪笖娌℃湁琚叾浠栬妭鐐圭鏀广€傚鏋滈獙绛惧紓甯革紝liquid鍚屾牱浼氬垹闄よ娑堟伅銆� 閫氳繃浜岃€呯殑缁撳悎锛屼繚璇佹秷鎭殑鏉ユ簮鏄竴涓妭鐐筰d鏄庣‘鐨勮仈鐩熸垚鍛橈紝涓旀秷鎭唴瀹规病鏈夎鍏朵粬浜虹鏀广€傛墍浠ュ彧瑕佷繚璇佹秷鎭彂甯冭€呯殑TLS璇佷功鍚堟硶锛屽氨鍙互纭畾杩欎釜娑堟伅鐨勫彲闈犳€с€傚鏋淭LS璇佷功涓嶅悎娉曪紝鍦═LS鎻℃墜鏃讹紝liquid灏变細鎷掔粷杩欎釜杩炴帴銆� 缁间笂鎵€杩帮紝liquid鍦ㄩ€氫俊灞傞潰瀵规秷鎭簮澶磋韩浠姐€佹秷鎭槻绡℃敼鍋氫簡鍏呭垎鐨勫畨鍏ㄤ繚闅溿€� #### 鏈潵璁″垝 鏈潵鎴戜滑浼氳€冭檻瀹炵幇浣跨敤WebSocket銆丼CTP绛夊叾浠栧簳灞備紶杈撳崗璁殑浼犺緭灞傦紝褰撶劧寮€鍙戣€呬篃鍙嚜宸卞疄鐜颁紶杈撳眰锛屽彧闇€瑕佸疄鐜發iquid/core/network涓帴鍙e畾涔夌殑鏂规硶鍗冲彲鎺ュ叆Liquid銆� ### 缃戠粶绠$悊灞� #### 搴旂敤鍗忚 搴旂敤鍗忚ID鍗砅rotocol.ID锛屾槸灏哃iquid鑺傜偣闂寸浉鍚屽簲鐢ㄥ叧鑱旇捣鏉ョ殑閲嶈渚濇嵁锛屽彧鏈夊簲鐢ㄥ崗璁甀D鐩稿悓鐨凩iquid搴旂敤鎵嶈兘澶熶簰鐩搁€氳銆備笂灞傚簲鐢ㄥ湪鍙戦€佹秷鎭椂锛屼細灏嗚搴旂敤鐨勫崗璁甀D灏佽鍦ㄧ綉缁滄暟鎹寘涓紝鎺ユ敹鏂逛細鏍规嵁鎺ユ敹鐨勬暟鎹寘涓殑鍗忚ID鏉ュ皢鏀跺埌鐨勬暟鎹憡鐭ユ嫢鏈夌浉鍚屽崗璁甀D鐨勪笂灞傚簲鐢ㄣ€� 姣忎釜涓婂眰搴旂敤蹇呴』鎷ユ湁鍏ㄥ眬鍞竴鐨勫簲鐢ㄥ崗璁甀D锛孡iquid浼氭嫆缁濆娆$殑鐩稿悓搴旂敤鍗忚ID娉ㄥ唽璇锋眰銆� 鐢变簬Liquid鍐呯疆閮ㄥ垎缁勪欢涔熸槸鍩轰簬搴旂敤鍗忚瀹炵幇锛屽紑鍙戣€呭湪瀹氫箟涓婂眰搴旂敤鍗忚ID鏃讹紝搴旈伩鍏嶄笌鍐呯疆缁勪欢搴旂敤鍗忚鍐茬獊銆� liquid鏀寔閾鹃殧绂诲姛鑳斤紙鎴栬€呭彨閾剧骇娑堟伅鍙戝竷锛夈€傚湪涓嶅悓閾句笂鐨勫崗璁甀D涓€瀹氫笉鍚岋紝鑰屼笖鏁版嵁闅旂銆備絾鏄悓涓€鏉¢摼涓婄殑涓嶅悓鍗忚鍙互鍏辩敤涓€涓暟鎹€氶亾銆傝繖涓ょ鏂瑰紡鐩哥粨鍚堢殑濂藉鏄細鑺傜害缃戠粶璧勬簮鐨勫墠鎻愪笅淇濊瘉搴旂敤灞傜殑鏁版嵁闅旂鎬с€� #### 绠$悊缁勪欢 ##### 杩炴帴绠$悊 杩炴帴绠$悊鍣ㄨ礋璐g鐞嗕笌鍏朵粬鑺傜偣闂村缓绔嬬殑閾炬帴锛屾帴鍙e畾涔夊湪core/mgr/connmgr.go涓璵gr.ConnMgr interface銆� ###### 鍐呯疆杩炴帴绠$悊鍣ㄥ疄鐜� Liquid鍐呯疆浜嗕竴绉嶅熀浜庝紭鍏堢骇鐨勮繛鎺ョ鐞嗗櫒鈥斺€攕imple.LevelConnManager锛屽疄鐜颁唬鐮佸湪simple/level_connmgr.go鏂囦欢涓€� LevelConnManager鍏佽閽堝姣忎釜鑺傜偣娣诲姞涓€瀹氭暟閲忕殑杩炴帴锛岃嫢鑺傜偣杩炴帴鏁伴噺杈惧埌璁剧疆涓婇檺锛屽垯IsAllowed鏂规硶杩斿洖false銆� LevelConnManager灏嗚妭鐐硅繛鎺ュ垎涓轰袱绉嶄紭鍏堢骇锛氶珮浼樺厛绾с€佷綆浼樺厛绾с€傚叡璇嗚妭鐐广€佺瀛愯妭鐐瑰皢琚缃负楂樹紭鍏堢骇锛屽叾浠栬妭鐐瑰皢琚缃负浣庝紭鍏堢骇銆� 浼樺厛绾т笌鑺傜偣ID缁戝畾锛岄珮浼樺厛绾ц妭鐐规暟閲忎笌浣庝紭鍏堢骇鑺傜偣鏁伴噺涔嬪拰浣滀负鎬昏妭鐐硅繛鎺ユ暟閲忋€� 褰撴€昏妭鐐硅繛鎺ユ暟杈惧埌璁剧疆涓婄嚎鏃讹紝鑻ユ坊鍔犳柊鑺傜偣杩炴帴锛屽垯鏍规嵁璁剧疆鐨勬窐姹拌鍒欐窐姹颁竴涓妭鐐癸紙鍏抽棴璇ヨ妭鐐规墍鏈夎繛鎺ワ級銆� 鎴戜滑鎻愪緵浜嗕笁绉嶆窐姹扮瓥鐣ワ細Random銆丗IFO銆丩IFO銆� 1锛塕andom绛栫暐锛� 濡傛灉鏂拌妭鐐逛紭鍏堢骇涓洪珮锛屼紭鍏堥殢鏈烘窐姹颁竴涓綆浼樺厛绾ц妭鐐癸紝鑻ユ病鏈変綆浼樺厛绾ц妭鐐癸紝鍒欓殢鏈烘窐姹颁竴涓珮浼樺厛绾ц妭鐐广€� 濡傛灉鏂拌妭鐐逛紭鍏堢骇涓轰綆锛岄殢鏈烘窐姹颁竴涓綆浼樺厛绾ц妭鐐癸紝鑻ユ病鏈変綆浼樺厛绾ц妭鐐癸紝鍒欐窐姹拌鏂拌妭鐐广€� 2锛塅IFO 鍏堣繘鍏堝嚭绛栫暐锛� 濡傛灉鏂拌妭鐐逛紭鍏堢骇涓洪珮锛屼紭鍏堟窐姹颁竴涓渶鏃╂坊鍔犵殑浣庝紭鍏堢骇鑺傜偣锛岃嫢娌℃湁浣庝紭鍏堢骇鑺傜偣锛屽垯娣樻卑涓€涓渶鏃╂坊鍔犵殑楂樹紭鍏堢骇鑺傜偣銆� 濡傛灉鏂拌妭鐐逛紭鍏堢骇涓轰綆锛屾窐姹颁竴涓綆浼樺厛绾ц妭鐐癸紝鑻ユ病鏈変綆浼樺厛绾ц妭鐐癸紝鍒欐窐姹拌鏂拌妭鐐广€� 3锛� LIFO 鍚庤繘鍏堝嚭绛栫暐锛� 濡傛灉鏂拌妭鐐逛紭鍏堢骇涓洪珮锛屼紭鍏堟窐姹颁竴涓渶鏅氭坊鍔犵殑浣庝紭鍏堢骇鑺傜偣锛岃嫢娌℃湁浣庝紭鍏堢骇鑺傜偣锛屽垯娣樻卑璇ユ柊鑺傜偣銆� 濡傛灉鏂拌妭鐐逛紭鍏堢骇涓轰綆锛屾窐姹拌鏂拌妭鐐广€� ##### 杩炴帴鐘舵€佺淮鎶� 閾炬帴鐘舵€佺淮鎶ょ粍浠惰礋璐g洃鐫e繀瑕佽妭鐐癸紙鍏辫瘑鑺傜偣銆佺瀛愯妭鐐癸級涓庢湰鑺傜偣閾炬帴鐘舵€侊紝鑻ュ繀瑕佽妭鐐规湭涓庢湰鑺傜偣寤虹珛杩炴帴锛屽垯浼氬皾璇曚笌涔嬪缓绔嬫柊杩炴帴銆傛帴鍙e畾涔夊湪core/mgr/connmgr.go涓璵gr.ConnSupervisor interface銆� ###### 鍐呯疆杩炴帴鐘舵€佺淮鎶� Liquid鍐呯疆浜嗕竴绉嶈繛鎺ョ姸鎬佺淮鎶ゅ疄鐜扳€斺€攕imple.connSupervisor锛屽疄鐜颁唬鐮佸湪simple/conn_supervisor.go鏂囦欢涓€� simple.connSupervisor淇濆瓨浜嗗繀瑕佽妭鐐笽D鍙婂叾缃戠粶鍦板潃鍒楄〃锛屾瘡闅�5绉掍細鑷姩妫€鏌ュ繀瑕佽妭鐐逛笌鏈妭鐐硅繛鎺ョ姸鎬侊紝鑻ュ繀瑕佽妭鐐规湭涓庢湰鑺傜偣杩炴帴锛屽垯浼氬惎鍔ㄤ竴涓皾璇曡繛鎺ヤ换鍔★紝姣忛殧涓€娈垫椂闂达紙闂撮殧鏃堕棿鎸夌収鏂愭尝閭e闃熷垪瑙勫垯閫掑锛夊皾璇曚笌涔嬪缓绔嬭繛鎺ャ€傚鏋滄湁蹇呰鑺傜偣鏂紑杩炴帴锛屽垯浼氱珛鍗冲惎鍔ㄤ竴涓皾璇曡繛鎺ヤ换鍔°€� ##### 搴旂敤鍗忚绠$悊锛嗗簲鐢ㄥ崗璁氦鎹㈡満 搴旂敤鍗忚绠$悊缁勪欢璁板綍鐫€鏈妭鐐规墍鏀寔鐨勫簲鐢ㄥ崗璁垪琛ㄥ強搴旂敤鍗忚瀵瑰簲鐨勬秷鎭鐞嗗櫒锛屽簲鐢ㄥ崗璁鐞嗙粍浠惰繕璁板綍鐫€涓庢湰鑺傜偣寤虹珛杩炴帴鐨勮妭鐐规墍鏀寔鐨勫簲鐢ㄥ崗璁垪琛ㄣ€傛帴鍙e畾涔夊湪core/mgr/protocolmgr.go涓璵gr.ProtocolManager interface銆� 搴旂敤鍗忚浜ゆ崲鏈虹粍浠惰礋璐e皢鏈妭鐐规敮鎸佺殑鍗忚鍒楄〃涓庡叾浠栨鍦ㄨ繛鎺ョ殑鑺傜偣鐨勫崗璁垪琛ㄤ氦鎹紝褰撴湁鏂板簲鐢ㄥ崗璁敞鍐屾垨娉ㄩ攢鏃讹紝灏嗕細閲嶆柊鎶婃湰鑺傜偣鏀寔鐨勫崗璁垪琛ㄦ帹閫佺粰宸茶繛鎺ョ殑鍏朵粬鑺傜偣銆傚簲鐢ㄥ崗璁鐞嗙粍浠朵笌搴旂敤鍗忚浜ゆ崲鏈洪厤鍚堜娇鐢ㄦ潵鍚屾鑺傜偣闂存敮鎸佸簲鐢ㄥ崗璁垪琛ㄣ€傚綋鏀跺埌鏉ヨ嚜鍏朵粬鑺傜偣鏂版敞鍐屽簲鐢ㄥ崗璁垨鏂版敞閿€搴旂敤鍗忚鎺ㄩ€佹椂锛屼細閫氳繃鍥炶皟鏈哄埗閫氱煡宸叉敞鍐岀殑涓婂眰搴旂敤銆� 褰撳彂閫佹暟鎹椂锛屼細鍏堟鏌ュ鏂规槸鍚︽敮鎸佺浉搴斿簲鐢ㄥ崗璁紝鑻ヤ笉鏀寔锛屽垯杩斿洖閿欒銆傝繖鏍风殑鏈哄埗鍙互鍑忓皯鏃犳晥娑堟伅鍦ㄧ綉缁滀笂浼犳挱娆℃暟銆� ###### 鍐呯疆搴旂敤鍗忚绠$悊 Liquid鍐呯疆浜嗕竴绉嶈繛鎺ュ簲鐢ㄥ崗璁鐞嗗疄鐜扳€斺€攕imple.simpleProtocolMgr锛屽疄鐜颁唬鐮佸湪simple/protocolmgr.go鏂囦欢涓€� ###### 鍐呯疆搴旂敤鍗忚浜ゆ崲鏈� Liquid鍐呯疆浜嗕竴绉嶈繛鎺ュ簲鐢ㄥ崗璁氦鎹㈡満瀹炵幇鈥斺€攕imple.protocolExchanger锛屽疄鐜颁唬鐮佸湪simple/protocolmgr.go鏂囦欢涓€� simple.protocolExchanger浼氬悜Host娉ㄥ唽濡備笅protocol.ID锛屽紑鍙戣€呭紑鍙戜笂灞傚簲鐢ㄦ椂搴旈伩鍏嶄笌涔嬪啿绐併€� > /protocol-exchanger/v0.0.1 ##### 娴佺鐞� 鏈夋椂鎴戜滑浼氶亣鍒拌繖绉嶅満鏅細涓や釜鑺傜偣涔嬮棿闇€瑕佸垱寤哄涓暟鎹€氳矾鏉ュ尯鍒嗕笉鍚岀殑涓氬姟锛屾瘮濡備袱涓妭鐐逛箣闂存湁涓ょ娑堟伅绫诲瀷锛屾垜浠笇鏈涘儚kafka鐨刾artition涓€鏍峰垎闅斾笖椤哄簭鐨勫鐞嗚繖涓ょ娑堟伅銆傛渶绠€鍗曠殑鏂规硶鏄垱寤轰袱涓猅CP杩炴帴锛屼絾鏄崟绾殑澧炲姞TCP杩炴帴浼氬鑷翠笉蹇呰璧勬簮鐨勬氮璐癸紙姣斿绔彛鍗犵敤锛岃繛鎺ユ睜澧炲ぇ锛夈€俵iquid寮曞叆浜嗏€滄祦鈥濈殑姒傚康锛岄€氳繃澶氭祦澶嶇敤鏉ヨВ鍐宠繖涓棶棰樸€� 杩欓噷鐨勫娴佸鐢紝鍗充袱涓妭鐐逛箣闂存湁涓€涓繛鎺ワ紝浣嗘槸鍙互鏈夊涓祦锛屾瘡涓祦鍦ㄥ簲鐢ㄥ眰鍙互瑙嗕负涓€涓嫭绔嬬殑涓茶鍙屽伐閫氶亾锛屼絾鏄湪浼犺緭灞傚叡鐢ㄤ竴涓猼cp鎴杣dp杩炴帴銆� 缁间笂鎵€杩帮細澶氭祦鏈川涓婃槸瀵瑰簲鐢ㄥ眰鐨勫鐢紝澧炲己浜嗗簲鐢ㄥ眰鐨勫苟鍙戞€с€傚湪浼犺緭鏂归潰锛屽疄闄呬笂杩樻槸鍚屼竴鏉$墿鐞嗛摼鎺ワ紝杩樻槸椤哄簭鍙戦€佺殑銆� 寮曞叆娴佺殑鍚屾椂锛宭iquid杩樻彁渚涗簡涓変釜缁勪欢鏉ュ府鍔╃鐞嗘祦銆� 娴佺鐞嗙粍浠朵富瑕佹湁涓変釜閮ㄥ垎缁勬垚锛氬彂閫佹祦姹狅紙SendStreamPool锛夈€佸彂閫佹祦姹犵鐞嗭紙SendStreamPoolManager锛夈€佹帴鏀舵祦绠$悊锛圧eceiveStreamManager锛夈€� 1锛夊彂閫佹祦姹狅紙SendStreamPool锛夛細 鍙戦€佹祦姹犺礋璐g鐞嗚繛鎺ユ墍鍒涘缓鐨勬墍鏈夊彂閫佹祦锛屾瘡涓繛鎺ュ搴斿垱寤轰竴涓彂閫佹祦姹狅紝鍦ㄥ垱寤烘椂鍙垵濮嬪寲涓€瀹氭暟閲忕殑鍙戦€佹祦锛屽綋姹犱腑绌洪棽鍙戦€佹祦鏁伴噺浣庝簬闃堝€间笖鎬诲彂閫佹祦鏁伴噺浣庝簬鍏佽鐨勬渶澶у€兼椂锛屽彂閫佹祦姹犱細鑷姩鍒涘缓涓€瀹氭暟閲忔柊鐨勫彂閫佹祦銆傚鏋滃彂閫佹祦鍦ㄥ彂閫佽繃绋嬩腑鍙戠敓閿欒锛屽垯閫氳繃DropStream鏂规硶寮冪敤璇ュ彂閫佹祦銆傚鏋滆繛鎺ュ叧闂紝鍒欎細寮冪敤鎵€鏈夊彂閫佹祦骞跺叧闂彂閫佹祦姹犮€� 鍙戦€佹祦姹犳帴鍙e畾涔夊湪core/mgr/streammgr.go涓璵gr.SendStreamPool interface銆� 2锛夊彂閫佹祦姹犵鐞嗭紙SendStreamPoolManager锛夛細 鍙戦€佹祦姹犵鐞嗙粍浠惰礋璐g鐞嗕笌鍏朵粬鎵€鏈夎妭鐐瑰缓绔嬬殑鎵€鏈夎繛鎺ョ殑鍙戦€佹祦姹犮€傚湪鍚戞煇鑺傜偣鍙戦€佹暟鎹椂锛屼細浠庡彂閫佹祦姹犵鐞嗙粍浠惰幏鍙栬礋杞芥渶浣庣殑杩炴帴瀵瑰簲鐨勫彂閫佹祦姹犲€熶竴涓彂閫佹祦鍙戦€佹暟鎹€� 鍙戦€佹祦姹犵鐞嗙粍浠舵帴鍙e畾涔夊湪core/mgr/streammgr.go涓璵gr.SendStreamPoolManager interface銆� 3锛夋帴鏀舵祦绠$悊锛圧eceiveStreamManager锛� 鎺ユ敹娴佺鐞嗙粍浠惰礋璐g鐞嗕笌鍏朵粬鎵€鏈夎妭鐐瑰缓绔嬬殑鎵€鏈夎繛鎺ヤ笂鎺ュ彈鐨勬墍鏈夋帴鏀舵祦銆傚鏋滄煇涓繛鎺ュ叧闂紝鍒欎細鍏抽棴璇ヨ繛鎺ョ殑鎵€鏈夋帴鏀舵祦銆� 鎺ユ敹娴佺鐞嗙粍浠舵帴鍙e畾涔夊湪core/mgr/streammgr.go涓璵gr.ReceiveStreamManager interface. ###### 鍐呯疆娴佺鐞� Liquid鍐呯疆娴佺鐞嗗疄鐜帮細 鍙戦€佹祦姹犫€斺€攕imple.sendSteamPool锛屽疄鐜颁唬鐮佸湪simple/streammgr_sendstreampool.go涓€� 鍙戦€佹祦姹犵鐞嗏€斺€攕imple.sendStreamPoolManager锛屽疄鐜颁唬鐮佸湪simple/streammgr_sendstreampoolmgr.go涓€� 鎺ユ敹娴佺鐞嗏€斺€攕imple.receiveStreamManager锛屽疄鐜颁唬鐮佸湪simple/streammgr_receivestreammgr.go涓€� ##### 榛戝悕鍗� 榛戝悕鍗曠粍浠剁敤浜庢帶鍒舵嫆缁濇煇浜涜繛鎺ュ垱寤鸿姹傦紝榛戝悕鍗曢噷鍙互鏄妭鐐笽D鎴朓P鍦板潃鎴朓P鍦板潃+绔彛銆� 榛戝悕鍗曟帴鍙e畾涔夊湪core/blacklist/blacklist.go涓璪lacklist.BlackList interface銆� Liquid鍐呯疆榛戝悕鍗曞疄鐜扳€斺€攕imple.simpleBlackList锛屽疄鐜颁唬鐮佸湪simple/blacklist.go涓€� ##### 鑺傜偣淇℃伅绠$悊 鑺傜偣淇℃伅绠$悊锛圥eerStore锛変富瑕佽礋璐h褰曟墍鏈夎妭鐐圭殑缃戠粶鍦板潃鍒楄〃鍙婃敮鎸佺殑搴旂敤鍗忚鍒楄〃銆� 鑺傜偣淇℃伅绠$悊鎺ュ彛瀹氫箟鍦╟ore/store/store.go涓璼tore.PeerStore interface銆� Liquid鍐呯疆鑺傜偣淇℃伅绠$悊瀹炵幇鈥斺€攕imple.SimplePeerStore锛屽疄鐜颁唬鐮佸湪simple/peerstore.go涓€� ### 搴旂敤灞� #### 鍐呯疆PubSub Liquid鏍稿績鍖呮湁涓篜ubSub瀹氫箟鎺ュ彛锛屽湪core/broadcast/pubsub.go涓璪roadcast.PubSub interface銆� Liquid鍐呯疆浜嗕竴涓鎺ュ彛鐨勫疄鐜扳€斺€攑ubsub.ChainPubSub銆侰hainPubSub鏄熀浜庡簲鐢ㄥ崗璁疄鐜扮殑閾剧骇鏁版嵁闅旂娑堟伅鍙戝竷鍙婅闃呮湇鍔°€侰hainPubSub浠g爜鍦╬ubsub鍖呬腑銆� ChainPubSub灏嗚妭鐐归棿杩炴帴鍏崇郴鍒掑垎涓篎ullMsg銆丮etaDataOnly銆丗anOut涓夌鐘舵€併€傚綋鏌愪竴鑺傜偣鍙戝竷娑堟伅鏃讹紝FullMsg杩炴帴浼氫紶杈撳叏閲忔暟鎹紱MetaDataOnly杩炴帴浼氫紶杈撳厓鏁版嵁锛汧anOut杩炴帴浼氫紶杈撳叏閲忔暟鎹€傚厓鏁版嵁鍙互鐞嗚В涓轰粎鍖呭惈娑堟伅鐨勫師濮嬪垱寤鸿€呭拰娑堟伅鐨勭紪鍙凤紝涓嶅寘鍚缁嗕俊鎭€侰hainPubSub浣跨敤绫籊ossip杩涜杈呭姪浼犳挱绛夈€� 鍏充簬FanOut锛氬亣濡傛湁杩欐牱涓€涓儏鍐碉紝鑺傜偣A璁㈤槄浜唗opicA锛屼絾鏄拰A鏈夎繛鎺ョ殑鑺傜偣閮芥病鏈夎闃卼opicA锛岄偅A鍦ㄨtopic涓婂彂甯冧竴涓秷鎭紝鎬庝箞浼犳挱鍒版暣涓綉缁滐紵绛旀灏辨槸FanOut銆侳anOut杩炴帴浼氫紶杈撳叏閲忔暟鎹紝涓斿厑璁歌繛鎺ヤ腑鐨勪竴涓妭鐐规病鏈夎闃呭搴旂殑topic銆傚鏋滆鑺傜偣鐢辨湭璁㈤槄杞崲鎴愬凡璁㈤槄锛孎anOut浼氱珛鍒诲崌绾т负FullMsg杩炴帴銆傚悓鐞嗗浜嶧ullMsg杩炴帴鐨勮妭鐐瑰鏋滃彇娑堣闃咃紝鍒欎細闄嶇骇涓篎anOut杩炴帴銆傝繖绉嶈繛鎺ョ姸鎬佸湪淇濇寔鍏ㄩ噺娑堟伅浼犺緭鐨勫悓鏃讹紝杩樿捣鍒颁簡鏍囪瘑鑺傜偣鏄惁璁㈤槄鐨勪綔鐢ㄣ€� 涓轰簡婊¤冻chainmaker澶氶摼鏁版嵁闅旂闇€姹傦紝ChainPubSub宸у鐨勫熀浜庡簲鐢ㄥ崗璁師鐢熸敮鎸佸閾炬暟鎹殧绂汇€� ChainPubSub浼氬悜Host娉ㄥ唽濡備笅鏍煎紡鐨刾rotocol.ID锛屽紑鍙戣€呭紑鍙戜笂灞傚簲鐢ㄦ椂搴旈伩鍏嶄笌涔嬪啿绐併€� > /chain-pubsub/v0.0.1/chain-%s #### 鍐呯疆鑺傜偣鍙戠幇鏈嶅姟 涓€涓妭鐐规兂瑕佸姞鍏ユ暣涓猵2p缃戠粶锛岄渶瑕佸拰绉嶅瓙鑺傜偣鍒涘缓杩炴帴锛屼絾鏄瀛愯妭鐐圭殑鏁伴噺鏈夐檺锛岄€氬父闇€瑕佸拰鍏朵粬闈炵瀛愯妭鐐瑰垱寤鸿繛鎺ワ紝鎵嶈兘杈惧埌瓒冲鐨勮繛鎺ユ暟閲忋€傚浣曡涓€涓妭鐐癸紝鍙戠幇鍏朵粬鑺傜偣鐨勭綉缁滃湴鍧€锛屽氨鏄妭鐐瑰彂鐜版湇鍔¢渶瑕佸疄鐜扮殑鍔熻兘銆� liquid鐨勮妭鐐瑰彂鐜版湇鍔★紝鍏舵帴鍙e畾涔夊湪core/discovery/discovery.go涓璬iscovery.Discovery interface銆� Liquid鍐呯疆浜嗕竴涓鎺ュ彛鐨勫疄鐜扳€斺€攑rotocoldiscovery.ProtocolBasedDiscovery銆侾rotocolBasedDiscovery鏄熀浜庡簲鐢ㄥ崗璁敞鍐岃凯浠f煡璇㈠疄鐜扮殑鑺傜偣鍙戠幇鏈嶅姟銆侾rotocolBasedDiscovery婧愪唬鐮佸湪discovery/protocoldiscovery鍖呬腑銆� ProtocolBasedDiscovery浼氬悜Host娉ㄥ唽濡備笅鏍煎紡鐨刾rotocol.ID锛屽紑鍙戣€呭紑鍙戜笂灞傚簲鐢ㄦ椂搴旈伩鍏嶄笌涔嬪啿绐併€� > /chain-discovery/v0.0.1/%s 姣忎釜liquid鑺傜偣锛屼細瀹氭椂鍚戝叾浠栧凡寤鸿仈鐨勮妭鐐瑰彂閫佹煡鎵捐姹傦紝鍏朵粬鑺傜偣浼氫粠鑷繁鐨勮繛鎺ュ垪琛ㄩ噷鎵惧嚭鍗忚鐩稿悓鐨勮妭鐐逛俊鎭紙id鍜屽湴鍧€锛夛紝浣滀负鍝嶅簲杩斿洖缁欏彂閫佽姹傜殑閭d釜鑺傜偣锛岃鑺傜偣鏀跺埌鍝嶅簲鍚庝細涓茶閬嶅巻鑺傜偣淇℃伅骞跺皾璇曡繛鎺ワ紝鐩村埌杩炴帴绠$悊妯″潡鍙戠幇杩炴帴鏁伴噺宸茬粡绗﹀悎棰勬湡涓烘銆� 浣嗘槸浠呬粎杩欐牱鎵ц浼氬嚭鐜拌澶氶棶棰橈紝姣斿鍝嶅簲涓細鏈夐噸澶嶇殑鑺傜偣淇℃伅锛屾垨鑰呭搷搴斾腑鐨勬煇涓妭鐐圭殑杩炴帴鏁伴噺宸茶揪鍒颁笂闄愩€傚浜庡墠鑰咃紝liquid浼氳褰曟渶杩戝皾璇曡繛鎺ヨ繃浣嗗け璐ョ殑鑺傜偣id锛岀煭鏈熷唴涓嶄細鍐嶆杩炴帴杩欎簺鑺傜偣銆傚浜庡悗鑰咃紝liquid浼氱淮鎶や竴涓繛鎺ヨ揪鍒颁笂闄愮殑鑺傜偣鍒楄〃鏉ヨВ鍐宠繖涓棶棰橈紝閭d簺杩炴帴鏁伴噺宸茶揪涓婇檺鐨勮妭鐐逛細閫氱煡鍏朵粬鑺傜偣锛岃嚜宸辩殑杩炴帴鏁伴噺宸叉弧銆傚叾浠栬妭鐐瑰皢涓嶄細鎶婅繖绉嶈妭鐐规斁鍏ュ搷搴斿垪琛ㄤ腑銆� #### 娑堟伅浼樺厛绾� 鍦ㄥ尯鍧楅摼涓紝鍚屾鍜屽叡璇嗘槸鑺傜偣涔嬮棿鏈€棰戠箒鐨勪袱涓搷浣溿€傚鏋滀笉鍖哄垎浼樺厛绾э紝浠荤敱涓よ€呯浉浜掓姠澶虹綉缁滆祫婧愶紝浼氫弗閲嶅奖鍝嶆暣涓猵2p缃戠粶鐨勬晥鐜囥€� liquid涓烘璁捐浜嗘秷鎭紭鍏堢骇锛岄€氳繃涓€绉嶅彂绁ㄧ殑鏂瑰紡锛岃楂樹紭鍏堢骇娑堟伅浼樺厛浣跨敤缃戠粶璧勬簮姣斿TCP杩炴帴銆傚嵆姣忎竴娆′粠楂樺埌浣庯紝缁欓珮浼樺厛绾ф秷鎭彂绁紝璁╄娑堟伅"鎸佺エ"閫氳繃锛岀洿鍒伴珮浼樺厛绾ф秷鎭叏閮ㄩ€氳繃锛屽啀渚濇闄嶄綆浼樺厛绾э紝璁╀綆浼樺厛绾ф秷鎭�"鎸佺エ"閫氳繃銆傚悓鏃朵负浜嗛槻姝㈣繖浜�"vip浠�"鏃犻檺鍗犵敤璧勬簮锛宭iquid姣忕粡杩囦竴瀹氱殑娆℃暟锛屼細缁欎綆浼樺厛绾ф秷鎭€傚綋鍙戠エ锛岄伩鍏嶄粬浠棤闄愮瓑寰呫€傝繖鏍锋棦璁╁叡璇嗘ā鍧楁洿蹇殑鎵撳寘銆佹墽琛屽叡璇嗐€佸嚭鍧楋紝鍙堥伩鍏嶅叾浠栨秷鎭棤闄愰樆濉炴渶缁堚€滈タ姝烩€濄€� ### 涓巆hainmaker闆嗘垚 #### LiquidNet LiquidNet鏄痗hainmaker鐨� Net interface鐨勫疄鐜帮紝浠g爜鍦╨iquid_net.go涓€� LiquidNet宸茶闆嗘垚鍦╟hainmaker-go涓紝鍏蜂綋璇﹁chainmaker-go/module/net/net_factory.go銆� <span id="relay_introduce"></span> ### 涓户Relay Liquid Relay锛堜腑缁э級鐨勪娇鐢ㄥ拰閰嶇疆[璇锋煡鐪婸2P缃戠粶绠$悊-Relay锛堜腑缁э級绔犺妭](../manage/P2P缃戠粶绠$悊.md) ChainMaker鐨凱2P缃戠粶姣忎竴涓妭鐐瑰嵆鍙互鏄鎴风鍙堝彲浠ユ槸鏈嶅姟绔紝濡傛灉鎵€鏈夌殑鑺傜偣閮藉浜庣浉鍚岀殑缃戠粶鐜涓紝涓€鑸笉浼氬嚭鐜伴棶棰樸€傚綋涓嶅悓鐨勮妭鐐逛綅浜庝笉鍚岀殑鍐呯綉鐜涓紝鑺傜偣涓庤妭鐐逛箣闂撮€氫俊鍙兘浼氶亣鍒伴樆纰嶃€備緥濡備笅鍥炬墍绀猴細  鍋囪node1鍜宯ode2鍦ㄥ唴缃�1涓紝鑰宯ode3鍜宯ode4鍦ㄥ唴缃�2涓紝杩欐椂鍊檔ode1鍜宯ode2鍙互閫氳繃鍐呯綉鍦板潃杩炴帴閫氫俊锛宯ode3鍜宯ode4鍙互閫氳繃鍐呯綉鍦板潃杩炴帴閫氫俊銆備絾鏄唴缃�1涓殑node1鍜宯ode2锛屾兂瑕佷笌鍐呯綉2涓殑node3鍜宯ode4寤虹珛P2P缃戠粶锛屽氨蹇呴』鐭ラ亾node3鍜宯ode4鐨勬槧灏勭殑澶栫綉鍦板潃锛屼笉鐒舵牴鏈棤娉曟壘鍒皀ode3鍜宯ode4涓庡叾閫氫俊銆� #### Relay鐨勫姛鑳� Liquid缃戠粶鎻愪緵浜嗕腑缁ц浆鍙戠殑鍔熻兘锛屽綋涓や釜鑺傜偣鍥犱负缃戠粶鐜鐨勫師鍥狅紝涓嶈兘鐩存帴杩炴帴锛屽彲浠ュ埄鐢ㄤ腑缁ц妭鐐癸紝瀵规祦閲忔暟鎹繘琛岃浆鍙戯紝浠庤€岃揪鍒扮偣瀵圭偣浼犺緭鐨勬晥鏋溿€傚涓嬪浘绀猴細  #### Relay鐨勫熀鏈祦绋� Relay鐨勫師鐞嗘瘮杈冪畝鍗曪紝鍋囪涓户鑺傜偣涓篟锛孉鑺傜偣鍙互鎷ㄥ彿杩炴帴鍒颁腑缁ц妭鐐筊锛孊鑺傜偣鍙互鎷ㄥ彿杩炴帴鍒颁腑缁ц妭鐐筊锛孉鑺傜偣閫氳繃涓户鑺傜偣R锛屽皢鏁版嵁杞彂鍒癇鑺傜偣锛岃繖鏍蜂娇A鍜孊鑺傜偣涔熻兘鍋氬埌鏁版嵁浜や簰銆� 涓嬮潰寮曠敤libp2p涓户娴佺▼鎻忚堪锛� - phase I: Open a request for a relayed stream (A to R). - A dials a new stream `sAR` to R using protocol `liquid-relay`. - A sends a CircuitRelay message with `{ type: 'HOP', srcPeer: '/p2p/QmA', dstPeer: '/p2p/QmB' }` to R through `sAR`. - R receives stream `sAR` and reads the message from it. - phase II: Open a stream to be relayed (R to B). - R opens a new stream `sRB` to B using protocol `liquid-relay`. - R sends a CircuitRelay message with `{ type: 'STOP', srcPeer: '/p2p/QmA', dstPeer: '/p2p/QmB' }` on `sRB`. - R sends a CircuitRelay message with `{ type: 'STATUS', code: 'SUCCESS' }` on `sAR`. - phase III: Streams are piped together, establishing a circuit - B receives stream `sRB` and reads the message from it - B sends a CircuitRelay message with `{ type: 'STATUS', code: 'SUCCESS' }` on `sRB`. - B passes stream to `NewConnHandler` to be handled like any other new incoming connection. 鍦ㄥ尯鍧楅摼涓垜浠渶瑕侀伒寰换浣曚簨鐗╅兘鏄笉鍙俊鐨勫師鍒欙紝涓户鑺傜偣涔熶笉渚嬪銆備腑缁ц妭鐐逛綔涓鸿浆鍙戣€咃紝鑲畾鏄笉鑳藉厑璁稿叾鏈変綔鎭惰兘鍔涚殑銆傛垜浠€氳繃浠ヤ笅涓ょ偣闃叉涓户鑺傜偣浣滄伓锛� 1. 涓户鑺傜偣鏈韩灏卞睘浜庣綉缁滄垚鍛橈紝闇€瑕佽窡鍏朵粬鑺傜偣tls鎻℃墜寤虹珛杩炴帴鎵嶈兘宸ヤ綔銆� 2. 涓户杩囩▼灞炰簬绔埌绔姞瀵嗙殑锛屼篃灏辨槸琚腑缁ц妭鐐逛箣闂寸殑鏁版嵁浼犺緭杩樻槸鍔犲瘑鐨勶紝涓户鑺傜偣鍙槸璐熻矗杞彂鍔犲瘑鍚庣殑瀵嗘枃銆� 缁间笂鎵€杩帮紝鍏蜂綋鐨勪腑缁ф祦绋嬪浘濡備笅锛�  ### NAT绌块€� NAT锛圢et Address Translation锛夛紝鎸囩綉缁滃湴鍧€杞崲銆� NAT绌块€忥紙NAT traversal锛夛紝鍙互绠€鍗曠悊瑙d负锛氬湪涓嶅崟鐙慨鏀筃AT绛栫暐鐨勬儏鍐典笅锛屽浜庝娇鐢ㄤ簡NAT璁惧鐨勭鏈夌綉缁滀腑鐨勪富鏈轰箣闂村缓绔嬬綉缁滆繛鎺ャ€� Liquid NAT绌块€忕殑浣跨敤鍜岄厤缃甗璇锋煡鐪婸2P缃戠粶绠$悊-NAT绔犺妭](../manage/P2P缃戠粶绠$悊.md) #### NAT绌块€忓姛鑳� liquid鎻愪緵NAT绌块€忓姛鑳斤紝tcp鍜寀dp锛堝寘鎷琿uic锛夊潎閫傜敤銆� 澶勪簬NAT璁惧鐨勭鏈夌綉缁滅殑涓や釜涓绘満锛堝彲浠ユ槸鏈烘埧鐨勬湇鍔″櫒鎴栬€呮槸浣跨敤灏忓尯瀹藉甫鐨勪釜浜虹數鑴戯級锛岄€氬父鏄棤娉曠洿鎺ュ垱寤虹綉缁滆繛鎺ョ殑锛孨AT绌块€忔妧鏈彲浠ヨВ鍐宠繖涓€鐩磋繛闂銆� NAT绫诲瀷鍙互绠€鍗曞垎涓�4绉嶏細瀹屽叏閿ュ瀷锛堝叏閿ュ瀷锛夛紝鍙楅檺閿ュ瀷锛岀鍙e彈闄愰敟鍨嬶紝瀵圭О鍨嬨€傜綉涓婃湁澶氱NAT妫€娴嬪伐鍏凤紝鏈枃涓嶅鍋氳禈杩般€� NAT绌块€忛€傜敤浜庣粷澶ч儴鍒嗗満鏅紙骞堕潪鎵€鏈夊満鏅紒锛夈€備笅鍥句腑锛屽墠8绉嶇粍鍚堟槸鍙互閫氳繃鎵撴礊鏉ュ疄鐜癗AT绌块€忕殑锛屾渶鍚�2绉嶇粍鍚堟棤娉曠┛閫忥細  #### NAT绌块€忔祦绋� NAT绌块€忕殑鍩烘湰娴佺▼鏄細閫氳繃鐩镐簰鍙戦€佺綉缁滄姤鏂囷紝鍦∟AT璁惧涓暀涓嬬浉搴旂殑缂撳瓨锛屾渶缁堝缓绔嬬綉缁滆繛鎺ャ€� 涓嬪浘鎻忚堪浜嗕袱涓妭鐐圭殑NAT绌块€忔祦绋嬶細  <br> <br>