Hyperledger fabric查询区块错误问题解决:“error Entry not found in index”

2023-11-02

最近写了一个Hyperledger Fabric区块监控的程序,功能是应用程序监听区块生成事件,并查询新生成区块的信息。然而,当客户端收到Peer发来的blockEvent事件后,调用Channel对象的queryBlockByNumber()方法时,出现了“error Entry not found in index”错误。

一、错误描述

在调用queryBlockByNumber()方法时,向peer发送一个proposal,调用fabric的系统链码qscc,从下面的错误描述看出,由于链码执行出现错误,因此报了代码为500的错。

[2019/04/01 10:21:35.429] [pool-15-thread-1] [Sending proposal to peer1.crossborder.unionpayintl.com failed because of: gRPC failure=Status{code=UNKNOWN, description=chaincode error (status: 500, message: Failed to get block number 36566, error Entry not found in index), cause=null}]
java.lang.Exception: io.grpc.StatusRuntimeException: UNKNOWN: chaincode error (status: 500, message: Failed to get block number 36566, error Entry not found in index)
	at org.hyperledger.fabric.sdk.Channel.sendProposalToPeers(Channel.java:2241)
	at org.hyperledger.fabric.sdk.Channel.sendProposal(Channel.java:2155)
	at org.hyperledger.fabric.sdk.Channel.queryBlockByNumber(Channel.java:1680)
	at org.hyperledger.fabric.sdk.Channel.queryBlockByNumber(Channel.java:1586)
	at com.cup.blocklistener.hyperfabric.FabricServiceImpl.lambda$reconstructChannel$0(FabricServiceImpl.java:65)
	at org.hyperledger.fabric.sdk.Channel.lambda$null$0(Channel.java:2612)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: io.grpc.StatusRuntimeException: UNKNOWN: chaincode error (status: 500, message: Failed to get block number 36566, error Entry not found in index)
	at io.grpc.Status.asRuntimeException(Status.java:526)
	at io.grpc.stub.ClientCalls$UnaryStreamToFuture.onClose(ClientCalls.java:427)
	at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:419)
	at io.grpc.internal.ClientCallImpl.access$100(ClientCallImpl.java:60)
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:493)
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$500(ClientCallImpl.java:422)
	at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:525)
	at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
	at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:102)
	... 3 more

相对应的,peer端也有相应的错误日志打印,如下所示,即peer模拟执行交易失败

simulateProposal() resulted in chaincode response status 500 for txid: ...

二、查询流程分析

查询的流程涉及到SDK端、Peer端以及peer上运行的系统链码,下面进行分析:

SDK端

  1. 程序调用Channel对象的queryBlockByNumber()方法;
  2. Channel对象创建QuerySCCRequest请求,设置Fcb为"GetBlockByNumber",设置Args为通道的名字和区块号;
  3. 调用sendProposal方法将请求发给peer(通过Endorser对象的ProcessProposal方法进行grpc调用)。

Peer端

  1. core/endoser/endorser.go文件中的ProcessProposal方法处理请求;
  2. 对proposal进行一系列预处理;
  3. 调用simulateProposal方法模拟执行交易;;
  4. 调用callChaincode方法将proposal交给智能合约执行;
  5. 调用core/chaincode/chaincodeexec.go中的ExecuteChaincode方法执行交易;
  6. core/chaincode/exectransaction.go中的Execute方法执行交易,如果chaincode没有运行先调用launch方法启动chaincode;
  7. 然后调用theChaincodeSupport.Execute方法执行交易;
  8. 调用handler.sendExecuteMessage方法把proposal发给chaincode实例进行执行,由于是QueryScc请求,所以发给qscc合约进行执行。

