Peer cannot discover orderer when node.js application is used to invoke chaincode #hyperledger-fabric #fabric-sdk-node #fabric-orderer #fabric-peer


h.dungca@...
 

Hello everyone,

I've been running into a problem with a Hyperledger Fabric network that I’ve deployed non-locally and I would like to ask for some insights or assistance regarding this problem.

I deployed a simple network to AWS, using separate VM instances for an orderer, two peers, and their respective CAs. So I have one VM instance for the orderer, one instance for the orderer CA, and so on.

I was able to start the network, create a channel, and deploy the sample fabcar chaincode. I can also query and invoke the chaincode from inside any of the two peers using  peer chaincode query/invoke. The problem I’m experiencing happens when I use a node.js application (that is outside of the network and is using the fabric-network module) to query or invoke the chaincode. Whenever I try to query/invoke the chaincode using the application, I get the following error:

error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: xxx.xxx.xxx.xxx:7050, url:grpcs://xxx.xxx.xxx.xxx:7050, connected:false, connectAttempted:true
error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server xxx.xxx.xxx.xxx:7050 url:grpcs://xxx.xxx.xxx.xxx:7050 timeout:3000
error: [DiscoveryService]: _buildOrderer[channel1] - Unable to connect to the discovered orderer xxx.xxx.xxx.xxx:7050 due to Error: Failed to connect before the deadline on Committer- name: xxx.xxx.xxx.xxx:7050, url:grpcs://xxx.xxx.xxx.xxx:7050, connected:false, connectAttempted:true 

If my understanding is correct, it seems that the peer can’t find the orderer through discovery even though there were no problems during channel creation and chaincode deployment. I assume that the peers communicate with the orderer during these steps, so I can’t figure out why the peer suddenly can’t find the orderer when I use the application to query/invoke the chaincode.

I tried editing the /etc/hosts/ of each VM instance and the machine running the application (my own computer) to include the IP addresses of the orderer and the peers. It looks something like:

xxx.xxx.xxx.xxx   orderer.example.com
xxx.xxx.xxx.xxx   peer0.org1.example.com
xxx.xxx.xxx.xxx   peer0.org2.example.com

The VM instances have the internal IP addresses (since they belong to the same network anyway), while my computer (where the application is running) has the external IP addresses. Even after updating /etc/hosts/, I was still getting the same error.

The connection profile that the node.js application uses is shown below. I changed the URLs from localhost to the actual (external) IP addresses of the peer and peer CA. 

{
    "name": "test-network-org1",
    "version": "1.0.0",
    "client": {
        "organization": "Org1",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "300"
                }
            }
        }
    },
    "organizations": {
        "Org1": {
            "mspid": "Org1MSP",
            "peers": [
                "peer0.org1.example.com"
            ],
            "certificateAuthorities": [
                "ca.org1.example.com"
            ]
        }
    },
    "peers": {
        "peer0.org1.example.com": {
            "url": "grpcs://xxx.xxx.xxx.xxx:7051",
            "tlsCACerts": {
                "pem": <pem_string>
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org1.example.com",
                "hostnameOverride": "peer0.org1.example.com"
            }
        }
    },
    "certificateAuthorities": {
        "ca.org1.example.com": {
            "url": "https://xxx.xxx.xxx.xxx:7054",
            "caName": "ca-org1",
            "tlsCACerts": {
                "pem": [<pem_string>]
            },
            "httpOptions": {
                "verify": false
            }
        }
    }
}

I guess another thing to note is that I edited /test-network/configtx/configtx.yaml and changed the OrdererEndpoints so that it's xxx.xxx.xxx.xxx:7050 (the internal IP address of the orderer VM) instead of the default orderer.example.com:7050. I did this because the peers could not connect to the orderer when I used the default OrdererEndpoints value.

On the side of the node.js application, I’ve set discovery to true and asLocalhost to false.

