繁体   English   中英

Hyperledger Fabric-多个并发事务

Hyperledger Fabric - Multiple concurrent transactions

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

我正在尝试使用在官方fabric-samples存储库中找到的invoke函数同时将两个事务提交到Fabric。

如果我每次提交一笔交易,则该交易已成功提交到分类账。

相反,当我尝试执行多个并发事务时,出现此错误:

Error: Shutdown due to disconnect on transaction id registration
at ChannelEventHub._callTransactionListener (/Users/node_modules/fabric-client/lib/ChannelEventHub.js:1304:21)
at ChannelEventHub._checkTransactionId (/Users/node_modules/fabric-client/lib/ChannelEventHub.js:1282:9)
at ChannelEventHub._processTxEvents (/Users/node_modules/fabric-client/lib/ChannelEventHub.js:1261:11)
at ClientDuplexStream._stream.on (/Users/node_modules/fabric-client/lib/ChannelEventHub.js:405:11)
at emitOne (events.js:116:13)
at ClientDuplexStream.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at ClientDuplexStream.Readable.push (_stream_readable.js:208:10)
at Object.onReceiveMessage (/Users/node_modules/grpc/src/client_interceptors.js:1276:19)
at InterceptingListener.recvMessageWithContext (/Users/node_modules/grpc/src/client_interceptors.js:603:19)
at /Users/node_modules/grpc/src/client_interceptors.js:702:14

这是我正在使用的代码片段

var invokeChaincode = async function(peerNames, channelName, chaincodeName, fcn, args, username, org_name) {
    logger.debug(util.format('\n============ invoke transaction on channel %s ============\n', channelName));
    var error_message = null;
    var tx_id_string = null;
    try {
        // first setup the client for this org
        var client = await helper.getClientForOrg(org_name, username);
        logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
        var channel = client.getChannel(channelName);
        if(!channel) {
            let message = util.format('Channel %s was not defined in the connection profile', channelName);
            logger.error(message);
            throw new Error(message);
        }
        var tx_id = client.newTransactionID();
        // will need the transaction ID string for the event registration later
        tx_id_string = tx_id.getTransactionID();

        // send proposal to endorser
        var request = {
            targets: peerNames,
            chaincodeId: chaincodeName,
            fcn: fcn,
            args: args,
            chainId: channelName,
            txId: tx_id
        };

        let results = await channel.sendTransactionProposal(request);

        // the returned object has both the endorsement results
        // and the actual proposal, the proposal will be needed
        // later when we send a transaction to the orderer
        var proposalResponses = results[0];
        var proposal = results[1];

        // lets have a look at the responses to see if they are
        // all good, if good they will also include signatures
        // required to be committed
        var all_good = true;
        for (var i in proposalResponses) {
            let one_good = false;
            if (proposalResponses && proposalResponses[i].response &&
                proposalResponses[i].response.status === 200) {
                one_good = true;
                logger.info('invoke chaincode proposal was good');
            } else {
                logger.error('invoke chaincode proposal was bad');
            }
            all_good = all_good & one_good;
        }

        if (all_good) {
            logger.info(util.format(
                'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
                proposalResponses[0].response.status, proposalResponses[0].response.message,
                proposalResponses[0].response.payload, proposalResponses[0].endorsement.signature));

            // wait for the channel-based event hub to tell us
            // that the commit was good or bad on each peer in our organization
            var promises = [];
            let event_hubs = channel.getChannelEventHubsForOrg();
            event_hubs.forEach((eh) => {
                logger.debug('invokeEventPromise - setting up event');
                let invokeEventPromise = new Promise((resolve, reject) => {
                    let event_timeout = setTimeout(() => {
                        let message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr();
                        logger.error(message);
                        eh.disconnect();
                    }, 3000);
                    eh.registerTxEvent(tx_id_string, (tx, code, block_num) => {
                        logger.info('The chaincode invoke chaincode transaction has been committed on peer %s',eh.getPeerAddr());
                        logger.info('Transaction %s has status of %s in blocl %s', tx, code, block_num);
                        clearTimeout(event_timeout);

                        if (code !== 'VALID') {
                            let message = util.format('The invoke chaincode transaction was invalid, code:%s',code);
                            logger.error(message);
                            reject(new Error(message));
                        } else {
                            let message = 'The invoke chaincode transaction was valid.';
                            logger.info(message);
                            resolve(message);
                        }
                    }, (err) => {
                        clearTimeout(event_timeout);
                        logger.error(err);
                        reject(err);
                    },
                        // the default for 'unregister' is true for transaction listeners
                        // so no real need to set here, however for 'disconnect'
                        // the default is false as most event hubs are long running
                        // in this use case we are using it only once
                        {unregister: true, disconnect: true}
                    );
                    eh.connect();
                });
                promises.push(invokeEventPromise);
            });

            var orderer_request = {
                txId: tx_id,
                proposalResponses: proposalResponses,
                proposal: proposal
            };
            var sendPromise = channel.sendTransaction(orderer_request);
            // put the send to the orderer last so that the events get registered and
            // are ready for the orderering and committing
            promises.push(sendPromise);
            let results = await Promise.all(promises);
            logger.debug(util.format('------->>> R E S P O N S E : %j', results));
            let response = results.pop(); //  orderer results are last in the results
            if (response.status === 'SUCCESS') {
                logger.info('Successfully sent transaction to the orderer.');
            } else {
                error_message = util.format('Failed to order the transaction. Error code: %s',response.status);
                logger.debug(error_message);
            }

            // now see what each of the event hubs reported
            for(let i in results) {
                let event_hub_result = results[i];
                let event_hub = event_hubs[i];
                logger.debug('Event results for event hub :%s',event_hub.getPeerAddr());
                if(typeof event_hub_result === 'string') {
                    logger.debug(event_hub_result);
                } else {
                    if(!error_message) error_message = event_hub_result.toString();
                    logger.debug(event_hub_result.toString());
                }
            }
        } else {
            error_message = util.format('Failed to send Proposal and receive all good ProposalResponse');
            logger.debug(error_message);
        }
    } catch (error) {
        logger.error('Failed to invoke due to error: ' + error.stack ? error.stack : error);
        error_message = error.toString();
    }

    if (!error_message) {
        let message = util.format(
            'Successfully invoked the chaincode %s to the channel \'%s\' for transaction ID: %s',
            org_name, channelName, tx_id_string);
        logger.info(message);

        return tx_id_string;
    } else {
        let message = util.format('Failed to invoke chaincode. cause:%s',error_message);
        logger.error(message);
        throw new Error(message);
    }
};

