我在下面的逻辑下编码了结构网络事件侦听器,它将侦听事务提交。但是,当事务成功背书时,它工作正常,但当交易背书不成功时,它工作不正常。如果我错过了什么,请告诉我。
代码快照:
const transaction = networkObj.contract.createTransaction('addOrg');
const tx_id = transaction.getTransactionID().getTransactionID();
await transaction.addCommitListener((err: any, txId: any, status: any, blockHeight: any) => {
console.log('inside listener');
if (err) {
console.log(err)
return
}
if (status === 'VALID') {
console.log('transaction committed');
console.log('txId: ',txId,'status: ',status,'blockHeight: ',blockHeight);
console.log('transaction committed end');
} else {
console.log('err transaction failed');
console.log(status);
}
});
transaction.submit(OrgAdd.organization, OrgAdd.orgShortName, OrgAdd.orgType, OrgAdd.industryType)
let responseMessage: ResponseMessage = new ResponseMessage({ message: tx_id });
console.log('before return');
return responseMessage;
记录事务成功与失败背书的时间。
成功的:
Connected to mychannel.
Connected to contract. p2pmembers
Done connecting to network.
OrgAdd: {
organization: 'Manufacturer 10',
orgShortName: 'MF10',
orgType: 'manufacturer',
industryType: 'Electronics'
}
before return
inside listener
transaction committed
<<txId:>> 7b1767397a9821e0e2e0b16c7f7ad4ada9d15a8a7b838c5cc542be50e260d497 <<status:>> VALID <<blockHeight:>> 116
transaction committed end
不成功
Connected to mychannel.
Connected to contract. p2pmembers
Done connecting to network.
OrgAdd: {
organization: 'Manufacturer 10',
orgShortName: 'MF10',
orgType: 'manufacturer',
industryType: 'Electronics'
}
before return
2020-06-22T11:32:13.973Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G0:0 - endorsement failed - Error: transaction returned with failure: Error: MF10 organization does exist
2020-06-22T11:32:13.975Z - error: [DiscoveryEndorsementHandler]: _endorse - endorsement failed::Error: Endorsement has failed
如果背书失败(或发送到排序者失败(,则对transaction.submit()
的调用将引发错误。请注意,transaction.submit()
是一个异步函数,因此您应该使用await transaction.submit()
调用它。如果没有等待,您将面临未处理的承诺拒绝。
另请注意,对transaction.submit()
的调用会返回事务调用的响应有效负载,因此,除非您的事务函数不返回任何有效负载,否则您应该捕获该响应:
const response = await transaction.submit(OrgAdd.organization, OrgAdd.orgShortName, OrgAdd.orgType, OrgAdd.industryType);
通常,您不需要执行自己的提交侦听,因为对transaction.submit()
的调用会为您执行此操作。您可以更改默认行为,以便提交不会等待提交事件,或者更改用于决定提交何时成功的策略,但默认情况下,它将执行该提交等待您。如果提交失败,transaction.submit()
将再次引发错误。出现的错误附加了建议响应,允许您调查失败的原因。
try {
const response = await transaction.submit(OrgAdd.organization, OrgAdd.orgShortName, OrgAdd.orgType, OrgAdd.industryType);
// Successful transaction endorsement and commit
} catch (error) {
// Failure to endorse or commit
}
您可能需要将所描述的模式与单独的提交侦听器一起使用的一些原因是:
- 您希望在将事务发送到排序器后立即处理事务响应,但仍在客户端检查提交是否成功。
- 您希望完全异步地检查提交成功;出于性能原因,可能在不同的过程中。
这些都是非典型情况,如果后续事务与上一个事务相同的账本键交互,并且由尚未提交上一个事务的对等方处理,则可能会导致后续事务出现意外状态。通常,只需等待对transaction.submit()
的单行调用并让它为您处理等待提交事件即可获得最佳体验。
用于交易的 Fabric 模型遵循"认可"(或执行(、"订单"、"提交"。 提案在一个或多个对等方发送以供背书,如果背书成功,客户将提案和背书组合成一个交易,该交易提交给订购。 一旦交易被订购,对等方就会在一个区块中接收它,并执行验证(确保存在正确的背书(和版本控制检查(确保执行的所有输入都是未修改的(。 有关详细的体系结构回顾,请参阅本文。
事件侦听器用于"提交事件",这些事件在对等方检查事务是否有效/一致的最后阶段发出。 如果初始背书失败,则客户端永远不会将事务提交到排序,因此不会发生提交事件。
您可能会将"背书失败"与"背书政策失败"混淆。 当客户端没有寻求足够的背书或来自正确对等方的背书,但仍然提交交易时,就会发生背书策略失败。 在这种情况下,您将看到一个失败的事件,但在认可时没有错误。