Hyperledger Fabric 排序節點處理 Deliver 請求的過程

來源:互聯網
上載者:User

Hyperledger 源碼分析之 Fabric

Deliver,意味著用戶端通過 gRPC 介面從 Ordering 服務擷取資料(例如指定區塊的資料)。

Orderer 節點收到請求訊息,會首先交給 orderer.common.server 包中 server 結構體的 Deliver(srv ab.AtomicBroadcast_DeliverServer) error 方法處理。該方法進一步調用 orderer.common.deliver 包中 deliverServer 結構的 Handle(srv ab.AtomicBroadcast_DeliverServer) error 方法進行處理。

deliverServer 結構體十分重要,完成對 Deliver 請求的處理過程。

type deliverServer struct {    sm SupportManager}func (ds *deliverServer) Handle(srv ab.AtomicBroadcast_DeliverServer) error
整體過程

整體處理過程如下圖所示。


Handle(srv ab.AtomicBroadcast_DeliverServer) error 方法會開啟一個迴圈來從 srv 中不斷讀取請求訊息並進行處理,直到結束。

核心代碼如下所示,包括提取訊息和對訊息進行處理兩個步驟。

for {    envelope, err := srv.Recv() // 從請求中提取一個 Envelope 訊息    ds.deliverBlocks(srv, envelope) // 對訊息進行處理並回覆,核心過程}

可見,對單個請求的處理都在 deliverBlocks(srv ab.AtomicBroadcast_DeliverServer, envelope *cb.Envelope) 方法中。該方法的處理過程包括解析訊息、檢查合法性、發送區塊以及返迴響應四個步驟。

下面具體對其進行具體分析。 解析訊息

首先,從請求的 Envelope 結構中提取載荷(Payload),進一步從載荷中提取通道頭部資訊。利用通道頭部資訊擷取對應的本地鏈結構,並擷取當前最新的配置序號。

// 提取載荷payload, err := utils.UnmarshalPayload(envelope.Payload)// 提取通道頭chdr, err := utils.UnmarshalChannelHeader(payload.Header.ChannelHeader)// 擷取鏈結構,映射到 orderer.common.multichannel 包中 Registrar 結構體中對應方法chain, ok := ds.sm.GetChain(chdr.ChannelId)// 擷取當前配置序號lastConfigSequence := chain.Sequence()
檢查合法性

包括對許可權和 seekInfo 資料進行檢查。

首先,檢查請求方是否對通道擁有讀許可權。

sf := msgprocessor.NewSigFilter(policies.ChannelReaders, chain.PolicyManager())if err := sf.Apply(envelope); err != nil {    logger.Warningf("[channel: %s] Received unauthorized deliver request from %s: %s", chdr.ChannelId, addr, err)    return sendStatusReply(srv, cb.Status_FORBIDDEN)}

接下來,從 Envelope 結構的 payload.data 域中解析出 seekInfo 結構,並檢查其合法性。

proto.Unmarshal(payload.Data, seekInfo)chain.Reader().Iterator(seekInfo.Start)// 檢查 seekInfo 的cursor, number := chain.Reader().Iterator(seekInfo.Start)switch stop := seekInfo.Stop.Type.(type) {case *ab.SeekPosition_Oldest: // 截止到最早的區塊    stopNum = numbercase *ab.SeekPosition_Newest: // 截止到最新的區塊    stopNum = chain.Reader().Height() - 1case *ab.SeekPosition_Specified: // 截止到特定的區塊    stopNum = stop.Specified.Number    if stopNum < number {        logger.Warningf("[channel: %s] Received invalid seekInfo message from %s: start number %d greater than stop number %d", chdr.ChannelId, addr, number, stopNum)        return sendStatusReply(srv, cb.Status_BAD_REQUEST)    }}
發送區塊

在指定的起始和截止範圍內,逐個從本地賬本讀取區塊,並發送對應的區塊資料,

核心代碼如下所示。

for {    block, status := cursor.Next() // 擷取區塊    sendBlockReply(srv, block) // 發送區塊    if stopNum == block.Header.Number {        break    }}
返迴響應

如果處理成功,則返回成功響應訊息。

sendStatusReply(srv, cb.Status_SUCCESS)


===========================


《區塊鏈原理、設計與應用》一書已經正式出版,以超級賬本項目為例,介紹了區塊鏈和分散式總帳技術的底層原理、設計架構、應用實踐的大量細節,歡迎大家閱讀指正。


===== 關於 TechFirst 公眾號 =====

專註金融科技、人工智慧、雲端運算、大資料相關領域的熱門技術與前瞻方向。

發送關鍵詞(如區塊鏈、雲端運算、大資料、容器),擷取熱門點評與技術乾貨。

歡迎投稿。

如果你喜歡公眾號內容,歡迎鼓勵一杯 coffee~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.