How to query a chaincode from outside an organization - hyperledger-fabric

I have 4 Orgs:
Org1 -- 2 peer
Org2 -- 2 peer
OrgCam -- 0 peer, 1 client
OrgView -- 0 peer, 1 client
Org1's peers have a chaincode installed on them that access some private data only available to Org1.
As a client of OrgCam, I want to access the chaincode installed on Org1's peers.
When I try to do that:
const result = await contract.evaluateTransaction('getPoints','ID1');
This error occurs
2019-05-19T15:20:20.084Z - error: [SingleQueryHandler]: evaluate: message=No peers available to query. Errors: [], stack=FabricError: No peers available to query. Errors: []
at SingleQueryHandler.evaluate (/home/zanna/fabric-samples/first-network/clientCode/node_modules/fabric-network/lib/impl/query/singlequeryhandler.js:39:17)
at Transaction.evaluate (/home/zanna/fabric-samples/first-network/clientCode/node_modules/fabric-network/lib/transaction.js:246:29)
at Contract.evaluateTransaction (/home/zanna/fabric-samples/first-network/clientCode/node_modules/fabric-network/lib/contract.js:172:39)
at main (/home/zanna/fabric-samples/first-network/clientCode/camera.js:41:39)
at <anonymous>, name=FabricError
Failed to evaluate transaction: FabricError: No peers available to query. Errors: []
My question is: How can I query the Org1's chaincode even if I'm not a client from Org1?

I am a bit confused by your configuration, but I'll try to answer as best as I can.
Lets make it clear
A chaincode does not "belong" to an organization. A chaincode belongs to a channel and has particular endorsement policies.
Considering that, you could say a chaincode belongs to the peers that are member of the channel.
An organization can only interact with a chaincode if it possesses a peer that is member of the channel that has the chaincode.
Answer
You did not provide any information about your channel. Considering you error, I suppose you did not join the OrgCam peer to the channel in which Org1 peer(s) deployed the chaincode.
You OrgCam peer is not part of the channel, you cannot query the chaincode of the channel.
Moreover, you cannot use a OrgCam client certificate to interact with a Org1 peer, because the certificate is not known/accepted by the Org1 peers. Only Org1 explicitly defined clients can interact with org1 peers.

I finally managed to do that.
1.
const result = await contract.evaluateTransaction('getPoints','ID1');
must be changed to:
const result = await contract.submitTransaction('getPoints','ID1');
in order to get the information from peers in an external organization.
2.
If private data are in use, it's important that the fields "memberOnlyRead" and "memberOnlyWrite" (1) must be removed or set to false in the collections_config.json file.
example:
[
{
"name": "collectionFacepoints",
"policy": "OR('Org1MSP.member')",
"requiredPeerCount": 2,
"maxPeerCount": 2,
"blockToLive": 0,
"memberOnlyRead": false
}
]
3.
In the gateway.connect(connectionProfile, connectionOptions) it is important to add discovery.enable=true to the connectionOptions.
example:
await gateway.connect(
connectionProfile,
{
wallet,
identity: identityConfig.identityLabel,
discovery: {
enabled: true,
asLocalhost: true
},
eventHandlerOptions: {
strategy: DefaultEventHandlerStrategies.NETWORK_SCOPE_ALLFORTX
}
}
);
4.
Unfortunately it seems that a client from OrgCam cannot directly query a chaincode installed in org1's peers, but It can be done adding an empty (2) OrgCam's peer that act as an anchor peer.
(1): "memberOnlyWrite" is not available yet. See here.
(2): With "empty" I mean without any chaincode installed on it.

Related

Hyper Ledge Fabric : Endorsement policy not reflecting

I have a three ORG setup and I have installed chain code on all three ORG peers with endorsement policy OutOf(2, 'Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member'). Chain code installed on ORG2 is different with ORG1 and ORG3 as it produces response with different value then ORG1 and ORG3 chaincode . One of the attribute of response is hard coded in contract of ORG2.
Now with above policy and setup, i would assume that with ORG2 response is different then ORG1 and ORG3 response ,and ORG1 and ORG3 response are identical , still the transaction should be successful as 2 out of three are satisfied . But I am getting below error when I am submitting the transaction. It works fine when I install correct chaincode on ORG2 . Can anyone please help in pointing out what am I doing wrong. For chaincode and application i am using java sdk. Please let me know if you need any specific details.
Error : The proposal responses have 2 inconsistent groups with 0 that
are invalid. Expected all to be consistent and none to be invalid
I found my mistake . I had set discovery false in my client application code . Due to which it was failing . Once i turned it on (set as true) it worked fine as expected . You can use below discovery command to check the endorsement policies applicable on chaincode installed .
discover --configFile discovery/config.yaml endorsers --channel mychannel --server peer0.org3.example.com:11051 --chaincode papercontract

Hyperledger 2.0: reconciliation error when trying to fetch missing items from different peers: Empty membership

