Fabric1.0源代码分析PeerBroadcastClient(Broadcast客户端)
兄弟连区块链技术培训Fabric 1.0源代码分析(17)gossip(流言算法) #deliverclient(deliver客户端)

兄弟连区块链技术培训Fabric 1.0源代码分析(17)gossip (流言算法)#deliverclient(deliver客户端)# Fabric 1.0源代码笔记之 gossip(流言算法) #deliverclient(deliver客户端)## 1、deliverclient概述deliverclient代码分布在gossip/service、core/deliverservice目录下,目录结构如下:* gossip/service目录:* gossip_service.go,DeliveryServiceFactory接口定义及实现。
* core/deliverservice目录:* deliveryclient.go,DeliverService接口定义及实现。
* client.go,broadcastClient结构体,实现AtomicBroadcast_BroadcastCli ent接口。
* requester.go,blocksRequester结构体及方法。
* blocksprovider目录,BlocksProvider接口定义及实现。
## 2、DeliveryServiceFactory接口定义及实现```gotype DeliveryServiceFactory interface {Service(g GossipService, endpoints []string, msc api.MessageCryptoS ervice) (deliverclient.DeliverService, error)}type deliveryFactoryImpl struct {}// Returns an instance of delivery clientfunc (*deliveryFactoryImpl) Service(g GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) { return deliverclient.NewDeliverService(&deliverclient.Config{CryptoSvc: mcs,Gossip: g,Endpoints: endpoints,ConnFactory: deliverclient.DefaultConnectionFactory,ABCFactory: deliverclient.DefaultABCFactory,})}//代码在gossip/service/gossip_service.go```## 3、DeliverService接口定义及实现### 3.1、DeliverService接口定义用于与orderer沟通获取新区块,并发送给committer。
兄弟连区块链教程Fabric1.0源代码分析gRPC Fabric中注册的gRPC Service一

兄弟连区块链教程Fabric1.0源代码分析gRPC(Fabric中注册的gRPC Service)一兄弟连区块链教程Fabric1.0源代码分析gRPC(Fabric中注册的gRPC Service)一,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。
但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
# Fabric 1.0源代码笔记之 -gRPC(Fabric中注册的gRPC Service)Peer节点中注册的gRPC Service,包括:* Events Service(事件服务):Chat* Admin Service(管理服务):GetStatus、StartServer、GetModuleLogLevel、SetModuleLogLevel、RevertLogLevels* Endorser Service(背书服务):ProcessProposal* ChaincodeSupport Service(链码支持服务):Register* Gossip Service(Gossip服务):GossipStream、PingOrderer节点中注册的gRPC Service,包括:* AtomicBroadcast Service(广播服务):Broadcast、Deliver## 1、Peer节点中注册的gRPC Service### 1.1、Events Service(事件服务)#### 1.1.1、Events Service客户端```gotype EventsClient interface {// event chatting using EventChat(ctx context.Context, opts ...grpc.CallOption) (Events_ChatClient, error)}type eventsClient struct {cc *grpc.ClientConn}func NewEventsClient(cc *grpc.ClientConn) EventsClient {return &eventsClient{cc}}func (c *eventsClient) Chat(ctx context.Context, opts ...grpc.CallOption) (Events_ChatClient, error) {stream, err := grpc.NewClientStream(ctx,&_Events_serviceDesc.Streams[0], , "/protos.Events/Chat", opts...) if err != nil {return nil, err}x := &eventsChatClient{stream}return x, nil}//代码在protos/peer/events.pb.go```#### 1.1.2、Events Service服务端```gotype EventsServer interface {Chat(Events_ChatServer) error}func RegisterEventsServer(s *grpc.Server, srv EventsServer) {s.RegisterService(&_Events_serviceDesc, srv)}func _Events_Chat_Handler(srv interface{}, stream grpc.ServerStream) error {return srv.(EventsServer).Chat(&eventsChatServer{stream})}var _Events_serviceDesc = grpc.ServiceDesc{ServiceName: "protos.Events",HandlerType: (*EventsServer)(nil),Methods: []grpc.MethodDesc{},Streams: []grpc.StreamDesc{{StreamName: "Chat",Handler: _Events_Chat_Handler,ServerStreams: true,ClientStreams: true,},},Metadata: "peer/events.proto",}//代码在protos/peer/events.pb.go```### 1.2、Admin Service(管理服务)#### 1.2.1、Admin Service客户端```gotype AdminClient interface {// Return the serve status.GetStatus(ctx context.Context, in *google_protobuf.Empty,opts ...grpc.CallOption) (*ServerStatus, error)StartServer(ctx context.Context, in *google_protobuf.Empty,opts ...grpc.CallOption) (*ServerStatus, error)GetModuleLogLevel(ctx context.Context, in *LogLevelRequest,opts ...grpc.CallOption) (*LogLevelResponse, error)SetModuleLogLevel(ctx context.Context, in *LogLevelRequest,opts ...grpc.CallOption) (*LogLevelResponse, error)RevertLogLevels(ctx context.Context, in *google_protobuf.Empty,opts ...grpc.CallOption) (*google_protobuf.Empty, error)}type adminClient struct {cc *grpc.ClientConn}func NewAdminClient(cc *grpc.ClientConn) AdminClient {return &adminClient{cc}}func (c *adminClient) GetStatus(ctx context.Context, in*google_protobuf.Empty, opts ...grpc.CallOption) (*ServerStatus, error) { out := new(ServerStatus)err := grpc.Invoke(ctx, "/protos.Admin/GetStatus", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) StartServer(ctx context.Context, in*google_protobuf.Empty, opts ...grpc.CallOption) (*ServerStatus, error) {out := new(ServerStatus)err := grpc.Invoke(ctx, "/protos.Admin/StartServer", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) GetModuleLogLevel(ctx context.Context, in*LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) { out := new(LogLevelResponse)err := grpc.Invoke(ctx, "/protos.Admin/GetModuleLogLevel", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) SetModuleLogLevel(ctx context.Context, in*LogLevelRequest, opts ...grpc.CallOption) (*LogLevelResponse, error) { out := new(LogLevelResponse)err := grpc.Invoke(ctx, "/protos.Admin/SetModuleLogLevel", in, out, , opts...)if err != nil {return nil, err}return out, nil}func (c *adminClient) RevertLogLevels(ctx context.Context, in*google_protobuf.Empty, opts ...grpc.CallOption) (*google_protobuf.Empty, error) {out := new(google_protobuf.Empty)err := grpc.Invoke(ctx, "/protos.Admin/RevertLogLevels", in, out, , opts...)if err != nil {return nil, err}return out, nil}//代码在protos/peer/admin.pb.go```#### 1.2.2、Admin Service服务端```gotype AdminServer interface {GetStatus(context.Context, *google_protobuf.Empty) (*ServerStatus, error)StartServer(context.Context, *google_protobuf.Empty) (*ServerStatus, error)GetModuleLogLevel(context.Context, *LogLevelRequest)(*LogLevelResponse, error)SetModuleLogLevel(context.Context, *LogLevelRequest)(*LogLevelResponse, error)RevertLogLevels(context.Context, *google_protobuf.Empty)(*google_protobuf.Empty, error)}func RegisterAdminServer(s *grpc.Server, srv AdminServer) {s.RegisterService(&_Admin_serviceDesc, srv)}func _Admin_GetStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(google_protobuf.Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).GetStatus(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/GetStatus",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).GetStatus(ctx,req.(*google_protobuf.Empty))}return interceptor(ctx, in, info, handler)}func _Admin_StartServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(google_protobuf.Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).StartServer(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/StartServer",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).StartServer(ctx,req.(*google_protobuf.Empty))}return interceptor(ctx, in, info, handler)}func _Admin_GetModuleLogLevel_Handler(srv interface{}, ctxcontext.Context, dec func(interface{}) error, interceptorgrpc.UnaryServerInterceptor) (interface{}, error) {in := new(LogLevelRequest)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).GetModuleLogLevel(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/GetModuleLogLevel",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).GetModuleLogLevel(ctx,req.(*LogLevelRequest))}return interceptor(ctx, in, info, handler)}func _Admin_SetModuleLogLevel_Handler(srv interface{}, ctxcontext.Context, dec func(interface{}) error, interceptorgrpc.UnaryServerInterceptor) (interface{}, error) {in := new(LogLevelRequest)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).SetModuleLogLevel(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/SetModuleLogLevel",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).SetModuleLogLevel(ctx,req.(*LogLevelRequest))}return interceptor(ctx, in, info, handler)}func _Admin_RevertLogLevels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {in := new(google_protobuf.Empty)if err := dec(in); err != nil {return nil, err}if interceptor == nil {return srv.(AdminServer).RevertLogLevels(ctx, in)}info := &grpc.UnaryServerInfo{Server: srv,FullMethod: "/protos.Admin/RevertLogLevels",}handler := func(ctx context.Context, req interface{}) (interface{}, error) {return srv.(AdminServer).RevertLogLevels(ctx,req.(*google_protobuf.Empty))}return interceptor(ctx, in, info, handler)}var _Admin_serviceDesc = grpc.ServiceDesc{ServiceName: "protos.Admin",HandlerType: (*AdminServer)(nil),Methods: []grpc.MethodDesc{{MethodName: "GetStatus",Handler: _Admin_GetStatus_Handler,},{MethodName: "StartServer",Handler: _Admin_StartServer_Handler,},{MethodName: "GetModuleLogLevel",Handler: _Admin_GetModuleLogLevel_Handler, },{MethodName: "SetModuleLogLevel",Handler: _Admin_SetModuleLogLevel_Handler, },{MethodName: "RevertLogLevels",Handler: _Admin_RevertLogLevels_Handler, },},Streams: []grpc.StreamDesc{},Metadata: "peer/admin.proto",}//代码在protos/peer/admin.pb.go```未完待续感谢关注兄弟连区块链教程分享!。
兄弟连区块链技术培训Fabric 1.0源代码分析(4) Chaincode(链码) platforms(链码语言平台)

兄弟连区块链技术培训Fabric 1.0源代码分析(4)Chain code(链码)#platforms(链码语言平台)Fabric 1.0源代码笔记之 Chaincode(链码) #platforms(链码语言平台)## 1、platforms概述platforms代码集中在core/chaincode/platforms目录下。
* core/chaincode/platforms目录,链码的编写语言平台实现,如golang或java。
* platforms.go,Platform接口定义,及platforms相关工具函数。
* util目录,Docker相关工具函数。
* java目录,java语言平台实现。
* golang目录,golang语言平台实现。
## 2、Platform接口定义```gotype Platform interface {//验证ChaincodeSpecValidateSpec(spec *pb.ChaincodeSpec) error//验证ChaincodeDeploymentSpecValidateDeploymentSpec(spec *pb.ChaincodeDeploymentSpec) error//获取部署PayloadGetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error)//生成DockerfileGenerateDockerfile(spec *pb.ChaincodeDeploymentSpec) (string, erro r)//生成DockerBuildGenerateDockerBuild(spec *pb.ChaincodeDeploymentSpec, tw *tar.Write r) error}//代码在core/chaincode/platforms/platforms.go```## 3、platforms相关工具函数### 3.1、platforms相关工具函数```go//按链码类型构造Platform接口实例,如golang.Platform{}func Find(chaincodeType pb.ChaincodeSpec_Type) (Platform, error)//调取platform.GetDeploymentPayload(spec),获取部署Payloadfunc GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error)//优先获取tls根证书,如无则获取tls证书func getPeerTLSCert() ([]byte, error)//调取platform.GenerateDockerfile(cds),创建Dockerfilefunc generateDockerfile(platform Platform, cds *pb.ChaincodeDeploymentS pec, tls bool) ([]byte, error)//调取platform.GenerateDockerBuild(cds, tw),创建DockerBuildfunc generateDockerBuild(platform Platform, cds *pb.ChaincodeDeployment Spec, inputFiles InputFiles, tw *tar.Writer) error//调取generateDockerfile(platform, cds, cert != nil)func GenerateDockerBuild(cds *pb.ChaincodeDeploymentSpec) (io.Reader, e rror)//代码在core/chaincode/platforms/platforms.go```### 3.2、Docker相关工具函数```go//contents+hash合并后再哈希func ComputeHash(contents []byte, hash []byte) []byte//哈希目录下文件并打包func HashFilesInDir(rootDir string, dir string, hash []byte, tw *tar.Wr iter) ([]byte, error)//目录是否存在func IsCodeExist(tmppath string) error//编译链码func DockerBuild(opts DockerBuildOptions) error//代码在core/chaincode/platforms/util/utils.go```func DockerBuild(opts DockerBuildOptions) error代码如下:```gotype DockerBuildOptions struct {Image stringEnv []stringCmd stringInputStream io.ReaderOutputStream io.Writer}func DockerBuild(opts DockerBuildOptions) error {client, err := cutil.NewDockerClient()if err != nil {return fmt.Errorf("Error creating docker client: %s", err)}if opts.Image == "" {//通用的本地编译环境opts.Image = cutil.GetDockerfileFromConfig("chaincode.builder") }//确认镜像是否存在或从远程拉取_, err = client.InspectImage(opts.Image)if err != nil {err = client.PullImage(docker.PullImageOptions{Repository: opts. Image}, docker.AuthConfiguration{})}//创建一个暂时的容器container, err := client.CreateContainer(docker.CreateContainerOpti ons{Config: &docker.Config{Image: opts.Image,Env: opts.Env,Cmd: []string{"/bin/sh", "-c", opts.Cmd},AttachStdout: true,AttachStderr: true,},})//删除容器defer client.RemoveContainer(docker.RemoveContainerOptions{ID: cont ainer.ID})//上传输入err = client.UploadToContainer(container.ID, docker.UploadToContain erOptions{Path: "/chaincode/input",InputStream: opts.InputStream,})stdout := bytes.NewBuffer(nil)_, err = client.AttachToContainerNonBlocking(docker.AttachToContain erOptions{Container: container.ID,OutputStream: stdout,ErrorStream: stdout,Logs: true,Stdout: true,Stderr: true,Stream: true,})//启动容器err = client.StartContainer(container.ID, nil)//等待容器返回retval, err := client.WaitContainer(container.ID)//获取容器输出err = client.DownloadFromContainer(container.ID, docker.DownloadFro mContainerOptions{Path: "/chaincode/output/.",OutputStream: opts.OutputStream,})return nil}//代码在core/chaincode/platforms/util/utils.go```## 4、golang语言平台实现### 4.1、golang.Platform结构体定义及方法Platform接口golang语言平台实现,即golang.Platform结构体定义及方法。
兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二

兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二兄弟连区块链教程Fabric1.0源代码分析blockfile区块文件存储二。
涉及方法如下:```go//构造blockIndexfunc newBlockIndex(indexConfig *blkstorage.IndexConfig, db*leveldbhelper.DBHandle) *blockIndex//获取最后一个块索引(或编号),取key为"indexCheckpointKey"的值,即为最新的区块编号func (index *blockIndex) getLastBlockIndexed() (uint64, error)func (index *blockIndex) indexBlock(blockIdxInfo *blockIdxInfo) error //索引区块//根据区块哈希,获取文件区块指针func (index *blockIndex) getBlockLocByHash(blockHash []byte)(*fileLocPointer, error)//根据区块编号,获取文件区块指针func (index *blockIndex) getBlockLocByBlockNum(blockNum uint64)(*fileLocPointer, error)//根据交易ID,获取文件交易指针func (index *blockIndex) getTxLoc(txID string) (*fileLocPointer, error) //根据交易ID,获取文件区块指针func (index *blockIndex) getBlockLocByTxID(txID string) (*fileLocPointer, error)//根据区块编号和交易编号,获取文件交易指针func (index *blockIndex) getTXLocByBlockNumTranNum(blockNum uint64, tranNum uint64) (*fileLocPointer, error)//根据交易ID,获取交易验证代码func (index *blockIndex) getTxValidationCodeByTxID(txID string)(peer.TxValidationCode, error)//代码在common/ledger/blkstorage/fsblkstorage/blockindex.go```补充blockIdxInfo结构体定义:块索引信息。
fabric项目源代码

