Hyperledger fabric0.6 peer启动过程源码分析



由图片可以看出peer启动节点后先初始化一下日志

然后进入Server函数

//==============================================================================

//peer node start 之后做日志初始化之后就进入到server函数
//==============================================================================
func serve(args []string) error {
    // Parameter overrides must be processed before any paramaters are
    // cached. Failures to cache cause the server to terminate immediately.
    //在其他参数被缓存起来之前参数覆盖必须处理,失败缓存导致服务立即结束
    if chaincodeDevMode {
        logger.Info("Running in chaincode development mode")
        logger.Info("Set consensus to NOOPS and user starts chaincode")
        logger.Info("Disable loading validity system chaincode")
 
        viper.Set("peer.validator.enabled", "true")
        viper.Set("peer.validator.consensus", "noops")
        viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
 
    }
 
    if err := peer.CacheConfiguration(); err != nil {
        return err
    }
 
    peerEndpoint, err := peer.GetPeerEndpoint()
    if err != nil {
        err = fmt.Errorf("Failed to get Peer Endpoint: %s", err)
        return err
    }
 
    //启动grpc服务,监听7051端口
    listenAddr := viper.GetString("peer.listenAddress")
 
    if "" == listenAddr {
        logger.Debug("Listen address not specified, using peer endpoint address")
        listenAddr = peerEndpoint.Address
    }
 
    lis, err := net.Listen("tcp", listenAddr)
    if err != nil {
        grpclog.Fatalf("Failed to listen: %v", err)
    }
    //创建EventHub服务器,通过调用createEventHubServer方法实现,该服务也是grpc,只有VP
    //才能开启
    ehubLis, ehubGrpcServer, err := createEventHubServer()
    if err != nil {
        grpclog.Fatalf("Failed to create ehub server: %v", err)
    }
 
    logger.Infof("Security enabled status: %t", core.SecurityEnabled())
    if viper.GetBool("security.privacy") {
        if core.SecurityEnabled() {
            logger.Infof("Privacy enabled status: true")
        } else {
            panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
        }
    } else {
        logger.Infof("Privacy enabled status: false")
    }
    //启动rockdb数据库
    db.Start()
 
    var opts []grpc.ServerOption
    if comm.TLSEnabled() {
        creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"),
            viper.GetString("peer.tls.key.file"))
 
        if err != nil {
            grpclog.Fatalf("Failed to generate credentials %v", err)
        }
        opts = []grpc.ServerOption{grpc.Creds(creds)}
    }
 
    //创建一个grpc服务
    grpcServer := grpc.NewServer(opts...)
 
    //注册Chaincode支持服务器
    secHelper, err := getSecHelper()
    if err != nil {
        return err
    }
 
    secHelperFunc := func() crypto.Peer {
        return secHelper
    }
 
    registerChaincodeSupport(chaincode.DefaultChain, grpcServer, secHelper)
 
    var peerServer *peer.Impl
 
    // 创建peer服务器,主意区分VP和NVP节点
    if peer.ValidatorEnabled() {
        logger.Debug("Running as validating peer - making genesis block if needed")
        makeGenesisError := genesis.MakeGenesis()
        if makeGenesisError != nil {
            return makeGenesisError
        }
        logger.Debugf("Running as validating peer - installing consensus %s",
            viper.GetString("peer.validator.consensus"))
 
        peerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine)
    } else {
        logger.Debug("Running as non-validating peer")
        peerServer, err = peer.NewPeerWithHandler(secHelperFunc, peer.NewPeerHandler)
    }
 
    if err != nil {
        logger.Fatalf("Failed creating new peer with handler %v", err)
 
        return err
    }
 
    // 注册peer服务
    pb.RegisterPeerServer(grpcServer, peerServer)
 
    // 注册管理服务器
    pb.RegisterAdminServer(grpcServer, core.NewAdminServer())
 
    // 注册Devops服务器
    serverDevops := core.NewDevopsServer(peerServer)
    pb.RegisterDevopsServer(grpcServer, serverDevops)
 
    // 注册ServerOpenchain服务器
    serverOpenchain, err := rest.NewOpenchainServerWithPeerInfo(peerServer)
    if err != nil {
        err = fmt.Errorf("Error creating OpenchainServer: %s", err)
        return err
    }
 
    pb.RegisterOpenchainServer(grpcServer, serverOpenchain)
 
    // 如果配置了的话创建和注册REST服务
    if viper.GetBool("rest.enabled") {
        go rest.StartOpenchainRESTServer(serverOpenchain, serverDevops)
    }
 
    logger.Infof("Starting peer with ID=%s, network ID=%s, address=%s, rootnodes=%v, validator=%v",
        peerEndpoint.ID, viper.GetString("peer.networkId"), peerEndpoint.Address,
        viper.GetString("peer.discovery.rootnode"), peer.ValidatorEnabled())
 
    // 启动GRPC服务器. 如果是必须的话在一个goroutine中完成这样我们能够部署genesis
    serve := make(chan error)
 
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        serve <- nil
    }()
 
    go func() {
        var grpcErr error
        if grpcErr = grpcServer.Serve(lis); grpcErr != nil {
            grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr)
        } else {
            logger.Info("grpc server exited")
        }
        serve <- grpcErr
    }()
 
    if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil {
        return err
    }
 
    // 启动eventHub服务
    if ehubGrpcServer != nil && ehubLis != nil {
        go ehubGrpcServer.Serve(ehubLis)
    }
 
    if viper.GetBool("peer.profile.enabled") {
        go func() {
            profileListenAddress := viper.GetString("peer.profile.listenAddress")
            logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress)
            if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil {
                logger.Errorf("Error starting profiler: %s", profileErr)
            }
        }()
    }
 
    // Block until grpc server exits 产生块直到grpc服务退出
    return <-serve
}

所过程在代码中的注释可以看明白

由图片可以看出peer启动节点后先初始化一下日志

然后进入Server函数

//==============================================================================

//peer node start 之后做日志初始化之后就进入到server函数
//==============================================================================
func serve(args []string) error {
    // Parameter overrides must be processed before any paramaters are
    // cached. Failures to cache cause the server to terminate immediately.
    //在其他参数被缓存起来之前参数覆盖必须处理,失败缓存导致服务立即结束
    if chaincodeDevMode {
        logger.Info("Running in chaincode development mode")
        logger.Info("Set consensus to NOOPS and user starts chaincode")
        logger.Info("Disable loading validity system chaincode")
 
        viper.Set("peer.validator.enabled", "true")
        viper.Set("peer.validator.consensus", "noops")
        viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
 
    }
 
    if err := peer.CacheConfiguration(); err != nil {
        return err
    }
 
    peerEndpoint, err := peer.GetPeerEndpoint()
    if err != nil {
        err = fmt.Errorf("Failed to get Peer Endpoint: %s", err)
        return err
    }
 
    //启动grpc服务,监听7051端口
    listenAddr := viper.GetString("peer.listenAddress")
 
    if "" == listenAddr {
        logger.Debug("Listen address not specified, using peer endpoint address")
        listenAddr = peerEndpoint.Address
    }
 
    lis, err := net.Listen("tcp", listenAddr)
    if err != nil {
        grpclog.Fatalf("Failed to listen: %v", err)
    }
    //创建EventHub服务器,通过调用createEventHubServer方法实现,该服务也是grpc,只有VP
    //才能开启
    ehubLis, ehubGrpcServer, err := createEventHubServer()
    if err != nil {
        grpclog.Fatalf("Failed to create ehub server: %v", err)
    }
 
    logger.Infof("Security enabled status: %t", core.SecurityEnabled())
    if viper.GetBool("security.privacy") {
        if core.SecurityEnabled() {
            logger.Infof("Privacy enabled status: true")
        } else {
            panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
        }
    } else {
        logger.Infof("Privacy enabled status: false")
    }
    //启动rockdb数据库
    db.Start()
 
    var opts []grpc.ServerOption
    if comm.TLSEnabled() {
        creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"),
            viper.GetString("peer.tls.key.file"))
 
        if err != nil {
            grpclog.Fatalf("Failed to generate credentials %v", err)
        }
        opts = []grpc.ServerOption{grpc.Creds(creds)}
    }
 
    //创建一个grpc服务
    grpcServer := grpc.NewServer(opts...)
 
    //注册Chaincode支持服务器
    secHelper, err := getSecHelper()
    if err != nil {
        return err
    }
 
    secHelperFunc := func() crypto.Peer {
        return secHelper
    }
 
    registerChaincodeSupport(chaincode.DefaultChain, grpcServer, secHelper)
 
    var peerServer *peer.Impl
 
    // 创建peer服务器,主意区分VP和NVP节点
    if peer.ValidatorEnabled() {
        logger.Debug("Running as validating peer - making genesis block if needed")
        makeGenesisError := genesis.MakeGenesis()
        if makeGenesisError != nil {
            return makeGenesisError
        }
        logger.Debugf("Running as validating peer - installing consensus %s",
            viper.GetString("peer.validator.consensus"))
 
        peerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine)
    } else {
        logger.Debug("Running as non-validating peer")
        peerServer, err = peer.NewPeerWithHandler(secHelperFunc, peer.NewPeerHandler)
    }
 
    if err != nil {
        logger.Fatalf("Failed creating new peer with handler %v", err)
 
        return err
    }
 
    // 注册peer服务
    pb.RegisterPeerServer(grpcServer, peerServer)
 
    // 注册管理服务器
    pb.RegisterAdminServer(grpcServer, core.NewAdminServer())
 
    // 注册Devops服务器
    serverDevops := core.NewDevopsServer(peerServer)
    pb.RegisterDevopsServer(grpcServer, serverDevops)
 
    // 注册ServerOpenchain服务器
    serverOpenchain, err := rest.NewOpenchainServerWithPeerInfo(peerServer)
    if err != nil {
        err = fmt.Errorf("Error creating OpenchainServer: %s", err)
        return err
    }
 
    pb.RegisterOpenchainServer(grpcServer, serverOpenchain)
 
    // 如果配置了的话创建和注册REST服务
    if viper.GetBool("rest.enabled") {
        go rest.StartOpenchainRESTServer(serverOpenchain, serverDevops)
    }
 
    logger.Infof("Starting peer with ID=%s, network ID=%s, address=%s, rootnodes=%v, validator=%v",
        peerEndpoint.ID, viper.GetString("peer.networkId"), peerEndpoint.Address,
        viper.GetString("peer.discovery.rootnode"), peer.ValidatorEnabled())
 
    // 启动GRPC服务器. 如果是必须的话在一个goroutine中完成这样我们能够部署genesis
    serve := make(chan error)
 
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        serve <- nil
    }()
 
    go func() {
        var grpcErr error
        if grpcErr = grpcServer.Serve(lis); grpcErr != nil {
            grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr)
        } else {
            logger.Info("grpc server exited")
        }
        serve <- grpcErr
    }()
 
    if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil {
        return err
    }
 
    // 启动eventHub服务
    if ehubGrpcServer != nil && ehubLis != nil {
        go ehubGrpcServer.Serve(ehubLis)
    }
 
    if viper.GetBool("peer.profile.enabled") {
        go func() {
            profileListenAddress := viper.GetString("peer.profile.listenAddress")
            logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress)
            if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil {
                logger.Errorf("Error starting profiler: %s", profileErr)
            }
        }()
    }
 
    // Block until grpc server exits 产生块直到grpc服务退出
    return <-serve
}
所过程在代码中的注释可以看明白


对图中peer节点启动之后的peer address 172.17.0.3:7051灰色部分的的代码提取分析,7051:peer gRPC 服务监听端口。下面是Hyperledger中相关监听的服务端口

默认包括:以下监听的服务端口对应hyperledger0.6版本,与其他版本无关。

7050: REST 服务端口

7051:peer gRPC 服务监听端口

7052:peer CLI 端口

7053:peer 事件服务端口

7054:eCAP7055:eCAA

7056:tCAP

7057:tCAA

7058:tlsCAP

7059:tlsCAA

图中的CacheConfiguration()这个函数到底做了什么?请看下面

// CacheConfiguration计算和缓存经常使用的常量且计算常量做为包变量,按照惯例前面的全局变量

// 已经被嵌入在这里为了保留原始的抽象状态
func CacheConfiguration() (err error) {
    // getLocalAddress 返回正在操作的本地peer的address:port,受到env:peer.addressAutoDetect的影响
    getLocalAddress := func() (peerAddress string, err error) {
        if viper.GetBool("peer.addressAutoDetect") {
            // 需要从peer.address设置中获取端口号,并将其添加到已经确定的主机ip后
            _, port, err := net.SplitHostPort(viper.GetString("peer.address"))
            if err != nil {
                err = fmt.Errorf("Error auto detecting Peer's address: %s", err)
                return "", err
            }
            peerAddress = net.JoinHostPort(GetLocalIP(), port)
            peerLogger.Infof("Auto detected peer address: %s", peerAddress)
        } else {
            peerAddress = viper.GetString("peer.address")
        }
        return
    }
 
    // getPeerEndpoint 对于这个Peer实例来说,返回PeerEndpoint,受到env:peer.addressAutoDetect的影响
    getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
        var peerAddress string
        var peerType pb.PeerEndpoint_Type
        peerAddress, err := getLocalAddress()
        if err != nil {
            return nil, err
        }
        if viper.GetBool("peer.validator.enabled") {
            peerType = pb.PeerEndpoint_VALIDATOR
        } else {
            peerType = pb.PeerEndpoint_NON_VALIDATOR
        }
        return &pb.PeerEndpoint{ID: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress, Type: peerType}, nil
    }
 
    localAddress, localAddressError = getLocalAddress()
    peerEndpoint, peerEndpointError = getPeerEndpoint()
 
    syncStateSnapshotChannelSize = viper.GetInt("peer.sync.state.snapshot.channelSize")
    syncStateDeltasChannelSize = viper.GetInt("peer.sync.state.deltas.channelSize")
    syncBlocksChannelSize = viper.GetInt("peer.sync.blocks.channelSize")
    validatorEnabled = viper.GetBool("peer.validator.enabled")
 
    securityEnabled = viper.GetBool("security.enabled")
 
    configurationCached = true
 
    if localAddressError != nil {
        return localAddressError
    } else if peerEndpointError != nil {
        return peerEndpointError
    }
    return
}
 
// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// GetPeerEndpoint 从缓存配置中返回peerEndpoint
func GetPeerEndpoint() (*pb.PeerEndpoint, error) {
    if !configurationCached {
        cacheConfiguration()
    }
    return peerEndpoint, peerEndpointError
}

// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }

由图片可以看出peer启动节点后先初始化一下日志

然后进入Server函数

//==============================================================================

//peer node start 之后做日志初始化之后就进入到server函数
//==============================================================================
func serve(args []string) error {
    // Parameter overrides must be processed before any paramaters are
    // cached. Failures to cache cause the server to terminate immediately.
    //在其他参数被缓存起来之前参数覆盖必须处理,失败缓存导致服务立即结束
    if chaincodeDevMode {
        logger.Info("Running in chaincode development mode")
        logger.Info("Set consensus to NOOPS and user starts chaincode")
        logger.Info("Disable loading validity system chaincode")
        viper.Set("peer.validator.enabled", "true")
        viper.Set("peer.validator.consensus", "noops")
        viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
    }
    if err := peer.CacheConfiguration(); err != nil {
        return err
    }
    peerEndpoint, err := peer.GetPeerEndpoint()
    if err != nil {
        err = fmt.Errorf("Failed to get Peer Endpoint: %s", err)
        return err
    }
    //启动grpc服务,监听7051端口
    listenAddr := viper.GetString("peer.listenAddress")
    if "" == listenAddr {
        logger.Debug("Listen address not specified, using peer endpoint address")
        listenAddr = peerEndpoint.Address
    }
    lis, err := net.Listen("tcp", listenAddr)
    if err != nil {
        grpclog.Fatalf("Failed to listen: %v", err)
    }
    //创建EventHub服务器,通过调用createEventHubServer方法实现,该服务也是grpc,只有VP
    //才能开启
    ehubLis, ehubGrpcServer, err := createEventHubServer()
    if err != nil {
        grpclog.Fatalf("Failed to create ehub server: %v", err)
    }
    logger.Infof("Security enabled status: %t", core.SecurityEnabled())
    if viper.GetBool("security.privacy") {
        if core.SecurityEnabled() {
            logger.Infof("Privacy enabled status: true")
        } else {
            panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
        }
    } else {
        logger.Infof("Privacy enabled status: false")
    }
    //启动rockdb数据库
    db.Start()
    var opts []grpc.ServerOption
    if comm.TLSEnabled() {
        creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"),
            viper.GetString("peer.tls.key.file"))
        if err != nil {
            grpclog.Fatalf("Failed to generate credentials %v", err)
        }
        opts = []grpc.ServerOption{grpc.Creds(creds)}
    }
    //创建一个grpc服务
    grpcServer := grpc.NewServer(opts...)
    //注册Chaincode支持服务器
    secHelper, err := getSecHelper()
    if err != nil {
        return err
    }
    secHelperFunc := func() crypto.Peer {
        return secHelper
    }
    registerChaincodeSupport(chaincode.DefaultChain, grpcServer, secHelper)
    var peerServer *peer.Impl
    // 创建peer服务器,主意区分VP和NVP节点
    if peer.ValidatorEnabled() {
        logger.Debug("Running as validating peer - making genesis block if needed")
        makeGenesisError := genesis.MakeGenesis()
        if makeGenesisError != nil {
            return makeGenesisError
        }
        logger.Debugf("Running as validating peer - installing consensus %s",
            viper.GetString("peer.validator.consensus"))
        peerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine)
    } else {
        logger.Debug("Running as non-validating peer")
        peerServer, err = peer.NewPeerWithHandler(secHelperFunc, peer.NewPeerHandler)
    }
    if err != nil {
        logger.Fatalf("Failed creating new peer with handler %v", err)
        return err
    }
    // 注册peer服务
    pb.RegisterPeerServer(grpcServer, peerServer)
    // 注册管理服务器
    pb.RegisterAdminServer(grpcServer, core.NewAdminServer())
    // 注册Devops服务器
    serverDevops := core.NewDevopsServer(peerServer)
    pb.RegisterDevopsServer(grpcServer, serverDevops)
    // 注册ServerOpenchain服务器
    serverOpenchain, err := rest.NewOpenchainServerWithPeerInfo(peerServer)
    if err != nil {
        err = fmt.Errorf("Error creating OpenchainServer: %s", err)
        return err
    }
    pb.RegisterOpenchainServer(grpcServer, serverOpenchain)
    // 如果配置了的话创建和注册REST服务
    if viper.GetBool("rest.enabled") {
        go rest.StartOpenchainRESTServer(serverOpenchain, serverDevops)
    }
    logger.Infof("Starting peer with ID=%s, network ID=%s, address=%s, rootnodes=%v, validator=%v",
        peerEndpoint.ID, viper.GetString("peer.networkId"), peerEndpoint.Address,
        viper.GetString("peer.discovery.rootnode"), peer.ValidatorEnabled())
    // 启动GRPC服务器. 如果是必须的话在一个goroutine中完成这样我们能够部署genesis
    serve := make(chan error)
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        serve <- nil
    }()
    go func() {
        var grpcErr error
        if grpcErr = grpcServer.Serve(lis); grpcErr != nil {
            grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr)
        } else {
            logger.Info("grpc server exited")
        }
        serve <- grpcErr
    }()
    if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil {
        return err
    }
    // 启动eventHub服务
    if ehubGrpcServer != nil && ehubLis != nil {
        go ehubGrpcServer.Serve(ehubLis)
    }
    if viper.GetBool("peer.profile.enabled") {
        go func() {
            profileListenAddress := viper.GetString("peer.profile.listenAddress")
            logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress)
            if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil {
                logger.Errorf("Error starting profiler: %s", profileErr)
            }
        }()
    }
    // Block until grpc server exits 产生块直到grpc服务退出
    return <-serve
}
所过程在代码中的注释可以看明白

