Section2.4 fabric message structure

我们要实现的peer.go中函数接受*pb.Message类型的消息,消息定义在fabric.pb.go

type Message struct {  
        Type      Message_Type  
        Timestamp *google_protobuf.Timestamp  
        Payload   []byte  
        Signature []byte    
}

其中Type为消息类型,其值为uint类型,Timestamp为时间戳,Payload为消息内容的编码,Signature为签名。 Payload消息内容编码之前有一下几种类型:

type Message_RequestBatch struct {
    RequestBatch *RequestBatch
}
type Message_PrePrepare struct {
    PrePrepare *PrePrepare 
}
type Message_Prepare struct {
    Prepare *Prepare 
}
type Message_Commit struct {
    Commit *Commit 
}
type Message_Checkpoint struct {
    Checkpoint *Checkpoint 
}
type Message_ViewChange struct {
    ViewChange *ViewChange 
}
type Message_NewView struct {
    NewView *NewView 
}
type Message_FetchRequestBatch struct {
    FetchRequestBatch *FetchRequestBatch
}
type Message_ReturnRequestBatch struct {
    ReturnRequestBatch *RequestBatch 
}

1、RequestBatch类型的 batch.go 145行:给出Payload和Type

func (op *obcBatch) broadcastMsg(msg *BatchMessage) {
    msgPayload, _ := proto.Marshal(msg)
    ocMsg := &pb.Message{
        Type:    pb.Message_CONSENSUS,
        Payload: msgPayload,
    }
    op.broadcaster.Broadcast(ocMsg)
}

batch.go 135行:Payload取自这儿

func (op *obcBatch) submitToLeader(req *Request) events.Event {
    ...
    op.broadcastMsg(&BatchMessage{Payload: &BatchMessage_Request{Request: req}})
    ...
}

batch.go 445行:打包成批

func (op *obcBatch) wrapMessage(msgPayload []byte) *pb.Message {
    batchMsg := &BatchMessage{Payload: &BatchMessage_PbftMessage{PbftMessage: msgPayload}}
    packedBatchMsg, _ := proto.Marshal(batchMsg)
    ocMsg := &pb.Message{
        Type:    pb.Message_CONSENSUS,
        Payload: packedBatchMsg,
    }
    return ocMsg
}

2、Preprepare类型的 pbft-core 659行:此处获得Payload

func (instance *pbftCore) sendPrePrepare(reqBatch *RequestBatch, digest string) {
        ...
    instance.seqNo = n
    preprep := &PrePrepare{
        View:           instance.view,
        SequenceNumber: n,
        BatchDigest:    digest,
        RequestBatch:   reqBatch,
        ReplicaId:      instance.id,
    }
    cert := instance.getCert(instance.view, n)
    cert.prePrepare = preprep
    cert.digest = digest
    instance.innerBroadcast(&Message{Payload: &Message_PrePrepare{PrePrepare: preprep}})
    ...
}

batch.go 445行:对Payload进行进一步的包装并给出消息类型Type

func (op *obcBatch) wrapMessage(msgPayload []byte) *pb.Message {
    batchMsg := &BatchMessage{Payload: &BatchMessage_PbftMessage{PbftMessage: msgPayload}}
    packedBatchMsg, _ := proto.Marshal(batchMsg)
    ocMsg := &pb.Message{
        Type:    pb.Message_CONSENSUS,
        Payload: packedBatchMsg,
    }
    return ocMsg
}

3、PreparecommitCheckpointViewChange类型的和Preprepare消息产生的过程类似, pbft-core.go 693行 recvPrePrepare方法中获得Prepare类型的Payloadpbft-core.go 798行 maybeSendCommit方法中获得commit类型的Payloadpbft-core.go 958行 Checkpoint方法中获得checkpoint类型的Payloadviewchange.go 125行 sendViewChange方法中获得ViewChange类型的Payload,和对消息的签名, viewchange.go 257行 sendNewView方法中获得NewView类型的Payloadpbft-core.go 1222行 fetchRequestBatches方法中获得FetchRequestBatch类型的Payload, 然后都是经过一系列的调用后经过wrapMessagePayload进行进一步的包装并给出消息类型Type

Last updated

Was this helpful?