Hyperledger Fabric继peer启动之后的源码解析二

Hyperledger Fabric 链码启动过程实现 注:本文最早发表于 2017-09-22. 简介 这里讲的 Chaincode 是用户链码(User Chaincode,UCC),对应用开发者来说十分重要,它提供了基于区块链分布式账本的状态处理逻辑,基于它可以开发出多种复杂的应用。 Hyperledger Fabric 中,Chaincode 默认运行在 Docker 容器中。Peer 通过调用 Docker 阅读详情

如图所示,我们要分析的是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"`
}


Fabric v2.0 源码解析——容器运行智能合约(chaincode) 1. Fabric各个组件的交互 Fabric v1.x 的组件包括client、orderer节点、peer节点、chaincode容器,各个容器节点间的交互关系如下: 上图中可知,最主要的5个交互步骤为: Client → Peer: EndorseProposal,Client向Endorser发送交易提案,请求背书; Peer ↔ Chaincode: ChaincodeIntera... 阅读详情

相关推荐

ABB机器人C#二次开发实战:从通信打通到数据读写的落地指南(附完整工程)

最近在做自动化产线升级项目时,遇到一个核心需求:用C#上位机实时读取ABB机器人的关节角度、IO信号,同时下发运动指令和参数配置。翻遍全网,要么是Robot Studio的基础操作教程,要么是C++/VC++的老旧案例,C#相关的实操内容要么只给片段代码,要么跳过通信配置、权限设置等关键步骤,导致刚上手时踩了无数坑——连接超时、数据读不到、写入无响应,甚至误触发机器人安全保护。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1394

Hyperledger Fabric处理Peer与Peer之间通信的源码解析