任何想法?

1 个回复

我发现了问题。

// the default for 'unregister' is true for transaction listeners
// so no real need to set here, however for 'disconnect'
// the default is false as most event hubs are long running
// in this use case we are using it only once
{unregister: true, disconnect: false}

断开连接选项必须设置为false,否则在将事务通知给事件时关闭连接。

1 Fabric - 在单个主机上并行运行多个命令

我有一个管理脚本,我们称之为mngcntl.sh 。 此脚本最多可能需要5秒才能运行。 它位于每台服务器上的x不同位置。 我想为所有这些位置并行执行此脚本,并在不同的StringIO()实例中获取每个执行的输出。 目前的做法: 我的方法的问题是我必须等待每个脚本执 ...

2 iOS上的Fabric-能耗

我正在对iOS应用程序的能耗进行故障排除,并且发现Fabric似乎将能耗保持在较高/非常高的范围内,即使该应用程序在后台也是如此。 它在调试模式下运行。 还有其他人看到吗? 有什么我可以做的吗? 这是我从Fabric获得的调试信息: ...

3 为什么hyperledger-fabric需要多个orderer?

基本上我有很多问题,但我会问最需要的问题。 谢谢你的帮助。 1)为什么hyperledger网络需要多个订购者节点? 如果我理解正确,在节点验证事务之后,它们会将这些事务传递给orderer节点。 orderer节点将对这些事务加时间戳,将它们推入块中并将该块发送回节点。 节点会将 ...

5 Fabric - 答案未在iOS上注册

我在我的项目中通过在app delegate didFinishLaunchingWithOptions:添加以下行来配置Answers didFinishLaunchingWithOptions: 我已经接受了Fabric仪表板中的条款,我看到了“Waiting for events” ...

6 Fabric - 加载游戏时 EntrypointException 崩溃

我目前正在探索使用 Fabric 进行改装。 大约一个月前,我制作了一个运行良好的 mod,无论是从 VSCode 中的调试器运行时,还是在真正的 Minecraft 安装上编译和运行时。 编译后我添加了一些东西,但现在新编译的版本在加载时会导致游戏崩溃。 然而,奇怪的是,在 VSCode 中从调试 ...

7 Fabric - 无法完成设置下载

我正在使用Fabric应用程序在我的iOS应用程序中集成Twitter。 我已经按照所有步骤进行了操作,但过程仍然停留在“验证安装阶段”。 我可以在Xcode控制台日志中看到此错误: [Fabric]无法完成设置下载Error Domain = NSCocoaErrorDomain ...

8 Fabric-如何确保我的命令完全运行

所以我一直在尝试使用Fabric运行以下功能。 我的版本是Fabric 1.14.0和Paramiko 2.4.1 当我在VM上运行此“ service arangodb3.cluster start”命令时,得到以下输出。 但是,当我从python代码运行上述函数时,得到以下 ...

9 Fabric-取得实例IP地址

我正在EC2上运行一些实例,需要将其IP地址保存在数据库中。 为了保存主机名,我使用了以下函数(以伪代码给出) 但是,我还需要一种类似的方式来访问实例的公共IP。 我该如何使用面料呢? ...

10 Fabric - 在本地文件上运行sed

我试图在本地运行sed文件,这是我的代码: 然后它会提示我指定主机。 有什么方法可以像这样在本地运行sed吗? 我也尝试过: 但是我收到以下错误: sed:-i不能与stdin一起使用 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM