一 hyperledger fabric 结构分析是什么?hyperledger fabric的架构设计指的什么?( 二 )


HandlerType: (*DevopsServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: Login,
Handler:_Devops_Login_Handler,
},
{
MethodName: Build,
Handler:_Devops_Build_Handler,
},
{
MethodName: Deploy,
Handler:_Devops_Deploy_Handler,
},
{
MethodName: Invoke,
Handler:_Devops_Invoke_Handler,
},
{
MethodName: Query,
Handler:_Devops_Query_Handler,
},
{
MethodName: EXP_GetApplicationTCert,
Handler:_Devops_EXP_GetApplicationTCert_Handler,
},
{
MethodName: EXP_PrepareForTx,
Handler:_Devops_EXP_PrepareForTx_Handler,
},
{
MethodName: EXP_ProduceSigma,
Handler:_Devops_EXP_ProduceSigma_Handler,
},
{
MethodName: EXP_ExecuteWithBinding,
Handler:_Devops_EXP_ExecuteWithBinding_Handler,
},
},
Streams: []grpc.StreamDesc{},
}
3)其中_Devops_Invoke_Handler函数在Protos模块,其负责将Client接入的信息传递到对应的Server模块
func _Devops_Invoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(ChaincodeInvocationSpec)
if err := dec(in); err != nil {
return nil, err
}
out, err := srv.(DevopsServer).Invoke(ctx, in)
if err != nil {
return nil, err
}
return out, nil
}
4)在函数在devops服务端代码中处理
func (d *Devops) Invoke(ctx context.Context, chaincodeInvocationSpec *pb.ChaincodeInvocationSpec) (*pb.Response, error) {
return d.invokeOrQuery(ctx, chaincodeInvocationSpec, chaincodeInvocationSpec.ChaincodeSpec.Attributes, true)
}
5)精简invokeOrQuery代码,d.coord 是PeerServer对象,ExecuteTransaction 是对应Engine的实现方法
func (d *Devops) invokeOrQuery(ctx context.Context, chaincodeInvocationSpec *pb.ChaincodeInvocationSpec, attributes []string, invoke bool) (*pb.Response, error) {
resp := d.coord.ExecuteTransaction(transaction)
}
6)本次请求被封装成交易Struct,该处理是在PeerServer中 。
func (p *Impl) ExecuteTransaction(transaction *pb.Transaction) (response *pb.Response) {
if p.isValidator {
response = p.sendTransactionsToLocalEngine(transaction)
} else {
peerAddresses := p.discHelper.GetRandomNodes(1)
response = p.SendTransactionsToPeer(peerAddresses[0], transaction)
}
return response
}
7)思考可知,最终这笔transaction是要交给到Consensus进行处理,那么如何传递的呢?就在下面p.engine.ProcessTransactionMsg,其中p代指PeerServer,engine是在创建PeerServer的时候指定的Engine,而这个Engine的handler实现在Consensus里,在实现EngineHandler过程中加载了PBFT算法 。所以ProcessTransactionMsg函数的实现在consensus模块engine代码里 。这样解决了开始时提出的疑问3) 。
func (p *Impl) sendTransactionsToLocalEngine(transaction *pb.Transaction) *pb.Response {
peerLogger.Debugf(Marshalling transaction %s to send to local engine, transaction.Type)
data, err := proto.Marshal(transaction)
if err != nil {
return pb.Response{Status: pb.Response_FAILURE, Msg: []byte(fmt.Sprintf(Error sending transaction to local engine: %s, err))}
}
var response *pb.Response
msg := pb.Message{Type: pb.Message_CHAIN_TRANSACTION, Payload: data, Timestamp: util.CreateUtcTimestamp()}
peerLogger.Debugf(Sending message %s with timestamp %v to local engine, msg.Type, msg.Timestamp)
response = p.engine.ProcessTransactionMsg(msg, transaction)
return response
}
8)从这里开始进入了consensus内部处理,在这里Consensus模块是单独分析 。
func (eng *EngineImpl) ProcessTransactionMsg(msg *pb.Message, tx *pb.Transaction) (response *pb.Response) {
err := eng.consenter.RecvMsg(msg, eng.peerEndpoint.ID)

推荐阅读