Peer端的qscc系统链码

  1. core/scc/qscc/qscc.go根据fcn的名字调用GetBlockByNumber方法进行执行;
  2. 调用core/ledger包中的GetBlockByNumber接口从账本中获取区块;
  3. 调用core/ledger/kvledger包中的kvLedger对象的GetBlockByNumber方法,从kv账本中获取区块;
  4. 调用common/ledger/blkstorage包中BlockStore对象的RetrieveBlockByNumber方法从区块存储中获取区块;
  5. 调用common/ledger/blkstorage/fsblkstorage包中的fsBlockStore对象的RetrieveBlockByNumber方法;
  6. 调用common/ledger/blkstorage/fsblkstorage包中的blockfileMgr对象的retrieveBlockByNumber方法;
  7. 调用common/ledger/blkstorage/fsblkstorage包中的index接口中的getBlockLocByBlockNum方法从leveldb的index中获取区块位置。由于从index中获取区块不存在,所以返回"Entry not found in index"错误。
// common/ledger/blockstorage/fsblkstorage/blockindex.go文件
func (index *blockIndex) getBlockLocByBlockNum(blockNum uint64) (*fileLocPointer, error) {
	if _, ok := index.indexItemsMap[blkstorage.IndexableAttrBlockNum]; !ok {
		return nil, blkstorage.ErrAttrNotIndexed
	}
	b, err := index.db.Get(constructBlockNumKey(blockNum))
	if err != nil {
		return nil, err
	}
	// 在此处返回"Entry not found in index"错误
	if b == nil {
		return nil, blkstorage.ErrNotFoundInIndex
	}
	blkLoc := &fileLocPointer{}
	blkLoc.unmarshal(b)
	return blkLoc, nil
}

三、原因分析及解决方法

从上面的原因分析可以看出,抛出"Entry not found in index"错误的原因是在leveldb中无法找到对应的区块。而通过应用程序和peer端报的日志的时间可以看出,在区块写入leveldb完成之前,peer就会把blockEvent发给应用程序,而应用程序在进行查询发生在区块写入leveldb之前,因此,在leveldb的index中无法找到对应区块。猜测是由于运行时间过长,底层存储的数据量较大,影响了区块写入的速度。

分析了原因之后,解决方法就很显然了,要么是进行重试,要么就延时查询。由于对监控区块的实时性要求并不高,因此,我采用了Thread.sleep(2000)使线程在收到blockEvent后休眠2s再进行查询,然后上面的问题就再没有出现。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Hyperledger fabric查询区块错误问题解决:“error Entry not found in index” 的相关文章

  • 谷歌云

    Cloud Ace 是谷歌云全球战略合作伙伴 拥有 300 多名工程师 也是谷歌最高级别合作伙伴 多次获得 Google Cloud 合作伙伴奖 作为谷歌托管服务商 我们提供谷歌云 谷歌地图 谷歌办公套件 谷歌云认证培训服务 您知道通过调整

