How to make connection between Fabric Node SDK and Fabric network, when deployed on different hosts?

861 views Asked by At

I am testing Running a Fabric Application tutorial. I deployed network on one host (let's say: HOST1). Then, on another host with different ip address (HOST2) I wanted to run application (like in tutorial). To do this, I copied connection profile, which has been generated, when I run ./network.sh deployCC script, and changed url of peer from localhost, to IP address of HOST1. So, the connection profile on HOST2 is as below:

{
"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://<HOST1IP>:7051",
        "tlsCACerts": {
            "pem": "-----BEGIN CERTIFICATE-----\nCERTBODY\n-----END CERTIFICATE-----\n"
        },
        "grpcOptions": {
            "ssl-target-name-override": "peer0.org1.example.com",
            "hostnameOverride": "peer0.org1.example.com"
        }
    }
},
"certificateAuthorities": {
    "ca.org1.example.com": {
        "url": "https://<HOST1IP>:7054",
        "caName": "ca-org1",
        "tlsCACerts": {
            "pem": ["-----BEGIN CERTIFICATE-----\nCERTBODY\n-----END CERTIFICATE-----\n"]
        },
        "httpOptions": {
            "verify": false
        }
    }
}

Also, I changed discovery option in gateway.connect() method in app.js file, to avoid looking fabric network in local network:

try {

    const ccp = buildCCPOrg1();
    const caClient = buildCAClient(FabricCAServices, ccp, 'ca.org1.example.com');
    const wallet = await buildWallet(Wallets, walletPath);
    await enrollAdmin(caClient, wallet, mspOrg1);
    await registerAndEnrollUser(caClient, wallet, mspOrg1, org1UserId, 'org1.department1');

    const gateway = new Gateway();

    try {

        await gateway.connect(ccp, {
            wallet,
            identity: org1UserId,
            discovery: { enabled: true, asLocalhost: false } 
        });
        //first exception here

        const network = await gateway.getNetwork(channelName);
        //second exception here, and app closes

        const contract = network.getContract(chaincodeName);

        console.log('\n--> Submit Transaction: InitLedger...');
        await contract.submitTransaction('InitLedger');
        console.log('*** Result: committed');
        
        //rest of method from original app.js was cut
    } finally {

        gateway.disconnect();
    }

Other than these changes, everything has remained the default. Application can connect to CA and register and enroll admin and appUser (as in tutorial), but crashes when connecting to network.

Copy of the logs and errors:

Loaded the network configuration located at \fabric-samples\test-network\conn\connection-org1.json
Built a CA Client named ca-org1
Built a file system wallet at \fabric-samples\asset-transfer-basic\application-javascript\wallet
Successfully enrolled admin user and imported it into the wallet
Successfully registered and enrolled user appUser and imported it into the wallet
2021-04-30T11:49:34.232Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer0.org1.example.com, url:grpcs://<HOST1IP>:7051, connected:false, connectAttempted:true
2021-04-30T11:49:34.232Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org1.example.com url:grpcs://<HOST1IP>:7051 timeout:3000
2021-04-30T11:49:34.264Z - info: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer0.org1.example.com due to Error: Failed to connect before the deadline on Endorser- name: peer0.org1.example.com, url:grpcs://<HOST1IP>:7051, connected:false, connectAttempted:true
    at checkState (\fabric-samples\asset-transfer-basic\application-javascript\node_modules\@grpc\grpc-js\build\src\client.js:69:26)
    at Timeout._onTimeout (\fabric-samples\asset-transfer-basic\application-javascript\node_modules\@grpc\grpc-js\build\src\channel.js:292:17)
    at listOnTimeout (internal/timers.js:549:17)
    at processTimers (internal/timers.js:492:7) {
connectFailed: true
}
2021-04-30T11:49:37.389Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Discoverer- name: peer0.org1.example.com, url:grpcs://<HOST1IP>:7051, connected:false, connectAttempted:true
2021-04-30T11:49:37.391Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org1.example.com url:grpcs://<HOST1IP>:7051 timeout:3000
2021-04-30T11:49:37.393Z - error: [ServiceEndpoint]: ServiceEndpoint grpcs://mchm5pza:7051 reset connection failed :: Error: Failed to connect before the deadline on Discoverer- name: peer0.org1.example.com, url:grpcs://<HOST1IP>:7051, connected:false, connectAttempted:true
2021-04-30T11:49:37.396Z - error: [DiscoveryService]: send[mychannel] - no discovery results
******** FAILED to run the application: Error: DiscoveryService has failed to return results

As can be seen, user is enrolled successfully, but connection to the network cannot be established. I think there can be something under cover, but I don't know where should I look. There are for sure no conflicts with wallets, and certs.

How can I connect app to this network from another host?

//EDIT

Sometimes you can't even trust yourself. It turned out, that tlcCACerts were incorrect. But after correcting connection profile, there were some new errors:

2021-04-30T15:10:02.760Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: orderer.example.com:7050, url:grpcs://orderer.example.com:7050, connected:false, connectAttempted:true
2021-04-30T15:10:02.760Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server orderer.example.com:7050 url:grpcs://orderer.example.com:7050 timeout:3000
2021-04-30T15:10:02.760Z - error: [DiscoveryService]: _buildOrderer[mychannel] - Unable to connect to the discovered orderer orderer.example.com:7050 due to Error: Failed to connect before the deadline on Committer- name: orderer.example.com:7050, url:grpcs://orderer.example.com:7050, connected:false, connectAttempted:true
2021-04-30T15:10:05.776Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer0.org1.example.com:7051, url:grpcs://peer0.org1.example.com:7051, connected:false, connectAttempted:true
2021-04-30T15:10:05.778Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org1.example.com:7051 url:grpcs://peer0.org1.example.com:7051 timeout:3000
2021-04-30T15:10:05.780Z - error: [DiscoveryService]: _buildPeer[mychannel] - Unable to connect to the discovered peer peer0.org1.example.com:7051 due to Error: Failed to connect before the deadline on Endorser- name: peer0.org1.example.com:7051, url:grpcs://peer0.org1.example.com:7051, connected:false, connectAttempted:true
2021-04-30T15:10:08.782Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer0.org2.example.com:9051, url:grpcs://peer0.org2.example.com:9051, connected:false, connectAttempted:true
2021-04-30T15:10:08.782Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org2.example.com:9051 url:grpcs://peer0.org2.example.com:9051 timeout:3000
2021-04-30T15:10:08.782Z - error: [DiscoveryService]: _buildPeer[mychannel] - Unable to connect to the discovered peer peer0.org2.example.com:9051 due to Error: Failed to connect before the deadline on Endorser- name: peer0.org2.example.com:9051, url:grpcs://peer0.org2.example.com:9051, connected:false, connectAttempted:true

It seems, like app on HOST2 doesn't see peers and orderer on HOST1...

1

There are 1 answers

0
Marcin Beza On

I finally found a solution for a second problem (with connection to network on another host). You have to edit your /etc/hosts file, and translate orderer and peers hostnames into IP address of machine, where network is deployed.


On Linux:

  1. Open /etc/hosts file in text-editor with admin privileges
  2. Add necessary hosts and IP translations
  3. Save file

On Windows:

  1. Open start menu
  2. Type notepad and press ctrl+shift+enter, to open notepad in User Access Mode
  3. From notepad app enter to directory: c:\Windows\System32\drivers\etc
  4. Filter all file types, then open the hosts file
  5. Add necessary hosts and IP translations
  6. Save file