首页 > 解决方案 > Hyperledger Fabric v1.2 - 无法调用链代码名称:“qscc”,错误:执行事务时超时已过期

问题描述

我有带有 3 个虚拟机的 Fabric 网络设置,其中包含 4 个组织,每个组织有 2 个对等点以及各自的 CouchDB 实例、1 个专用 CA 和单个订购者。我正在使用 Hyperledger Java SDK 来公开 rest API 以供使用。

我们在进行查询时经常遇到问题,无论是富文本查询还是有时下面提到的历史查询异常。根据日志,我可以看到用户 Chaincode 已成功检索查询结果,但在执行“qscc”Chaincode 调用时失败。

2018-08-29 02:43:33.749 UTC [lockbasedtxmgr] Next -> DEBU 26591 queryResultsItr.Next() returned a record:{"availableDate":"","refTxId":"3b9c439f918a4c4ff558ab803611877d5cd990255f57c5b0b2a1944866982384","userId":"ABC0002","updatedBy":"system"}
2018-08-29 02:43:33.749 UTC [chaincode] HandleGetQueryResult -> DEBU 26592 Got keys and values. Sending RESPONSE
2018-08-29 02:43:33.749 UTC [chaincode] HandleTransaction -> DEBU 26593 [4e6c0cc5] Completed GET_QUERY_RESULT. Sending RESPONSE
2018-08-29 02:43:33.750 UTC [chaincode] handleMessage -> DEBU 26594 [4e6c0cc5] Fabric side handling ChaincodeMessage of type: QUERY_STATE_CLOSE in state ready
2018-08-29 02:43:33.750 UTC [chaincode] HandleTransaction -> DEBU 26595 [4e6c0cc5] handling QUERY_STATE_CLOSE from chaincode
2018-08-29 02:43:33.750 UTC [chaincode] HandleTransaction -> DEBU 26596 [4e6c0cc5] Completed QUERY_STATE_CLOSE. Sending RESPONSE
2018-08-29 02:43:33.751 UTC [chaincode] handleMessage -> DEBU 26597 [4e6c0cc5] Fabric side handling ChaincodeMessage of type: COMPLETED in state ready
2018-08-29 02:43:33.751 UTC [chaincode] Notify -> DEBU 26598 [4e6c0cc5] notifying Txid:4e6c0cc5d95c5686c20d33d6bafa2cf850b1d1615f240c56831c44cf5bb69c79, channelID:mychannel
2018-08-29 02:43:33.751 UTC [chaincode] Execute -> DEBU 26599 Exit
2018-08-29 02:43:33.751 UTC [endorser] callChaincode -> DEBU 2659a [mychannel][4e6c0cc5d95c5686c20d33d6bafa2cf850b1d1615f240c56831c44cf5bb69c79] Exit
2018-08-29 02:43:33.751 UTC [lockbasedtxmgr] GetTxSimulationResults -> DEBU 2659b Simulation completed, getting simulation results
2018-08-29 02:43:33.751 UTC [lockbasedtxmgr] Done -> DEBU 2659c Done with transaction simulation / query execution [4e6c0cc5d95c5686c20d33d6bafa2cf850b1d1615f240c56831c44cf5bb69c79]
2018-08-29 02:43:33.751 UTC [endorser] SimulateProposal -> DEBU 2659d [mychannel][4e6c0cc5] Exit
2018-08-29 02:43:33.751 UTC [endorser] endorseProposal -> DEBU 2659e [mychannel][4e6c0cc5] Entry chaincode: name:"mychaincode"
2018-08-29 02:43:33.751 UTC [endorser] endorseProposal -> DEBU 2659f [mychannel][4e6c0cc5] escc for chaincode name:"mychaincode"  is escc
2018-08-29 02:43:33.751 UTC [endorser] EndorseWithPlugin -> DEBU 265a0 Entering endorsement for {plugin: escc, channel: mychannel, tx: 4e6c0cc5d95c5686c20d33d6bafa2cf850b1d1615f240c56831c44cf5bb69c79, chaincode: mychaincode}
2018-08-29 02:43:33.751 UTC [endorser] EndorseWithPlugin -> DEBU 265a1 Exiting {plugin: escc, channel: mychannel, tx: 4e6c0cc5d95c5686c20d33d6bafa2cf850b1d1615f240c56831c44cf5bb69c79, chaincode: mychaincode}
2018-08-29 02:43:33.751 UTC [endorser] endorseProposal -> DEBU 265a2 [mychannel][4e6c0cc5] Exit
2018-08-29 02:43:33.751 UTC [lockbasedtxmgr] Done -> DEBU 265a3 Done with transaction simulation / query execution [4e6c0cc5d95c5686c20d33d6bafa2cf850b1d1615f240c56831c44cf5bb69c79]
2018-08-29 02:43:33.751 UTC [endorser] ProcessProposal -> DEBU 265a4 Exit: request from 10.255.0.4:47828
2018-08-29 02:43:33.977 UTC [gossip/discovery] periodicalSendAlive -> DEBU 265a5 Sleeping 5s
2018-08-29 02:43:34.198 UTC [gossip/discovery] periodicalReconnectToDead -> DEBU 265a6 Sleeping 25s
2018-08-29 02:43:34.711 UTC [gossip/election] waitForInterrupt -> DEBU 265a7 [40 227 139 114 173 5 75 157 49 97 134 49 223 250 188 122 25 48 140 50 245 198 39 79 233 243 124 193 89 118 85 88] : Exiting
2018-08-29 02:43:34.711 UTC [gossip/election] IsLeader -> DEBU 265a8 [40 227 139 114 173 5 75 157 49 97 134 49 223 250 188 122 25 48 140 50 245 198 39 79 233 243 124 193 89 118 85 88] : Returning true
2018-08-29 02:43:34.711 UTC [gossip/election] waitForInterrupt -> DEBU 265a9 [40 227 139 114 173 5 75 157 49 97 134 49 223 250 188 122 25 48 140 50 245 198 39 79 233 243 124 193 89 118 85 88] : Entering
2018-08-29 02:43:35.075 UTC [chaincode] Execute -> DEBU 265aa Exit
2018-08-29 02:43:35.075 UTC [endorser] callChaincode -> DEBU 265ab [mychannel][8fb2e3710e44df19e8255177885c5ce29a940ea5239b20e7a94791fe2e4faee9] Exit
2018-08-29 02:43:35.077 UTC [endorser] SimulateProposal -> ERRO 265ac [mychannel][8fb2e371] failed to invoke chaincode name:"qscc" , error: timeout expired while executing transaction
github.com/hyperledger/fabric/core/chaincode.(*Handler).Execute
        /opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/handler.go:919
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).execute
        /opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/chaincode_support.go:253
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).Invoke
        /opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/chaincode_support.go:239
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).Execute
        /opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/chaincode_support.go:179
