События Chaincode в фабрике hyperledger не вызывают текущее зарегистрированное событие - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь использовать цепочечные события в Hyperledger Fabric v1.3.0.Он вызывает событие chaincode, зарегистрированное в предыдущем вызове invoke-транзакции (я хочу, чтобы он вызывал текущий).Я использую слой SDK с балансом-переносом с модификациями (представлен в сэмплах).Вот фрагмент кода invoke -action.js, который я изменил -

var promises = [];
        let event_hubs = channel.getChannelEventHubsForOrg();
        event_hubs.forEach((eh) => {
            eh.connect(true);
            let invokeCCEventPromise = new Promise((resolve, reject) => {
                let event_timeout1 = setTimeout(() => {
                    let message = 'REQUEST_TIMEOUT:' + eh.getPeerAddr();
                    logger.error(message);
                    eh.disconnect();
                }, 3000);

                regid = eh.registerChaincodeEvent(chaincodeName, 'evtsender*', (event, block_num, txnid, status) => {
                        // This callback will be called when there is a chaincode event name
                        // within a block that will match on the second parameter in the registration
                        // from the chaincode with the ID of the first parameter.
                        console.log('Successfully got a chaincode event with transid:' + txnid + ' with status:' + status);


                        // to see the event payload, the channel_event_hub must be connected(true)
                        let event_payload = event.payload.toString('utf8');
                        logger.info('Event Payload: ', event_payload);

                        if (event_payload.indexOf('code') > -1) {
                            clearTimeout(event_timeout1);
                            // Chaincode event listeners are meant to run continuously
                            // Therefore the default to automatically unregister is false
                            // So in this case we want to shutdown the event listener once
                            // we see the event with the correct payload
                            eh.unregisterChaincodeEvent(regid);
                            console.log('Successfully received the chaincode event on block number ' + block_num);
                            resolve('RECEIVED');
                        } else {
                            console.log('Successfully got chaincode event ... just not the one we are looking for on block number ' + block_num);
                        }
                    }, (error) => {
                        clearTimeout(event_timeout1);
                        console.log('Failed to receive the chaincode event ::' + error);
                        reject(error);
                    },
                    // no options specified
                    // startBlock will default to latest
                    // endBlock will default to MAX
                    // unregister will default to false
                    // disconnect will default to false
                    {
                        unregister: true
                    }

                );

            });
            promises.push(invokeCCEventPromise);





            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 block %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);

Мое понимание проблемы - события регистрируются и хранятся в блоках.Fabric начинает поиск зарегистрированных событий из «последнего блока» в цепочке, если это не указано явно в параметре [, OPTIONS].Fabric вызывает «событие цепного кода» до того, как текущий блок будет зафиксирован в регистре, повторно найдя его при поиске в предыдущем блокеЭто не похоже на 'TxEvent', который вызывается после фиксации блока.Мне нужно, чтобы «событие-код цепочки» вызывалось сразу после фиксации текущей транзакции, так как мне нужно вызывать другую функцию, используя параметры из «полезной нагрузки».Это предназначено?Есть ли обходной путь для этого?

Пожалуйста, укажите, является ли мое понимание неверным в любом случае.Я все еще учусь использовать ткань.

1 Ответ

0 голосов
/ 10 июля 2019

Если вы хотите получить запущенное в данный момент chaincodeEvent, вызовите функцию registerChaincodeEvent внутри registerTxEvent, т. Е. Как только получено событие транзакции, это означает, что транзакция была зафиксирована на партнере.Теперь вы можете получить текущее событие кода цепи.Вы можете изменить свой код, как написано ниже:

        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 block %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);


            regid = eh.registerChaincodeEvent(chaincodeName, 'evtsender*', (event, block_num, txnid, status) => {
                    // This callback will be called when there is a chaincode event name
                    // within a block that will match on the second parameter in the registration
                    // from the chaincode with the ID of the first parameter.
                    console.log('Successfully got a chaincode event with transid:' + txnid + ' with status:' + status);


                    // to see the event payload, the channel_event_hub must be connected(true)
                    let event_payload = event.payload.toString('utf8');

                    logger.info('Event Payload: ', event_payload);
                    //do something with the payload
                    if (event_payload.indexOf('code') > -1) {
                        clearTimeout(event_timeout1);
                        // Chaincode event listeners are meant to run continuously
                        // Therefore the default to automatically unregister is false
                        // So in this case we want to shutdown the event listener once
                        // we see the event with the correct payload
                        eh.unregisterChaincodeEvent(regid);
                        console.log('Successfully received the chaincode event on block number ' + block_num);
                    } else {
                        console.log('Successfully got chaincode event ... just not the one we are looking for on block number ' + block_num);
                    }
                }, (error) => {
                    clearTimeout(event_timeout1);
                    console.log('Failed to receive the chaincode event ::' + error);
                },
                // no options specified
                // startBlock will default to latest
                // endBlock will default to MAX
                // unregister will default to false
                // disconnect will default to false
                {
                    unregister: true,
                    disconnect: true
                }

            );

                        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: false
                }
            );
            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);
...