Why do chaincode queries write to ledger? (Marbles Private Sample Chaincode only)

165 Views Asked by At

I am testing Private Data Collections using the Fabric Marble Private Chaincode sample and have encountered a perplexing issue: Peer Logs appear to show that new blocks are added to the ledger upon doing a query.

When I invoke the "ReadMarble" chaincode function:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/user/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["ReadMarble","marble1"]}'

both Org1 and Org2 Peer logs show the following messages:

2020-11-26 17:20:23.034 UTC [gossip.privdata] StoreBlock -> INFO 080 Received block [7] from buffer channel=mychannel
2020-11-26 17:20:23.036 UTC [committer.txvalidator] Validate -> INFO 081 [mychannel] Validated block [7] in 1ms
2020-11-26 17:20:23.056 UTC [kvledger] commit -> INFO 082 [mychannel] Committed block [7] with 1 transaction(s) in 19ms (state_validation=0ms block_and_pvtdata_commit=5ms state_commit=12ms) commitHash=[93f46d1c133896b222d3dfa4dd7571704aec625332c503a296e918bf7765e2c1]

That new blocks are being committed to the ledger is confirmed by the fact that the marble private price data disappears after 3 transactions from the Org1 Private collection based on the default collection configuration. In addition, this behavior only happens after initMarble is called. If ReadMarble is called prior to marbles getting added to the ledger, no new blocks are written. The same behavior (new blocks appearing to be written) is also observed when invoking "GetMarblesByRange" and "ReadMarblePrivateDetails" functions. (However, invoking "GetMarblesByRange" will result in additional blocks being written regardless of whether initMarble has already been called.)

I am using the latest fabric samples (v2.3) and referencing the tutorial at this page.

I tried using the 2.3 Private Data tutorial which uses the asset-transfer-private chaincode sample instead of the Private Marbles sample and could not reproduce this issue; When using the Asset-transfer-Private sample chaincode, no new blocks are created on calling queries. I didn't notice any obvious differences between these sample chaincodes that would explain this difference in behavior, but I also don't have a background in programming.

1

There are 1 best solutions below

1
On BEST ANSWER

I think the problem is with the CLI command you are using to do the invocation. You are running peer chaincode invoke. The help for this command states:

Invoke the specified chaincode. It will try to commit the endorsed transaction to the network.

Notice that the comments at the top of the chaincode that you linked suggests this command to query a marble:

peer chaincode query -C mychannel -n marblesp -c '{"Args":["ReadMarble","marble1"]}'

And the help for the peer chaincode query command reads:

Get endorsed result of chaincode function call and print it. It won't generate transaction.

The peer chaincode query command is just sending a proposal to peer(s) to get the transaction result. The peer chaincode invoke command is sending a proposal to peer(s) to gather endorsed responses, and then sending the proposal and these endorsements on to the orderer(s) to be committed as a transaction to the ledger. There is more detail on this flow here:

https://hyperledger-fabric.readthedocs.io/en/release-2.2/peers/peers.html#phase-1-proposal