I am using Fabric v2.2.3Fabric CA v1.5.0, and fabric-network v2.2.8.

Am I missing something or is there anything else I should change so that the peer can see the orderer through discovery when using the node.js application? Any help is appreciated. Thank you so much!


Marcos Sarres
 

My guess has something to do with the TLS certs. In order to access your peers by the HL Fabric client, you need to configure the certificates properly.

 

If you access them by IP instead of FQDN, you should create your network with all TLS certificates for each peer IP.

 

Also check if the ports between the client and peer, that may cause connection fail as well.

 

Hope it helps.

 

Regards,

 

Marcos Sarres | CEO | +55 61 98116 7866

 

 

De: fabric@... <fabric@...> Em nome de h.dungca via lists.hyperledger.org
Enviada em: terça-feira, 31 de agosto de 2021 12:13
Para: fabric@...
Assunto: [Hyperledger Fabric] Peer cannot discover orderer when node.js application is used to invoke chaincode #hyperledger-fabric #fabric-sdk-node #fabric-orderer #fabric-peer

 

Hello everyone,

I've been running into a problem with a Hyperledger Fabric network that I’ve deployed non-locally and I would like to ask for some insights or assistance regarding this problem.

I deployed a simple network to AWS, using separate VM instances for an orderer, two peers, and their respective CAs. So I have one VM instance for the orderer, one instance for the orderer CA, and so on.

I was able to start the network, create a channel, and deploy the sample fabcar chaincode. I can also query and invoke the chaincode from inside any of the two peers using  peer chaincode query/invoke. The problem I’m experiencing happens when I use a node.js application (that is outside of the network and is using the fabric-network module) to query or invoke the chaincode. Whenever I try to query/invoke the chaincode using the application, I get the following error:

 

error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: xxx.xxx.xxx.xxx:7050, url:grpcs://xxx.xxx.xxx.xxx:7050, connected:false, connectAttempted:true
error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server xxx.xxx.xxx.xxx:7050 url:grpcs://xxx.xxx.xxx.xxx:7050 timeout:3000
error: [DiscoveryService]: _buildOrderer[channel1] - Unable to connect to the discovered orderer xxx.xxx.xxx.xxx:7050 due to Error: Failed to connect before the deadline on Committer- name: xxx.xxx.xxx.xxx:7050, url:grpcs://xxx.xxx.xxx.xxx:7050, connected:false, connectAttempted:true 


If my understanding is correct, it seems that the peer can’t find the orderer through discovery even though there were no problems during channel creation and chaincode deployment. I assume that the peers communicate with the orderer during these steps, so I can’t figure out why the peer suddenly can’t find the orderer when I use the application to query/invoke the chaincode.

I tried editing the /etc/hosts/ of each VM instance and the machine running the application (my own computer) to include the IP addresses of the orderer and the peers. It looks something like:

xxx.xxx.xxx.xxx   orderer.example.com
xxx.xxx.xxx.xxx   peer0.org1.example.com
xxx.xxx.xxx.xxx   peer0.org2.example.com


The VM instances have the internal IP addresses (since they belong to the same network anyway), while my computer (where the application is running) has the external IP addresses. Even after updating /etc/hosts/, I was still getting the same error.


The connection profile that the node.js application uses is shown below. I changed the URLs from localhost to the actual (external) IP addresses of the peer and peer CA. 

