[Fabric/源碼分析] Proposal 消息處理流程(v1.0)

Fabric1.0的架構(gòu)中引入了client -> endorser -> order ->commiter的概念??蛻舳耸紫葘⒔灰装l(fā)送到背書節(jié)點進行模擬執(zhí)行,然后收集一定數(shù)量的背書結(jié)果構(gòu)造交易發(fā)送到排序節(jié)點進行排序,最后排序節(jié)點對收到的交易進行排序并打包發(fā)送給commiter節(jié)點進行驗證和計入賬本。本文將針對交易執(zhí)行的第一個階段client -> endorser的相關(guān)流程結(jié)合源碼進行分析。

一、Proposal交互流程

1.客戶端向endorser 發(fā)送proposal, proposal 定義如下:

message SignedProposal {
    // Proposal 消息序列化bytes
    bytes proposal_bytes = 1;
    //針對proposal_bytes的簽名
    bytes signature = 2;
}
//Proposal消息的實際定義
message Proposal {

    // The header of the proposal. It is the bytes of the Header
    bytes header = 1;

    // 具體的Proposal消息體的序列化內(nèi)容,消息體類型由header類型確定
    bytes payload = 2;

    // 擴展字段對于 CHAINCODE類型, 其可能使
    bytes extension = 3;
}
  1. endorserproposal 執(zhí)行結(jié)果返回給客戶端,propose response的定義如下:
message ProposalResponse {

    // Version indicates message protocol version
    int32 version = 1;
    google.protobuf.Timestamp timestamp = 2;
    //表示執(zhí)行是否成功
    Response response = 4;

    // 返回結(jié)果ProposalResponsePayload的序列化bytes
    bytes payload = 5;

    // The endorsement of the proposal, basically
    // the endorser's signature over the payload
    Endorsement endorsement = 6;
}

message Response {

    // A status code that should follow the HTTP status codes.
    int32 status = 1;

    // A message associated with the response code.
    string message = 2;

    // A payload that can be used to include metadata with this response.
    bytes payload = 3;
}

message ProposalResponsePayload {
    bytes proposal_hash = 1; 
    bytes extension = 2;
}

message Endorsement {
    bytes endorser = 1; // endorser id
    bytes signature = 2;// endorser  的簽名
}
  1. 客戶端收集背書組裝成一個交易transaction

一個完整的transaction包含一個或者多個proposal以及其對應的返回response。交易將會被發(fā)送到共識節(jié)點orders, 經(jīng)過排序之后batch形式的交易會被廣播到peer節(jié)點進行驗證以及寫入賬本。

二、Endorser節(jié)點的處理流程

源文件fabric/core/endorser.go中ProcessProposal函數(shù)負責具體的Proposel的處理。

  1. 檢查message是否有效,消息體個個字段的完整性以及chaincode id以及調(diào)用類型的檢查,例如proposal的消息不能調(diào)用system chaincode;
  2. 檢查proposal是否滿足channel的policy, tx的重復性判斷;
  3. 模擬執(zhí)行proposal中的chaincode調(diào)用,其實也就是實際執(zhí)行,這里需要兩個關(guān)鍵組件:
var txsim ledger.TxSimulator
var historyQueryExecutor ledger.HistoryQueryExecutor
    ...
    //1 -- simulate
cd, res, simulationResult, ccevent, err := e.simulateProposal(ctx, chainID, txid, signedProp, prop, hdrExt.ChaincodeId, txsim)

4.生成endorsement結(jié)果返回

pResp, err = e.endorseProposal(ctx, chainID, txid, signedProp, prop, res, simulationResult, ccevent, hdrExt.PayloadVisibility, hdrExt.ChaincodeId, txsim, cd)
    

2.1 simulate proposal 詳細流程

以上便是ProcessProposal的整體流程,這里關(guān)鍵的是simulateProposal這一步,接下來對該函數(shù)進行展開分析。

  1. 解析chaincode調(diào)用參數(shù):cis, err := putils.GetChaincodeInvocationSpec(prop)

  2. 為chancode檢查ESCC和VSCC, 該函數(shù)暫時未實現(xiàn)

    if err = e.checkEsccAndVscc(prop); err != nil {
        return nil, nil, nil, nil, err
    }
  1. 獲取chaincode的相關(guān)數(shù)據(jù)ChancodeData
cdLedger, err = e.getCDSFromLSCC(ctx, chainID, txid, signedProp, prop, cid.Name, txsim)
  1. 執(zhí)行chaincode并獲取結(jié)果
var simResult *ledger.TxSimulationResults
    var pubSimResBytes []byte
    var res *pb.Response
    var ccevent *pb.ChaincodeEvent
    res, ccevent, err = e.callChaincode(ctx, chainID, version, txid, signedProp, prop, cis, cid, txsim)
    if err != nil {
        endorserLogger.Errorf("failed to invoke chaincode %s on transaction %s, error: %s", cid, txid, err)
        return nil, nil, nil, nil, err
    }

    if txsim != nil {
        if simResult, err = txsim.GetTxSimulationResults(); err != nil {
            return nil, nil, nil, nil, err
        }

        if pubSimResBytes, err = simResult.GetPubSimulationBytes(); err != nil {
            return nil, nil, nil, nil, err
        }
    }
    return cdLedger, res, pubSimResBytes, ccevent, nil
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容