github.com/hyperledger/fabric/core/endorser.(*SupportImpl).Execute
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/support.go:141
github.com/hyperledger/fabric/core/endorser.(*Endorser).callChaincode
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/endorser.go:136
github.com/hyperledger/fabric/core/endorser.(*Endorser).SimulateProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/endorser.go:287
github.com/hyperledger/fabric/core/endorser.(*Endorser).ProcessProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/endorser.go:501
github.com/hyperledger/fabric/core/handlers/auth/filter.(*expirationCheckFilter).ProcessProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/handlers/auth/filter/expiration.go:61
github.com/hyperledger/fabric/core/handlers/auth/filter.(*filter).ProcessProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/handlers/auth/filter/filter.go:31
github.com/hyperledger/fabric/protos/peer._Endorser_ProcessProposal_Handler
        /opt/gopath/src/github.com/hyperledger/fabric/protos/peer/peer.pb.go:112
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).processUnaryRPC
        /opt/gopath/src/github.com/hyperledger/fabric/vendor/google.golang.org/grpc/server.go:923
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).handleStream
        /opt/gopath/src/github.com/hyperledger/fabric/vendor/google.golang.org/grpc/server.go:1148
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).serveStreams.func1.1
        /opt/gopath/src/github.com/hyperledger/fabric/vendor/google.golang.org/grpc/server.go:637
runtime.goexit
        /opt/go/src/runtime/asm_amd64.s:2361
error sending
failed to execute transaction 8fb2e3710e44df19e8255177885c5ce29a940ea5239b20e7a94791fe2e4faee9
github.com/hyperledger/fabric/core/chaincode.(*ChaincodeSupport).Execute
        /opt/gopath/src/github.com/hyperledger/fabric/core/chaincode/chaincode_support.go:181
github.com/hyperledger/fabric/core/endorser.(*SupportImpl).Execute
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/support.go:141
github.com/hyperledger/fabric/core/endorser.(*Endorser).callChaincode
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/endorser.go:136
github.com/hyperledger/fabric/core/endorser.(*Endorser).SimulateProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/endorser.go:287
github.com/hyperledger/fabric/core/endorser.(*Endorser).ProcessProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/endorser/endorser.go:501
github.com/hyperledger/fabric/core/handlers/auth/filter.(*expirationCheckFilter).ProcessProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/handlers/auth/filter/expiration.go:61
github.com/hyperledger/fabric/core/handlers/auth/filter.(*filter).ProcessProposal
        /opt/gopath/src/github.com/hyperledger/fabric/core/handlers/auth/filter/filter.go:31
github.com/hyperledger/fabric/protos/peer._Endorser_ProcessProposal_Handler
        /opt/gopath/src/github.com/hyperledger/fabric/protos/peer/peer.pb.go:112
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).processUnaryRPC
        /opt/gopath/src/github.com/hyperledger/fabric/vendor/google.golang.org/grpc/server.go:923
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).handleStream
        /opt/gopath/src/github.com/hyperledger/fabric/vendor/google.golang.org/grpc/server.go:1148
github.com/hyperledger/fabric/vendor/google.golang.org/grpc.(*Server).serveStreams.func1.1
        /opt/gopath/src/github.com/hyperledger/fabric/vendor/google.golang.org/grpc/server.go:637
runtime.goexit
        /opt/go/src/runtime/asm_amd64.s:2361
2018-08-29 02:43:35.077 UTC [endorser] SimulateProposal -> DEBU 265ad [mychannel][8fb2e371] Exit
2018-08-29 02:43:35.077 UTC [endorser] ProcessProposal -> DEBU 265ae Exit: request from 10.255.0.4:47818

标签: hyperledger-fabrichyperledgerblockchain

解决方案


我最近也遇到了这个问题。在检查了一些相关问题和文档后,我的临时解决方案是重新启动您Failed to invoke chaincode name "qscc"在其日志中找到的对等点:

docker restart <peer container's id>

但是,这种方案并不能完全解决问题。但是您可以检查此问题以获取更多信息(问题与重复,但仍未解决)。

以下是 Manish Sethi 的相关评论,用于解释查询分类帐背后发生的事情:

Ledger 公开了两组 API,一组 API 与状态读取和操作相关,另一组 API 与查询区块链状态(例如GetBlockByNumberGetTransactionByID)相关。第一组 API 通过交易模拟器公开,并且(用于在交易模拟期间使用链代码),第二组 API 在账本接口中作为直接 API 公开(并且旨在让客户了解账本状态)。

牢记上述内容,分类帐设计中的一个默认假设是,单个 gorouting 将其使用限制为上述一组 API 中的一个。链码将自身限制为与状态相关的 API,并且账本状态查询客户端不需要创建模拟器。

然而,在更高层上,由于与账本状态相关的 API 是通过链码(qscc具体来说是 )公开的,因此上述假设被打破。回答账本状态查询的执行路径在到达qscc代码之前获得了一个交易模拟器(交易模拟器实际上并没有什么用处)。

更具体地说,对这两组 API 的额外限制与以下事实有关:对任何分类帐 API 的两个独立外部调用应该给块存储和状态提供原子提交的感知概念。例如,客户端查询 API 时不应发生这种情况GetBlockchainInfo并发现 10 号区块已提交,但当他提交后续状态查询时,查询返回区块 9 的状态(因为区块 10 的状态更新仍处于挂起状态)。这是通过一对锁实现的,一个锁同步模拟和statementb提交之间的状态,另一个同步账本状态相关调用与整体提交。这样做是为了通过将模拟暂停到最低限度(仅当更新实际转储到磁盘时)以与账本状态相关的查询为代价来实现更好的性能。因为,qscc带了一个事务模拟器,上面提到的交互导致报死锁。我相信未来,其中一个建议是通过 grpc 接口公开这些账本状态相关的 API,这将解决这个问题。然而,

qscc 路径不占用事务模拟器(否则也是需要的,因为事务模拟器是一种昂贵的资源,因为它需要对 stateb 进行读取锁定才能与提交同步,因此应该仅用于事务模拟)。

另一种解决方法可能是通过更粗略的单锁实现上述对块存储和状态的原子提交的感知概念,但这会影响吞吐量,而不是理想的解决方案。

以不同的方式实现原子提交的感知概念。这需要在分类帐存储和声明b之间的交互方面做一些重要的工作。简而言之,将分类帐存储暴露为两阶段提交。第一步,我们追加区块,然后在第二步,更新 BlockchainInfo 和区块索引,并与 stateb 更新同步。鉴于上述情况,由于无论如何都需要第一个,我的建议是针对 1.1 和 1.2 修复该问题。


推荐阅读