what are the steps to troubleshoot below error when trying to invoke a chaincode?
Error: could not assemble transaction: ProposalResponsePayloads do not match - proposal response: version:1 response:<status:200 payload:"[\"00000\"]" > ...
we get this error when trying to invoke a chaincode using peer chaincode invoke
#morpheus: Has answered it excellently:
So I thought I will add to the above list of possible reasons:
I had by mistake added something like getting the current timestamp, and was using this for capturing the event date. This led to the different transaction responses by the endorsers, thus leading to the Response Payload not matching. The whole point to remember is that the result of execution should be deterministic as it is going to be run on all of the selected endorsing peers.
So use ctx.GetStub().GetTxTimestamp() for capturing the event time. This is the time when the transaction began and it will be constant across the endorser executions.
Check that you have installed the chaincode on all the peers your peer chaincode invoke command is targetting. That is the most likely cause of this error.
Other ways this error can occur:
You modified your chaincode and instead of installing a new version and upgrading the chaincode, you tried to be smart and overwrite the chaincode with the new file thinking that Fabric would not notice.
It can also happen if there is no chaincode container running on target peer and Docker daemon cannot be found on the peer node when it tries to instantiate a container or instantiation fails for some other reason
Another reason why this error can happen is if some peer nodes are using LevelDB and others are using CouchDB
The error itself originates from here. The first step to debug this error is to invoke the chaincode individually one-by-one on one peer node at a time.
Another reason that I forgot to check is using storing randomly generated values.
I never used random "Id" until now and didn't notice that it leads to ENDORSEMENT_MISMATCH
Related
I was trying to test out the endorsement policy feature of Fabric with the Running a Fabric Application tutorial and I have encountered a few questions/issues.
Instead of using LevelDB, I up the network using CouchDB by changing the command to ./network.sh up createChannel -c mychannel -ca -s couchdb.
After the call to InitLedger, I manually edit asset2's "Size" field value to another random value through fauxton, accessed from http://127.0.0.1:5984/_utils/ (couchdb0, which belongs to organization 1). So at this point, asset2 has 2 different value sitting in couchdb0 and couchdb1.
Then I invoke the UpdateAsset function in the chaincode to update asset2's value. I was expecting an error about endorsement policy is not met or something to be thrown as the different value of asset2 in couchdb0 and couchdb1 should results in different RW set.
peer0.org1.example.com|2021-03-23 09:03:09.568 UTC [statecouchdb] commitUpdates -> WARN 0b4 CouchDB batch document update encountered an problem. Reason:Document update conflict., Retrying update for document ID:asset2
I did notice this warning in logspout however there was no error caught in my try catch block, and it seems that a valid block is committed and the world states is getting updated as usual without any error.
Shouldn't the different RW Set would cast the transaction as invalid and the world states wouldn't be updated?
This is working as expected. You updated the size field but not the version field. The read set check only checks the version field. It is up to the chaincode to check other fields such as asset ownership (and size, if there are business rules around that, such as size not being allowed to change in an update). The asset transfer chaincode is a trivial sample and only checks for asset existence in state database by key. So in your case chaincode execution succeeded because it passed the asset existence check, endorsements succeeded, and validation succeeded since both endorsements were over the same read set (version) and write set.
You get the CouchDB warning because the internal CouchDB revision number was different due to your external update, but this is not a fatal problem and gets resolved by a retry (CouchDB internal revision numbers are not guaranteed to be the same across state databases since peer may update the same state multiple times, e.g. in crash recovery scenarios).
What steps are required in order to add an endorsing peer to a blockchain network (in hyperledger-fabric)? What about promoting a committing peer in an endorsing one?
Should I just alter files crypto-config.yaml and configtx.yaml by adding the new peer?
I am using the fabcar example from the fabric-samples repo (https://github.com/hyperledger/fabric-samples), so should I change the docker-compose(-cli).yaml also? When starting the network with startFabric.sh script, should I just install chaincode on the new peers, or are other steps requires also?
I tried it with just installing a chaincode on the new peers, however I got an error stating that "... Consortium was not met when instantiating the chaincode ..."
Edit:
I was able to install the chaincode on all four peers and instantiate it on the channel. Initial non-query transaction is successful and another one after it. However, after the first two transactions I get:
Failed to submit transaction createInquiry: Error: Peer localhost:8051 has rejected transaction "e8a83c12bfbcae97c7a3f2baaad7735fe8b44195a0ce252a3533a7b4a2a8103b" with code "ENDORSEMENT_POLICY_FAILURE"
can you stop, remove and kill containers and try once again to instantiate.
I have a hyperledger fabric network setup in multiple servers and I successfully installed chaincode in different peers(peer0.org1.com and peer0.org2.com) of different organizations.
When I call the chaincode with putState(key,value) from peer0.org1.com I am able to commit the change but when I call the same chaincode from peer0.org2.com putstate(key, value) is failing with endorsement error.
This might be because you didn't include peer0.org2.com in the endorsement policy while installing the chaincode.
Ex: Include OR/AND ('ORG1MSP.member','ORG2MSP.member') in chaincode installation step
I hope this solves the issue
I started a new composer network (two org setup), i.e. a second chaincode (one was already installed and running). I installed it and while starting, couple of chaincode containers were stuck while downloading node modules, and the command to start chaincode was timed out. To start again I removed the chaincode containers and tried to start again. But I am getting error : status: 500, message: chaincode exists.
That message from hyperledger fabric means that the chaincode has already been instantiated, so you do not need to invoke composer network start again. Any request you send to a peer will try to bring up a chaincode container to process that request if there isn't one already started.
composer network start sends the instantiate transaction to peers and as such the peers need to simulate the request proposal and to do that it needs a chaincode container so goes through the process of creating a chaincode container image and chaincode container to execute the request (but any transaction proposal causes the same process to be followed). So long as the instantiation policy is satisfied (and the default I believe is for 1 successful instantiation proposal) then the chaincode is then defined as instantiated.
I've been studying Hyperledger Fabric for about 1 year.
But I still can't tell how a chaincode works and is dealt with exactly, especially in terms of its implementation and process.
This is how I understand a chaincode below.
A chaincode is running and is isolated from peers, as one of docker containers for its integrity in the network. The chaincode is a program which defines how functions in transactions(e.g., AddTwoIntegerValues()) should update the ledger
Also, endorsing peers access the chaincode for executing functions in the transaction proposals from clients or other peers to respond with endorsement.(This process is not clear)
In that case, I'd like to ask you how those endorsing peers can execute or access the chaincode container in parallel? I heard 'chaincode execution' means simulation of the chaincode logic computation. But I can't get that.
In other words, my question is how can they execute or access that at the same time? Do they have copies of that chaincode? How do peers know the chaincode logic? Could you please correct me or explain chaincode process if I'm wrong?
Please tell me if you have any idea about my question. I'm looking forward to your answer!
Each peer has its own chaincode container for each version of a given chaincode code.
When the chaincode is installed on a peer, the code package of the chaincode's code is written to the file system.
Later on, when the peer receives a request to invoke a function on the chaincode (Init() or Invoke(), when Init() runs on instantiate), the peer checks to see if the chaincode is already running, and if not, it:
Spins a container to compile the chaincode code package to produce the chaincode shim binary and afterwards destroys it
Spins a container that would actually run the chaincode shim binary.
The chaincode shim binary:
Connects to the peer via gRPC and registers itself to be the name it is installed with.
Runs an endless loop in which it waits for commands to simulate transactions from the peer.
Whenever the peer receives a proposal from a client, it:
Locates the chaincode container gRPC stream and forwards the proposal from the client to the chaincode
Prepares a map of key reads and writes that the chaincode shim would ask the peer during its execution, which is called a Read-Write set.
Then, the chaincode shim, running inside the container - extracts the arguments from the proposal and starts running the chaincode logic (part of its binary).
If the chaincode logic contains data access operations such as GetState or PutState, it sends a request to the peer down the same gRPC stream it is connected to the peer, and then the peer does the following:
If the data operation is a read operation, it adds to the read-write set the key and the version read from the key, and sends back the key and the value to the chaincode shim container over the gRPC stream.
If the data operation is a write operation, it adds to the read-write set the key and the value and the version, and then sends back an "OK" to the chaincode shim(*).
(*) I personally think this step is not necessary... it just prolongs the execution time
After the chaincode shim finished computing the transaction, it sends back the result (i.e "OK") to the peer, along with a marker that denotes that the transaction finished executing.
Since the values that are written, are not really written to the DB but just added to an in-memory map, this is called a "transaction simulation".
The peer then proceeds to sign the transaction simulation's results (the read-write set map and the result from the chaincode shim) and then returns the signed transaction simulation (also called an "endorsement") back to the client as a response.
In that case, I'd like to ask you how those endorsing peers can execute or access the chaincode container in parallel?
You can do that in parallel because when the chaincode shim invokes the transaction, it does so on a separate goroutine.