Hyperledger Fabric学习(四)Endorser背书流程

一、Endorser背书流程

        Peer节点执行背书的时候,会执行/core/endorser/endorser.go的ProcessProposal()方法,具体流程如下:

  • 检验提案消息的合法性,以及相关的权限;
    • 调用ValidateProposalMessage()方法对提案格式进行检查
      • Channel头部格式:头部类型是否合法;
      • 签名头格式: 是否包括了nonce和creator数据;
      • 签名域: creator证书MSP是否合法,签名是否正确;
    • 如果是系统链码调用,检查是否是允许从外部调用的三种SCC之一;
    • 如果chainID不为空,获取对应chain的账本结构;检查TxID的唯一性,确保同一个交易未曾提交到账本中
    • 对于用户链码调用,检查ACL:资源为Propose,默认策略是Channel/Writers;
  • 模拟执行提案:启动链码容器,对世界状态的最新版本进行临时快照,基于临时快照执行链码,将结果记录在读写集中;
    • 如果chainID不为空,获取对应账本的交易模拟器(TxSimulator)和历史查询器(HistoryQueryExecutor),这两个结构将会在执行链码时被使用;
    • 如果chainID不为空,调用simulatorProposal()方法获取模拟执行的结果,检查返回的响应Response状态,如果状态码不小于500则创建并返回一个失败的ProposalResponse;
  • 对提案内容和读写集合进行签名,并返回提案响应消息;
    • 如果chainID不为空,调用endorserProposal()方法,利用ESCC,对之前得到的模拟执行的结果进行背书;
    • 检查模拟执行提案时调用simulatorProposal()方法返回的响应Response的状态码,如果状态码不小于400(也就是在400与499之间),返回含有检查链码模拟执行结果状态的ProposalResponse以及链码错误chaincodeError;
    • 将调用endorserProposal()方法返回的response.Payload值覆盖掉之前调用simulatorProposal()方法返回的ProposalResponse.Response.Payload值,因为原来的ProposalResponse.Response.Payload值含有链码调用的结果;

二、交易模拟器执行流程

        其中调用simulatorProposal()方法,模拟执行的流程如下:

  • 从提案结构的载荷(Payload)中提取ChaincodeInvovationSpec结构,其中包括了所调用链码(包括系统链码和用户链码)的路径、名称和版本,以及调用时传入的参数列表;
  • 检查ESCC和VSCC(这一步还未实现);
  • 如果调用的是用户链码,检查提案中的实例化策略跟账本上记录的该链码的实例化策略是否一致。账本上记录的该链码的实例化策略是在来链码被安装的时候就指定了的。这一步是为了防止有人修改权限在其他通道非法实例化;
  • 调用callChaincode()方法执行Proposal,返回Response和Event;通过一层一层调用SupportImpl.Execute()、ExecuteChaincode()、Execute()、ChaincodeSupport.Launch()以及ChaincodeSupport.Execute()方法,把交易模拟器和历史查询器通过上下文结构体传入方法中,创建并启动链码容器,创建链码gRPC消息,发送消息给CC(Chaincode)容器,执行相关合约,接收链码容器返回的响应(ChaincodeMessage结构)。在此过程中,会将读写集记录到交易模拟器结构体中;
  • 如果chainID不为空,调用GetTxSimulatorResults()方法拿到执行结果(TxSimulatorResults结构),从中解析读写集数据;
  • 返回链码标准数据结构(ChaincodeDefinition)、响应消息(ChaincodeMessage)、交易读写集(PubSimulationResults)、链码事件(ChaincodeEvent)
发布了622 篇原创文章 · 获赞 150 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/feizaoSYUACM/article/details/104974810
今日推荐