I am trying to execute a smart contract on the Hyperledger fabric test-network (Fabcar javascript smart contract) and I get the follwing error when I try to invoke the chaincode using the invoke.js file present in the fabcar javascript example:
error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Committer- name: orderer0.example.com:7050, url:grpcs://localhost:7050, connected:false, connectAttempted:true
2021-05-05T23:44:02.951Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server orderer0.example.com:7050 url:grpcs://localhost:7050 timeout:3000
2021-05-05T23:44:02.952Z - error: [DiscoveryService]: _buildOrderer[mychannel] - Unable to connect to the discovered orderer orderer0.example.com:7050 due to Error: Failed to connect before the deadline on Committer- name: orderer0.example.com:7050, url:grpcs://localhost:7050, connected:false, connectAttempted:true
2021-05-05T23:44:05.957Z - error: [ServiceEndpoint]: Error: Failed to connect before the deadline on Endorser- name: peer0.org01.example.com:7051, url:grpcs://localhost:7051, connected:false, connectAttempted:true
2021-05-05T23:44:05.957Z - error: [ServiceEndpoint]: waitForReady - Failed to connect to remote gRPC server peer0.org01.example.com:7051 url:grpcs://localhost:7051 timeout:3000
2021-05-05T23:44:05.958Z - error: [DiscoveryService]: _buildPeer[mychannel] - Unable to connect to the discovered peer peer0.org01.example.com:7051 due to Error: Failed to connect before the deadline on Endorser- name: peer0.org01.example.com:7051, url:grpcs://localhost:7051, connected:false, connectAttempted:true
One thing to note is that I have changed port forwardings and peer/org names in the default test-network. My connection profile is as follows (removed certificates for clarity):
{
"name": "test-network-org1",
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"channels": {
"mychannel": {
"orderers": [
"orderer0.example.com"
],
"peers": [
"peer0.org01.example.com"
]
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org01.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
}
},
"peers": {
"peer0.org01.example.com": {
"url": "grpcs://localhost:6041",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----**********-----END CERTIFICATE-----\n"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org01.example.com",
"hostnameOverride": "peer0.org01.example.com"
}
}
},
"orderers": {
"orderer0.example.com": {
"url": "grpcs://localhost:6040",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----**********-----END CERTIFICATE-----\n"
},
"grpcOptions": {
"ssl-target-name-override": "orderer0.example.com"
}
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "https://localhost:6054",
"caName": "ca-org1",
"tlsCACerts": {
"pem": ["-----BEGIN CERTIFICATE-----******-----END CERTIFICATE-----\n"]
},
"httpOptions": {
"verify": false
}
}
}
}
One thing that puzzles me (which I believe is the root cause of the error) is the grpcs url for the orderer. In the connection profile I have clearly specified it to be grpcs://localhost:6041, however as can be seen in the error, the error states the url as grpcs://localhost:7050. I have gone over the various files in the test-network and have not been able to figure out why the grpcs url is not read from the connection profile.
This problem is only limited to the query.js and invoke.js files in the fabcar example (I am able to successfully execute enrollAdmin.js and registerUser.js on the network).
Following is the invoke.js file I execute which leads to aforementioned error:
'use strict';
const { Gateway, Wallets } = require('fabric-network');
const fs = require('fs');
const path = require('path');
async function main() {
try {
// load the network configuration
const ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json');
let ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const identity = await wallet.get('appUser3');
if (!identity) {
console.log('An identity for the user "appUser3" does not exist in the wallet');
console.log('Run the registerUser.js application before retrying');
return;
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: 'appUser3', discovery: { enabled: true, asLocalhost: true } });
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');
// Get the contract from the network.
const contract = network.getContract('fabcar');
// Submit the specified transaction.
// createCar transaction - requires 5 argument, ex: ('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom')
// changeCarOwner transaction - requires 2 args , ex: ('changeCarOwner', 'CAR12', 'Dave')
await contract.submitTransaction('createCar', 'CAR312', 'Skoda', 'Kadiq', 'White', 'JOHNSON');
console.log('Transaction has been submitted');
// Disconnect from the gateway.
await gateway.disconnect();
} catch (error) {
console.error(`Failed to submit transaction: ${error}`);
process.exit(1);
}
}
main();
Any help would be appreciated. Thank You
I think the key piece of information is this part of the error message:
Unable to connect to the discovered orderer orderer0.example.com:7050
This is a node that has been located by the client using service discovery, not defined in your connection profile.
What I suspect has happened is that, even though you have changed the port mappings between your local machine and the Docker network, the orderer is still listening on port 7050 within your Docker network.
The discovery.asLocalhost connection option is there to support the scenario where the blockchain network is running within a Docker network on the client's local machine, so it causes any discovered hostnames to be treated as localhost, but it leaves the discovered port numbers unchanged. So, when using the discovery.asLocalhost option, the port numbers that nodes are listening on within the Docker network must be mapped to the same port numbers on the local machine.
If you want to change the port numbers then you need to change them on the actual nodes themselves, not just in your Docker network mappings.
Related
I have a Lambda function that makes a GetObject request to an S3 bucket.
However, I'm getting the following error:
AccessDenied: Access Denied
at deserializeAws_restXmlGetObjectCommandError (/node_modules/#aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:6284:41)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at /node_modules/#aws-sdk/middleware-serde/dist-cjs/deserializerMiddleware.js:6:20
at /node_modules/#aws-sdk/middleware-signing/dist-cjs/middleware.js:11:20
at StandardRetryStrategy.retry (/node_modules/#aws-sdk/middleware-retry/dist-cjs/StandardRetryStrategy.js:51:46)
at /node_modules/#aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:6:22
at GetS3Data (/src/input.ts:21:26)
at Main (/src/main.ts:8:34)
at Runtime.run [as handler] (/handler.ts:6:9) {
Code: 'AccessDenied',
RequestId: '3K61PMQGW4825D3W',
HostId: '5PpmWpu2I4WZPx37Y0pRfDAcdCmjX8fchuE+HLpUzy7uqoJirtb9Os0g96kWfluM/ctkn/mEC5o=',
'$fault': 'client',
'$metadata': {
httpStatusCode: 403,
requestId: undefined,
extendedRequestId: '5PpmWpu2I4WZPx37Y0pRfDAcdCmjX8fchuE+HLpUzy7uqoJirtb9Os0g96kWfluM/ctkn/mEC5o=',
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
}
}
I've given access to the Lambda function to make this request.
What is the issue?
serverless.ts
import type { AWS } from "#serverless/typescript";
const serverlessConfiguration: AWS = {
service: "affiliations",
frameworkVersion: "2",
custom: {
esbuild: {
bundle: true,
minify: false,
sourcemap: true,
exclude: ["aws-sdk"],
target: "node14",
define: { "require.resolve": undefined },
platform: "node",
},
},
plugins: ["serverless-esbuild"],
provider: {
name: "aws",
region: "us-east-2",
runtime: "nodejs14.x",
apiGateway: {
minimumCompressionSize: 1024,
shouldStartNameWithService: true,
},
environment: {
AWS_NODEJS_CONNECTION_REUSE_ENABLED: "1",
NODE_OPTIONS: "--enable-source-maps --stack-trace-limit=1000",
},
lambdaHashingVersion: "20201221",
vpc: {
securityGroupIds: ["<redacted>"],
subnetIds: ["redacted>"],
},
iam: {
role: {
statements: [
{
Effect: "Allow",
Action: ["s3:GetObject"],
Resource: "<redacted>",
},
],
},
},
},
useDotenv: true,
// import the function via paths
functions: {
run: {
handler: "handler.run",
timeout: 300,
events: [
{
sns: {
arn: "<redacted>",
},
},
],
},
},
};
module.exports = serverlessConfiguration;
s3.ts
export const GetS3Data = async (payload: GetObjectRequest) => {
try {
const response = await S3Service.getObject(payload);
const result = await new Promise((resolve, reject) => {
const data = [];
response.Body.on("data", (chunk) => data.push(chunk));
response.Body.on("err", reject);
response.Body.once("end", () => resolve(data.join("")));
});
return [result, null];
} catch (err) {
Logger.error({
method: "GetS3Data",
error: err.stack,
});
return [null, err];
}
};
package.json
"#aws-sdk/client-s3": "^3.36.0",
Forgot to add /* to the end of the resource
Resource: "<redacted>/*",
Your 403 Access Denied error is masking a 404 Not Found error, as your code & Serverless config looks perfectly fine & should work as expected provided you've specified the resource correctly.
If you do not have correct s3:ListBucket permissions, the S3 endpoint will not return a 404 Not Found error if the object does not exist for the specified key.
GetObject's API reference highlights this nuance:
If you have the s3:ListBucket permission on the bucket, Amazon S3 will return an HTTP status code 404 ("no such key") error.
If you don’t have the s3:ListBucket permission, Amazon S3 will return an HTTP status code 403 ("access denied") error.
This is to prevent attackers from enumerating public buckets & knowing what objects actually exist in the bucket.
The absence of a 404, in this case, is not allowing information to be leaked on if the object exists or not (just like an Invalid Credentials message on a login page as opposed to Invalid Password which indicates a user with the provided username exists).
Provide the Lambda with permission to carry out the s3:ListBucket action to unmask the 404 error and/or ultimately double-check your GetObjectRequest to make sure the key is being specified correctly for an object that does exist:
iam: {
role: {
statements: [
{
Effect: "Allow",
Action: ["s3:GetObject", "s3:ListBucket"],
Resource: "<redacted>",
},
],
},
}
I have a test environment for hyperledger fabric 2.2. Two organizations with 2 peers, each.
I wanted to simulate an offline peer, so I shut down peer2-org1 for testing purposes, which results in a broken application for org1.
This is the node application code, which is basically taken from the example:
this.gateway = new Gateway();
const gatewayOpts = {
wallet: this.wallet,
identity: username,
discovery: {
enabled: true,
asLocalhost: false
}
} as GatewayOptions;
await this.gateway.connect(this.config, gatewayOpts);
this.network = await this.gateway.getNetwork('somechannel');
The last command gateway.getNetwork throws the following exception:
Error: Failed to connect before the deadline on Discoverer- name: peer2-org1, url:grpcs://peer2-org1:7051, connected:false, connectAttempted:true
at checkState (/usr/src/app/node_modules/#grpc/grpc-js/build/src/client.js:69:26)
at Timeout._onTimeout (/usr/src/app/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
}
I found out, that the application will work if I remove the offline peer peer2-org1 from the gateway.connect configuration object, which looks like this:
(...)
"organizations": {
"org1": {
"mspid": "org1",
"peers": [
"peer1-org1", "peer2-org1"
],
"certificateAuthorities": [
"rca-org1"
]
}
},
(...)
How can I make this work and tell the library to continue with peer1 if peer2 is not available?
My fabric sdk server is working as a docker container. It is running on mac.
Fabric docker containers(peers, orderers and CAs...) are also running on mac.
Now I'm trying to send invoke request from sdk container(ubuntu:18.04) to peer.
And I'm using first-network of fabric-samples.
This is peer config file(docker-compose-base.yaml).
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
extends:
file: peer-base.yaml
service: orderer-base
volumes:
- ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
- orderer.example.com:/var/hyperledger/production/orderer
ports:
- 7050:7050
peer0.org1.example.com:
container_name: peer0.org1.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LISTENADDRESS=0.0.0.0:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
- peer0.org1.example.com:/var/hyperledger/production
ports:
- 7051:7051
peer1.org1.example.com:
container_name: peer1.org1.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org1.example.com
- CORE_PEER_ADDRESS=peer1.org1.example.com:8051
- CORE_PEER_LISTENADDRESS=0.0.0.0:8051
- CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:8052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:8052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:8051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls
- peer1.org1.example.com:/var/hyperledger/production
ports:
- 8051:8051
peer0.org2.example.com:
container_name: peer0.org2.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer0.org2.example.com
- CORE_PEER_ADDRESS=peer0.org2.example.com:9051
- CORE_PEER_LISTENADDRESS=0.0.0.0:9051
- CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:10051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls
- peer0.org2.example.com:/var/hyperledger/production
ports:
- 9051:9051
peer1.org2.example.com:
container_name: peer1.org2.example.com
extends:
file: peer-base.yaml
service: peer-base
environment:
- CORE_PEER_ID=peer1.org2.example.com
- CORE_PEER_ADDRESS=peer1.org2.example.com:10051
- CORE_PEER_LISTENADDRESS=0.0.0.0:10051
- CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:10052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:10052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:10051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051
- CORE_PEER_LOCALMSPID=Org2MSP
volumes:
- /var/run/:/host/var/run/
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp
- ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls
- peer1.org2.example.com:/var/hyperledger/production
ports:
- 10051:10051
This is connection file (connection-org1.json).
{
"name": "first-network-org1",
"version": "1.0.0",
"client": {
"organization": "Org1",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"organizations": {
"Org1": {
"mspid": "Org1MSP",
"peers": [
"peer0.org1.example.com",
"peer1.org1.example.com"
],
"certificateAuthorities": [
"ca.org1.example.com"
]
}
},
"peers": {
"peer0.org1.example.com": {
"url": "grpcs://host.docker.internal:7051",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQIrzVUkH/VhPQNk1YHCtj3jAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xOTEyMTIwODIwMDBaFw0yOTEyMDkwODIw\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAE8TqkZLAW+F2rYwnicTo2NTo1+2kYUvI28UKvgAdm1iavbwunNlBB+Gph\nLT4z/XVDjp2XP3VYdv4jmCRSmBkREKNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCDW8LHjcUuWGmLSfNXZym6gDPb9twcHkByS3Yoa/rM4YTAKBggqhkjOPQQD\nAgNIADBFAiEAieGWQzmyWS2pUORmXczUM/XCaB4t33HNtizkr62YgWUCIB7HVwss\ny7l1k9ifxb0VN7q4pzIeHTFMeH6+e6Nl3p2C\n-----END CERTIFICATE-----\n"
},
"grpcOptions": {
"ssl-target-name-override": "peer0.org1.example.com"
}
},
"peer1.org1.example.com": {
"url": "grpcs://host.docker.internal:8051",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQIrzVUkH/VhPQNk1YHCtj3jAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xOTEyMTIwODIwMDBaFw0yOTEyMDkwODIw\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAE8TqkZLAW+F2rYwnicTo2NTo1+2kYUvI28UKvgAdm1iavbwunNlBB+Gph\nLT4z/XVDjp2XP3VYdv4jmCRSmBkREKNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCDW8LHjcUuWGmLSfNXZym6gDPb9twcHkByS3Yoa/rM4YTAKBggqhkjOPQQD\nAgNIADBFAiEAieGWQzmyWS2pUORmXczUM/XCaB4t33HNtizkr62YgWUCIB7HVwss\ny7l1k9ifxb0VN7q4pzIeHTFMeH6+e6Nl3p2C\n-----END CERTIFICATE-----\n"
}
}
},
"certificateAuthorities": {
"ca.org1.example.com": {
"url": "https://host.docker.internal:7054",
"caName": "ca-org1",
"tlsCACerts": {
"pem": "-----BEGIN CERTIFICATE-----\nMIICUTCCAfegAwIBAgIQeWwAs49jzhe2XsEmY4M0jDAKBggqhkjOPQQDAjBzMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu\nb3JnMS5leGFtcGxlLmNvbTAeFw0xOTEyMTIwODIwMDBaFw0yOTEyMDkwODIwMDBa\nMHMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMRwwGgYDVQQD\nExNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nhvJll8VoZC+0seO0fKrpbxWWAABOt2UoCbyq540wY3YSM2GCKuD2XMTtCsiC8XEB\nbKaokdxo5WyWXOsamK1hEKNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1UdJQQWMBQG\nCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCC2\nwW1+TNe+qJeskHsq1AoNdYrmgKJ2Pf12KqootThXNDAKBggqhkjOPQQDAgNIADBF\nAiEA+2pAiOxL64KxOFWoqavs5NWeO+GLN0ArS14zCsBxS4MCIAQ7nBMVPYyOHYLS\nBy/zxDAzC+NsFq1iKxyWQxq3Yu9I\n-----END CERTIFICATE-----\n"
},
"httpOptions": {
"verify": false
}
}
}
}
And this is invoke file (invoke.js).
'use strict';
const { Gateway, Wallets } = require('fabric-network');
const path = require('path');
const ccpPath = path.resolve(__dirname, 'connection-org1.json');
module.exports = async function (key, data) {
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const identity = await wallet.get('user1');
if (!identity) {
console.log('An identity for the user "user1" does not exist in the wallet');
console.log('Run the registerUser.js application before retrying');
return;
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork('mychannel');
// Get the contract from the network.
const contract = network.getContract('save-file-hash');
// Submit the specified transaction.
await contract.submitTransaction('registerHash', key, data.length.toString());
for(var i = 0; i < data.length; i++) {
await contract.submitTransaction('registerHash', key + i.toString(), data[i]);
}
console.log('Transactions has been submitted');
// Disconnect from the gateway.
await gateway.disconnect();
} catch (error) {
console.error(`Failed to submit transaction: ${error}`);
process.exit(1);
}
}
And this is error log.
# node main.js
Wallet path: /usr/src/app/wallet
2019-12-13T13:03:10.930Z - error: [Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:7051 timeout:3000
2019-12-13T13:03:10.935Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G0:1 - endorsement failed - Error: Failed to connect before the deadline URL:grpcs://localhost:7051 timeout:3000
2019-12-13T13:03:10.937Z - error: [Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:9051 timeout:3000
2019-12-13T13:03:10.938Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G1:0 - endorsement failed - Error: Failed to connect before the deadline URL:grpcs://localhost:9051 timeout:3000
2019-12-13T13:03:13.938Z - error: [Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:8051 timeout:3000
2019-12-13T13:03:13.941Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G0:1 - endorsement failed - Error: Failed to connect before the deadline URL:grpcs://localhost:8051 timeout:3000
2019-12-13T13:03:13.944Z - error: [Remote.js]: Error: Failed to connect before the deadline URL:grpcs://localhost:10051 timeout:3000
2019-12-13T13:03:13.944Z - warn: [DiscoveryEndorsementHandler]: _build_endorse_group_member >> G1:0 - endorsement failed - Error: Failed to connect before the deadline URL:grpcs://localhost:10051 timeout:3000
2019-12-13T13:03:13.947Z - error: [DiscoveryEndorsementHandler]: _endorse - endorsement failed::Error: Endorsement has failed
at DiscoveryEndorsementHandler._endorse (/usr/src/app/node_modules/fabric-client/lib/impl/DiscoveryEndorsementHandler.js:185:19)
at process._tickCallback (internal/process/next_tick.js:68:7)
Failed to submit transaction: Error: Endorsement has failed
When sdk server runs on mac and not a docker container, invoke request success.
And when it is a docker container, invoke request fail.
Also, user1 is already enrolled in CA-org1.
I think it is a problem with connection.
Please tell me how to send invoke request from sdk server container.
I think this is the line that is causing you a problem in the "SDK Container":
await gateway.connect(ccpPath, { wallet, identity: 'user1', discovery: { enabled: true, asLocalhost: true } });
asLocalhost: true will be substituting all the addresses with localhost and they just try to connect bsack into the SDK container which is causing the errors. When running directly on the mac the port forwarding into the docker containers works with localhost.
After you use asLocalhost: false you may have to change the various urls in the connection profile to be peer1.org1.example.com etc.
First:you can read the document:
https://hyperledger-fabric.readthedocs.io/en/latest/developapps/connectionprofile.html
There has a sample and your config miss channels:{} and orderers:{}
Second:If you don't enable tls, use the grpc:XXX.XXX, or you should use grpcs:XXX.XXX.
For example, your orderer not enable tls and you should use "url": "grpc://host.docker.internal:7050", your peers enable tls and you should use "url": "grpcs://host.docker.internal:8051".
Third:After last two steps, the query transaction should be ok. But invoke(some write transactions) may still fail. I still block here...
I am trying to register the multiple user at one time however I am getting error while doing it as
"error: [FabricCAClientService.js]: Failed to enroll 0006, error:%o message=Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]], stack=Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]
at IncomingMessage.response.on (/vagrant/Dfarm-app/node/node_modules/fabric-ca-client/lib/FabricCAClient.js:470:22)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
Failed to register user: Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]"
I am trying to implement with one user its running fine we I am trying to implement with multiple user its giving error.
Can anyone suggest me how can multiple user can register in Blockchain.
Please see below registerUser.js file
'use strict';
const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network');
const fs = require('fs');
const path = require('path');
// capture network variables from config.json
// var configPath = path.join(process.cwd(), 'config.json');
// const configJSON = fs.readFileSync(configPath, 'utf8');
var configJSON = fs.readFileSync('config.json');
var config = JSON.parse(configJSON);
var connection_file = config.connection_file;
var appAdmin = config.appAdmin;
var orgMSPID = config.orgMSPID;
var userName = config.userName;
var gatewayDiscovery = config.gatewayDiscovery;
const ccpPath = path.join(process.cwd(), connection_file);
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
async function main() {
try {
var userDetails = config.userDetails;
// console.log('test', userDetails)
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
for(var i=0; i< userDetails.length;i++){
// console.log('test',walletPath)
let userExists = await wallet.exists(userDetails[i].userName);
if (userExists) {
// console.log('test',userDetails[0].userName)
console.log(`An identity for the user ${userDetails[i].userName} already exists in the wallet`);
return;
}
}
// console.log('test',walletPath)
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists(appAdmin);
if (!adminExists) {
console.log(`An identity for the admin user ${appAdmin} does not exist in the wallet`);
console.log('Run the enrollAdmin.js application before retrying');
return;
}
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccp, { wallet, identity: appAdmin, discovery: gatewayDiscovery });
// Get the CA client object from the gateway for interacting with the CA.
const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();
// Register the user, enroll the user, and import the new identity into the wallet.
for(var i=0; i< userDetails.length;i++){
var secret = await ca.register({ enrollmentID:userDetails[i].enrollmentID,userName:userDetails[i].userName, role:userDetails[i].role }, adminIdentity);
var enrollment = await ca.enroll({ enrollmentID:userDetails[i].enrollmentID, enrollmentSecret: userDetails[i].enrollmentSecret });
var userIdentity = X509WalletMixin.createIdentity(orgMSPID, enrollment.certificate, enrollment.key.toBytes());
wallet.import(userDetails[i].userName, userIdentity);
console.log('Successfully registered and enrolled admin user ' + userDetails[i].userName + ' and imported it into the wallet');
}
} catch (error) {
console.error(`Failed to register user: ${error}`);
process.exit(1);
}
}
main();
The config.json file
{
"connection_file": "connection.json",
"appAdmin": "admin",
"appAdminSecret": "adminpw",
"orgMSPID": "DfarmadminMSP",
"caName": "ca.dfarmadmin.com",
"userDetails": [{"username":"user1","enrollmentID":"0006","role":"client","enrollmentSecret": "1234"},
{"username":"user2", "enrollmentID":"0002","role":"client","enrollmentSecret": "abcs" },
{"username":"user3", "enrollmentID":"0003","role":"client","enrollmentSecret": "9807" },
{"username":"user4","enrollmentID":"0004","role":"client","enrollmentSecret": "abcd" }
],
"gatewayDiscovery": { "enabled": false }
}
The connection.json file
{
"name": "basic-network",
"version": "1.0.0",
"client": {
"tlsEnable": false,
"adminUser": "admin",
"adminPassword": "adminpw",
"enableAuthentication": false,
"organization": "dfarmadmin",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
},
"orderer": "300"
}
}
},
"channels": {
"dfarmchannel": {
"orderers": [
"orderer.dfarmadmin.com"
],
"peers": {
"peer0.dfarmadmin.com": {
"endorsingPeer": true,
"chaincodeQuery": true,
"ledgerQuery": true,
"eventSource": true
},
"connection": {
"timeout": {
"peer": {
"endorser": "6000",
"eventHub": "6000",
"eventReg": "6000"
}
}
},
"peer0.dfarmretail.com": {
"endorsingPeer": false,
"chaincodeQuery": true,
"ledgerQuery": true,
"eventSource": false
}
}
}
},
"organizations": {
"dfarmadmin": {
"mspid": "DfarmadminMSP",
"peers": [
"peer0.dfarmadmin.com"
],
"certificateAuthorities": [
"ca.dfarmadmin.com"
]
},
"dfarmretail": {
"mspid": "DfarmretailMSP",
"peers": [
"peer0.dfarmretail.com"
],
"certificateAuthorities": [
"ca.dfarmadmin.com"
]
}
},
"orderers": {
"orderer.dfarmadmin.com": {
"url": "grpc://localhost:7050",
"eventUrl": "grpc://localhost:7053"
}
},
"peers": {
"peer0.dfarmadmin.com": {
"url": "grpc://localhost:7051"
},
"peer0.dfarmretail.com": {
"url": "grpc://localhost:8051"
}
},
"certificateAuthorities": {
"ca.dfarmadmin.com": {
"url": "http://localhost:7054",
"caName": "ca.dfarmadmin.com"
}
}
}
AdminIdentiy console
adminIdentity User {
_name: 'admin',
_roles: null,
_affiliation: '',
_enrollmentSecret: '',
_identity:
Identity {
_certificate: '-----BEGIN CERTIFICATE-----\nMIIB/jCCAaSgAwIBAgIUdrt0WjnSmGsX1WuBWvXVTizqFKUwCgYIKoZIzj0EAwIw\nbzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xFzAVBgNVBAoTDmRmYXJtYWRtaW4uY29tMRowGAYDVQQDExFj\nYS5kZmFybWFkbWluLmNvbTAeFw0xOTA4MTQxMTEyMDBaFw0yMDA4MTMxMTE3MDBa\nMCExDzANBgNVBAsTBmNsaWVudDEOMAwGA1UEAxMFYWRtaW4wWTATBgcqhkjOPQIB\nBggqhkjOPQMBBwNCAARXptenPPGpVnJsEFv0wmJeybDYNoClJCyAv3GcRPb04WLR\nAynEoSXf+jwYIjypV98oeR127haGcDo7jHUn0DnBo2wwajAOBgNVHQ8BAf8EBAMC\nB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUW1YmLO6OaZB7FwXv6Gu7yc9jhNMw\nKwYDVR0jBCQwIoAgeD1bXE22u42++Y2v96xX+EKLzk8JkEcheGl5g8XGRkkwCgYI\nKoZIzj0EAwIDSAAwRQIhALluXWayFpylTOLCDIp925yn0rrtl77D/rM8AkOksTsE\nAiAEQ+w5pElSLFBINH/c0N1CgGN1snsdK1LRkUNjCk29Fg==\n-----END CERTIFICATE-----\n',
_publicKey: ECDSA_KEY { _key: [Object] },
_mspId: 'DfarmadminMSP',
_cryptoSuite:
CryptoSuite_ECDSA_AES {
_keySize: 256,
_hashAlgo: 'SHA2',
_cryptoKeyStore: [Object],
_curveName: 'secp256r1',
_ecdsaCurve: [Object],
_hashFunction: [Function],
_hashOutputSize: 32,
_ecdsa: [Object] } },
_signingIdentity:
SigningIdentity {
_certificate: '-----BEGIN CERTIFICATE-----\nMIIB/jCCAaSgAwIBAgIUdrt0WjnSmGsX1WuBWvXVTizqFKUwCgYIKoZIzj0EAwIw\nbzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNh\nbiBGcmFuY2lzY28xFzAVBgNVBAoTDmRmYXJtYWRtaW4uY29tMRowGAYDVQQDExFj\nYS5kZmFybWFkbWluLmNvbTAeFw0xOTA4MTQxMTEyMDBaFw0yMDA4MTMxMTE3MDBa\nMCExDzANBgNVBAsTBmNsaWVudDEOMAwGA1UEAxMFYWRtaW4wWTATBgcqhkjOPQIB\nBggqhkjOPQMBBwNCAARXptenPPGpVnJsEFv0wmJeybDYNoClJCyAv3GcRPb04WLR\nAynEoSXf+jwYIjypV98oeR127haGcDo7jHUn0DnBo2wwajAOBgNVHQ8BAf8EBAMC\nB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUW1YmLO6OaZB7FwXv6Gu7yc9jhNMw\nKwYDVR0jBCQwIoAgeD1bXE22u42++Y2v96xX+EKLzk8JkEcheGl5g8XGRkkwCgYI\nKoZIzj0EAwIDSAAwRQIhALluXWayFpylTOLCDIp925yn0rrtl77D/rM8AkOksTsE\nAiAEQ+w5pElSLFBINH/c0N1CgGN1snsdK1LRkUNjCk29Fg==\n-----END CERTIFICATE-----\n',
_publicKey: ECDSA_KEY { _key: [Object] },
_mspId: 'DfarmadminMSP',
_cryptoSuite:
CryptoSuite_ECDSA_AES {
_keySize: 256,
_hashAlgo: 'SHA2',
_cryptoKeyStore: [Object],
_curveName: 'secp256r1',
_ecdsaCurve: [Object],
_hashFunction: [Function],
_hashOutputSize: 32,
_ecdsa: [Object] },
_signer: Signer { _cryptoSuite: [Object], _key: [Object] } },
_mspId: 'DfarmadminMSP',
_cryptoSuite:
CryptoSuite_ECDSA_AES {
_keySize: 256,
_hashAlgo: 'SHA2',
_cryptoKeyStore:
CryptoKeyStore {
logger: [Object],
_store: [Object],
_storeConfig: [Object],
_getKeyStore: [Function] },
_curveName: 'secp256r1',
_ecdsaCurve:
PresetCurve {
curve: [Object],
g: <EC Point x: 6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 y: 4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5>,
n: <BN: ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551>,
hash: [Object] },
_hashFunction: [Function],
_hashOutputSize: 32,
_ecdsa:
EC {
curve: [Object],
n: <BN: ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551>,
nh: <BN: 7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a8>,
g: <EC Point x: 6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 y: 4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5>,
hash: [Object] } } }
2019-08-14T11:17:28.526Z - error: [FabricCAClientService.js]: Failed to enroll 005, error:%o message=Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]], stack=Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]
at IncomingMessage.response.on (/vagrant/Dfarm-app/Node/node_modules/fabric-ca-client/lib/FabricCAClient.js:470:22)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
Failed to register user: Error: Enrollment failed with errors [[{"code":20,"message":"Authentication failure"}]]
Error: Authentication failure
It is clear that you are providing wrong credentials which means the wrong secret
For enrollment, we need ID & Secret
Double-check the secret and make sure that you have registered before proceeding for the enrolment
I suspect the issue is because you have a coding error (or error in your JSON :-)). The code is looking for userNamefield in an element, but your JSON array has a field username (lc). You could easily change your JSON to match.
If a user is to be enrolled for multiple times, you will need to specify maxEnrollments in the json of ca.register. Otherwise, ca.enroll will prompt { code: 20, message: 'Authentication failure'}.
For example, for registration you may have
var secret = await ca.register({
enrollmentID: userDetails[i].enrollmentID,
userName: userDetails[i].userName,
role: userDetails[i].role,
maxEnrollments: -1 // -1 means no limit on number of enrollments after registration
}, adminIdentity);
I've installed both Laravel echo server and Laravel echo client.
Following is the laravel-echo-server.json configuration.
{
"authHost": "http://taxation.com",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "APP_ID",
"key": "someKey"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": true,
"host": "127.0.0.1",
"port": "3000",
"protocol": "http",
"socketio": {},
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": ""
}
The following script listens for channel events. It builds fine with npm run dev.
import Echo from 'laravel-echo'
let token = document.head.querySelector('meta[name="token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
window.Echo = new Echo({
broadcaster: 'socket.io',
host: '127.0.0.1:3000',
reconnectionAttempts: 5
});
window.Echo.join('checked-in-1')
.listen('.user.checked_in', (e) => {
console.log(e);
});
When trying to listen for any event on start laravel-echo-server command. It keeps throwing Client can not be authenticated, got HTTP status 500.
Note :
I really didn't find anything helpful on laravel-echo-serve nor on google.
Any help will be appreciated a lot.
Laravel V5.4
Thanks
Just getting the issue because of CSRF token. Didn't passed the token to the echo.
window.Echo = new Echo({
broadcaster: 'socket.io',
host: '127.0.0.1:3000',
reconnectionAttempts: 5,
csrfToken: token.content <--
});