随机推荐

  • 静态逆向简单的ELF

    看到csdn中一篇文章 http blog csdn net fisher jiang article details 6783922 该文章使用动态调试进行破解找到密码 由于自己对linux不熟悉需要学习段时间 就使用ida静态反汇编进行
  • gerrit "missing Change-Id"

    场景 你用 git push 向 gerrit 提交了待审核代码 一切都很顺利 你脑袋里冒出了 代码头上加了 佛祖保佑 果然有效 的想法 此时 git 打印出如下提示 你的内心OS同步打印 心情 5 remote Resolving del
  • vue ui 创建vue项目时报错command failed: npm install --loglevel error --legacy-peer-deps解决

    command failed npm install loglevel error legacy peer deps 新手对于这个报错 第一次安装nodejs 只需要更改nodejs安装目录的权限 改成更高的权限即可 不用看网上其他对于这个
  • java成员变量、局部变量、静态变量等问题

    java成员变量 局部变量 静态变量等问题 知乎 https www zhihu com question 294221894 answer 493705474 CSDN https blog csdn net du minchao art
  • 【OpenCV学习笔记】【类型转换】一(IplImage和cv::Mat的类型相互转换)

    OpenCV1和OpenCV2混合使用中的IplImage和cv Mat的类型转换 假设img为cv Mat类型 而Image为IplImage类型 1 cv Mat转换为IplImage IplImage Image Image IplI
  • linux lftp 参数配置

    vi etc lftp conf 直接lft 进入 gt help 帮助查看帮助 gt set a 可列出可以有什么参数设置
  • 微信小程序轮播图的实现

    在Android或者ios中几乎所有的app都有轮播图这个效果 在android中一般是使用viewpager来实现的 在微信小程序中一般是用 swiper这个标签来实现的 我们在微信小程序文档中可以查看所有的标签 如图 这些组件看做是An
  • jupyte中动态更新matplotlib的曲线

    使用python进行数值实验的时候 我们常常会在程序运行结束之后利用matplotlib绘制出结果的曲线 问题是 当程序需要运行很长世间的时候 我们不能立即查看出图的效果 错误做法 如果简单地多次调用plot 几次绘制的曲线会堆在一个图里
  • vue 项目中神策埋点

    如何配置神策埋点信息 1 安装依赖 npm install save sa sdk javascript 2 项目配置 在 utils 文件夹下新建 sensors js 配置单页应用的固定代码 非单页应用不需要加上配置对象 is trac
  • Oracle ROWNUM用法和分页查询总结

    原文地址 http blog csdn net fw0124 article details 42737671 转载 Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用 Oracle分页查询格式 一 http yangting
  • 了解聊天机器人ChatGPT的深度学习技术

    近年来 随着深度学习技术的飞速发展 聊天机器人已经逐渐走进了我们的生活中 这些聊天机器人可以和人类进行语言交互 能够回答问题 解决问题 提供服务等等 为人们的日常生活提供了极大的便利 其中 ChatGPT就是一种基于深度学习技术的聊天机器人
  • 程序员如何90天成功转行黑客(网络安全)?

    有人说 黑客到底比程序员高在哪 为什么很多人开始转行了 其实黑客都是程序员 但是并不是所有的程序员都是黑客 从企业和社会需求来看 现在真不缺程序猿 反而大量的缺安全工程师 同样8000块月薪 程序猿一大把 安全工程师却很难招到 最重要的是程
  • java中实现多线程的三种方式

    java中实现多线程的三种方式 1 实现多线程的方法 在java中实现多线程的两途径 继承Thread类 实现Runable接口 Callable 2 继承Thread类实现多线程 继承类Thread是支持多线程的功能类 只要创建一个子类就
  • docker安装jupyter科学镜像及使用

    2020 04 03 镜像 为了方便在虚拟机上进行实验研究 本次在自己的虚拟机上安装jupyter 因为要使用jupyter 同时还要有python的环境 在docker上搜索了相关的镜像 但都是个人做的 后来发现了jupyter官方制作了
  • SQL中binary 和 varbinary的区别 blob

    http www cnblogs com lovevivi archive 2013 09 25 3339087 html binary 和 varbinary 固定长度 binary 的或可变长度 varbinary 的 binary 数
  • 查看文件的MD5 值

    从网上下载到资源文件后 为了确保下载的文件没有被黑客非法篡改 一般都会校验一下MD5是否与最初上传的版本是否一致 查看两个文件的MD5 值可以判断文件在传输过程中有没有损坏 或者丢失字节 Windows电脑 window 键盘左下角Ctrl
  • SpringBoot前后端调用接口下划线与驼峰之间转换

    1 前言 最近在开发过程中 自测自己的接口的时候 会出现一下驼峰与下划线转换问题 今天就出篇文章写下吧 顺便加深下印象 2 步骤 2 1导入maven依赖 注意 因为我的项目中引入了Redisson的依赖 所以就不用单独引入jackson依
  • 解决 Element-UI 的 el-dialog 对话框移动问题的方法

    系列文章目录 文章目录 系列文章目录 前言 一 问题描述 二 解决方法 1 安装 vuedraggable 库 2 引入并使用 vuedraggable 3 将 el dialog 放入 draggable 组件 总结 前言 Element
  • python3.8 环境下安装 robot framework 遇到的问题及解决

    博客原址 https testerhome com topics 23384 安装过程就不多说了 反正就是很心酸 以下是安装步骤 1 安装python3 8 2 在线安装robotframework pip install robotfra
  • Hyperledger fabric查询区块错误问题解决:“error Entry not found in index”

    最近写了一个Hyperledger Fabric区块监控的程序 功能是应用程序监听区块生成事件 并查询新生成区块的信息 然而 当客户端收到Peer发来的blockEvent事件后 调用Channel对象的queryBlockByNumber