首页 > 解决方案 > 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>);
        

不走运,交易仍然失败,同样的背书策略失败。如果背书人签名证书正确存在,我验证了交易对象。它们存在,但仍然出现相同的错误。

出于好奇,我将背书政策从两个组织更改为只有一个组织,一切都按预期工作。仅当政策包含多个认可组织时,该问题才存在。

请帮助调试此问题。

标签: hyperledger-fabrichyperledgerhyperledger-chaincode

解决方案


发生 ENDORSEMENT_POLICY_FAILURE 的原因有很多。首先是您没有足够的签名,这就是您所说的已经检查过的内容。另一个原因是并非所有签名都与已发送的提案相匹配。

在 1.4 网关 API 中,提案被接收,并且在将提案发送给排序者之前不进行比较以查看它们是否都匹配。SDK 将发送所有签名和收到的提案之一。签名是在每个对等方的个人提案响应上创建的。

如果这些提案不匹配(这意味着您的链码不是确定性的),那么其中一个签名将是可以的,但另一个不会,因为它与发送给订购者的提案不匹配。

我会检查您的链码是否具有确定性,因为每个对等点都可能生成不同的响应。例如,非确定性链码的一个示例是它创建一个新日期并将其存储在世界状态中。每个对等点将创建稍微不同的日期值,从而导致不同的响应。


推荐阅读