1.网络初始化的过程中执行以下内容,在创建节点Engine过程中该节点作为客户端的身份连接到其他PeerpeerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine) 2.创建一个使用提供的处理程序工厂函数在新的聊天服务调用上创建新的处理程序的Peerfunc NewPeerWithEngine(secHelperF

Hacker的博客 6345

告别手动连接!一键搞定Mumu模拟器与Android Studio的ADB配置

本文详细介绍了如何通过编写自动化脚本,一键完成Mumu模拟器与Android Studio的ADB连接配置。告别繁琐的手动命令输入,该脚本能智能检查环境、判断连接状态并自动处理端口转发,显著提升Android开发者的调试与测试效率。

yog99的博客 498

Hyperledger Fabric继peer启动之后的源码解析三

我们都知道,Hyperledger用的数据库是rocksDB,如果你不做修改的话,数据会存储在/var/hyperledger/production/db目录下。 现在我们来分析一下图中灰色部分的相关代码。 代码结构图如下 // 启动数据库, 初始化openchainDB实例并打开数据库.注意该方法不能保证正确行为的并发调用 func Start() {     opencha

Hacker的博客 2335

十五天学会Autodesk Inventor,看完这一系列就够了(七),工程图纸

不管哪种绘图软件,二维或三维绘图,最终均需要转换成工程图纸,才能交给现场人员进行制作,这是任一产品图都要经历的过程。那本章开始,我们一起看一下Inventor是如何实现工程图纸?

Crazydoubao的博客 4911

PP触发EWM产生PMR捡配

PP触发EWM产生PMR捡配 前言 PMR: Production Material Request 在流程订单/生产订单下达后,可以在EWM中产生PMR,在EWM中, PMR其实代表了ERP中的流程订单/生产订单。 You can use SAP EWM in conjunction with the following PP application components: • Production Orders • Process Orders • Repetitive Manufacturing •

ZevYang的博客 1918

Hyperledger fabric 源码分析之 peer 服务启动过程

peer 服务是主服务。 该服务支持各种 peer 命令。 包括查询状态,和启动、停止节点服务等。 serve 函数 最重要的是 func serve(args []string) error 函数。 当执行 peer node start 命令时候被调用,启动一个节点服务。 首先是进行配置管理,根据配置信息和一些计算来构建 cache 结构,探测节点信息等。

yeasy的专栏 1万+

Java开发者终极抉择:IntelliJ IDEA vs VS Code —— 4大维度深度对比评测

🔥关注墨瑾轩,带你探索Java的奥秘!🚀🔥超萌技术攻略,轻松晋级编程高手!🚀🔥技术宝库已备好,就等你来挖掘!🚀🔥订阅墨瑾轩,智趣学习不孤单!🚀🔥即刻启航,编程之旅更有趣!🚀在Java开发领域,选择合适的集成开发环境(IDE)对于提高开发效率和代码质量至关重要。和(简称VS Code)是两个广受好评的开发工具,各自拥有独特的特性和庞大的用户群。本篇将从多个维度深入探讨这两款IDE对Java开发者来说的优劣,包括但不限于性能、用户体验、生态系统、调试能力、以及特定Java功能的支持等方面。

java专栏 8590

Hyperledger Fabric从源码分析链码容器启动过程

链码容器启动过程 每个实例化之后的链码都会以容器的形式启动起来,下面举一个byfn.sh启动的例子: $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS

pigff的博客 2054

【漏洞复现】永恒之蓝 MS17-010 远程溢出漏洞(CVE-2017-0143)

文章目录声明前言一、漏洞原理简述二、漏洞代码深层解析三、实验步骤四、漏洞补丁总结 声明 本篇文章仅用于技术研究与技术学习,切勿用于非授权下攻击行为,切记! 前言 Windows7 存在 MS17-010 永恒之蓝(远程溢出漏洞) ,该漏洞是方程式组织在其漏洞利用框架中一个针对SMB服务进行攻击的漏洞,该漏洞导致攻击者在目标系统上可以执行任意代码 一、漏洞原理简述 MS17-010漏洞出现在Windows SMB v1中的内核态函数 srv!SrvOs2FeaListToNt 在处理FEA(File Ex

李同學AI安全 9627

《Python全栈系列教程》专栏介绍及文章汇总

《Python全栈系列教程》专栏介绍及文章汇总

孤寒者的博客 71万+

hyperledger-fabric1.1 单机多点部署(3)-部署peer0.org1节点

有了Orderer排序服务启动文件,还需要专门为Peer节点所准备的docker-peer.yaml启动文件。 docker-peer.yaml内部源码如下 version: "2" service: couchdb: container_name: couchdb image: hyperledger/fabric-couchdb # Comment/...

tank_ft的博客 948

爬取B站评论+AI情感分析:Python批量抓数据+BERT正负向分类(全流程)

B站作为年轻群体聚集的内容平台,评论区蕴含海量用户真实态度(如好评、吐槽、中立观点),是情感分析的优质数据源!本文分享完整流程:批量爬取B站视频评论→数据清洗去噪→BERT模型情感分类→可视化分析,基于预训练BERT模型实现高精度正负向判断,新手也能快速复刻情感分析系统! 前置配置(关键!获取B站API访问权限) B站评论通过官方API接口返回,无需复杂解析,只需配置用户Cookie即可正常请求: 2. 完整代码(直接复制运行) 三、使用步骤(5步搞定,新手友好) 步骤1:配置关键参数 打开,在类中修改

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1069

Hyperledger Fabric继peer启动之后的源码解析一

对图中peer节点启动之后的peer address 172.17.0.3:7051灰色部分的的代码提取分析 图中的CacheConfiguration()这个函数到底做了什么?请看下面 // CacheConfiguration计算和缓存经常使用的常量且计算常量做为包变量,按照惯例前面的全局变量 // 已经被嵌入在这里为了保留原始的抽象状态 func CacheConfigurati

Hacker的博客 2397

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Fabric.Peer源码分析

Fabric.Peer源码分析 这部分,主要分析链码安装到实例化(启动容器)的过程。操作链码是通过peer chaincode命令进行的,这就是我们所谓的一个命令行的客户端,通过它我们就可以和fabric交互,注意peer node start启动的peer服务,即启动一个peer节点。 以下是从e2e_cli/scripts/scripts.sh提取的安装、实例化链码的命令,注意该命令前,要先完...

longtails的博客 966

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Hyperledger Fabric从源码分析账本

参考资料: 官方文档——账本关键概念 Fabric源码分析之九数据库存储源码分析leveldb fabric源码解析5——kvledger初始化 文章目录什么是账本?世界状态区块链命名空间源码分析idStorehistorydbProviderledgerStoreProvidervdbProvider账本存储目录结构 什么是账本? Fabric 中的账本存储了有关业务对象的重要事实信息,既包括了对象属性当前的值,也包括产生这些当前值的交易的历史。这两个概念可以用下面的术语来概括,即账本包括

pigff的博客 1340

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Fabric1.4源码解析:Peer节点启动过程

看一下Peer节点的启动过程,通常在Fabric网络中,Peer节点的启动方式有两种,通过Docker容器启动,或者是通过执行命令直接启动。 一般情况下,我们都是执行docker-compose -f docker-*.yaml up命令通过容器启动了Peer节点,而如果直接启动Peer节点则是执行了peer node start这条命令。看起来,这两种方式所使用的命令毫无关系,但事实上,在Doc...

weixin_30832983的博客 450

Hyperledger Fabric智能合约开发实战:Chaincode容器化部署与gRPC通信原理

Hyperledger Fabric是一个开源的企业级区块链平台,支持智能合约(Chaincode)的开发与部署。Chaincode作为Fabric的核心组件,运行在隔离的容器环境中,并通过gRPC协议与Peer节点通信,确保交易的安全性和可靠性。本文将详细介绍Chaincode的容器化部署流程及gRPC通信原理,帮助开发者快速掌握智能合约开发的关键技术。 ## 一、Chaincode容器化部署

gitblog_00077的博客 766

Hyperledger Fabric从源码分析系统链码

系统链码简介 在 Fabric 中,有一些链码是比较特殊的,叫系统链码。它们作为peer进程的一部分运行,而不是像用户链码一样运行在独立的 docker 容器中。因此它们有更高的权限来访问 peer 中的资源来实现用户链码难以实现或者不能实现的功能。 在 Fabric 1.4 版本之前,总共有五种系统链码,它们分别是: Life Cycle System Chaincode (LSCC):生命周期系统链码 Configuration System Chaincode (CSCC):配置系统链码 Query

pigff的博客 1653

深入解析fabric的peer命令(一)

mainCmd。

qq_41683167的博客 439

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

由图片可以看出peer启动节点后先初始化一下日志 然后进入Server函数 //============================================================================== //peer node start 之后做日志初始化之后就进入到server函数 //==================================

Anonymous 1101

Hyperledger Fabric源码解析

Hyperledger Fabric开源于2015年12月,截至2018年2月初有185个公司/组织成员加入。最初由IBM和DAH的工程师贡献,现在约有70名的代码贡献者,4000+代码提交,代码行数12万行左右。应用开发者使用SDK与Fabric平台交互,目前提供Node, Java和Python SDK,在Github上都可以搜索到。代码贡献方式介绍:https://hyperledger-f...

weixin_34061042的博客 443

Fabric学习:Fabric源码

系统运行架构。 下图是上图简化版。 Orderer排序节点配置文件: orderer.yaml 通用配置文、账本配置、Kafka配置 ...

好好休息.. 1295

Fabric.Peer.Node源码分析(1)

Fabric.Peer.Node源码分析(1) start函数有400+行… 测试node下的start_test.go文件(fabric/peer/node/start_test.go) func TestStartCmd(t *testing.T): 首先设置peer的一些参数,包括peer.address,peer.listenAdderess,peer.chaincodeListenAd...

longtails的博客 603

【DEBUG】Hyperledger Fabric链码安装失败:深入解析Go版本兼容性问题与解决方案

本文深入解析了Hyperledger Fabric链码安装失败并报错“status: 500”的常见原因——Go版本兼容性问题。文章通过真实案例,详细阐述了从宿主机Go版本、peer二进制文件到fabric-ccenv构建镜像的完整兼容性链条,并提供了四步诊断法和四种根治方案,帮助开发者系统性地解决链码构建失败难题。

milk5的博客 683

学习记录:fabric(10)- fabric本身编译(2)

分析 编译完成就是来分析一下代码,为了接下来的修改。 已经有很多对源码的分析,但是看日期都是18年左右,肯定都是1.x版本(甚至是0.8),2.x改变了链码的调用部分,我关注的恰恰是这部分,所以还是得自己动手看。 我看的版本是2.3。还是有一些不同,看的过程我也记下来,方便以后查看。 fabric编译:fabric的docker镜像,在make之后,会直接加入到docker的镜像列表里。 整体结构 fabric从网上git下来就是如下的结构: 我这里用goland打开了项目。文件和文件夹很多,build

ychyssss的专栏 8539
上一篇: Hyperledger Fabric继peer启动之后的源码解析一
下一篇: Hyperledger Fabric继peer启动之后的源码解析三
The_Web3_社区
博客等级 码龄10年 388粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

The_Web3_社区

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值