I have a problem with fabric 1.4 while using fabric-gateway-java. Sometimes, it throw TimeoutException when sending proposal to peers. In most cases, it works well. Can anyone help? thanks!
Here is the error log.
2020-09-03 10:02:34,202 [ERROR]--org.hyperledger.fabric.sdk.Channel 4451 -- Channel
Channel{id:1,name: mychannel} sending proposal with transaction
e1d7313d8f8fc09fbae9a3ac2027bbf33ba3714c028a609f26380a4b0810466e to
Peer{ id: 6, name: peer1.org1.example.com, channelName: mychannel,
url:grpcs://192.168.1.1:7051, mspid: Org1MSP} failed because of
timeout(35000 milliseconds) expiration
java.util.concurrent.TimeoutException: null
at com.google.common.util.concurrent.AbstractFuture.get(AbstractFuture.java:432)
at org.hyperledger.fabric.sdk.Channel.sendProposalToPeers(Channel.java:4434)
at org.hyperledger.fabric.sdk.Channel.sendProposal(Channel.java:4358)
at org.hyperledger.fabric.sdk.Channel.sendTransactionProposal(Channel.java:3908)
Actually I do not have any direct solution for your problem but I try to help you.
The problem is happened in "fabric-sdk-java" not in "fabric-gateway-java".
More specifically :
catch (TimeoutException e) {
message = format("Channel %s sending proposal with transaction %s to %s failed because of timeout(%d milliseconds) expiration",
toString(), txID, peerName, transactionContext.getProposalWaitTime());
logger.error(message, e);
}
Links: https://github.com/hyperledger/fabric-sdk-java/blob/master/src/main/java/org/hyperledger/fabric/sdk/Channel.java
For "fabric-sdk-java" you may follow this:
You may increase your setProposalWaitTime.
setProposalWaitTime
public void setProposalWaitTime(long proposalWaitTime)
Sets the timeout for a single proposal request to endorser in milliseconds.
Parameters:
proposalWaitTime - the timeout for a single proposal request to endorser in milliseconds
Links: https://javadoc.io/static/org.hyperledger.fabric-sdk-java/fabric-sdk-java/2.2.0/org/hyperledger/fabric/sdk/TransactionRequest.html#setProposalWaitTime-long-
So your code may look something like that:
TransactionProposalRequest request = fabClient.getInstance().newTransactionProposalRequest();
ChaincodeID ccid = ChaincodeID.newBuilder().setName(Config.CHAINCODE_1_NAME).build();
request.setChaincodeID(ccid);
request.setFcn("createCar");
String[] arguments = { "CAR1", "Chevy", "Volt", "Red", "Nick" };
request.setArgs(arguments);
request.setProposalWaitTime(4000);
For "fabric-gateway-java" you may follow this:
TimeoutException - If the transaction was successfully submitted to the orderer but timed out before a commit event was received from peers.
Links: https://hyperledger.github.io/fabric-gateway-java/master/org/hyperledger/fabric/gateway/Contract.html#createTransaction-java.lang.String-
So you may increase setCommitTimeout.
setCommitTimeout -Set the maximum length of time to wait for commit events to be received after submitting a transaction to the orderer.
Transaction setCommitTimeout(long timeout,
TimeUnit timeUnit)
Parameters:
timeout - the maximum time to wait.
timeUnit - the time unit of the timeout argument.
Returns:
this transaction object to allow method chaining.
Links: https://hyperledger.github.io/fabric-gateway-java/master/org/hyperledger/fabric/gateway/Transaction.html
Related
After 30 minute I get this error:
Channel closed by server: 406 (PRECONDITION-FAILED) with message "PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more"
I read online that this error is generated because the consumer does not acknowledge the message but I put noAck:false so it should acknowledge the message automatically, also in the queue I can see it has been unacked from rabbitmq manager. So why am I getting this error? How can I solve this? From what is come from?
this is how my queues look like:
Here is the code for the consumer:
const channel = await connection.createChannel();
await channel.assertExchange(exchange, exchangeType, { durable: true });
const assertedQueue = await channel.assertQueue('', {
exclusive: true,
});
await channel.bindQueue(assertedQueue.queue, exchange, routingKey);
await channel.consume(assertedQueue.queue, msg => dbOperation(msg, channel), {
noAck: false, // send always an answer of confirmation back
});
I have a network on hyperledger fabric 1.4.4 with 5 organizations A , B, C , D , E. I created a channel with these 5 orgs and installed my chaincode on org A and org B because only they are apart of the endorsement policy.
This is the endorsement policy :
{"identities":[{"role":{"name":"member","mspId":"AMSP"}},{"role":{"name":"member","mspId":"BMSP"}},{"role":{"name":"member","mspId":"CMSP"}},{"role":{"name":"member","mspId":"DMSP"}},{"role":{"name":"member","mspId":"EMSP"}}],"policy":{"2-of":[{"signed-by":0},{"signed-by":1}]}}
I am using a gateway with the below configuration to invoke the chain code
const walletPath = path.join('wallet' );
const wallet = new FileSystemWallet(walletPath);
let connectionOptions = {
identity: userName,
wallet: wallet,
discovery: { enabled:true, asLocalhost: true },
eventHandlerOptions: {
commitTimeout: 100,
strategy: DefaultEventHandlerStrategies.NETWORK_SCOPE_ALLFORTX
}
};
logger.debug('Connecting to Fabric gateway');
await gateway.connect(clientConnectionProfileJson, connectionOptions);
const network = await gateway.getNetwork(channelName);
const contract = await network.getContract(chaincodeName , contractName);
const transaction = contract.createTransaction(functionName);
await transaction.submit(<arguments>);
This is the error which I a getting , at the client level
2021-02-17T05:28:13.063Z - warn: [TransactionEventHandler]: _strategyFail: strategy fail for transaction "9be4da8b1d52ddde804d6c7c08d134ef4b6ac2043cbe0258b5b4c921424c9f04": TransactionError: Peer a-org-peer1.a-org.com:7051 has rejected transaction "9be4da8b1d52ddde804d6c7c08d134ef4b6ac2043cbe0258b5b4c921424c9f04" with code "ENDORSEMENT_POLICY_FAILURE"
This is what I see in all the peer logs
2021-02-17 05:28:12.313 UTC [vscc] Validate -> ERRO 0db VSCC error: stateBasedValidator.Validate failed, err validation of endorsement policy for chaincode {chaincodeName} in tx 26:0 failed: signature set did not satisfy policy
After some research , I found that this is a failure that is occurring when the org peer is trying to commit the transaction to the ledger , and finds that the signature set did not satisfy the policy.
I have gone ahead and looked at the transaction object using the getTransactionByID method. I see that there are two endorsers MSP with the correct sign certificates , these certificates belong to the one of the peers of A and B orgs. So the discovery service correctly identified the peers and even the peers have endorsed the transaction , but not sure why the transaction is not getting committed.
What am I missing here ?
How can I verify if the signatures are correct ?
To explicitly say to the gateway that the request should go to specific endorsing peers , I have used the below code.
const walletPath = path.join('wallet' );
const wallet = new FileSystemWallet(walletPath);
let connectionOptions = {
identity: userName,
wallet: wallet,
discovery: { enabled: true , asLocalhost: true },
eventHandlerOptions: {
commitTimeout: 100,
strategy: DefaultEventHandlerStrategies.NETWORK_SCOPE_ALLFORTX
}
};
logger.debug('Connecting to Fabric gateway');
await gateway.connect(clientConnectionProfileJson, connectionOptions);
const network = await gateway.getNetwork(channelName);
const channel = network.getChannel();
let endorsingPeers = [];
endorsingPeers.push(channel.getChannelPeer('a-org-peer1.a-org.com'));
endorsingPeers.push(channel.getChannelPeer('b-org-peer1.b-org.com'));
// Get addressability to org.cargoesnetwork.ebilloflading contract
// Use chaincodeName that is used for installing
const contract = await network.getContract(chaincodeName , contractName);
const transaction = contract.createTransaction(functionName).setEndorsingPeers(endorsingPeers);
await transaction.submit(<arguments>);
No luck , the transaction still fails with the same endorsement policy failure. I verified the transaction object if the endorser sign certs are correctly present. They are present , but still got the same error.
Out of curiosity , I changed the endorsement policy to only one org from two orgs , every thing worked as expected. The issue exists only when the policy contains more than one endorsing organisations.
Please help in debugging this issue.
An ENDORSEMENT_POLICY_FAILURE can occur for a number of reasons. The first being you don't have enough signatures which is what you have said you have already checked. Another reason is that not all the signatures match to the proposal that was sent.
In the 1.4 gateway apis the proposals are received and not compared to see if they all match before a proposal is sent to the orderer. The SDK will send all the signatures and one of the proposals that was received back. The signatures are created over the each peer's individual proposal response.
If those proposals don't match (which would mean that your chaincode is not deterministic) then one of those signatures will be ok, but the other one won't because it won't match the proposal that was sent to the orderer.
I would check that your chaincode is deterministic because it's possible that each peer is generating different responses. An example of non-deterministic chaincode for example is where it creates a new date and stores that in the world state. Each peer would create a slightly different date value resulting in differing responses.
I am reaching out to you, because of an exception with hyperledger fabric endorsement policy belonging lifecycle.
What I have done:
Packaged, Installed, approved, and committed my chaincode on Three Peers out of 9, all in the same Organisational MSP.
Since I have the test case, that I should enforce an endorsement policy that looks like this:
OutOf(2, Org1MSP.member) which is in my eyes similar to: AND(Org1MSP.member, Org1MSP.member). Am I wrong?
Never the less, when I issue my chaincode I am getting back a message:
server returned: failed constructing descriptor for chaincodesname:"mycc": no peer combination can satisfy the endorsement policy
Confusing enough, when I using the Policy: AND(Org1MSP.member) everything is crystal clear and my chaincode is invoked. And using the discovery command in this case returns every single peer on a server, great. But it is not the case I want to achieve! I want to enforce an endorsement by 2 of 3 Endorsers.
I appreciate your help!
Here is my connection profile. Only containing the three endorsement-peers:
---
certificateAuthorities:
Org1CA:
caName: ca
url: http://<IP is correct links to the right server>:7054
client:
connection:
timeout:
orderer: '300'
peer:
endorser: '300'
organization: Org1MSP
name: example.com
organizations:
Org1MSP:
certificateAuthorities:
- Org1CA
mspid: Org1MSP
peers:
- peer0.org1.example.com
- peer1.org1.example.com
- peer9.org1.example.com
peers:
peer0.org1.example.com:
url: grpc://peer0.org1.example.com:7051
peer9.org1.example.com:
url: grpc://peer9.org1.example.com16051
peer1.org1.example.com:
url: grpc://peer1.org1.example.com:8051
version: 1.0.0
Every peer is on a different machine.
Here is an sample on how I am doing the Transaction invoke:
Gateway.Builder builder = Gateway.createBuilder();
Wallet wallet = Wallets.newInMemoryWallet();
X509Identity ident;
try {
ident = Identities.newX509Identity("Org1MSP",
Identities.readX509Certificate("removed key due to security porpuse"),
Identities.readPrivateKey("removed key due to security porpuse"));
String userName = "admin";
Contract contract = null;
InputStream input = classLoader.getResourceAsStream("connection-org1.yaml");
wallet.put("admin", ident);
builder.identity(wallet, userName).networkConfig(input).discovery(true);
Gateway gateway = builder.connect();
Network network = gateway.getNetwork("crm-field-1");
contract = network.getContract(contractName);
byte[] response = null;
Transaction trans = contract.createTransaction("createCrmContact");
Map<String, byte[]> data = new HashMap<String, byte[]>();
data.put("value", value.getBytes());
data.putAll(initialize());
trans = trans.setTransient(data);
response = trans.submit(pk, fieldName);
// response = contract.submitTransaction("createCrmContact", pk, fieldName,
// value);
LOGGER.error("Logging: Response - " + response);
if (response == null)
return null;
return decode(response);
} catch (Exception e) {
LOGGER.error("Logging: Error" + e.getMessage());
e.printStackTrace();
}
So, I figured out by my self:
If the network does not have any Anchor peers set, the discovery fails, because there is no endpoint, where he gets the information about every one in the network. So added them to the network solved my issue.
Thanks for all advice
Getting below gRPC error when tls is enabled and tried to send transaction proposal to peer.
Taken reference code from here: https://developer.ibm.com/tutorials/hyperledger-fabric-java-sdk-for-tls-enabled-fabric-network/
I have enabled TLS on all peers and on overall network. I tried by giving certificate/pem string directly also in code. But, same exception.
What I am missing here? I am running client application from Eclipse directly.
Thank you in advance.
------------------------- Code starts ---------------
HFClient hfClient = HFClient.createNewInstance();
hfClient.setCryptoSuite(cryptoSuite);
hfClient.setUserContext(admin_registar);
String peer_name = "peer0.org1.example.com";
String peer_url = "grpcs://localhost:7051"; // Ensure that port is of peer1
String peerTLSCertFileName = "crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"; ***// Taking TLS certitifcate***
Properties peerProperties = new Properties();
peerProperties.setProperty("pemFile", peerCertFile.getAbsolutePath());
peerProperties.setProperty("allowAllHostNames", "true");
Path peerPath = Paths.get(peerTLSCertFileName); ;
peerProperties.put("pemBytes", Files.readAllBytes(peerPath));
**peerProperties.setProperty("sslProvider", "openSSL"); // SETTING TLS properties
peerProperties.setProperty("negotiationType", "TLS"); // SETTING TLS properties**
Peer peer = hfClient.newPeer(peer_name, peer_url, peerProperties);
<< --- Similar code to add Orderer to HFClient --->>
Channel channel = hfClient.newChannel("mychannel");
channel.addPeer(peer);
channel.addOrderer(orderer);
channel.initialize();
TransactionProposalRequest request = hfClient.newTransactionProposalRequest();
String cc = "fabcar"; // Chaincode name
ChaincodeID ccid = ChaincodeID.newBuilder().setName(cc).build();
request.setChaincodeID(ccid);
request.setFcn("createCar"); // Chaincode invoke funtion name
String[] arguments = {"CAR11", "VgW", "Poglo", "Ggrey", "Margy"}; // Arguments that Chaincode function takes
request.setArgs(arguments);
request.setProposalWaitTime(3000);
**Collection<ProposalResponse> responses = channel.sendTransactionProposal(request); // this is line throwing exception**
------------------------- Code ends ---------------
Below exception is at last line of code above:
Exception in thread "main" org.hyperledger.fabric.sdk.exception.ProposalException: org.hyperledger.fabric.sdk.exception.TransactionException: org.hyperledger.fabric.sdk.exception.ProposalException: getConfigBlock for channel mychannel failed with peer peer0.org1.example.com. Status FAILURE, details: Channel Channel{id: 3, name: mychannel} Sending proposal with transaction: 353dde2899c1993b9e643ac32b7b9c27ae4eeda1aaa17bc13f1c35f91795a9f7 to Peer{ id: 1, name: peer0.org1.example.com, channelName: mychannel, url: grpcs://localhost:7051} failed because of: gRPC failure=Status{code=UNAVAILABLE, description=io exception
Channel Pipeline: [SslHandler#0, ProtocolNegotiators$ClientTlsHandler#0, WriteBufferingAndExceptionHandler#0, DefaultChannelPipeline$TailContext#0], cause=javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
at
I was getting this issue when I had not run the CreateChannel command.
java -cp blockchain-client.jar org.example.network.CreateChannel
I am converting a certificate signing request to self signed certificate using hyper ledger chaincode. But while storing information regarding the certificate, transaction is not being successful and it gives me no ledger context error.
Nodejs version : 8.9.4
My chaincode function is:
async registerDomain(ctx, csr) {
let buff = new Buffer(csr, 'base64')
let csrData = buff.toString('ascii')
pem.createPrivateKey(2048, {
aes128: "11223344"
}, async function (err, pk) {
let domain = new Domain(ctx, "abcd", "data.detail", "keys.certificate", "pk.key");
await ctx.stub.putState(domain.domainId, Buffer.from(JSON.stringify(domain)));
});
While transaction this is what I am getting inside peer docker logs:
HandleTransaction -> ERRO 09f [ddc81d1b] Failed to handle PUT_STATE. error: no ledger context
runtime.goexit
/opt/go/src/runtime/asm_amd64.s:1333
PUT_STATE failed: transaction ID: ddc81d1bcb69eecd6c6bbcf85ba16b2168486d4b232ef3c03fe5bbc7bb2adea1
github.com/hyperledger/fabric/core/chaincode.
runtime.goexit
Any help would be much appreciated.
I have also faced a similar issue. Though there is no any proper solution for this error.
As per my understanding, this error is thrown when tx takes more time to complete and lose the context instance provided by state db api's.
In your example, createPrivateKey might be taking more time to generate pk and thus causing "no ledger context" issue.
Reference:
https://jira.hyperledger.org/browse/FAB-17512?focusedCommentId=69269&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-69269