对图中peer节点启动之后的peer address 172.17.0.3:7051灰色部分的的代码提取分析,7051:peer gRPC 服务监听端口。下面是Hyperledger中相关监听的服务端口

默认包括:以下监听的服务端口对应hyperledger0.6版本,与其他版本无关。

7050: REST 服务端口

7051:peer gRPC 服务监听端口

7052:peer CLI 端口

7053:peer 事件服务端口

7054:eCAP7055:eCAA

7056:tCAP

7057:tCAA

7058:tlsCAP

7059:tlsCAA

图中的CacheConfiguration()这个函数到底做了什么?请看下面

// CacheConfiguration计算和缓存经常使用的常量且计算常量做为包变量,按照惯例前面的全局变量

// 已经被嵌入在这里为了保留原始的抽象状态
func CacheConfiguration() (err error) {
    // getLocalAddress 返回正在操作的本地peer的address:port,受到env:peer.addressAutoDetect的影响
    getLocalAddress := func() (peerAddress string, err error) {
        if viper.GetBool("peer.addressAutoDetect") {
            // 需要从peer.address设置中获取端口号,并将其添加到已经确定的主机ip后
            _, port, err := net.SplitHostPort(viper.GetString("peer.address"))
            if err != nil {
                err = fmt.Errorf("Error auto detecting Peer's address: %s", err)
                return "", err
            }
            peerAddress = net.JoinHostPort(GetLocalIP(), port)
            peerLogger.Infof("Auto detected peer address: %s", peerAddress)
        } else {
            peerAddress = viper.GetString("peer.address")
        }
        return
    }
    // getPeerEndpoint 对于这个Peer实例来说,返回PeerEndpoint,受到env:peer.addressAutoDetect的影响
    getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
        var peerAddress string
        var peerType pb.PeerEndpoint_Type
        peerAddress, err := getLocalAddress()
        if err != nil {
            return nil, err
        }
        if viper.GetBool("peer.validator.enabled") {
            peerType = pb.PeerEndpoint_VALIDATOR
        } else {
            peerType = pb.PeerEndpoint_NON_VALIDATOR
        }
        return &pb.PeerEndpoint{ID: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress, Type: peerType}, nil
    }
    localAddress, localAddressError = getLocalAddress()
    peerEndpoint, peerEndpointError = getPeerEndpoint()
    syncStateSnapshotChannelSize = viper.GetInt("peer.sync.state.snapshot.channelSize")
    syncStateDeltasChannelSize = viper.GetInt("peer.sync.state.deltas.channelSize")
    syncBlocksChannelSize = viper.GetInt("peer.sync.blocks.channelSize")
    validatorEnabled = viper.GetBool("peer.validator.enabled")
    securityEnabled = viper.GetBool("security.enabled")
    configurationCached = true
    if localAddressError != nil {
        return localAddressError
    } else if peerEndpointError != nil {
        return peerEndpointError
    }
    return
}
// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// GetPeerEndpoint 从缓存配置中返回peerEndpoint
func GetPeerEndpoint() (*pb.PeerEndpoint, error) {
    if !configurationCached {
        cacheConfiguration()
    }
    return peerEndpoint, peerEndpointError
}

// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }



如图所示,我们要分析的是registering BLOCK,registering CHAINCODE,registering REJECTION和registering REGISTER的整个过程


下图是代码流程图


func createEventHubServer() (net.Listener, *grpc.Server, error) {

    var lis net.Listener
    var grpcServer *grpc.Server
    var err error
    // ValidatorEnabled返回peer.validator.enabled是否可用
    if peer.ValidatorEnabled() {
        lis, err = net.Listen("tcp", viper.GetString("peer.validator.events.address"))
        if err != nil {
            return nil, nil, fmt.Errorf("failed to listen: %v", err)
        }
        //TODO - do we need different SSL material for events ?
        var opts []grpc.ServerOption
        // TLSEnabled返回peer.tls.enabled配置好的值的缓存值
        if comm.TLSEnabled() {
            //NewServerTLSFromFile是gRPC库的函数,主要目的是为获取tls的证书和密钥
            creds, err := credentials.NewServerTLSFromFile(
                viper.GetString("peer.tls.cert.file"),
                viper.GetString("peer.tls.key.file"))
            if err != nil {
                return nil, nil, fmt.Errorf("Failed to generate credentials %v", err)
            }
            opts = []grpc.ServerOption{grpc.Creds(creds)}
        }
        grpcServer = grpc.NewServer(opts...)
        ehServer := producer.NewEventsServer(
            uint(viper.GetInt("peer.validator.events.buffersize")),
            viper.GetInt("peer.validator.events.timeout"))
        //注册事件服务
        pb.RegisterEventsServer(grpcServer, ehServer)
    }
    return lis, grpcServer, err
}

// ValidatorEnabled返回peer.validator.enabled是否可用

func ValidatorEnabled() bool {
    if !configurationCached {
        cacheConfiguration()
    }
    return validatorEnabled
}
// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// TLSEnabled返回peer.tls.enabled配置好的值的缓存值
func TLSEnabled() bool {
    if !configurationCached {
        cacheConfiguration()
    }
    return tlsEnabled
}
// cacheConfiguration如果检查失败打错误日志.
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        commLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// NewEventsServer 返回一个事件服务器
func NewEventsServer(bufferSize uint, timeout int) *EventsServer {
    if globalEventsServer != nil {
        panic("Cannot create multiple event hub servers")
    }
    globalEventsServer = new(EventsServer)
    //初始化并且开启事件
    initializeEvents(bufferSize, timeout)
    //initializeCCEventProcessor(bufferSize, timeout)
    return globalEventsServer
}
//初始化并且开启事件
func initializeEvents(bufferSize uint, tout int) {
    if gEventProcessor != nil {
        panic("should not be called twice")
    }
    gEventProcessor = &eventProcessor{eventConsumers: make(map[pb.EventType]handlerList), eventChannel: make(chan *pb.Event, bufferSize), timeout: tout}
    addInternalEventTypes()
    //启动事件进程器
    go gEventProcessor.start()
}

func addInternalEventTypes() {
    AddEventType(pb.EventType_BLOCK)
    AddEventType(pb.EventType_CHAINCODE)
    AddEventType(pb.EventType_REJECTION)
    AddEventType(pb.EventType_REGISTER)
}
//AddEventType 添加支持的事件类型
func AddEventType(eventType pb.EventType) error {
    gEventProcessor.Lock()
    producerLogger.Debugf("registering %s", pb.EventType_name[int32(eventType)])
    if _, ok := gEventProcessor.eventConsumers[eventType]; ok {
        gEventProcessor.Unlock()
        return fmt.Errorf("event type exists %s", pb.EventType_name[int32(eventType)])
    }
    switch eventType {
    case pb.EventType_BLOCK:
        gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)}
    case pb.EventType_CHAINCODE:
        gEventProcessor.eventConsumers[eventType] = &chaincodeHandlerList{handlers: make(map[string]map[string]map[*handler]bool)}
    case pb.EventType_REJECTION:
        gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)}
    }
    gEventProcessor.Unlock()
    return nil
}
func (ep *eventProcessor) start() {
    producerLogger.Info("event processor started")
    for {
        //等待事件
        e := <-ep.eventChannel
        var hl handlerList
        eType := getMessageType(e)
        ep.Lock()
        if hl, _ = ep.eventConsumers[eType]; hl == nil {
            producerLogger.Errorf("Event of type %s does not exist", eType)
            ep.Unlock()
            continue
        }
        //lock the handler map lock
        ep.Unlock()
        hl.foreach(e, func(h *handler) {
            if e.Event != nil {
                h.SendMessage(e)
            }
        })
    }
}
// 获取消息类型
func getMessageType(e *pb.Event) pb.EventType {
    switch e.Event.(type) {
    case *pb.Event_Register:
        return pb.EventType_REGISTER
    case *pb.Event_Block:
        return pb.EventType_BLOCK
    case *pb.Event_ChaincodeEvent:
        return pb.EventType_CHAINCODE
    case *pb.Event_Rejection:
        return pb.EventType_REJECTION
    default:
        return -1
    }
}
// SendMessage 通过流发送一条消息给远程的peer
func (d *handler) SendMessage(msg *pb.Event) error {
    err := d.ChatStream.Send(msg)
    if err != nil {
        return fmt.Errorf("Error Sending message through ChatStream: %s", err)
    }
    return nil
}

func RegisterEventsServer(s *grpc.Server, srv EventsServer) {

    s.RegisterService(&_Events_serviceDesc, srv)
}

一些重要的变量

type eventProcessor struct {

    sync.RWMutex
    eventConsumers map[pb.EventType]handlerList
    //we could generalize this with mutiple channels each with its own size
    // 产生多个大小限定的channels
    eventChannel chan *pb.Event
    //milliseconds timeout for producer to send an event.
    //毫秒级别的超时触发器发送一个事件
    //if < 0, if buffer full, unblocks immediately and not send
    //如果小于0,如果缓冲区满的,立即解锁并且不发送事件
    //if 0, if buffer full, will block and guarantee the event will be sent out
    // 如是0,如果缓冲区满的,将上锁并保证事件不会被发出去
    //if > 0, if buffer full, blocks till timeout
    //如果是0,如果缓冲区是满的,上锁直到超时
    timeout int
}
// 通过initializeEvents函数来创建全局eventProcessor单列模式 Openchain producers
// Openchain仅仅通过一个重入的静态方法生产并发送事件
var gEventProcessor *eventProcessor

type EventType int32


const (
    EventType_REGISTER  EventType = 0
    EventType_BLOCK     EventType = 1
    EventType_CHAINCODE EventType = 2
    EventType_REJECTION EventType = 3
)
var EventType_name = map[int32]string{
    0: "REGISTER",
    1: "BLOCK",
    2: "CHAINCODE",
    3: "REJECTION",
}
var EventType_value = map[string]int32{
    "REGISTER":  0,
    "BLOCK":     1,
    "CHAINCODE": 2,
    "REJECTION": 3,
}

// Event is used by

//  - consumers (adapters) to send Register
//  - producer to advertise supported types and events
type Event struct {
    // Types that are valid to be assigned to Event:
    //    *Event_Register
    //    *Event_Block
    //    *Event_ChaincodeEvent
    //    *Event_Rejection
    //    *Event_Unregister
    Event isEvent_Event `protobuf_oneof:"Event"`
}

由图片可以看出peer启动节点后先初始化一下日志

然后进入Server函数

//==============================================================================

//peer node start 之后做日志初始化之后就进入到server函数
//==============================================================================
func serve(args []string) error {
    // Parameter overrides must be processed before any paramaters are
    // cached. Failures to cache cause the server to terminate immediately.
    //在其他参数被缓存起来之前参数覆盖必须处理,失败缓存导致服务立即结束
    if chaincodeDevMode {
        logger.Info("Running in chaincode development mode")
        logger.Info("Set consensus to NOOPS and user starts chaincode")
        logger.Info("Disable loading validity system chaincode")
        viper.Set("peer.validator.enabled", "true")
        viper.Set("peer.validator.consensus", "noops")
        viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
    }
    if err := peer.CacheConfiguration(); err != nil {
        return err
    }
    peerEndpoint, err := peer.GetPeerEndpoint()
    if err != nil {
        err = fmt.Errorf("Failed to get Peer Endpoint: %s", err)
        return err
    }
    //启动grpc服务,监听7051端口
    listenAddr := viper.GetString("peer.listenAddress")
    if "" == listenAddr {
        logger.Debug("Listen address not specified, using peer endpoint address")
        listenAddr = peerEndpoint.Address
    }
    lis, err := net.Listen("tcp", listenAddr)
    if err != nil {
        grpclog.Fatalf("Failed to listen: %v", err)
    }
    //创建EventHub服务器,通过调用createEventHubServer方法实现,该服务也是grpc,只有VP
    //才能开启
    ehubLis, ehubGrpcServer, err := createEventHubServer()
    if err != nil {
        grpclog.Fatalf("Failed to create ehub server: %v", err)
    }
    logger.Infof("Security enabled status: %t", core.SecurityEnabled())
    if viper.GetBool("security.privacy") {
        if core.SecurityEnabled() {
            logger.Infof("Privacy enabled status: true")
        } else {
            panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
        }
    } else {
        logger.Infof("Privacy enabled status: false")
    }
    //启动rockdb数据库
    db.Start()
    var opts []grpc.ServerOption
    if comm.TLSEnabled() {
        creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"),
            viper.GetString("peer.tls.key.file"))
        if err != nil {
            grpclog.Fatalf("Failed to generate credentials %v", err)
        }
        opts = []grpc.ServerOption{grpc.Creds(creds)}
    }
    //创建一个grpc服务
    grpcServer := grpc.NewServer(opts...)
    //注册Chaincode支持服务器
    secHelper, err := getSecHelper()
    if err != nil {
        return err
    }
    secHelperFunc := func() crypto.Peer {
        return secHelper
    }
    registerChaincodeSupport(chaincode.DefaultChain, grpcServer, secHelper)
    var peerServer *peer.Impl
    // 创建peer服务器,主意区分VP和NVP节点
    if peer.ValidatorEnabled() {
        logger.Debug("Running as validating peer - making genesis block if needed")
        makeGenesisError := genesis.MakeGenesis()
        if makeGenesisError != nil {
            return makeGenesisError
        }
        logger.Debugf("Running as validating peer - installing consensus %s",
            viper.GetString("peer.validator.consensus"))
        peerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine)
    } else {
        logger.Debug("Running as non-validating peer")
        peerServer, err = peer.NewPeerWithHandler(secHelperFunc, peer.NewPeerHandler)
    }
    if err != nil {
        logger.Fatalf("Failed creating new peer with handler %v", err)
        return err
    }
    // 注册peer服务
    pb.RegisterPeerServer(grpcServer, peerServer)
    // 注册管理服务器
    pb.RegisterAdminServer(grpcServer, core.NewAdminServer())
    // 注册Devops服务器
    serverDevops := core.NewDevopsServer(peerServer)
    pb.RegisterDevopsServer(grpcServer, serverDevops)
    // 注册ServerOpenchain服务器
    serverOpenchain, err := rest.NewOpenchainServerWithPeerInfo(peerServer)
    if err != nil {
        err = fmt.Errorf("Error creating OpenchainServer: %s", err)
        return err
    }
    pb.RegisterOpenchainServer(grpcServer, serverOpenchain)
    // 如果配置了的话创建和注册REST服务
    if viper.GetBool("rest.enabled") {
        go rest.StartOpenchainRESTServer(serverOpenchain, serverDevops)
    }
    logger.Infof("Starting peer with ID=%s, network ID=%s, address=%s, rootnodes=%v, validator=%v",
        peerEndpoint.ID, viper.GetString("peer.networkId"), peerEndpoint.Address,
        viper.GetString("peer.discovery.rootnode"), peer.ValidatorEnabled())
    // 启动GRPC服务器. 如果是必须的话在一个goroutine中完成这样我们能够部署genesis
    serve := make(chan error)
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        serve <- nil
    }()
    go func() {
        var grpcErr error
        if grpcErr = grpcServer.Serve(lis); grpcErr != nil {
            grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr)
        } else {
            logger.Info("grpc server exited")
        }
        serve <- grpcErr
    }()
    if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil {
        return err
    }
    // 启动eventHub服务
    if ehubGrpcServer != nil && ehubLis != nil {
        go ehubGrpcServer.Serve(ehubLis)
    }
    if viper.GetBool("peer.profile.enabled") {
        go func() {
            profileListenAddress := viper.GetString("peer.profile.listenAddress")
            logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress)
            if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil {
                logger.Errorf("Error starting profiler: %s", profileErr)
            }
        }()
    }
    // Block until grpc server exits 产生块直到grpc服务退出
    return <-serve
}
所过程在代码中的注释可以看明白

对图中peer节点启动之后的peer address 172.17.0.3:7051灰色部分的的代码提取分析,7051:peer gRPC 服务监听端口。下面是Hyperledger中相关监听的服务端口

默认包括:以下监听的服务端口对应hyperledger0.6版本,与其他版本无关。

7050: REST 服务端口

7051:peer gRPC 服务监听端口

7052:peer CLI 端口

7053:peer 事件服务端口

7054:eCAP7055:eCAA

7056:tCAP

7057:tCAA

7058:tlsCAP

7059:tlsCAA

图中的CacheConfiguration()这个函数到底做了什么?请看下面

// CacheConfiguration计算和缓存经常使用的常量且计算常量做为包变量,按照惯例前面的全局变量

// 已经被嵌入在这里为了保留原始的抽象状态
func CacheConfiguration() (err error) {
    // getLocalAddress 返回正在操作的本地peer的address:port,受到env:peer.addressAutoDetect的影响
    getLocalAddress := func() (peerAddress string, err error) {
        if viper.GetBool("peer.addressAutoDetect") {
            // 需要从peer.address设置中获取端口号,并将其添加到已经确定的主机ip后
            _, port, err := net.SplitHostPort(viper.GetString("peer.address"))
            if err != nil {
                err = fmt.Errorf("Error auto detecting Peer's address: %s", err)
                return "", err
            }
            peerAddress = net.JoinHostPort(GetLocalIP(), port)
            peerLogger.Infof("Auto detected peer address: %s", peerAddress)
        } else {
            peerAddress = viper.GetString("peer.address")
        }
        return
    }
    // getPeerEndpoint 对于这个Peer实例来说,返回PeerEndpoint,受到env:peer.addressAutoDetect的影响
    getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
        var peerAddress string
        var peerType pb.PeerEndpoint_Type
        peerAddress, err := getLocalAddress()
        if err != nil {
            return nil, err
        }
        if viper.GetBool("peer.validator.enabled") {
            peerType = pb.PeerEndpoint_VALIDATOR
        } else {
            peerType = pb.PeerEndpoint_NON_VALIDATOR
        }
        return &pb.PeerEndpoint{ID: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress, Type: peerType}, nil
    }
    localAddress, localAddressError = getLocalAddress()
    peerEndpoint, peerEndpointError = getPeerEndpoint()
    syncStateSnapshotChannelSize = viper.GetInt("peer.sync.state.snapshot.channelSize")
    syncStateDeltasChannelSize = viper.GetInt("peer.sync.state.deltas.channelSize")
    syncBlocksChannelSize = viper.GetInt("peer.sync.blocks.channelSize")
    validatorEnabled = viper.GetBool("peer.validator.enabled")
    securityEnabled = viper.GetBool("security.enabled")
    configurationCached = true
    if localAddressError != nil {
        return localAddressError
    } else if peerEndpointError != nil {
        return peerEndpointError
    }
    return
}
// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// GetPeerEndpoint 从缓存配置中返回peerEndpoint
func GetPeerEndpoint() (*pb.PeerEndpoint, error) {
    if !configurationCached {
        cacheConfiguration()
    }
    return peerEndpoint, peerEndpointError
}

// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }

如图所示,我们要分析的是registering BLOCK,registering CHAINCODE,registering REJECTION和registering REGISTER的整个过程


下图是代码流程图


func createEventHubServer() (net.Listener, *grpc.Server, error) {

    var lis net.Listener
    var grpcServer *grpc.Server
    var err error
    // ValidatorEnabled返回peer.validator.enabled是否可用
    if peer.ValidatorEnabled() {
        lis, err = net.Listen("tcp", viper.GetString("peer.validator.events.address"))
        if err != nil {
            return nil, nil, fmt.Errorf("failed to listen: %v", err)
        }
        //TODO - do we need different SSL material for events ?
        var opts []grpc.ServerOption
        // TLSEnabled返回peer.tls.enabled配置好的值的缓存值
        if comm.TLSEnabled() {
            //NewServerTLSFromFile是gRPC库的函数,主要目的是为获取tls的证书和密钥
            creds, err := credentials.NewServerTLSFromFile(
                viper.GetString("peer.tls.cert.file"),
                viper.GetString("peer.tls.key.file"))
            if err != nil {
                return nil, nil, fmt.Errorf("Failed to generate credentials %v", err)
            }
            opts = []grpc.ServerOption{grpc.Creds(creds)}
        }
        grpcServer = grpc.NewServer(opts...)
        ehServer := producer.NewEventsServer(
            uint(viper.GetInt("peer.validator.events.buffersize")),
            viper.GetInt("peer.validator.events.timeout"))
        //注册事件服务
        pb.RegisterEventsServer(grpcServer, ehServer)
    }
    return lis, grpcServer, err
}

// ValidatorEnabled返回peer.validator.enabled是否可用

func ValidatorEnabled() bool {
    if !configurationCached {
        cacheConfiguration()
    }
    return validatorEnabled
}
// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// TLSEnabled返回peer.tls.enabled配置好的值的缓存值
func TLSEnabled() bool {
    if !configurationCached {
        cacheConfiguration()
    }
    return tlsEnabled
}
// cacheConfiguration如果检查失败打错误日志.
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        commLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// NewEventsServer 返回一个事件服务器
func NewEventsServer(bufferSize uint, timeout int) *EventsServer {
    if globalEventsServer != nil {
        panic("Cannot create multiple event hub servers")
    }
    globalEventsServer = new(EventsServer)
    //初始化并且开启事件
    initializeEvents(bufferSize, timeout)
    //initializeCCEventProcessor(bufferSize, timeout)
    return globalEventsServer
}
//初始化并且开启事件
func initializeEvents(bufferSize uint, tout int) {
    if gEventProcessor != nil {
        panic("should not be called twice")
    }
    gEventProcessor = &eventProcessor{eventConsumers: make(map[pb.EventType]handlerList), eventChannel: make(chan *pb.Event, bufferSize), timeout: tout}
    addInternalEventTypes()
    //启动事件进程器
    go gEventProcessor.start()
}

func addInternalEventTypes() {
    AddEventType(pb.EventType_BLOCK)
    AddEventType(pb.EventType_CHAINCODE)
    AddEventType(pb.EventType_REJECTION)
    AddEventType(pb.EventType_REGISTER)
}
//AddEventType 添加支持的事件类型
func AddEventType(eventType pb.EventType) error {
    gEventProcessor.Lock()
    producerLogger.Debugf("registering %s", pb.EventType_name[int32(eventType)])
    if _, ok := gEventProcessor.eventConsumers[eventType]; ok {
        gEventProcessor.Unlock()
        return fmt.Errorf("event type exists %s", pb.EventType_name[int32(eventType)])
    }
    switch eventType {
    case pb.EventType_BLOCK:
        gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)}
    case pb.EventType_CHAINCODE:
        gEventProcessor.eventConsumers[eventType] = &chaincodeHandlerList{handlers: make(map[string]map[string]map[*handler]bool)}
    case pb.EventType_REJECTION:
        gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)}
    }
    gEventProcessor.Unlock()
    return nil
}
func (ep *eventProcessor) start() {
    producerLogger.Info("event processor started")
    for {
        //等待事件
        e := <-ep.eventChannel
        var hl handlerList
        eType := getMessageType(e)
        ep.Lock()
        if hl, _ = ep.eventConsumers[eType]; hl == nil {
            producerLogger.Errorf("Event of type %s does not exist", eType)
            ep.Unlock()
            continue
        }
        //lock the handler map lock
        ep.Unlock()
        hl.foreach(e, func(h *handler) {
            if e.Event != nil {
                h.SendMessage(e)
            }
        })
    }
}
// 获取消息类型
func getMessageType(e *pb.Event) pb.EventType {
    switch e.Event.(type) {
    case *pb.Event_Register:
        return pb.EventType_REGISTER
    case *pb.Event_Block:
        return pb.EventType_BLOCK
    case *pb.Event_ChaincodeEvent:
        return pb.EventType_CHAINCODE
    case *pb.Event_Rejection:
        return pb.EventType_REJECTION
    default:
        return -1
    }
}
// SendMessage 通过流发送一条消息给远程的peer
func (d *handler) SendMessage(msg *pb.Event) error {
    err := d.ChatStream.Send(msg)
    if err != nil {
        return fmt.Errorf("Error Sending message through ChatStream: %s", err)
    }
    return nil
}

func RegisterEventsServer(s *grpc.Server, srv EventsServer) {

    s.RegisterService(&_Events_serviceDesc, srv)
}

一些重要的变量

type eventProcessor struct {

    sync.RWMutex
    eventConsumers map[pb.EventType]handlerList
    //we could generalize this with mutiple channels each with its own size
    // 产生多个大小限定的channels
    eventChannel chan *pb.Event
    //milliseconds timeout for producer to send an event.
    //毫秒级别的超时触发器发送一个事件
    //if < 0, if buffer full, unblocks immediately and not send
    //如果小于0,如果缓冲区满的,立即解锁并且不发送事件
    //if 0, if buffer full, will block and guarantee the event will be sent out
    // 如是0,如果缓冲区满的,将上锁并保证事件不会被发出去
    //if > 0, if buffer full, blocks till timeout
    //如果是0,如果缓冲区是满的,上锁直到超时
    timeout int
}
// 通过initializeEvents函数来创建全局eventProcessor单列模式 Openchain producers
// Openchain仅仅通过一个重入的静态方法生产并发送事件
var gEventProcessor *eventProcessor

type EventType int32


const (
    EventType_REGISTER  EventType = 0
    EventType_BLOCK     EventType = 1
    EventType_CHAINCODE EventType = 2
    EventType_REJECTION EventType = 3
)
var EventType_name = map[int32]string{
    0: "REGISTER",
    1: "BLOCK",
    2: "CHAINCODE",
    3: "REJECTION",
}
var EventType_value = map[string]int32{
    "REGISTER":  0,
    "BLOCK":     1,
    "CHAINCODE": 2,
    "REJECTION": 3,
}

// Event is used by

//  - consumers (adapters) to send Register
//  - producer to advertise supported types and events
type Event struct {
    // Types that are valid to be assigned to Event:
    //    *Event_Register
    //    *Event_Block
    //    *Event_ChaincodeEvent
    //    *Event_Rejection
    //    *Event_Unregister
    Event isEvent_Event `protobuf_oneof:"Event"`
}

我们都知道,Hyperledger用的数据库是rocksDB,如果你不做修改的话,数据会存储在/var/hyperledger/production/db目录下。

现在我们来分析一下图中灰色部分的相关代码。

代码结构图如下

// 启动数据库, 初始化openchainDB实例并打开数据库.注意该方法不能保证正确行为的并发调用