I have 3 Orgs with currently 1 peer per org running and one Orderer.
I have a private data collection defined for 2 orgs.
"name": "privateOrg1-2",
"policy": "OR('Org1MSP.member','Org2MSP.member')",
"requiredPeerCount": 0,
"maxPeerCount": 3,
"blockToLive": 30000,
"memberOnlyRead": true
However, when I add data as member of Org1, these data are not synced with Org2. When I add data for Org2, these data are not synced with Org1. The following errors are seen in logs:
2020-05-11 15:30:28.137 UTC [gossip.privdata] fetchPrivateData -> WARN 7a0a Do not know any peer in the channel( data-channel ) that matches the policies , aborting
2020-05-11 15:30:28.137 UTC [gossip.privdata] reconcile -> ERRO 7a0b reconciliation error when trying to fetch missing items from different peers: Empty membership
2020-05-11 15:30:28.137 UTC [gossip.privdata] run -> ERRO 7a0c Failed to reconcile missing private info, error: Empty membership
Non-private data is synced without problems.
What could be the problem?
I fixed the issue. But I believe the way everything works is not optimal.
I simulate a distributed network. Each peer runs on a separate machine. All the docker containers run standalone and not as a part of kubernetes or docker network.
I did the following steps:
update the config of each peer with the Org1MSPanchors.tx, Org2MSPanchors.tx, Org3MSPanchors.tx generated by configtxgen. Earlier I didn't do that.
I analyzed the logs and found out that each peer tries to connect to an anchor peer of another org directly. This connection failed. To make it work, I added the anchor peers of all the orgs to extra_hosts of my peer docker_compose files.
Initially I thought that the ordering service knows each anchor peer and peers of Org1 should get IP adresses of Org2 peers from the ordering service. This was a little bit naive.

How can I get an endorsement back from a specific peer?

Is there a way to get endorsements back from specific peer(s) after submitting a transaction in Hyperledger fabric, using contract.submitTransaction() or channel.sendTransaction()?
So far the endorsements always seem to come back from the same peer and not other peers in the organization. Please see my environment details below.
Also if I target specific peers using the node sdk sendTransactionProposal(request)'s ChaincodeInvokeRequest preferred or ignore list, that doesn't seem to make any difference.
Is there any specific documentation or an alternative resource available that addresses this issue?
ChaincodeInvokeRequest{
targets: allPeers or peer2, // or a different peer
preferred: peer2,
ignore, peer1
}
Environment details
Current setup:
1 org with 2 peers
Simple Endorsement policy:
{"identities":[{"role":{"name":"member","mspId":"Org1MSP"}}],policy:{"1-of":[{"signed-by":0}]}}
Fabric sdk libraries:
fabric-ca-client - v1.4.1
fabric-client - v1.4.1
fabric-network - v1.4.1
Hyperledger Fabric version: v1.4.1
Using the following approach to target specific peers in the sdk:
const request = {
targets: peers or peer[1] or [peer2], -- target specific peer
chaincodeId: chaincodeName,
txId,
fcn: functionName,
args,
transientMap: transientMapData // , // private data,
ignore: list of peer[s] to ignore
preferred: list of peer[s] to prefer
};
const endorsementResults = await channel.sendTransactionProposal(request);
if (channel.verifyProposalResponse(endorsementResults[0][0])) {
const transactionRequest = {
proposalResponses: endorsementResults[0],
proposal: endorsementResults[1]
};
invokeResponse = await channel.sendTransaction(transactionRequest);
}
Expected results:
transaction1 - client submits a transaction to peer1 and gets an endorsement back from peer1.
transaction2 - client submits a transaction to peer2 and gets an endorsement back from peer2.
Actual results:
transaction1 - client submits a transaction to peer1 and gets an endorsement back from peer1.
transaction2 - client submits a transaction to peer2 and gets an endorsement back from peer1.

Identify the Peer/Org executing the chaincode from within the chaincode [Fabric 1.2 or 1.3]

I am working with private data collections (PDC) and trying to set up a separate PDC for each org with only 1 member (i.e the org itself).
For example, in a 3 org network, I am looking to create 3 private data collections:
1) "org1-private" with only Org1 as member,
2) "org2-private" with only Org2 as member,
3) "org3-private" with only Org3 as member
When a transaction is invoked by the client, the data needs to be shared only between 2 orgs. The client app will send the transaction to the 2 relevant Org peers, but in the chaincode, to write to the correct PDC on a given org the chaincode needs to know which Org/Peer it is executing on.
What is the best way to find the current peer/org from inside the chaincode in Fabric 1.2?
Note: I understand PDCs with all possible pairs of Orgs can be created to solve this issue. In my experiment, there is a strict requirement NOT to create private data collections per pair.
tried calling GetLocalMSP from the package: "github.com/hyperledger/fabric/msp/mgmt" but it returns a memory address
GetLocalMSP().GetIdentifier() returns nil
import (
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
)
fmt.Println(mspmgmt.GetLocalMSP()) // prints mem-address
id, _ := mspmgmt.GetLocalMSP().GetIdentifier()
fmt.Println(id) // prints nil
You can use the Client Identity Chaincode Library.
https://github.com/hyperledger/fabric/tree/master/core/chaincode/lib/cid
This will return the MSPID from the certificate invoking the chaincode:
mspid, err := cid.GetMSPID(stub)

