ENDORSEMENT_POLICY_FAILURE 在调用链码时使用即使交易对象包含足够多的背书

ENDORSEMENT_POLICY_FAILURE while invoking chain code using even if the transaction object contains enough endorsements

我在 hyperledger fabric 1.4.4 上有一个网络,有 5 个组织 A、B、C、D、E。我用这 5 个组织创建了一个通道,并在组织 A 和组织 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

经过一些研究,我发现这是在组织节点试图将交易提交到分类帐时发生的故障,并且发现签名集不满足策略。

我已经使用 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 将发回所有签名和收到的提案之一。签名是在每个节点的单独提案响应上创建的。

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

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