2

I am using client.channel.Execute API in fabric-sdk-go to invoke the ledger update Txs in chaincode.

I know my chaincode for ledger update is correct because invoke Tx when run from cli container command line is working perfectly all the times.

Few times, randomly, ledger updates are not reflecting when executed as REST API call from POSTMAN like below. In those cases, response code is 200 with correct response payload suggestive of successful chaincode running.

`

chaincodeID := "hcc"
fcn := "GiftToken"
args := [][]byte{
    []byte(reqBody.TokenID),
    []byte(reqBody.GiftToUserID),
    []byte(GiftTokenCountAsString),
}

setup := lib.GetFabricSetup()

transientDataMap := make(map[string][]byte)
transientDataMap["result"] = []byte("Transient data in GiftToken invoke")

response, err := setup.Client.Execute(channel.Request{ChaincodeID: chaincodeID, Fcn: fcn, Args: args, TransientMap: transientDataMap})

I am running Fabric 1.4.4 images in docker containers. My network has 1 org with 4 peer nodes.

Surely missing some aspect which is leading to this sort of behaviour. Thanks in advance.

1 Answers1

1

It takes time for all peers to sync their blocks. Once peers receive these blocks they update their world state, so you can see your change via querying.

When you query for the "just executed" transaction, you may hit one of other peers. If you want immediate result, ensure that you're querying the same peer(s) where you actually executed your transaction. You may try putting some delay to see other peers as well get the block.

The reason why you see the change immediately on CLI, is about the way of the client implementation. On CLI command execution, you specify the peer explicitly. So transaction is executed on one peer and queried on the same peer (no issues). You may prove this behavior by immediately querying (via CLI) another organization's peer just after you execute the transaction (via CLI).

However with your client, probably since you don't explicitly specify the peer, your client SDK uses peers' discovery service and find a peer in the network for you and use it.

Due to this reason, when endorsement policy is formed like "AND(org1, org2)", client SDK actually queries 2 peers (one each org) and compare results.

hsnkhrmn
  • 961
  • 7
  • 20
  • Thanks @hsnkhrmn, that explains the anomaly quite intuitively. Prioritising the data consistency I could always run query and Invoke on the same peer, but I fear that would defeat the purpose of having multiple nodes. – ANIKET DHAR May 28 '20 at 11:59
  • Instead, wont it be better if the peerID was returned to client after every ledger update call & stored in some storage(client side) so that the subsequent ledger query calls can be made to that peer(ID stored in client storage) until another ledger update call is made thus overriding the peerID in storage. Is that possible? – ANIKET DHAR May 28 '20 at 12:12
  • Your concern is totally valid. In order to guarantee your transaction is committed, you can follow [this tutorial](https://hyperledger.github.io/fabric-sdk-node/release-1.4/tutorial-listening-to-events.html) or [this post](https://stackoverflow.com/questions/46462151/how-to-listen-to-the-eventcommit-event-in-hyperledger-fabric) to implement and see the difference. After sending transaction, you need to wait for commit event then execute query, this would grant some degree of consistency. – hsnkhrmn May 28 '20 at 12:56
  • Check [this post](https://stackoverflow.com/questions/56759271/how-to-ensure-data-integrity-in-hyperledger-fabric-when-someone-intentionally-ch) for data integrity concerns and how to deal with it. Also check the question "How to guarantee the query result is correct" on [hyperledger FAQ page](https://hyperledger-fabric.readthedocs.io/en/release-2.0/Fabric-FAQ.html). – hsnkhrmn May 28 '20 at 13:01