hyperledger-fabric - ENDORSEMENT_POLICY_FAILURE 在调用链码时使用即使交易对象包含足够的背书
问题描述
我在 hyperledger fabric 1.4.4 上有一个包含 5 个组织 A、B、C、D、E 的网络。我用这 5 个组织创建了一个通道,并将我的链码安装在 org A 和 org B 上,因为只有它们是背书政策的一部分.
这是背书政策:
{"identities":[{"role":{"name":"member","mspId":"AMSP"}},{"role":{"name":"member","mspId":"BMSP"}},{"role":{"name":"member","mspId":"CMSP"}},{"role":{"name":"member","mspId":"DMSP"}},{"role":{"name":"member","mspId":"EMSP"}}],"policy":{"2-of":[{"signed-by":0},{"signed-by":1}]}}
我正在使用具有以下配置的网关来调用链码
const walletPath = path.join('wallet' );
const wallet = new FileSystemWallet(walletPath);
let connectionOptions = {
identity: userName,
wallet: wallet,
discovery: { enabled:true, asLocalhost: true },
eventHandlerOptions: {
commitTimeout: 100,
strategy: DefaultEventHandlerStrategies.NETWORK_SCOPE_ALLFORTX
}
};
logger.debug('Connecting to Fabric gateway');
await gateway.connect(clientConnectionProfileJson, connectionOptions);
const network = await gateway.getNetwork(channelName);
const contract = await network.getContract(chaincodeName , contractName);
const transaction = contract.createTransaction(functionName);
await transaction.submit(<arguments>);
这是我在客户端级别遇到的错误
2021-02-17T05:28:13.063Z - warn: [TransactionEventHandler]: _strategyFail: strategy fail for transaction "9be4da8b1d52ddde804d6c7c08d134ef4b6ac2043cbe0258b5b4c921424c9f04": TransactionError: Peer a-org-peer1.a-org.com:7051 has rejected transaction "9be4da8b1d52ddde804d6c7c08d134ef4b6ac2043cbe0258b5b4c921424c9f04" with code "ENDORSEMENT_POLICY_FAILURE"
这是我在所有对等日志中看到的
2021-02-17 05:28:12.313 UTC [vscc] Validate -> ERRO 0db VSCC error: stateBasedValidator.Validate failed, err validation of endorsement policy for chaincode {chaincodeName} in tx 26:0 failed: signature set did not satisfy policy
经过一番研究,我发现这是 org peer 尝试将事务提交到账本时发生的故障,并且发现签名集不满足策略。
我已经继续并使用 getTransactionByID 方法查看了事务对象。我看到有两个背书者 MSP 具有正确的签名证书,这些证书属于 A 和 B 组织的对等方之一。所以发现服务正确地识别了对等点,甚至对等点已经认可了交易,但不确定为什么交易没有被提交。
我在这里想念什么?
如何验证签名是否正确?
为了明确告诉网关请求应该发送到特定的背书节点,我使用了下面的代码。
const walletPath = path.join('wallet' );
const wallet = new FileSystemWallet(walletPath);
let connectionOptions = {
identity: userName,
wallet: wallet,
discovery: { enabled: true , asLocalhost: true },
eventHandlerOptions: {
commitTimeout: 100,
strategy: DefaultEventHandlerStrategies.NETWORK_SCOPE_ALLFORTX
}
};
logger.debug('Connecting to Fabric gateway');
await gateway.connect(clientConnectionProfileJson, connectionOptions);
const network = await gateway.getNetwork(channelName);
const channel = network.getChannel();
let endorsingPeers = [];
endorsingPeers.push(channel.getChannelPeer('a-org-peer1.a-org.com'));
endorsingPeers.push(channel.getChannelPeer('b-org-peer1.b-org.com'));
// Get addressability to org.cargoesnetwork.ebilloflading contract
// Use chaincodeName that is used for installing
const contract = await network.getContract(chaincodeName , contractName);
const transaction = contract.createTransaction(functionName).setEndorsingPeers(endorsingPeers);
await transaction.submit(<arguments>);
不走运,交易仍然失败,同样的背书策略失败。如果背书人签名证书正确存在,我验证了交易对象。它们存在,但仍然出现相同的错误。
出于好奇,我将背书政策从两个组织更改为只有一个组织,一切都按预期工作。仅当政策包含多个认可组织时,该问题才存在。
请帮助调试此问题。
解决方案
发生 ENDORSEMENT_POLICY_FAILURE 的原因有很多。首先是您没有足够的签名,这就是您所说的已经检查过的内容。另一个原因是并非所有签名都与已发送的提案相匹配。
在 1.4 网关 API 中,提案被接收,并且在将提案发送给排序者之前不进行比较以查看它们是否都匹配。SDK 将发送所有签名和收到的提案之一。签名是在每个对等方的个人提案响应上创建的。
如果这些提案不匹配(这意味着您的链码不是确定性的),那么其中一个签名将是可以的,但另一个不会,因为它与发送给订购者的提案不匹配。
我会检查您的链码是否具有确定性,因为每个对等点都可能生成不同的响应。例如,非确定性链码的一个示例是它创建一个新日期并将其存储在世界状态中。每个对等点将创建稍微不同的日期值,从而导致不同的响应。
推荐阅读
- python - 如何公开 mininet(containernet)主机端口以在 localhost 上启动应用程序?
- excel - 基于用户的 VBA 文件夹路径
- javascript - 在没有开发依赖的 Svelte 中使用 Glider
- php - 自定义注册页面不输出任何错误消息
- python - 如何使用命令行导入模块?
- python - 如何在 python 中使用 BeautifulSoup 从以下链接返回日期和标题
- r - r中两个数据集的散点图
- python - 打开命令是否(或不)锁定文件?
- apache - 使用 Let's encrypt with Apache 和 Apache Tomcat
- python - 如何确定python中变量的类型?