func Start() {
    openchainDB.open()
}
// Open 打开已经存在于hyperledger中的数据库
func (openchainDB *OpenchainDB) open() {
    dbPath := getDBPath()
    missing, err := dirMissingOrEmpty(dbPath)
    if err != nil {
        panic(fmt.Sprintf("Error while trying to open DB: %s", err))
    }
    dbLogger.Debugf("Is db path [%s] empty [%t]", dbPath, missing)
    if missing {
        err = os.MkdirAll(path.Dir(dbPath), 0755)
        if err != nil {
            panic(fmt.Sprintf("Error making directory path [%s]: %s", dbPath, err))
        }
    }
    opts := gorocksdb.NewDefaultOptions()
    defer opts.Destroy()
    maxLogFileSize := viper.GetInt("peer.db.maxLogFileSize")
    if maxLogFileSize > 0 {
        dbLogger.Infof("Setting rocksdb maxLogFileSize to %d", maxLogFileSize)
        opts.SetMaxLogFileSize(maxLogFileSize)
    }
    keepLogFileNum := viper.GetInt("peer.db.keepLogFileNum")
    if keepLogFileNum > 0 {
        dbLogger.Infof("Setting rocksdb keepLogFileNum to %d", keepLogFileNum)
        opts.SetKeepLogFileNum(keepLogFileNum)
    }
    logLevelStr := viper.GetString("peer.db.loglevel")
    logLevel, ok := rocksDBLogLevelMap[logLevelStr]
    if ok {
        dbLogger.Infof("Setting rocks db InfoLogLevel to %d", logLevel)
        opts.SetInfoLogLevel(logLevel)
    }
    opts.SetCreateIfMissing(missing)
    opts.SetCreateIfMissingColumnFamilies(true)
    cfNames := []string{"default"}
    cfNames = append(cfNames, columnfamilies...)
    var cfOpts []*gorocksdb.Options
    for range cfNames {
        cfOpts = append(cfOpts, opts)
    }
    db, cfHandlers, err := gorocksdb.OpenDbColumnFamilies(opts, dbPath, cfNames, cfOpts)
    if err != nil {
        panic(fmt.Sprintf("Error opening DB: %s", err))
    }
    openchainDB.DB = db
    openchainDB.BlockchainCF = cfHandlers[1]
    openchainDB.StateCF = cfHandlers[2]
    openchainDB.StateDeltaCF = cfHandlers[3]
    openchainDB.IndexesCF = cfHandlers[4]
    openchainDB.PersistCF = cfHandlers[5]
}
// NewDefaultOptions 创建一个默认的Options.
func NewDefaultOptions() *Options {
    return NewNativeOptions(C.rocksdb_options_create())
}
// Options表示当以open形式打开一个数据库时所有可选的options
type Options struct {
    c *C.rocksdb_options_t
    // 保持引用GC.
    env  *Env
    bbto *BlockBasedTableOptions
    // 在Destroy的时候我们要保证能够释放他们的内存
    ccmp *C.rocksdb_comparator_t
    cmo  *C.rocksdb_mergeoperator_t
    cst  *C.rocksdb_slicetransform_t
    ccf  *C.rocksdb_compactionfilter_t
}
// NewDefaultOptions 创建一个默认的Options.
func NewDefaultOptions() *Options {
    return NewNativeOptions(C.rocksdb_options_create())
}
// NewNativeOptions 创建一个Options对象.
func NewNativeOptions(c *C.rocksdb_options_t) *Options {
    return &Options{c: c}
}
// NewNativeOptions 创建一个Options对象.
func NewNativeOptions(c *C.rocksdb_options_t) *Options {
    return &Options{c: c}
}
// Options表示当以open形式打开一个数据库时所有可选的options
type Options struct {
    c *C.rocksdb_options_t
    // 保持引用GC.
    env  *Env
    bbto *BlockBasedTableOptions
    // 在Destroy的时候我们要保证能够释放他们的内存
    ccmp *C.rocksdb_comparator_t
    cmo  *C.rocksdb_mergeoperator_t
    cst  *C.rocksdb_slicetransform_t
    ccf  *C.rocksdb_compactionfilter_t
}
// SetMaxLogFileSize 设置信息日志文件的最大尺寸
// 如果日志文件大于max_log_file_size常量,新的日志将会被创建
// 如果max_log_file_size等于0,所有的日志都被写到一个log日志
// 默认大小:0
func (opts *Options) SetMaxLogFileSize(value int) {
    C.rocksdb_options_set_max_log_file_size(opts.c, C.size_t(value))
}
// SetKeepLogFileNum 设置保存的最大日志信息文件
// 默认大小: 1000
func (opts *Options) SetKeepLogFileNum(value int) {
    C.rocksdb_options_set_keep_log_file_num(opts.c, C.size_t(value))
}
// SetInfoLogLevel 设置日志信息的级别.
// 默认级别: InfoInfoLogLevel
func (opts *Options) SetInfoLogLevel(value InfoLogLevel) {
    C.rocksdb_options_set_info_log_level(opts.c, C.int(value))
}
// InfoLogLevel描述日志级别.
type InfoLogLevel uint
// 日志级别.
const (
    DebugInfoLogLevel = InfoLogLevel(0)
    InfoInfoLogLevel  = InfoLogLevel(1)
    WarnInfoLogLevel  = InfoLogLevel(2)
    ErrorInfoLogLevel = InfoLogLevel(3)
    FatalInfoLogLevel = InfoLogLevel(4)
)
// SetCreateIfMissing 如果数据库丢失了指定数据库是不是应该被创建
// 默认值: false
func (opts *Options) SetCreateIfMissing(value bool) {
    C.rocksdb_options_set_create_if_missing(opts.c, boolToChar(value))
}
// SetCreateIfMissingColumnFamilies 如果指定的列丢失啦是不是应该被创建
func (opts *Options) SetCreateIfMissingColumnFamilies(value bool) {
    C.rocksdb_options_set_create_missing_column_families(opts.c, boolToChar(value))
}
// 打开列家族
    db, cfHandlers, err := gorocksdb.OpenDbColumnFamilies(opts, dbPath, cfNames, cfOpts)






由图片可以看出peer启动节点后先初始化一下日志

然后进入Server函数

//==============================================================================

//peer node start 之后做日志初始化之后就进入到server函数
//==============================================================================
func serve(args []string) error {
    // Parameter overrides must be processed before any paramaters are
    // cached. Failures to cache cause the server to terminate immediately.
    //在其他参数被缓存起来之前参数覆盖必须处理,失败缓存导致服务立即结束
    if chaincodeDevMode {
        logger.Info("Running in chaincode development mode")
        logger.Info("Set consensus to NOOPS and user starts chaincode")
        logger.Info("Disable loading validity system chaincode")
 
 
        viper.Set("peer.validator.enabled", "true")
        viper.Set("peer.validator.consensus", "noops")
        viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
 
 
    }
 
 
    if err := peer.CacheConfiguration(); err != nil {
        return err
    }
 
 
    peerEndpoint, err := peer.GetPeerEndpoint()
    if err != nil {
        err = fmt.Errorf("Failed to get Peer Endpoint: %s", err)
        return err
    }
 
 
    //启动grpc服务,监听7051端口
    listenAddr := viper.GetString("peer.listenAddress")
 
 
    if "" == listenAddr {
        logger.Debug("Listen address not specified, using peer endpoint address")
        listenAddr = peerEndpoint.Address
    }
 
 
    lis, err := net.Listen("tcp", listenAddr)
    if err != nil {
        grpclog.Fatalf("Failed to listen: %v", err)
    }
    //创建EventHub服务器,通过调用createEventHubServer方法实现,该服务也是grpc,只有VP
    //才能开启
    ehubLis, ehubGrpcServer, err := createEventHubServer()
    if err != nil {
        grpclog.Fatalf("Failed to create ehub server: %v", err)
    }
 
 
    logger.Infof("Security enabled status: %t", core.SecurityEnabled())
    if viper.GetBool("security.privacy") {
        if core.SecurityEnabled() {
            logger.Infof("Privacy enabled status: true")
        } else {
            panic(errors.New("Privacy cannot be enabled as requested because security is disabled"))
        }
    } else {
        logger.Infof("Privacy enabled status: false")
    }
    //启动rockdb数据库
    db.Start()
 
 
    var opts []grpc.ServerOption
    if comm.TLSEnabled() {
        creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"),
            viper.GetString("peer.tls.key.file"))
 
 
        if err != nil {
            grpclog.Fatalf("Failed to generate credentials %v", err)
        }
        opts = []grpc.ServerOption{grpc.Creds(creds)}
    }
 
 
    //创建一个grpc服务
    grpcServer := grpc.NewServer(opts...)
 
 
    //注册Chaincode支持服务器
    secHelper, err := getSecHelper()
    if err != nil {
        return err
    }
 
 
    secHelperFunc := func() crypto.Peer {
        return secHelper
    }
 
 
    registerChaincodeSupport(chaincode.DefaultChain, grpcServer, secHelper)
 
 
    var peerServer *peer.Impl
 
 
    // 创建peer服务器,主意区分VP和NVP节点
    if peer.ValidatorEnabled() {
        logger.Debug("Running as validating peer - making genesis block if needed")
        makeGenesisError := genesis.MakeGenesis()
        if makeGenesisError != nil {
            return makeGenesisError
        }
        logger.Debugf("Running as validating peer - installing consensus %s",
            viper.GetString("peer.validator.consensus"))
 
 
        peerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine)
    } else {
        logger.Debug("Running as non-validating peer")
        peerServer, err = peer.NewPeerWithHandler(secHelperFunc, peer.NewPeerHandler)
    }
 
 
    if err != nil {
        logger.Fatalf("Failed creating new peer with handler %v", err)
 
 
        return err
    }
 
 
    // 注册peer服务
    pb.RegisterPeerServer(grpcServer, peerServer)
 
 
    // 注册管理服务器
    pb.RegisterAdminServer(grpcServer, core.NewAdminServer())
 
 
    // 注册Devops服务器
    serverDevops := core.NewDevopsServer(peerServer)
    pb.RegisterDevopsServer(grpcServer, serverDevops)
 
 
    // 注册ServerOpenchain服务器
    serverOpenchain, err := rest.NewOpenchainServerWithPeerInfo(peerServer)
    if err != nil {
        err = fmt.Errorf("Error creating OpenchainServer: %s", err)
        return err
    }
 
 
    pb.RegisterOpenchainServer(grpcServer, serverOpenchain)
 
 
    // 如果配置了的话创建和注册REST服务
    if viper.GetBool("rest.enabled") {
        go rest.StartOpenchainRESTServer(serverOpenchain, serverDevops)
    }
 
 
    logger.Infof("Starting peer with ID=%s, network ID=%s, address=%s, rootnodes=%v, validator=%v",
        peerEndpoint.ID, viper.GetString("peer.networkId"), peerEndpoint.Address,
        viper.GetString("peer.discovery.rootnode"), peer.ValidatorEnabled())
 
 
    // 启动GRPC服务器. 如果是必须的话在一个goroutine中完成这样我们能够部署genesis
    serve := make(chan error)
 
 
    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        serve <- nil
    }()
 
 
    go func() {
        var grpcErr error
        if grpcErr = grpcServer.Serve(lis); grpcErr != nil {
            grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr)
        } else {
            logger.Info("grpc server exited")
        }
        serve <- grpcErr
    }()
 
 
    if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil {
        return err
    }
 
 
    // 启动eventHub服务
    if ehubGrpcServer != nil && ehubLis != nil {
        go ehubGrpcServer.Serve(ehubLis)
    }
 
 
    if viper.GetBool("peer.profile.enabled") {
        go func() {
            profileListenAddress := viper.GetString("peer.profile.listenAddress")
            logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress)
            if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil {
                logger.Errorf("Error starting profiler: %s", profileErr)
            }
        }()
    }
 
 
    // Block until grpc server exits 产生块直到grpc服务退出
    return <-serve
}
所过程在代码中的注释可以看明白

对图中peer节点启动之后的peer address 172.17.0.3:7051灰色部分的的代码提取分析,7051:peer gRPC 服务监听端口。下面是Hyperledger中相关监听的服务端口

默认包括:以下监听的服务端口对应hyperledger0.6版本,与其他版本无关。

7050: REST 服务端口

7051:peer gRPC 服务监听端口

7052:peer CLI 端口

7053:peer 事件服务端口

7054:eCAP7055:eCAA

7056:tCAP

7057:tCAA

7058:tlsCAP

7059:tlsCAA

图中的CacheConfiguration()这个函数到底做了什么?请看下面

// CacheConfiguration计算和缓存经常使用的常量且计算常量做为包变量,按照惯例前面的全局变量

// 已经被嵌入在这里为了保留原始的抽象状态
func CacheConfiguration() (err error) {
    // getLocalAddress 返回正在操作的本地peer的address:port,受到env:peer.addressAutoDetect的影响
    getLocalAddress := func() (peerAddress string, err error) {
        if viper.GetBool("peer.addressAutoDetect") {
            // 需要从peer.address设置中获取端口号,并将其添加到已经确定的主机ip后
            _, port, err := net.SplitHostPort(viper.GetString("peer.address"))
            if err != nil {
                err = fmt.Errorf("Error auto detecting Peer's address: %s", err)
                return "", err
            }
            peerAddress = net.JoinHostPort(GetLocalIP(), port)
            peerLogger.Infof("Auto detected peer address: %s", peerAddress)
        } else {
            peerAddress = viper.GetString("peer.address")
        }
        return
    }
 
 
    // getPeerEndpoint 对于这个Peer实例来说,返回PeerEndpoint,受到env:peer.addressAutoDetect的影响
    getPeerEndpoint := func() (*pb.PeerEndpoint, error) {
        var peerAddress string
        var peerType pb.PeerEndpoint_Type
        peerAddress, err := getLocalAddress()
        if err != nil {
            return nil, err
        }
        if viper.GetBool("peer.validator.enabled") {
            peerType = pb.PeerEndpoint_VALIDATOR
        } else {
            peerType = pb.PeerEndpoint_NON_VALIDATOR
        }
        return &pb.PeerEndpoint{ID: &pb.PeerID{Name: viper.GetString("peer.id")}, Address: peerAddress, Type: peerType}, nil
    }
 
 
    localAddress, localAddressError = getLocalAddress()
    peerEndpoint, peerEndpointError = getPeerEndpoint()
 
 
    syncStateSnapshotChannelSize = viper.GetInt("peer.sync.state.snapshot.channelSize")
    syncStateDeltasChannelSize = viper.GetInt("peer.sync.state.deltas.channelSize")
    syncBlocksChannelSize = viper.GetInt("peer.sync.blocks.channelSize")
    validatorEnabled = viper.GetBool("peer.validator.enabled")
 
 
    securityEnabled = viper.GetBool("security.enabled")
 
 
    configurationCached = true
 
 
    if localAddressError != nil {
        return localAddressError
    } else if peerEndpointError != nil {
        return peerEndpointError
    }
    return
}
 
 
// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
// GetPeerEndpoint 从缓存配置中返回peerEndpoint
func GetPeerEndpoint() (*pb.PeerEndpoint, error) {
    if !configurationCached {
        cacheConfiguration()
    }
    return peerEndpoint, peerEndpointError
}

// cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }

如图所示,我们要分析的是registering BLOCK,registering CHAINCODE,registering REJECTION和registering REGISTER的整个过程


下图是代码流程图


func createEventHubServer() (net.Listener, *grpc.Server, error) {

    var lis net.Listener
    var grpcServer *grpc.Server
    var err error
    // ValidatorEnabled返回peer.validator.enabled是否可用
    if peer.ValidatorEnabled() {
        lis, err = net.Listen("tcp", viper.GetString("peer.validator.events.address"))
        if err != nil {
            return nil, nil, fmt.Errorf("failed to listen: %v", err)
        }
        //TODO - do we need different SSL material for events ?
        var opts []grpc.ServerOption
        // TLSEnabled返回peer.tls.enabled配置好的值的缓存值
        if comm.TLSEnabled() {
            //NewServerTLSFromFile是gRPC库的函数,主要目的是为获取tls的证书和密钥
            creds, err := credentials.NewServerTLSFromFile(
                viper.GetString("peer.tls.cert.file"),
                viper.GetString("peer.tls.key.file"))
            if err != nil {
                return nil, nil, fmt.Errorf("Failed to generate credentials %v", err)
            }
            opts = []grpc.ServerOption{grpc.Creds(creds)}
        }
        grpcServer = grpc.NewServer(opts...)
        ehServer := producer.NewEventsServer(
            uint(viper.GetInt("peer.validator.events.buffersize")),
            viper.GetInt("peer.validator.events.timeout"))
        //注册事件服务
        pb.RegisterEventsServer(grpcServer, ehServer)
    }
    return lis, grpcServer, err
}

// ValidatorEnabled返回peer.validator.enabled是否可用

func ValidatorEnabled() bool {
    if !configurationCached {
        cacheConfiguration()
    }
    return validatorEnabled
}
//   cacheConfiguration如果检查失败打一个错误日志
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        peerLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
//   TLSEnabled返回peer.tls.enabled配置好的值的缓存值
func TLSEnabled() bool {
    if !configurationCached {
        cacheConfiguration()
    }
    return tlsEnabled
}
//   cacheConfiguration如果检查失败打错误日志.
func cacheConfiguration() {
    if err := CacheConfiguration(); err != nil {
        commLogger.Errorf("Execution continues after CacheConfiguration() failure : %s", err)
    }
}
//   NewEventsServer   返回一个事件服务器
func NewEventsServer(bufferSize uint, timeout int) *EventsServer {
    if globalEventsServer != nil {
        panic("Cannot create multiple event hub servers")
    }
    globalEventsServer = new(EventsServer)
    //初始化并且开启事件
    initializeEvents(bufferSize, timeout)
    //initializeCCEventProcessor(bufferSize, timeout)
    return globalEventsServer
}
//初始化并且开启事件
func initializeEvents(bufferSize uint, tout int) {
    if gEventProcessor != nil {
        panic("should not be called twice")
    }
    gEventProcessor = &eventProcessor{eventConsumers: make(map[pb.EventType]handlerList), eventChannel: make(chan *pb.Event, bufferSize), timeout: tout}
    addInternalEventTypes()
    //启动事件进程器
    go gEventProcessor.start()
}

func   addInternalEventTypes()   {
    AddEventType(pb.EventType_BLOCK)
    AddEventType(pb.EventType_CHAINCODE)
    AddEventType(pb.EventType_REJECTION)
    AddEventType(pb.EventType_REGISTER)
}
//AddEventType   添加支持的事件类型
func AddEventType(eventType pb.EventType) error {
    gEventProcessor.Lock()
    producerLogger.Debugf("registering %s", pb.EventType_name[int32(eventType)])
    if _, ok := gEventProcessor.eventConsumers[eventType]; ok {
        gEventProcessor.Unlock()
        return fmt.Errorf("event type exists %s", pb.EventType_name[int32(eventType)])
    }
    switch eventType {
    case pb.EventType_BLOCK:
        gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)}
    case pb.EventType_CHAINCODE:
        gEventProcessor.eventConsumers[eventType] = &chaincodeHandlerList{handlers: make(map[string]map[string]map[*handler]bool)}
    case pb.EventType_REJECTION:
        gEventProcessor.eventConsumers[eventType] = &genericHandlerList{handlers: make(map[*handler]bool)}
    }
    gEventProcessor.Unlock()
    return nil
}
func   ( ep   * eventProcessor )   start()   {
    producerLogger.Info("event processor started")
    for {
        //等待事件
        e := <-ep.eventChannel
        var hl handlerList
        eType := getMessageType(e)
        ep.Lock()
        if hl, _ = ep.eventConsumers[eType]; hl == nil {
            producerLogger.Errorf("Event of type %s does not exist", eType)
            ep.Unlock()
            continue
        }
        //lock the handler map lock
        ep.Unlock()
        hl.foreach(e, func(h *handler) {
            if e.Event != nil {
                h.SendMessage(e)
            }
        })
    }
}
//   获取消息类型
func getMessageType(e *pb.Event) pb.EventType {
    switch e.Event.(type) {
    case *pb.Event_Register:
        return pb.EventType_REGISTER
    case *pb.Event_Block:
        return pb.EventType_BLOCK
    case *pb.Event_ChaincodeEvent:
        return pb.EventType_CHAINCODE
    case *pb.Event_Rejection:
        return pb.EventType_REJECTION
    default:
        return -1
    }
}
//   SendMessage   通过流发送一条消息给远程的peer
func (d *handler) SendMessage(msg *pb.Event) error {
    err := d.ChatStream.Send(msg)
    if err != nil {
        return fmt.Errorf("Error Sending message through ChatStream: %s", err)
    }
    return nil
}

