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
Related
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
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
I'm trying to create a channel with the Fabric SDK node.js. When I create the channel through the bash commands, I have no problems (you can see the code below), but when I use the node.js SDK I got some errors.
I am using TLS and client authentication. I can't realize what the error means and how to solve it. Any help will be greatly appreciated.
Node JS code to create Channel, it was executed in host machine:
var Fabric_Client = require('fabric-client');
var fs=require('fs');
var fabric_client = new Fabric_Client();
// Obtain tls cert and key from client.
let clientcert = fs.readFileSync('/home/rosalva40/Documentos/Own2/Own/data/tls/peer1-org1-cli-client.crt');
let clientkey = fs.readFileSync('/home/rosalva40/Documentos/Own2/Own/data/tls/peer1-org1-cli-client.key');
fabric_client.setTlsClientCertAndKey(clientcert.toString(),clientkey.toString())
//Orderer configuration
let pem1 = fs.readFileSync('/home/rosalva40/Documentos/Own2/Own/data/org0-ca-chain.pem');
const connectionopts = {
pem: pem1.toString()
};
var order = fabric_client.newOrderer('grpcs://localhost:9101', connectionopts)
//setup identity admin
let cert = fs.readFileSync('/home/rosalva40/Documentos/Own2/Own/data/orgs/org1/admin/msp/signcerts/cert.pem');
let pk = fs.readFileSync('/home/rosalva40/Documentos/Own2/Own/data/orgs/org1/admin/msp/keystore/b17b8a06b4928a037e621cc784cac4f8a4913087c95c68162ecae6189993a1fa_sk');
const mspid = 'org1MSP';
fabric_client.setAdminSigningIdentity(pk, cert, mspid);
// Setup create channel
var chanelName = 'mychannel';
const envelope = fs.readFileSync('/home/rosalva40/Documentos/Own2/Own/data/channel.tx');
channelConfig = fabric_client.extractChannelConfig(envelope);
signature = fabric_client.signChannelConfig(channelConfig);
const request = {
name: chanelName,
orderer: order,
config: channelConfig,
signatures : [signature],
txId : fabric_client.newTransactionID(true)
};
//Create chanel
fabric_client.createChannel(request);
When I run createChannel.js, I get the following error in the console:
2019-01-17T14:30:42.278Z - error: [Remote.js]: Error: Failed to
connect before the deadline URL:grpcs://localhost:9101
2019-01-17T14:30:42.283Z - error: [Orderer.js]: Orderer
grpcs://localhost:9101 has an error Error: Failed to connect before
the deadline URL:grpcs://localhost:9101 (node:31051)
UnhandledPromiseRejectionWarning: Error: Failed to connect before the
deadline URL:grpcs://localhost:9101
at checkState (/home/rosalva40/fabric-samples/vote/node_modules/fabric-client/node_modules/grpc/src/client.js:720:16)
(node:31051) UnhandledPromiseRejectionWarning: Unhandled promise
rejection. This error originated either by throwing inside of an async
function without a catch block, or by rejecting a promise which was
not handled with .catch(). (rejection id: 2) (node:31051) [DEP0018]
DeprecationWarning: Unhandled promise rejections are deprecated. In
the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
And this is the orderer node log:
2019-01-17 16:08:40.977 UTC [grpc] Println -> DEBU 13a grpc:
Server.Serve failed to create ServerTransport: connection error: desc
= "transport: http2Server.HandleStreams failed to receive the preface from client: EOF" 2019-01-17 16:08:41.987 UTC [grpc] Println -> DEBU
13b grpc: Server.Serve failed to create ServerTransport: connection
error: desc = "transport: http2Server.HandleStreams failed to receive
the preface from client: EOF" 2019-01-17 16:08:43.572 UTC [grpc]
Println -> DEBU 13c grpc: Server.Serve failed to create
ServerTransport: connection error: desc = "transport:
http2Server.HandleStreams failed to receive the preface from client:
EOF"
This is the bash code executed in a container:
DATA=data
CHANNEL_TX_FILE=/$DATA/channel.tx
CHANNEL_NAME=mychannel
# ORDERER CONNECTION ARGUMENTS
ORDERER_HOST=orderer1-org0
ORDERER_PORT_INT=7050
INT_CA_CHAINFILE=/${DATA}/org0-ca-chain.pem
ORDERER_PORT_ARGS="-o $ORDERER_HOST:$ORDERER_PORT_INT --tls --cafile $INT_CA_CHAINFILE --clientauth"
export CORE_PEER_TLS_CLIENTCERT_FILE=/$DATA/tls/peer1-org1-cli-client.crt
export CORE_PEER_TLS_CLIENTKEY_FILE=/$DATA/tls/peer1-org1-cli-client.key
ORDERER_CONN_ARGS="$ORDERER_PORT_ARGS --keyfile $CORE_PEER_TLS_CLIENTKEY_FILE --certfile $CORE_PEER_TLS_CLIENTCERT_FILE"
#ORGANIZATION ADMIN ENVIROMENT ARGUMENTS
ORG_ADMIN_HOME=/${DATA}/orgs/org1/admin
export CORE_PEER_MSPCONFIGPATH=$ORG_ADMIN_HOME/msp
export CORE_PEER_LOCALMSPID=org1MSP
#CHANNEL CREATE COMMAND
peer channel create --logging-level=DEBUG -c $CHANNEL_NAME -f $CHANNEL_TX_FILE $ORDERER_CONN_ARGS
Its seems like the app has problems to connect to the orderer. Try using this method:
var Client = require('fabric-client');
var Channel = require('fabric-client').Channel;
const fs = require('fs');
var client = Client.loadFromConfig("config/configfile.yaml");
/**
* #param {String} channelName Channel name used in configtxgen to create the channel transaction (mychannel)
* #param {String} channelConfigPath Path of the channel transaction (/home/root/channel-artifacts/channel.tx)
* #param {String} orderer Orderer name (orderer.example.com)
* #description Create channel
*/
async createChannel(channelName,orderer, channelConfigPath) {
var envelope = fs.readFileSync(channelConfigPath);
var channelConfig = client.extractChannelConfig(envelope);
let signature = client.signChannelConfig(channelConfig);
let request = {
config: channelConfig,
orderer: client.getOrderer(orderer),
signatures: [signature],
name: channelName,
txId: client.newTransactionID(true)
};
const result = await client.createChannel(request)
return result;
}
You can check the structure of the configfile.yaml in this link.
Dont forget to set the client header in your configfile.yaml
I'm trying to interact with the peers from JavaScript and I keep getting
{ Error: 2 UNKNOWN: access denied: channel [mychannel] creator org [Org1MSP]
at Object.exports.createStatusError (/blockchain-api-js/node_modules/grpc/src/common.js:87:15)
at Object.onReceiveStatus (/blockchain-api-js/node_modules/grpc/src/client_interceptors.js:1188:28)
at InterceptingListener._callNext (/blockchain-api-js/node_modules/grpc/src/client_interceptors.js:564:42)
at InterceptingListener.onReceiveStatus (/blockchain-api-js/node_modules/grpc/src/client_interceptors.js:614:8)
at callback (/blockchain-api-js/node_modules/grpc/src/client_interceptors.js:841:24)
code: 2,
metadata: [Object],
details: 'access denied: channel [mychannel] creator org [Org1MSP]' }
I'm using the fabric-ca sample and I was able to execute transactions from cli and from cli through run-fabric.sh but I can't seem to do that from JS, I've created a new user and set the client and cert with client.setTlsClientCertAndKey(cert, key);, I even tried giving the admin cert and key from /data/orgs/org1/admin/msp/signcerts, /data/orgs/org1/admin/msp/admincerts and /data/orgs/org1/admin/msp/keystore as well as the ones from /data/tls/ but with no luck
And this is the portion of the code I use:
var channel = this.client.newChannel('mychannel')
let serverCert = fs.readFileSync('/data/org0-ca-chain.pem');
channel.addOrderer(
this.client.newOrderer(
config.orderers['orderer1-org0'].url,
{
pem: Buffer.from(serverCert).toString()
}
)
);
serverCert = fs.readFileSync('/data/org1-ca-chain.pem');
const peer1 = this.client.newPeer(
config.peers['peer1-org1'].url,
{
pem: Buffer.from(serverCert).toString()
}
);
channel.addPeer(peer1);
this.eventhubs = []
this.eventhubs.push(channel.newChannelEventHub(peer1));
serverCert = fs.readFileSync('/data/org2-ca-chain.pem');
const peer2 = this.client.newPeer(
config.peers['peer1-org2'].url,
{
'pem': Buffer.from(serverCert).toString()
}
);
channel.addPeer(peer2);
this.eventhubs.push(channel.newChannelEventHub(peer2));
this.channel = channel;
console.log(this.channel)
return this.channel.sendTransactionProposal(request);
Is there something wrong with my code or the way I do it? Can someone tell me what I am doing wrong? I've seen a few similar questions but those happened when composer was used mostly and I couldn't fix my problem with the answers from there,
You'd better check the user context of client I think.
user context has mspID. check whether mspId is Org1MSP or not.
The error could be because of the Certificates to sign the transaction.Double check your certificate received from CA and also checked the certificates and path used inside the docker container of peers.