I was trying to add a new org to my existing network using the Hyperledger Fabric node sdk. I turorial that i refrenced was https://fabric-sdk-node.github.io/tutorial-channel-create.html. Although the tutorial is for adding a new channel to a network, I assumed that the approach for updating the channel configs would be somewhat similar to creating a new channel configuration.
The api that I created using the tutorial and referencing the existing apis in the project is as follows.
/**
* Copyright 2017 IBM All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var fs = require('fs');
var path = require('path');
var superagent = require('superagent');
var helper = require('./helper.js');
var logger = helper.getLogger('Create-Channel');
//Attempt to send a request to the orderer with the sendTransaction method
var fetchConfigBlock = async function(channel_name, peers, username, org_name) {
try {
logger.info('Calling peers in organization "%s" to join the channel', org_name);
// first setup the client for this org
var client = await helper.getClientForOrg(org_name, username);
logger.debug('Successfully got the fabric client for the organization "%s"', org_name);
var channel = client.getChannel(channel_name);
var channel_config = fs.readFileSync(path.join(__dirname, '../artifacts/channel/mychannel.json'));
channel_config = JSON.parse(channel_config);
console.log(channel_config.payload.data.config_update);
var config_proto;
var response = await superagent.post('http://127.0.0.1:7059/protolator/encode/common.ConfigUpdate',
channel_config.payload.data.config_update)
.buffer()
.end((err, res) => {
if(err) {
logger.error(err);
return;
}
config_proto = res.body;
console.log("*******************************")
var signatures = [];
var signature = client.signChannelConfig(config_proto);
console.log("*******************************")
signatures.push(signature);
var orderer = channel.getOrderer("orderer.example.com");
let tx_id = client.newTransactionID();
//return config_proto
request = {
config: config_proto, //the binary config
signatures : signatures, // the collected signatures
name : 'mychannel', // the channel name
orderer : orderer, //the orderer from above
txId : tx_id //the generated transaction id
};
var response = client.updateChannel(request);
logger.debug(' response ::%j', response);
if (response && response.status === 'SUCCESS') {
logger.debug('Successfully update the channel.');
let response = {
success: true,
message: 'Channel created Successfully'
};
return response;
} else {
logger.error('\n!!!!!!!!! Failed to update the channel!!!!!!!!!\n\n');
//throw new Error('Failed to create the channel');
}
});
} catch(error) {
logger.error('Failed to join channel due to error: ' + error.stack ? error.stack : error);
error_message = error.toString();
}
};
exports.fetchConfigBlock = fetchConfigBlock;
- In the above api, the file that I am reading using the filesystem(fs) module has been generated by using the configtxlator tool as mentioned in the tutorial.
- I changed some of the attributes of the config_update section of the file so that instead of adding a new channel it updates the configuration of the existing channel. The configuration file is as follows
{
"payload": {
"data": {
"config_update": {
"channel_id": "mychannel",
"isolated_data": {},
"read_set": {
"groups": {
"Application": {
"groups": {
"Org1MSP": {
"groups": {},
"mod_policy": "",
"policies": {},
"values": {},
"version": "0"
},
"Org2MSP": {
"groups": {},
"mod_policy": "",
"policies": {},
"values": {},
"version": "0"
}
},
"mod_policy": "",
"policies": {},
"values": {},
"version": "0"
}
},
"mod_policy": "",
"policies": {},
"values": {
"Consortium": {
"mod_policy": "",
"value": null,
"version": "0"
}
},
"version": "0"
},
"write_set": {
"groups": {
"Application": {
"groups": {
"Org3MSP": {
"groups": {},
"mod_policy": "",
"policies": {},
"values": {},
"version": "0"
}
},
"mod_policy": "Admins",
"policies": {
"Admins": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "MAJORITY",
"sub_policy": "Admins"
}
},
"version": "0"
},
"Readers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Readers"
}
},
"version": "0"
},
"Writers": {
"mod_policy": "Admins",
"policy": {
"type": 3,
"value": {
"rule": "ANY",
"sub_policy": "Writers"
}
},
"version": "0"
}
},
"values": {},
"version": "1"
}
},
"mod_policy": "",
"policies": {},
"values": {
"Consortium": {
"mod_policy": "",
"value": {
"name": "SampleConsortium"
},
"version": "0"
}
},
"version": "0"
}
},
"signatures": []
},
"header": {
"channel_header": {
"channel_id": "mychannel",
"epoch": "0",
"extension": null,
"timestamp": "2019-04-15T12:51:02Z",
"tls_cert_hash": null,
"tx_id": "",
"type": 2,
"version": 0
},
"signature_header": null
}
},
"signature": null
}
Notice that the read set contains the information of Org1 and Org2 but the write set now contains the information for Org3.
3. Then as mentioned in the tutorial i used superagent to http://127.0.0.1:7059/protolator/encode/common.ConfigUpdate
4. The result that I got from there I signed it using the client object
5. Then I created request for channel configuration update, consisting the signed configuration update object.
6. Then I finally called the client.updateChannel(request)
method of the client object and passed the created request as
a parameter to it https://fabric-sdk-node.github.io/Client.html#updateChannel.
The response that i get from the client.updateChannel(request)
method is false.
The config_update part of the channel configuration should be properly versioned, so I possible problem might be the incorrect versioning of the components there.