key-level endorsement policy is not fully-functional in hyperledger fabric

397 Views Asked by At

I am setting up the Key-based endorsement policy on Hyperledger fabric v2.3.3. My chaincode endorsement policy is "OR('org1.peer','org2.peer','org3.peer','org4.peer')" and for a very specific key, the endorsement policy is "AND('org1.peer','org2.peer')". When a transaction is submitted very first time, it works fine because at that time chaincode endorsement policy works, but when I try to update the same key, it does not work. The node fabric-sdk sends the endorsement request to only 1 org i.e org1 (invoker) and the peer rejects the block and throws "Endorsement Policy Failure".

When I verified the block, I saw that the transaction was endorsed by only org1 not by both org1 and org2. Seems like the fabric-sdk did not send the transaction to the other org.

However, if I change my chaincode-endorsement policy to "AND('org1.peer','org2.peer','org3.peer','org4.peer')", everything works fine because the fabric-sdk is sending the transaction to every org's peer for endorsement.

The official document says

 In practice, this means that the key-level endorsement policy can be either less restrictive or more restrictive than the chaincode-level or collection-level endorsement policies.

but from the above scenario, it seems like it can only be less-restrictive. Peer logs:


2021-10-14 11:05:24.443 UTC [gossip.privdata] StoreBlock -> INFO 36d Received block [207] from buffer channel=assetschannel

2021-10-14 11:05:24.450 UTC [vscc] Validate -> ERRO 36e VSCC error: stateBasedValidator.Validate failed, err validation of key PUB-TEST-6 (coll'':ns'assets') in tx 207:0 failed: signature set did not satisfy policy

2021-10-14 11:05:24.454 UTC [committer.txvalidator] validateTx -> ERRO 36f Dispatch for transaction txId = b13b21ddd0cb351b93b47ccc556ea4b62bf41abd3a23a3734d56304c91e6066e returned error: validation of key PUB-TEST-6 (coll'':ns'assets') in tx 207:0 failed: signature set did not satisfy policy

2021-10-14 11:05:24.454 UTC [committer.txvalidator] Validate -> INFO 370 [assetschannel] Validated block [207] in 5ms

2021-10-14 11:05:24.459 UTC [validation] preprocessProtoBlock -> WARN 371 Channel [assetschannel]: Block [207] Transaction index [0] TxId [b13b21ddd0cb351b93b47ccc556ea4b62bf41abd3a23a3734d56304c91e6066e] marked as invalid by committer. Reason code [ENDORSEMENT_POLICY_FAILURE]

2021-10-14 11:05:24.495 UTC [kvledger] commit -> INFO 372 [assetschannel] Committed block [207] with 1 transaction(s) in 36ms (state_validation=0ms block_and_pvtdata_commit=6ms state_commit=29ms) commitHash=[35570558fc04d3dfa400f053f2a0f9bed92ea227c894ae4536990627a5a19036]

fabric-sdk logs:

2021-10-14T11:05:24.491Z - warn: [TransactionEventHandler]: strategyFail: commit failure for transaction "b13b21ddd0cb351b93b47ccc556ea4b62bf41abd3a23a3734d56304c91e6066e": TransactionError: Commit of transaction b13b21ddd0cb351b93b47ccc556ea4b62bf41abd3a23a3734d56304c91e6066e failed on peer peer1.org1.com:7051 with status ENDORSEMENT_POLICY_FAILURE

2021-10-14T11:05:24.491Z - warn: [TransactionEventHandler]: strategyFail: commit failure for transaction "b13b21ddd0cb351b93b47ccc556ea4b62bf41abd3a23a3734d56304c91e6066e": TransactionError: Commit of transaction b13b21ddd0cb351b93b47ccc556ea4b62bf41abd3a23a3734d56304c91e6066e failed on peer peer1.org1.com:7051 with status ENDORSEMENT_POLICY_FAILURE
1

There are 1 best solutions below

0
On BEST ANSWER

The problem here is that during endorsement the client does not know what ledger keys your transaction invocation will read/write or what key-based endorsement policies might be applied. All it knows about (using the discovery service) is the endorsement policy for the chaincode being invoked, and so it will pick endorsing peers to satisfy that policy.

If your transaction invocation is going to access private data collections or make chaincode-to-chaincode calls, you can indicate that to the client so it can (again using the discovery service) select an appropriate set of endorsing peers to satisfy the effective endorsement policy considering those collections and/or chaincode invocations. This tutorial page describes how this is done:

https://hyperledger.github.io/fabric-sdk-node/release-2.2/tutorial-discovery-fabric-network.html

This still doesn't cover the scenario of key-based endorsement policies since the ledger keys accessed are a determined by the business logic of your transaction function and parameters passed in by the client application. So you need to provide the knowledge of organizations that must endorse explicitly using Transaction.setEndorsingOrganizations(). This will override the normal mechanism for selecting endorsing peers and use the organizations you have specified.

At the time of writing, a newer Fabric Gateway client API (Node, Go and Java) is under development, which moves much of the logic that exists in the client-side SDKs today into a Gateway peer. It is targeted for release with Fabric v2.4. This Fabric Gateway implementation will inspect the read/write sets generated by simulation of the transaction invocation during endorsement, and use this to dynamically detect the endorsement requirements for a given transaction invocation. So you should no longer need to specify the required organizations, collections or chaincode-to-chaincode calls when making client invocations, and it should work out-of-the-box with key-based endorsement policies. The exception to this general rule is when passing private data, where you should specify the organizations that you will allow to receive the data to prevent accidental leakage of private information.