1

I'm running an HL Fabric private network and submitting transactions to the ledger from a Java Application using Fabric-Java-Sdk.

Occasionally, like 1/10000 of the times, the Java application throws an exception when I'm submitting the transaction to the ledger, like the message below:

ERROR 196664 --- [ Thread-4] org.hyperledger.fabric.sdk.Channel : Future completed exceptionally: sendTransaction

java.lang.IllegalArgumentException: The proposal responses have 2 inconsistent groups with 0 that are invalid. Expected all to be consistent and none to be invalid. at org.hyperledger.fabric.sdk.Channel.doSendTransaction(Channel.java:5574) ~[fabric-sdk-java-2.1.1.jar:na] at org.hyperledger.fabric.sdk.Channel.sendTransaction(Channel.java:5533) ~[fabric-sdk-java-2.1.1.jar:na] at org.hyperledger.fabric.gateway.impl.TransactionImpl.commitTransaction(TransactionImpl.java:138) ~[fabric-gateway-java-2.1.1.jar:na] at org.hyperledger.fabric.gateway.impl.TransactionImpl.submit(TransactionImpl.java:96) ~[fabric-gateway-java-2.1.1.jar:na] at org.hyperledger.fabric.gateway.impl.ContractImpl.submitTransaction(ContractImpl.java:50) ~[fabric-gateway-java-2.1.1.jar:na] at com.apidemoblockchain.RepositoryDao.BaseFunctions.Implementations.PairTrustBaseFunction.sendTrustTransactionMessage(PairTrustBaseFunction.java:165) ~[classes/:na] at com.apidemoblockchain.RepositoryDao.Implementations.PairTrustDataAccessRepository.run(PairTrustDataAccessRepository.java:79) ~[classes/:na] at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

While my submitting method goes like this:

 public void sendTrustTransactionMessage(Gateway gateway, Contract trustContract, String payload) throws TimeoutException, InterruptedException, InvalidArgumentException, TransactionException, ContractException {
        // Prepare
        checkIfChannelIsReady(gateway);

        // Execute
        trustContract.submitTransaction(getCreateTrustMethod(), payload);
 }

I'm using a 4 org network with 2 peers each and I am using 3 channels, one for each chaincode DataType, in order to keep the things clean.

I think that the error coming from the Channel doesn't make sense because I am using the Contract to submit it...

Like I'm opening the gateway and then I keep it open for continuously submit the txs.

      try (Gateway gateway = getBuilder(getTrustPeer()).connect()) {
            Contract trustContract = gateway.getNetwork(getTrustChaincodeChannelName()).getContract(getTrustChaincodeId(), getTrustChaincodeName());
            while (!terminateLoop) {
                 if (message) {
                    String payload = preparePayload();
                    sendTrustTransactionMessage(gateway, trustContract, payload);
                 }
                 ...
                 wait();
            } 
       ...
       }

EDIT:

After reading @bestbeforetoday advice, I've managed to catch the ContractException and analyze the logs. Still, I don't fully understand where might be the bug and, therefore, how to fix it.

I'll add 3 prints that I've taken to the ProposalResponses received in the exception and a comment after it.

ProposalResponses-1

ProposalResponses-2

ProposalResponses-3

So, in the first picture, I can see that 3 proposal responses were received at the exception and the exception cause message says: "The proposal responses have 2 inconsistent groups with 0 that are invalid. Expected all to be consistent and none to be invalid."

In pictures, 2/3 is represented the content of those responses and I notice that there are 2 fields saving null value, namely "ProposalRespondePayload" and "timestamp_", however, I don't know if those are the "two groups" referred at the message cause of the exception.

Thanks in advance...

devops2.0
  • 11
  • 3

1 Answers1

0

It seems that, while the endorsing peers all successfully endorsed your transaction proposal, those peer responses were not all byte-for-byte identical.

There are several things that might differ, including read/write sets or the value returned from the transaction function invocation. There are several reasons why differences might occur, including non-deterministic transaction function implementation, different transaction function behaviour between peers, or different ledger state at different peers.

To figure out what caused this specific failure you probably need to look at the peer responses to identify how they differ. You should be getting a ContractException thrown back from your transaction submit call, and this should allow you to access the proposal responses by calling e.getProposalResponses():

https://hyperledger.github.io/fabric-gateway-java/release-2.2/org/hyperledger/fabric/gateway/ContractException.html#getProposalResponses()

bestbeforetoday
  • 1,302
  • 1
  • 8
  • 12