I am trying to understand the "Query" transaction flow in Hyperledger Fabric. I understand the "write" flow in Fabric as it is well documented. However, things are not so clear when a read/query transaction is involved.
This is what I have understood so far:
- A client using an SDK prepares a transaction proposal for querying a chaincode.
- The proposal is transmitted via a committing peer to the Endorsing peers which validate as well as simulate the transaction in their end. Assuming everything is successful, the endorsing peers return their endorsements for the proposal. Each endorsement contains, among other things, a readset of the world state. Since this is just a query transaction, a writeset is not added inside each ensorsement. Is my understanding correct here?
- Once the client receives the required amount of endorsement, it prepares a transaction which is sent to the Orderer.
I am not so sure of the flow after this. A write transaction is understandable: the order, after carrying out some checks, will create a block and propagate the block to all peers connected to the corresponding channel. All peers will append the block in the ledger after carrying out the validation of all transactions in the block, this essentially updates the ledger.
But what about a read transaction? What does the orderer will return upon receiving a read transaction? What will be the flow hereafter?
Any help or pointers will be highly appreciated.
Thanks in advance.
You might want to take a look at https://github.com/hyperledger/fabric-samples/blob/release/fabcar/query.js which demonstrates how to query using the Node SDK. You'll notice that it uses the convenience method https://fabric-sdk-node.github.io/Channel.html#queryByChaincode__anchor provided by the SDK to help facilitate queries.
In terms of the flow you outlined in your post, steps 1 and 2 are correct.
Additionally, chaincode functions which are intended for query transactions will typically use the https://godoc.org/github.com/hyperledger/fabric/core/chaincode/shim#Success helper function to actually return the result of the query. In the sample I posted above, https://github.com/hyperledger/fabric-samples/blob/release/fabcar/query.js#L51 invokes https://github.com/hyperledger/fabric-samples/blob/release/chaincode/fabcar/fabcar.go#L135.
There is no need to send the responses from a query transaction to the orderer although you can as long as you meet the endorsement policy. Thanks to Dave Enyeart for the following:
This seems to contradict what you posted in your reply to this question: Roles (read+write) in hyperledger
The behavior you describe here makes sense, whereas the behavior in the above answer seems totally broken. Yet it seems that readers on a channel are not allowed to perform invokes.