Hyperledger fabric 1.2 service discovery error

I use Hyperledger Fabric 1.2 to build a blockchain cluster, which contains 3 peers and 3 orderers. I can successfully deploy and invoke the chaincode via both CLI and Java SDK. Everything works fine. However, when I notice the service discovery function and try to use it, I met two problems. First, after I build the discover tool and try to use it to get some discovered information, I can't access the peer and get the message as follow
"failed connecting to discovery service: failed to create new
connection: context deadline exceeded"
The config command is
discover --configFile conf.yaml --userKey ./crypto-config/peerOrganizations/org1.forchain.com/peers/peer0.org1.forchain.com/msp/keystore/7458b29b1fb6a89768585430dbf0e522a40ff4aefe600fc1e4fafe62c3c972e4_sk --userCert ./crypto-config/peerOrganizations/org1.forchain.com/peers/peer0.org1.forchain.com/msp/signcerts/peer0.org1.forchain.com-cert.pem --MSP Org1MSP saveConfig
The query command is
discover --configFile conf.yaml peers --channel lajiao --server localhost:6051
I guess it may be caused by the TLS config so I canceled the TLS and tried again. This time I successfully access the peer and get some messages, but I met another problem. When I use 'discover peers xxx ' command, I always get null result, in fact there are two peers in that channel. When I use 'discover endorsers xxx' command, I always get the following error message
'failed constructing descriptor for chaincodes:'
In the meantime, the peer log outputs the following message:
'Principal set computation failed: chaincode isn't installed on
sufficient organizations required by the endorsement policy 2018-08-01
10:21:50.860 UTC [discovery] chaincodeQuery -> ERRO 1441 Failed
constructing descriptor for chaincode chaincodes:
,: chaincode isn't installed on sufficient organizations required by
the endorsement policy'
I can assure that the chaincode is successfully installed in all peers. And I didn't use the endorsement policy when I instantiated the chaincode. I think it is not the policy problem because I still can invoke the chaincode and propose a transaction.
I also tried to use the Java SDK and found that I can get the orderer nodes info but I can't get the other peer nodes or chaincode info. The log always output: "Discover of chaincode names was empty.". But the chaincode is definitely instantiated and can be invoke via SDK. I refered to the test code in "org.hyperledger.fabric.sdkintegration.ServiceDiscoveryIT" and some key Java code is as follow:
channel.addPeer(peer, createPeerOptions().setPeerRoles(EnumSet.of(Peer.PeerRole.SERVICE_DISCOVERY,Peer.PeerRole.LEDGER_QUERY, Peer.PeerRole.EVENT_SOURCE,Peer.PeerRole.CHAINCODE_QUERY)));
channel.initialize();
System.out.println("================ orderer ===============");
for (Orderer orderer : channel.getOrderers()) {
System.out.println(orderer.getName());
}
System.out.println("================ peer ===============");
for (Peer p: channel.getPeers()) {
System.out.println(p.getName());
}
System.out.println("================ chaincode ===============");
for (String s: channel.getDiscoveredChaincodeNames()) {
System.out.println(s);
}
So, how can I use the 'discover' command under TLS configuration and how can I get the discovered information?
For the config command - you need to pass a TLS root CA, via --peerTLSCA. Please look at the examples in the documentation and act accordingly.
Now - for the second problem, I think that the peers might not know each other in the channel.
Make sure you have anchor peers defined in the channel and that both peers have external endpoints configured.
Feel free to bug me (yacovm) on chat.hyperledger.org if you're struggling for too long and can't solve the problem.
You must add an anchor peer from each organization in the channel, this solved the problem for me. Anchor peers are required for the service discovery since the service discovery uses gossip protocol- thanks #yacovm
I stumbled a similar error (regarding to service discovery) as below.
Go Fabric Client logs:
Failed to get endorsing peers: error getting channel response for channel [myc]:
Discovery status Code: (11) UNKNOWN. Description: error received from Discovery Server:
failed constructing descriptor for chaincodes:<name:"mycc">
Peer logs:
Failed constructing descriptor for chaincode chaincodes:<name:"mycc" > ,:
cannot satisfy any principal combination
It's fixed when I provide CORE_PEER_GOSSIP_EXTERNALENDPOINT environment attribute with a correct value on peer's configuration (in docker yaml file in my case).
As I understood since this attribute is missing, discovery services running on peers failed to communicate with each other to have a conclusion of what current network looks like.

Resources