zoukankan      html  css  js  c++  java
  • 超级账本fabric原理之gossip详解

    Goosip协议

    去中心化、容错和最终一致性的算法
    信息达到同步的最优时间:log(N)。

    功能
    节点发现
    数据广播

    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更新本地

    说到底,gossip服务是处理消息的,每种类型的消息有不同的用途

    消息类型

    gossip服务使用不同模块处理不同类型的消息。消息类型原型在/protos/message.proto中定义。gossip中传播的消息以GossipMessage形式传递,具体的消息数据存放在GossipMessage中的Content成员中。

    节点关系消息

    与频道成员身份、关系和存续相关的消息类型。
    AliveMessage - alive消息
    MembershipRequest - 成员关系请求消息
    MembershipResponse -成员关系应答消息

    pull机制消息

    pull进来的可以是以块数据为内容的消息,也可以是身份数据为内容的消息,下述4种消息中都有一个成员MsgType来表明这个消息中所携带的数据内容。从pull步骤上分为四种:
    GossipHello - hello消息
    DataDigest - 消息摘要
    DataRequest - 摘要请求
    DataUpdate - 摘要应答

    state消息

    和状态有关的消息。这里的状态指的是chain的数据状态,如一个结点所存储的块数据是否一致,可以说这里所谓的状态接近数据的意思。
    StateInfo - 状态消息
    DataMessage - 数据消息(block)
    TransactionMessage - 交易数据;

    辅助类消息

    这类消息不承担具体传送传播数据的任务,而是辅助性的:
    Empty - 空消息,用于结点间的Ping(来测试结点是否连通)和测试。
    ConnEstablish - 用于gossip之间的握手,即任何时候一个peer想与另一个peer连接通信,都需要先发送这个消息以证明其身份。

    gossip模块

    主要功能

    gossip部分接口

    type Gossip interface {
    	// Send sends a message to remote peers
    	Send(msg *proto.GossipMessage, peers ...*comm.RemotePeer)
    	// GetPeers returns the NetworkMembers considered alive
    	Peers() []discovery.NetworkMember
    
    	// PeersOfChannel returns the NetworkMembers considered alive
    	// and also subscribed to the channel given
    	PeersOfChannel(common.ChainID) []discovery.NetworkMember
    	// UpdateLedgerHeight updates the ledger height the peer
    	// publishes to other peers in the channel
    	UpdateLedgerHeight(height uint64, chainID common.ChainID)
    
    	// Gossip sends a message to other peers to the network
    	Gossip(msg *proto.GossipMessage)
    	
    	// Accept returns a dedicated read-only channel for messages sent by other nodes that match a certain predicate.
    	// If passThrough is false, the messages are processed by the gossip layer beforehand.
    	// If passThrough is true, the gossip layer doesn't intervene and the messages
    	// can be used to send a reply back to the sender
    	Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan proto.ReceivedMessage)
    
    	// JoinChan makes the Gossip instance join a channel
    	JoinChan(joinMsg api.JoinChannelMessage, chainID common.ChainID)
    
    	// LeaveChan makes the Gossip instance leave a channel.
    	// It still disseminates stateInfo message, but doesn't participate
    	// in block pulling anymore, and can't return anymore a list of peers
    	// in the channel.
    	LeaveChan(chainID common.ChainID)
    	
    	// Stop stops the gossip component
    	Stop()
    }
    

    主要模块

    初始化和服务启动

    消息广播

    PeerA通过gossip协议广播消息,PeerB为其中一个消息接收节点。

    代码应用框架

    //初始化并加入通道‘A’
    gossip = NewGossipInstance(15000, 1, 1000, isBoot)
    gossip.JoinChan(&JoinChanMsg{}, common.ChainID("A"))
    gossip.UpdateLedgerHeight(1, common.ChainID("A"))
    acceptChan, _ := gossip.Accept(AcceptData, false) //AcceptData未消息选择器
    	
    //通过gossip的方式来发送消息
    gossip.Gossip(msg *pb.GossipMessage)
    

    注:gossip发送消息后,对端节点接收到消息,会把过滤的消息坊到accetpChan通道中。

    gossip pull机制

    消息类型

    pull机制主要涉及四种消息类型
    GossipHello - hello消息
    DataDigest - 消息摘要
    DataRequest - 摘要请求
    DataUpdate - 摘要应答
    具体pull的内容包括: 未定义消息,块消息,身份消息

    初始化

    pull机制的四个步骤

    关键参数和函数

    PullPeerNum //从PullPeerNum个节点pull数据
    PullInterval //pull引擎每隔PullInterval开始一次pull同步
    
    createBlockPuller: //创建pull.Mediator
    - IngressDigFilter(大于本地高度的区块)//用来过滤digest,返回自己要同步数据的摘要
    - IdExtractor: seqNumFromMsg //要同步数据的唯一标识
                        
    

    注: IDExtractor是个接口,区块数据用块高标识;身份数据用证书或者公钥相关数据表示

  • 相关阅读:
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 697 数组的度(类似于数组的map)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 696 计数二进制子串(暴力)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    Java实现 LeetCode 695 岛屿的最大面积(DFS)
    PHP serialize() 函数
    PHP print_r() 函数
  • 原文地址:https://www.cnblogs.com/informatics/p/10417173.html
Copyright © 2011-2022 走看看