hyperledger fabric 结构分析(二)
来源:互联网 发布:什么是sql注入攻击 编辑:程序博客网 时间:2024/05/22 00:30
接着上图分析,经过Consensus Commit流程生成批数据后,是如何送入到ChainCode呢?我们还是以Invoke命令分析。1)在consensus的helper中调用chaincode的ExecuteTransactions 进入transaction处理流程
func (h *Helper) ExecTxs(id interface{}, txs []*pb.Transaction) ([]byte, error) {succeededTxs, res, ccevents, txerrs, err := chaincode.ExecuteTransactions(context.Background(), chaincode.DefaultChain, txs)}
2)该函数在core/chaincode 中处理,将命令封装成ChainCode识别的格式。其中的chain对象则是访问ChainCode对应的ChainCodeSupport,这样就说明访问ChainCode的接口类是ChainCodeSupportServer。
func Execute(ctxt context.Context, chain *ChaincodeSupport, t *pb.Transaction) ([]byte, *pb.ChaincodeEvent, error) {ccMsg, err = createTransactionMessage(t.Txid, cMsg)resp, err := chain.Execute(ctxt, chaincode, ccMsg, timeout, t)}3)该函数在ChainCodeSupport文件中,首先检测ChainCode是否建立成功、能否正常运行。其中chrte.handler的得来是比较复杂的,见下描述
func (chaincodeSupport *ChaincodeSupport) Execute(ctxt context.Context, chaincode string, msg *pb.ChaincodeMessage, timeout time.Duration, tx *pb.Transaction) (*pb.ChaincodeMessage, error) {chrte, ok := chaincodeSupport.chaincodeHasBeenLaunched(chaincode)chrte.handler.sendExecuteMessage(msg, tx)}3.1)在创建ChainCodeSupport的时候registerChaincodeSupport 调用 NewChaincodeSupport 实例化ChainCodeSupport(start.go),服务器的Name:
protos.ChaincodeSupport
ccStartupTimeout := time.Duration(tOut) * time.MillisecondccSrv := chaincode.NewChaincodeSupport(chainname, peer.GetPeerEndpoint, userRunsCC,ccStartupTimeout, secHelper)//Now that chaincode is initialized, register all system chaincodes.system_chaincode.RegisterSysCCs()pb.RegisterChaincodeSupportServer(grpcServer, ccSrv)var _ChaincodeSupport_serviceDesc = grpc.ServiceDesc{ ServiceName: "protos.ChaincodeSupport", HandlerType: (*ChaincodeSupportServer)(nil), Methods: []grpc.MethodDesc{}, Streams: []grpc.StreamDesc{ { StreamName: "Register", Handler: _ChaincodeSupport_Register_Handler, ServerStreams: true, ClientStreams: true, }, },}3.2)ChainCode 调用 err := shim.Start(new(SimpleChaincode)) 接入到ChainCodeSupportServer
err := shim.Start(new(SimpleChaincode))3.3)连接ChainCodeSupprotServer同时调用Register函数
func Start(cc Chaincode) error {chaincodeSupportClient := pb.NewChaincodeSupportClient(clientConn)stream, err := chaincodeSupportClient.Register(context.Background())err = chatWithPeer(chaincodename, stream, cc)}3.4)与此同时ChainCodeSupportServer会根据Client调用注册函数创建该Stream的Handler处理句柄,创建消息响应循环,等待Client发送命令.(注意该handler就是我们关心的
handler.sendExecuteMessage)func HandleChaincodeStream(chaincodeSupport *ChaincodeSupport, ctxt context.Context, stream ccintf.ChaincodeStream) error {</span>
deadline, ok := ctxt.Deadline()chaincodeLogger.Debugf("Current context deadline = %s, ok = %v", deadline, ok)handler := newChaincodeSupportHandler(chaincodeSupport, stream)return handler.processStream()}
3.5) 客户端shim/Chaincode发送RegisterMessage
handler.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTER, Payload: payload})3.6)对于Server而言,我们刚刚创建了handler又有ProcessStream消息响应循环,这样RegisterMessage就交到了ProcessStream手里,ProcessStream根据消息类型执行命令分发
调用beforeRegisterEvent函数。
func (handler *Handler) beforeRegisterEvent(e *fsm.Event, state string) {err = handler.chaincodeSupport.registerHandler(handler)}3.7)同理在client端(shim/chaincode)也建立响应的消息响应循环。
4)到目前为止还没有完,我们将invoke命令送给了Client的委托模块Shim进行处理。Shim模块根据来访事件类型送入指定处理函数
func (handler *Handler) enterTransactionState(e *fsm.Event) {msg, ok := e.Args[0].(*pb.ChaincodeMessage)if !ok {e.Cancel(fmt.Errorf("Received unexpected message type"))return}chaincodeLogger.Debugf("[%s]Received %s, invoking transaction on chaincode(Src:%s, Dst:%s)", shorttxid(msg.Txid), msg.Type.String(), e.Src, e.Dst)if msg.Type.String() == pb.ChaincodeMessage_TRANSACTION.String() {// Call the chaincode's Run function to invoke transactionhandler.handleTransaction(msg)}}5)调用ChainCode的invoke函数
func (handler *Handler) handleTransaction(msg *pb.ChaincodeMessage) {res, err := handler.cc.Invoke(stub, function, params)}
以上分析涉及两个过程 1) consensus结束后如何将命令送入ChainCode 2)ChainCodeSupportServer与ChainCode如何建立通信关系。
画一个 ChainCodeSupportServer与ChainCode如何建立通信关系 图:
- hyperledger fabric 结构分析(二)
- hyperledger fabric 结构分析(三)
- hyperledger fabric 结构分析(一)
- hyperledger fabric-0.6 结构分析(一)
- Hyperledger fabric 工程结构
- hyperledger fabric0.6 结构分析(二)
- 区块链(二)--Bitcoin、Ethereum、Hyperledger Fabric
- Hyperledger Fabric的PBFT源码分析(一)
- [区块链]Hyperledger Fabric源代码(基于v1.0 beta版本)阅读之乐扣老师解读系列 (二)Fabric模块分析
- Hyperledger Fabric入门 -------- ( Hyperledger-fabric-doc.pdf)
- Hyperledger fabric 学习笔记: fabric v1.0 代码结构
- Hyperledger Fabric
- hyperledger fabric0.6 结构分析(三)
- Hyperledger Fabric 1.0 链码(chaincode)的原理、接口和结构
- 区块链解读6-区块链框架分析+超级账本(Hyperledger Fabric)基础
- Hyperledger Fabric继peer启动之后的源码解析二
- (二) Hyperledger Fabric 启动你的第一个网络
- Hyperledger fabric 源码分析之 peer 服务启动过程
- 数据结构总结(1)——学习中要找规律
- tensorflow reverse_sequence实例
- struts2中action返回"json"字符串
- android开发技巧-记录未捕获的crash异常日志
- iOS开发- try catch
- hyperledger fabric 结构分析(二)
- lamp之源码包安装php
- MATLAB自带工具箱实现PCA降维代码,着重介绍实现方法
- (笔记)英腾技术开发实习生面试技术题(答案分析)
- 57. Insert Interval
- 简单的ViewPager实现
- java 二维码原理以及用java实现的二维码的生成、解码
- JVM的内存区域划分
- C语言枚举enum的定义