每当我尝试通过 NodeJS 执行事务时,我都会收到错误。
2021-02-12T09:33:58.302Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer1.peers.org1.com, url:grpcs://xxx.xxx.xxx.xxx:7051, connected:false, connectAttempted:true
2021-02-12T09:33:58.303Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer1.peers.org1.com url:grpcs://xxx.xxx.xxx.xxx:7051 timeout:3000
2021-02-12T09:33:58.306Z - info: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer1.peers.org1.com due to Error: Failed to connect before the deadline on Endorser- name: peer1.peers.org1.com, url:grpcs://xxx.xxx.xxx.xxx:7051, connected:false, connectAttempted:true
at checkState (/fabric23/node_modules/@grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/fabric23/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-02-12T09:34:01.308Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer1.peers.org2.com, url:grpcs://xxx.xxx.xxx.xxx:7051, connected:false, connectAttempted:true
2021-02-12T09:34:01.308Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer1.peers.org2.com url:grpcs://xxx.xxx.xxx.xxx:7051 timeout:3000
2021-02-12T09:34:01.309Z - info: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer1.peers.org2.com due to Error: Failed to connect before the deadline on Endorser- name: peer1.peers.org2.com, url:grpcs://xxx.xxx.xxx.xxx:7051, connected:false, connectAttempted:true
at checkState (/fabric23/node_modules/@grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/fabric23/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-02-12T09:34:04.314Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer1.peers.org3.com, url:grpcs://xxx.xxx.xxx.xxx:7051, connected:false, connectAttempted:true
2021-02-12T09:34:04.314Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer1.peers.org3.com url:grpcs://xxx.xxx.xxx.xxx:7051 timeout:3000
2021-02-12T09:34:04.315Z - info: [NetworkConfig]: buildPeer - Unable to connect to the endorser peer1.peers.org3.com due to Error: Failed to connect before the deadline on Endorser- name: peer1.peers.org3.com, url:grpcs://xxx.xxx.xxx.xxx:7051, connected:false, connectAttempted:true
at checkState (/fabric23/node_modules/@grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/fabric23/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-02-12T09:34:07.317Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: ord1.orderers.org1.com, url:grpcs://xxx.xxx.xxx.xxx:7050, connected:false, connectAttempted:true
2021-02-12T09:34:07.317Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server ord1.orderers.org1.com url:grpcs://xxx.xxx.xxx.xxx:7050 timeout:3000
2021-02-12T09:34:07.317Z - info: [NetworkConfig]: buildOrderer - Unable to connect to the committer ord1.orderers.org1.com due to Error: Failed to connect before the deadline on Committer- name: ord1.orderers.org1## Heading ##.com, url:grpcs://xxx.xxx.xxx.xxx:7050, connected:false, connectAttempted:true
at checkState (/fabric23/node_modules/@grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/fabric23/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
}
Failed to evaluate transaction: Error: Committer must be connectable
这是我的connection.json
{
"name": "byfn",
"version": "1.0.0",
"client": {
"organization": "ORG1",
"connection": {
"timeout": {
"peer": {
"endorser": "10000"
},
"orderer": "10000"
}
}
},
"channels": {
"supplychain": {
"orderers": [
"ord1.orderers.org1.com",
"ord2.orderers.org1.com",
"ord3.orderers.org1.com"
],
"peers": {
"peer1.peers.org2.com": {},
"peer1.peers.org3.com": {},
"peer1.peers.org1.com": {}
}
}
},
"organizations": {
"ORG1": {
"mspid": "ORG1",
"peers": [
"peer1.peers.org1.com",
"peer2.peers.org1.com"
]
}
},
"orderers": {
"ord1.orderers.org1.com": {
"url": "grpcs://xxx.xxx.xxx.xxx:7050",
"grpcOptions": {
"ssl-target-name-override": "ord1.orderers.org1.com",
"request-timeout": 12000
},
"tlsCACerts": {
"path": "ca.pem"
}
}
},
"peers": {
"peer1.peers.org2.com": {
"url": "grpcs://xxx.xxx.xxx.xxx:7051",
"grpcOptions": {
"ssl-target-name-override": "peer1.peers.org2.com",
"request-timeout": 12000,
"grpc.keepalive_time_ms": 600000
},
"tlsCACerts": {
"path": "ca.pem"
}
},
"peer1.peers.org3.com": {
"url": "grpcs://xxx.xxx.xxx.xxx:7051",
"grpcOptions": {
"ssl-target-name-override": "peer1.peers.org3.com",
"request-timeout": 12000,
"grpc.keepalive_time_ms": 600000
},
"tlsCACerts": {
"path": "ca.pem"
}
},
"peer1.peers.org1.com": {
"url": "grpcs://xxx.xxx.xxx.xxx:7051",
"grpcOptions": {
"ssl-target-name-override": "peer1.peers.org1.com",
"request-timeout": 12000,
"grpc.keepalive_time_ms": 600000
},
"tlsCACerts": {
"path": "ca.pem"
}
}
}
}
这是我的 test.js
'use strict';
const { Wallets, Gateway } = require('fabric-network');
const fs = require('fs');
const path = require('path');
const ccpPath = path.resolve(__dirname,'test-connection.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
async function main(){
try {
// const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet('wallet');
// console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.get('usernew');
const tlsExists = await wallet.get('tlsid');
if (!userExists) {
console.log('An identity for the user "usernew" does not exist in the wallet');
return;
}
if (!tlsExists) {
console.log('An identity for the user "tls" does not exist in the wallet');
return;
}
console.log("Here");
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: 'usernew', discovery: { enabled: false, asLocalhost: false }, clientTlsIdentity: 'tlsid' });
console.log("Here1");
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');
console.log("Here2");
//Get the channel object to fetch out peers
const channel = network.getChannel();
console.log("Here3");
//Get peers for endorsement
const org1Peer = channel.getPeer('peer1.peers.org1.com');
console.log(org1Peer);
const org2Peer = channel.getPeer('peer1.peers.org2.com');
console.log(org2Peer);
const org3Peer = channel.getPeer('peer1.peers.org3.com');
console.log(org3Peer);
// Get the contract from the network.
const contract = network.getContract('mycontract');
const result = await contract.createTransaction("transaction").setEndorsingPeers([org1Peer, org2Peer, org3Peer]).setTransient().submit(
"key",
"val1",
"val2"
);
console.log(`Transaction has been evaluated, result is: ${result.toString()}`);
} catch (error) {
console.error(`Failed to evaluate transaction: ${error}`);
}
}
main()
我的网络部署在 kubernetes 集群上,NodeJS 容器位于同一集群上。我用于 Pod 的 IP 是对等方 Pod 和排序者 Pod 的 ClusterIP。此外,我使用的证书不是 Fabric 生成的证书,这些证书是使用我们组织的 CA 创建和签名的,因此加密文件夹内有一个“tlsintermediatecerts”文件夹。我尝试使用“tlsca”文件夹中的pem 文件以及“tlsintermediatecerts”文件夹中的pem 文件作为connection.json 中的tlsca 路径。但没有一个奏效。 这是加密文件夹的目录结构。
我还通过向每个节点和订购者发出curl 请求来验证证书,并检查握手是否完成。
C:.
├───peers.org1.com
│ └───users
│ ├───[email protected]
│ │ ├───msp
│ │ │ ├───admincerts
│ │ │ ├───cacerts
│ │ │ ├───intermediatecerts
│ │ │ ├───keystore
│ │ │ ├───signcerts
│ │ │ ├───tlscacerts
│ │ │ └───tlsintermediatecerts
│ │ └───tls
│ └───[email protected]
│ ├───msp
│ │ ├───admincerts
│ │ ├───cacerts
│ │ ├───intermediatecerts
│ │ ├───keystore
│ │ ├───signcerts
│ │ ├───tlscacerts
│ │ └───tlsintermediatecerts
│ └───tls
├───peers.org2.com
│ └───users
│ ├───[email protected]
│ │ ├───msp
│ │ │ ├───admincerts
│ │ │ ├───cacerts
│ │ │ ├───intermediatecerts
│ │ │ ├───keystore
│ │ │ ├───signcerts
│ │ │ ├───tlscacerts
│ │ │ └───tlsintermediatecerts
│ │ └───tls
│ └───[email protected]
│ ├───msp
│ │ ├───admincerts
│ │ ├───cacerts
│ │ ├───intermediatecerts
│ │ ├───keystore
│ │ ├───signcerts
│ │ ├───tlscacerts
│ │ └───tlsintermediatecerts
│ └───tls
└───peers.org3.com
└───users
├───[email protected]
│ ├───msp
│ │ ├───admincerts
│ │ ├───cacerts
│ │ ├───intermediatecerts
│ │ ├───keystore
│ │ ├───signcerts
│ │ ├───tlscacerts
│ │ └───tlsintermediatecerts
│ └───tls
└───[email protected]
├───msp
│ ├───admincerts
│ ├───cacerts
│ ├───intermediatecerts
│ ├───keystore
│ ├───signcerts
│ ├───tlscacerts
│ └───tlsintermediatecerts
└───tls
如有任何帮助,我们将不胜感激。
在这里回答我的问题。 根据上面 @Gari Singh 的回答,必须通过将中间 CA 和根 CA 合并到单个文件中来创建在 connection.json 文件的“tlsCACerts”参数中使用的证书。文件中的第一个块应该是中间 CA,第二个块应该是根 CA。此证书链是必需的,因为中间 CA 由根 CA 签名,并且客户端应该通过这两个证书,以便可以正确验证它们。全面的解释可以在这里找到:https://www.thesslstore.com/blog/root-certificates-intermediate/
我错过的最后一件事是,我收到错误“无法评估事务:错误:提交者必须可连接”,因为我在配置的“通道”部分传递了 3 个排序者,并且只传递了其中之一他们的详细信息位于配置的“orderers”部分。添加其他 2 个订购者的 IP 和其他详细信息即可解决该问题。
此处的 URL 属性,例如
grpcs://peer0.org1.example.com:7051
,应从主机名更改为运行对等点的虚拟机上另一台计算机的 IP 地址 (grpcs://XX.XX.XX.XX:7051)容器。
示例:grpcs://123.456.7.8:7051
修复此问题
connection.json
这个bug花了我很多时间,我用上面的方法解决了这个问题,
就我而言,问题是这样的:
我的connection.json中对等点描述的端口和我的对等组织运行的端口不同,所以在更正端口后我解决了这个问题。