fabric项目源代码Fabric是一个区块链解决方案,它是一个模块化的、可拓展的、高效的平台,可以方便地部署和管理分布式网络。
Fabric的源代码是开源的,目前由Hyperledger项目管理,任何人都可以在Hyperledger的GitHub仓库中访问和使用它。
Fabric的代码结构非常清晰,其中包含了许多关键的组件和模块,例如peer节点、orderer节点、网络拓扑结构等。
Fabric基于模块化的结构设计,可以支持很多种不同的共识机制、加密算法、智能合约等,因此可以广泛应用于不同的场景。
Fabric代码的核心部分是它的智能合约。
智能合约是一组自动运行的规则,用于执行与交换一定价值相关的业务逻辑。
在Fabric中,智能合约是通过Chaincode实现的,可以通过基于golang的编译器编写。
Chaincode有两种类型,一种是System Chaincode,它是由Fabric提供的,包含了一些核心的功能,例如安全性、管理和查询等。
另一种是User Chaincode,它是由用户自己编写的,用于实现业务逻辑。
Fabric的交易流程是这样的:当用户发送一个交易请求时,交易请求会被广播给所有的peer节点。
当peer节点确认交易请求的有效性后,它会进行交易验证,并将交易请求发送给orderer节点。
orderer节点会将交易请求打包成交易块,并将其广播给所有peer节点。
peer节点会接受交易块,并验证交易是否正确。
如果交易被验证通过,peer节点会更新其状态数据库,并将交易结果返回给用户。
Fabric在将交易块传递给下一个peer节点时,采用了PBFT共识算法。
PBFT算法是一种拜占庭容错(BFT)算法,可以保证在不超过⅓的恶意节点的情况下,系统可以达成共识。
除了PBFT以外,Fabric还支持其他共识算法,例如Raft和Solo。
这些共识算法的选择取决于给定的场景和应用需求。
同时,Fabric还提供了灵活的身份和访问控制机制,可以在系统中实现不同级别的身份验证和授权。
兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现

兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现兄弟连区块链教程Fabric1.0源代码分析Peer peer node start命令实现,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。
但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
# Fabric 1.0源代码笔记之 Peer #peer node start命令实现有个图2## 1、peer node加载子命令start和statuspeer node加载子命令start和status,代码如下:```gofunc Cmd() *mand {nodeCmd.AddCommand(startCmd()) //加载子命令startnodeCmd.AddCommand(statusCmd()) //加载子命令statusreturn nodeCmd}var nodeCmd = &mand{Use: nodeFuncName,Short: fmt.Sprint(shortDes),Long: fmt.Sprint(longDes),}//代码在peer/node/node.go```startCmd()代码如下:其中serve(args)为peer node start的实现代码,比较复杂,本文将重点讲解。
另statusCmd()代码与startCmd()相近,暂略。
```gofunc startCmd() *mand {flags := nodeStartCmd.Flags()flags.BoolVarP(&chaincodeDevMode, "peer-chaincodedev", "", false, "Whether peer in chaincode development mode")flags.BoolVarP(&peerDefaultChain, "peer-defaultchain", "", false, "Whether to start peer with chain testchainid")flags.StringVarP(&orderingEndpoint, "orderer", "o", "orderer:7050", "Ordering service endpoint") //ordererreturn nodeStartCmd}var nodeStartCmd = &mand{Use: "start",Short: "Starts the node.",Long: `Starts a node that interacts with the network.`,RunE: func(cmd *mand, args []string) error {return serve(args) //serve(args)为peer node start的实现代码},}//代码在peer/node/start.go```**注:如下内容均为serve(args)的代码,即peer node start命令执行流程。
兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令

兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令一兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。
但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
# Fabric 1.0源代码笔记之 Peer #peer根命令入口及加载子命令## 1、加载环境变量配置和配置文件Fabric支持通过环境变量对部分配置进行更新,如:CORE_LOGGING_LEVEL为输出的日志级别、CORE_PEER_ID为Peer的ID等。
此部分功能由第三方包viper来实现,viper除支持环境变量的配置方式外,还支持配置文件方式。
viper使用方法参考:https:///spf13/viper。
如下代码为加载环境变量配置,其中cmdRoot为"core",即CORE_开头的环境变量。
```goviper.SetEnvPrefix(cmdRoot)viper.AutomaticEnv()replacer := strings.NewReplacer(".", "_")viper.SetEnvKeyReplacer(replacer)//代码在peer/main.go```加载配置文件,同样由第三方包viper来实现,具体代码如下:其中cmdRoot为"core",即/etc/hyperledger/fabric/core.yaml。
```goerr := common.InitConfig(cmdRoot)//代码在peer/main.go```如下代码为common.InitConfig(cmdRoot)的具体实现:```goconfig.InitViper(nil, cmdRoot)err := viper.ReadInConfig()//代码在peer/common/common.go```另附config.InitViper(nil, cmdRoot)的代码实现:优先从环境变量FABRIC_CFG_PATH中获取配置文件路径,其次为当前目录、开发环境目录(即:src//hyperledger/fabric/sampleconfig)、和OfficialPath(即:/etc/hyperledger/fabric)。
fabric 源码解析

fabric 源码解析(实用版)目录1.引言2.fabric 概述3.fabric 源码结构4.fabric 的主要组件5.fabric 的核心功能6.结论正文【引言】本文将对 fabric 源码进行解析。
fabric 是一款高性能、轻量级的微服务框架,提供了服务注册、服务发现、负载均衡、熔断降级等功能。
通过解析 fabric 的源码,可以更好地理解其内部机制和实现方式。
【fabric 概述】fabric 是一款基于 Go 语言编写的微服务框架,提供了高性能、轻量级的服务注册、服务发现、负载均衡、熔断降级等功能。
fabric 支持多种服务发现方式,如 DNS 方式、HTTP 和 RPC 方式等。
同时,fabric 还提供了丰富的监控指标和日志功能,方便用户对服务进行监控和调试。
【fabric 源码结构】fabric 的源码结构如下所示:```fabric├── cmd│├── server│├── client│└── fabric│├── config│├── internal│├── apis│├── controllers │├── log│├── metrics│├── plugins│└── service│├── pkg│├── errors│├── util│└── services│├── scripts│├── static│└── version.go```其中,cmd 目录包含了 fabric 的命令行工具,config 目录包含了fabric 的配置文件,internal 目录包含了 fabric 的主要组件,pkg 目录包含了 fabric 的一些公共库,scripts 目录包含了 fabric 的一些脚本文件,static 目录包含了 fabric 的一些静态资源文件,version.go 文件包含了 fabric 的版本信息。
【fabric 的主要组件】fabric 的主要组件如下所示:1.服务注册中心:服务注册中心是 fabric 的核心组件之一,负责服务的注册和发现。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
兄弟连区块链教程Fabric1.0源代码分析PeerBroadcastClient(Broadcast客户端)兄弟连区块链教程Fabric1.0源代码分析PeerBroadcastClient(Broadcast客户端),2018年下半年,区块链行业正逐渐褪去发展之初的浮躁、回归理性,表面上看相关人才需求与身价似乎正在回落。
但事实上,正是初期泡沫的渐退,让人们更多的关注点放在了区块链真正的技术之上。
# Fabric1.0源代码笔记之Peer DeliverClient(Deliver客户端)
## 1、DeliverClient概述
DeliverClient代码分布如下:
* peer/channel/deliverclient.go,deliverClientIntf接口定义及实现,以及DeliverClient工具函数。
* protos/orderer/ab.pb.go,AtomicBroadcast_DeliverClient接口定义和实现。
## 2、deliverClientIntf接口定义及实现
### 2.1、DeliverClient工具函数
```go
//构造deliverClient
func newDeliverClient(conn *grpc.ClientConn, client
ab.AtomicBroadcast_DeliverClient, chainID string) *deliverClient
//代码在peer/channel/deliverclient.go
```
### 2.2、deliverClientIntf接口定义及实现
```go
type deliverClientIntf interface {
getSpecifiedBlock(num uint64) (*common.Block, error)
getOldestBlock() (*common.Block, error)
getNewestBlock() (*common.Block, error)
Close() error
}
type deliverClient struct {
conn *grpc.ClientConn
client ab.AtomicBroadcast_DeliverClient
chainID string
}
//构造查询Envelope
func seekHelper(chainID string, position *ab.SeekPosition)
*common.Envelope
//r.client.Send(seekHelper(r.chainID, &ab.SeekPosition{Type:
&ab.SeekPosition_Specified{Specified: &ab.SeekSpecified{Number: blockNumber}}}))
func (r *deliverClient) seekSpecified(blockNumber uint64) error
//r.client.Send(seekHelper(r.chainID, &ab.SeekPosition{Type:
&ab.SeekPosition_Oldest{Oldest: &ab.SeekOldest{}}}))
func (r *deliverClient) seekOldest() error
//return r.client.Send(seekHelper(r.chainID, &ab.SeekPosition{Type: &ab.SeekPosition_Newest{Newest: &ab.SeekNewest{}}}))
func (r *deliverClient) seekNewest() error
//r.client.Recv()读取块
func (r *deliverClient) readBlock() (*common.Block, error)
//r.seekSpecified(num)和r.readBlock()
func (r *deliverClient) getSpecifiedBlock(num uint64) (*common.Block, error)
//r.seekOldest()和r.readBlock()
func (r *deliverClient) getOldestBlock() (*common.Block, error)
//r.seekNewest()和r.readBlock()
func (r *deliverClient) getNewestBlock() (*common.Block, error)
//r.conn.Close()
func (r *deliverClient) Close() error
//cf.DeliverClient.getSpecifiedBlock(0)获取创世区块
func getGenesisBlock(cf *ChannelCmdFactory) (*common.Block, error)
//代码在peer/channel/deliverclient.go
```
func seekHelper(chainID string, position *ab.SeekPosition)
*common.Envelope代码如下:
```go
func seekHelper(chainID string, position *ab.SeekPosition)
*common.Envelope {
seekInfo := &ab.SeekInfo{
Start: position,
Stop: position,
Behavior: ab.SeekInfo_BLOCK_UNTIL_READY,
}
msgVersion := int32(0)
epoch := uint64(0)
env, err :=
utils.CreateSignedEnvelope(common.HeaderType_CONFIG_UPDATE, chainID, localmsp.NewSigner(), seekInfo, msgVersion, epoch)
return env
}
//代码在peer/channel/deliverclient.go
```
感谢关注兄弟连区块链教程分享!。