func RegisterEventsServer(s *grpc.Server, srv EventsServer) {

    s.RegisterService(&_Events_serviceDesc, srv)
}

一些重要的变量

type eventProcessor struct {

    sync.RWMutex
    eventConsumers map[pb.EventType]handlerList
    //we could generalize this with mutiple channels each with its own size
    // 产生多个大小限定的channels
    eventChannel chan *pb.Event
    //milliseconds timeout for producer to send an event.
    //毫秒级别的超时触发器发送一个事件
    //if < 0, if buffer full, unblocks immediately and not send
    //如果小于0,如果缓冲区满的,立即解锁并且不发送事件
    //if 0, if buffer full, will block and guarantee the event will be sent out
    // 如是0,如果缓冲区满的,将上锁并保证事件不会被发出去
    //if > 0, if buffer full, blocks till timeout
    //如果是0,如果缓冲区是满的,上锁直到超时
    timeout int
}
// 通过initializeEvents函数来创建全局eventProcessor单列模式 Openchain producers
// Openchain仅仅通过一个重入的静态方法生产并发送事件
var gEventProcessor *eventProcessor

type EventType int32


const (
    EventType_REGISTER  EventType = 0
    EventType_BLOCK     EventType = 1
    EventType_CHAINCODE EventType = 2
    EventType_REJECTION EventType = 3
)
var EventType_name = map[int32]string{
    0: "REGISTER",
    1: "BLOCK",
    2: "CHAINCODE",
    3: "REJECTION",
}
var EventType_value = map[string]int32{
    "REGISTER":  0,
    "BLOCK":     1,
    "CHAINCODE": 2,
    "REJECTION": 3,
}

// Event is used by

//  - consumers (adapters) to send Register
//  - producer to advertise supported types and events
type Event struct {
    // Types that are valid to be assigned to Event:
    //    *Event_Register
    //    *Event_Block
    //    *Event_ChaincodeEvent
    //    *Event_Rejection
    //    *Event_Unregister
    Event isEvent_Event `protobuf_oneof:"Event"`
}

 

我们都知道,Hyperledger用的数据库是rocksDB,如果你不做修改的话,数据会存储在/var/hyperledger/production/db目录下。

现在我们来分析一下图中灰色部分的相关代码。

代码结构图如下

// 启动数据库, 初始化openchainDB实例并打开数据库.注意该方法不能保证正确行为的并发调用

func Start() {
    openchainDB.open()
}
//   Open   打开已经存在于hyperledger中的数据库
func (openchainDB *OpenchainDB) open() {
    dbPath := getDBPath()
    missing, err := dirMissingOrEmpty(dbPath)
    if err != nil {
        panic(fmt.Sprintf("Error while trying to open DB: %s", err))
    }
    dbLogger.Debugf("Is db path [%s] empty [%t]", dbPath, missing)
 
 
    if missing {
        err = os.MkdirAll(path.Dir(dbPath), 0755)
        if err != nil {
            panic(fmt.Sprintf("Error making directory path [%s]: %s", dbPath, err))
        }
    }
 
 
    opts := gorocksdb.NewDefaultOptions()
    defer opts.Destroy()
 
 
    maxLogFileSize := viper.GetInt("peer.db.maxLogFileSize")
    if maxLogFileSize > 0 {
        dbLogger.Infof("Setting rocksdb maxLogFileSize to %d", maxLogFileSize)
        opts.SetMaxLogFileSize(maxLogFileSize)
    }
 
 
    keepLogFileNum := viper.GetInt("peer.db.keepLogFileNum")
    if keepLogFileNum > 0 {
        dbLogger.Infof("Setting rocksdb keepLogFileNum to %d", keepLogFileNum)
        opts.SetKeepLogFileNum(keepLogFileNum)
    }
 
 
    logLevelStr := viper.GetString("peer.db.loglevel")
    logLevel, ok := rocksDBLogLevelMap[logLevelStr]
 
 
    if ok {
        dbLogger.Infof("Setting rocks db InfoLogLevel to %d", logLevel)
        opts.SetInfoLogLevel(logLevel)
    }
 
 
    opts.SetCreateIfMissing(missing)
    opts.SetCreateIfMissingColumnFamilies(true)
 
 
    cfNames := []string{"default"}
    cfNames = append(cfNames, columnfamilies...)
    var cfOpts []*gorocksdb.Options
    for range cfNames {
        cfOpts = append(cfOpts, opts)
    }
 
 
    db, cfHandlers, err := gorocksdb.OpenDbColumnFamilies(opts, dbPath, cfNames, cfOpts)
 
 
    if err != nil {
        panic(fmt.Sprintf("Error opening DB: %s", err))
    }
 
 
    openchainDB.DB = db
    openchainDB.BlockchainCF = cfHandlers[1]
    openchainDB.StateCF = cfHandlers[2]
    openchainDB.StateDeltaCF = cfHandlers[3]
    openchainDB.IndexesCF = cfHandlers[4]
    openchainDB.PersistCF = cfHandlers[5]
}
 
 // 
   
 NewDefaultOptions 
   
 创建一个默认的Options. 
  
 
func NewDefaultOptions() *Options {
    return NewNativeOptions(C.rocksdb_options_create())
}
// Options表示当以open形式打开一个数据库时所有可选的options
type Options struct {
    c *C.rocksdb_options_t
    // 保持引用GC.
    env  *Env
    bbto *BlockBasedTableOptions
    // 在Destroy的时候我们要保证能够释放他们的内存
    ccmp *C.rocksdb_comparator_t
    cmo  *C.rocksdb_mergeoperator_t
    cst  *C.rocksdb_slicetransform_t
    ccf  *C.rocksdb_compactionfilter_t
}
// NewDefaultOptions 创建一个默认的Options.
func NewDefaultOptions() *Options {
    return NewNativeOptions(C.rocksdb_options_create())
}
// NewNativeOptions 创建一个Options对象.
func NewNativeOptions(c *C.rocksdb_options_t) *Options {
    return &Options{c: c}
}
 
 // 
   
 NewNativeOptions 
   
 创建一个Options对象. 
  
 
func NewNativeOptions(c *C.rocksdb_options_t) *Options {
    return &Options{c: c}
}
//   Options表示当以open形式打开一个数据库时所有可选的options
type Options struct {
    c *C.rocksdb_options_t
 
 
    // 保持引用GC.
    env  *Env
    bbto *BlockBasedTableOptions
 
 
    // 在Destroy的时候我们要保证能够释放他们的内存
    ccmp *C.rocksdb_comparator_t
    cmo  *C.rocksdb_mergeoperator_t
    cst  *C.rocksdb_slicetransform_t
    ccf  *C.rocksdb_compactionfilter_t
}
//   SetMaxLogFileSize   设置信息日志文件的最大尺寸
// 如果日志文件大于max_log_file_size常量,新的日志将会被创建
// 如果max_log_file_size等于0,所有的日志都被写到一个log日志
// 默认大小:0
func (opts *Options) SetMaxLogFileSize(value int) {
    C.rocksdb_options_set_max_log_file_size(opts.c, C.size_t(value))
}
//   SetKeepLogFileNum   设置保存的最大日志信息文件
// 默认大小: 1000
func (opts *Options) SetKeepLogFileNum(value int) {
    C.rocksdb_options_set_keep_log_file_num(opts.c, C.size_t(value))
}
//   SetInfoLogLevel   设置日志信息的级别.
// 默认级别: InfoInfoLogLevel
func (opts *Options) SetInfoLogLevel(value InfoLogLevel) {
    C.rocksdb_options_set_info_log_level(opts.c, C.int(value))
}
 
 // 
   
 InfoLogLevel描述日志级别. 
  
 
type InfoLogLevel uint
 
 
// 日志级别.
const (
    DebugInfoLogLevel = InfoLogLevel(0)
    InfoInfoLogLevel  = InfoLogLevel(1)
    WarnInfoLogLevel  = InfoLogLevel(2)
    ErrorInfoLogLevel = InfoLogLevel(3)
    FatalInfoLogLevel = InfoLogLevel(4)
)
//   SetCreateIfMissing   如果数据库丢失了指定数据库是不是应该被创建
// 默认值: false
func (opts *Options) SetCreateIfMissing(value bool) {
    C.rocksdb_options_set_create_if_missing(opts.c, boolToChar(value))
}
//   SetCreateIfMissingColumnFamilies   如果指定的列丢失啦是不是应该被创建
func (opts *Options) SetCreateIfMissingColumnFamilies(value bool) {
    C.rocksdb_options_set_create_missing_column_families(opts.c, boolToChar(value))
}
//   打开列家族
    db, cfHandlers, err := gorocksdb.OpenDbColumnFamilies(opts, dbPath, cfNames, cfOpts)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值