Private data in chaincode
Hello,
I have been using fablo to generate fabric networks, and stumbled across this:
If you use privateData property in fablo-config.json, and create the network, the file that gets created (fablo-target/fablo-config/collections/private-collection.json) has the requiredPeerCount property set to 1, which creates problem when trying to use PutPrivateData function in order to put data inside the collection.
More specifically I was getting the error (real values replaced with 123): error in simulation: failed to distribute private collection, txID 123, channel 123: could not build private data dissemination plan for chaincode 123 and collection 123: required to disseminate to at least 1 peers, but know of only 0 eligible peers.
I was using golang when I encountered this, haven't tried rest languages.
Fabric sample with private data, which uses this collection file https://github.com/hyperledger/fabric-samples/blob/main/asset-transfer-private-data/chaincode-go/collections_config.json , has both private collections requiredPeerCount property set to 0. After manually editing the collections file, setting the requiredPeerCount property to 0, and reseting the network, I can now write to the private collection as expected.
Hi @hexnikolas thanks for submitting this issue!
This is our code that determines the requiredPeerCount property:
const anchorPeerCountsInChannel = channel.orgs.map((o) => (o.anchorPeers || []).length);
const maxPeerCount = anchorPeerCountsInChannel.reduce((a, b) => a + b, 0);
const requiredPeerCount = anchorPeerCountsInChannel.reduce((a, b) => Math.min(a, b), maxPeerCount) || 1;
First it gets the number of anchor peers in orgs that are members of the given channel (anchorPeerCountsInChannel).
Then it counts all anchor peers (maxPeerCount).
Then it takes the minimal number of anchor peers for an org in channel, but if it equals 0, it updates it to 1.
I guess in your case:
- There is an org with no peers in a channel
- There is another org (or org) which actually has some peers and which is supposed to update the private data collection.
Could you give us some more details about:
- the number of anchor peers for each org in a channel
- the number of anchor peers for each org that is a member of private data collection
As far as I understand the solution to your issue is to allow 0 as the requiredPeerCount (by removing the || 1 part).
If you want a workaround, you can use Fablo post-generate hook and use perl to replace requiredPeerCount, in a similar way we show in README: https://github.com/hyperledger-labs/fablo#hooks
Hey @dzikowski , thanks for the reply.
This is my fablo-config.json file. My network consists of an orderer and 2 organizations (farmer + transporter), each one of which has 1 peer. Both of them are on the same channel, and I want both of them to have a private data collection.
"$schema": "https://github.com/hyperledger-labs/fablo/releases/download/1.2.0/schema.json",
"global": {
"fabricVersion": "2.4.7",
"tls": true,
},
"orgs": [
{
"organization": {
"name": "Orderer",
"domain": "orderer.example.com"
},
"orderers": [
{
"groupName": "group1",
"type": "solo",
"instances": 1
}
]
},
{
"organization": {
"name": "Farmer",
"domain": "farmer.example.com"
},
"peer": {
"instances": 1
}
},
{
"organization": {
"name": "Transporter",
"domain": "transporter.example.com"
},
"peer": {
"instances": 1
}
}
],
"channels": [
{
"name": "my-channel",
"orgs": [
{
"name": "Farmer",
"peers": [
"peer0"
]
},
{
"name": "Transporter",
"peers": [
"peer0"
]
}
]
}
],
"chaincodes": [
{
"name": "product_private",
"version": "0.0.1",
"lang": "golang",
"endorsement": "OR('FarmerMSP.member', 'TransporterMSP.member')",
"channel": "my-channel",
"directory": "./chaincodes/chaincode-go",
"privateData": [{
"name": "FarmerMSPPrivateCollection",
"orgNames": ["Farmer"]
},
{
"name": "TransporterMSPPrivateCollection",
"orgNames": ["Transporter"]
}]
}
]
} ```
In this case shouldn't the `requiredPeerCount `be equal to zero?
Yes allowing the zero seems to be the solution for my issue.
l'll look into the post generate hooks and try it, thanks!
Hey @dzikowski , from my understanding and based on discussions in the issue thread, adjusting requiredPeerCount to 0 for private data collections seems to resolve the issue. However, this requires manual intervention post-generation or leveraging Fablo's post-generate hooks for automation.
Could you please provide guidance on how requiredPeerCount can be set to 0 by default or programmatically adjusted during network setup? Thanks
I think the solution is to edit this part:
const anchorPeerCountsInChannel = channel.orgs.map((o) => (o.anchorPeers || []).length);
const maxPeerCount = anchorPeerCountsInChannel.reduce((a, b) => a + b, 0);
const requiredPeerCount = anchorPeerCountsInChannel.reduce((a, b) => Math.min(a, b), maxPeerCount) || 1;
by removing the || 1 part. Feel free to take a stab 🙂
@dzikowski Kindly review the PR and let me know if any more changes are needed
resolved in https://github.com/hyperledger-labs/fablo/pull/460