{
    "name": "test-network-org1",
    "version": "1.0.0",
    "client": {
        "organization": "Org1",
        "connection": {
            "timeout": {
                "peer": {
                    "endorser": "300"
                }
            }
        }
    },
    "organizations": {
        "Org1": {
            "mspid": "Org1MSP",
            "peers": [
                "peer0.org1.example.com"
            ],
            "certificateAuthorities": [
                "ca.org1.example.com"
            ]
        }
    },
    "peers": {
        "peer0.org1.example.com": {
            "url": "grpcs://xxx.xxx.xxx.xxx:7051",
            "tlsCACerts": {
                "pem": <pem_string>
            },
            "grpcOptions": {
                "ssl-target-name-override": "peer0.org1.example.com",
                "hostnameOverride": "peer0.org1.example.com"
            }
        }
    },
    "certificateAuthorities": {
        "ca.org1.example.com": {
            "url": "https://xxx.xxx.xxx.xxx:7054",
            "caName": "ca-org1",
            "tlsCACerts": {
                "pem": [<pem_string>]
            },
            "httpOptions": {
                "verify": false
            }
        }
    }
}


I guess another thing to note is that I edited /test-network/configtx/configtx.yaml and changed the OrdererEndpoints so that it's xxx.xxx.xxx.xxx:7050 (the internal IP address of the orderer VM) instead of the default orderer.example.com:7050. I did this because the peers could not connect to the orderer when I used the default OrdererEndpoints value.

On the side of the node.js application, I’ve set discovery to true and asLocalhost to false.

I am using Fabric v2.2.3Fabric CA v1.5.0, and fabric-network v2.2.8.

Am I missing something or is there anything else I should change so that the peer can see the orderer through discovery when using the node.js application? Any help is appreciated. Thank you so much!


h.dungca@...
 

Good day,

Thank you for your reply! And apologies for my late reply.

For the TLS certificates, I used the registerEnroll.sh script that is included in the test-network files (in /test-network/organizations/fabric-ca/) to generate the certificates I needed. However, I modified the script so that it uses the IP addresses of the orderer and peers. I changed instances of localhost in the script to the appropriate internal IP addresses. I've attached the modified scripts to this reply.

With this, I do believe that I have the correct TLS certificates. I may be wrong though and I might be missing something, so your help would be greatly appreciated!

Another thing I noticed is that when I use the node.js application to query the chaincode, I still get the results of the query despite getting the error I mentioned in my first message. So when I query, the response is something like this:

error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: 172.31.42.206:7050, url:grpcs://172.31.42.206:7050, connected:false, connectAttempted:true

error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server 172.31.42.206:7050 url:grpcs://172.31.42.206:7050 timeout:3000

error: [DiscoveryService]: _buildOrderer[channel1] - Unable to connect to the discovered orderer 172.31.42.206:7050 due to Error: Failed to connect before the deadline on Committer- name: 172.31.42.206:7050, url:grpcs://172.31.42.206:7050, connected:false, connectAttempted:true

Results: [{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
success

However, when I try invoking the chaincode using the application, I get the error shown below and the invocation does not go through.

error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: 172.31.42.206:7050, url:grpcs://172.31.42.206:7050, connected:false, connectAttempted:true

error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server 172.31.42.206:7050 url:grpcs://172.31.42.206:7050 timeout:3000

error: [DiscoveryService]: _buildOrderer[channel1] - Unable to connect to the discovered orderer 172.31.42.206:7050 due to Error: Failed to connect before the deadline on Committer- name: 172.31.42.206:7050, url:grpcs://172.31.42.206:7050, connected:false, connectAttempted:true

error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: 172.31.42.206:7050, url:grpcs://172.31.42.206:7050, connected:false, connectAttempted:true

error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server 172.31.42.206:7050 url:grpcs://172.31.42.206:7050 timeout:3000

error: [DiscoveryService]: _buildOrderer[fabcar] - Unable to connect to the discovered orderer 172.31.42.206:7050 due to Error: Failed to connect before the deadline on Committer- name: 172.31.42.206:7050, url:grpcs://172.31.42.206:7050, connected:false, connectAttempted:true

Error: Error: No committers assigned to the channel

So in the case of the fabcar chaincode, I can query to get information on all the cars, but I cannot add a car by invoking the chaincode using the node.js application.

If it's not an issue with the TLS certificates, might there be something else that's causing the peer to not see the orderer when using the node.js application?

Thank you so much for your help!