Updating the channel configuration

Now we will turn our attention to the middleware. In Chapter 5Exposing Network Assets and Transactions, when we created tradechannel, the blockchain was initialized with the genesis block created using the configtxgen tool. The genesis block happens to be the first configuration block of a channel. Subsequent channel configuration changes involve appending new configuration blocks to the channel, each uniquely versioned, and the latest overriding the previous ones. In the upgrade scenario, it's the configuration in the genesis block that will be overridden, as we assume that no other changes have been made since our channel was created and made ready for use in Chapter 5Exposing Network Assets and Transactions.

The logic to upgrade channel configurations lies in upgrade-channel.js in the middleware folder in our code repository, and it is based on the Fabric SDK Node API. The following prerequisites are also required:

  • configtxlator: This was built from the Fabric source code earlier in this chapter. Please ensure that it lies in your system path.
  • jq: This is a command-line JSON processor, for creating and parsing JSON objects. On an Ubuntu system, you can install this using apt-get install jq. Please ensure that it lies in your system path too.

In the upgradeChannel function, there is boilerplate code to create client and channel objects, which the reader should already be familiar with. The channel upgrade procedure requires the collection of signatures over the new configuration from an administrative user of every existing organization (4 in our network) just as in the channel creation procedure. But many additional steps are required before signatures can be generated and collected. First, we will need to fetch the latest configuration block from the orderer. We do this in the code using the following function call:

channel.getChannelConfigFromOrderer(); 

This returns a block configuration_block, whose config field contains the current channel configuration. The version of this configuration can be extracted from the sequence field of the configuration as follows: configuration_block.config.sequence. The full configuration spec is defined in the Fabric source code as a protobuf (common.Config), and its examination is left as an exercise to the reader.

In the code, we now create a folder to store temporary files that will be created in the subsequent steps. These files are created using the configtxlator tool, which we use in the absence of equivalent API functions in the Fabric SDK Node API:

if(!fs.existsSync('./tmp/')) {
fs.mkdirSync('./tmp'),
}

Having obtained the configuration, we need to dump it in the protobuf format to a file:

fs.writeFileSync('./tmp/config.pb', configuration_block.config.toBuffer()); 

Next, we need to decode this configuration into JSON format using configtxlator. We do this purely for convenience because it is easier to parse a JSON and apply our intended configuration changes to it:

cproc.execSync('configtxlator proto_decode --input ./tmp/config.pb --type common.Config | jq . > ./tmp/config.json'),

This results in the creation of a file named config.json in the temporary folder. If you view the contents of this file, you will see the underlying configuration structure of the channel and the various properties that can be updated.

Now we need to append the configuration of the new (exporting entity) organization to it. The latter is contained in the file exportingEntityOrg.json, created using the configtxgen tool earlier in this section and saved to network/channel-artifacts. We create the new appended configuration modified_config.json using the jq tool as follows:

cproc.execSync('jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"ExportingEntityOrgMSP":.[1]}}}}}' ./tmp/config.json ../network/channel-artifacts/exportingEntityOrg.json > ./tmp/modified_config.json'),

If you view the contents of modified_config.json, you will see that it is very similar in structure to config.json; the difference is that it contains the definitions of 5 organizations where the latter contains only 4. We now convert this new configuration to protobuf format (modified_config.pb) so configtxlator can process it:

cproc.execSync('configtxlator proto_encode --input ./tmp/modified_config.json --type common.Config --output ./tmp/modified_config.pb'), 

Note that we use the same protobuf schema (common.Config) that we used to decode the configuration obtained from the orderer.

Finally, we will use configtxlator to compute the delta (or difference) between the original and the new configuration protobufs:

cproc.execSync('configtxlator compute_update --channel_id ' + channel_name + ' --original ./tmp/config.pb --updated ./tmp/modified_config.pb --output ./tmp/exportingEntityOrg_update.pb'), 

The generated protobuf exportingEntityOrg_update.pb contains full definitions of the exportingentityOrg and pointers to the existing 4 organizations. This is sufficient for a channel configuration update as the full definitions of the other organizations are already contained in the previous configuration block (in our example, the genesis block).

Now all we have to do is read the delta configuration and get admin signatures from each of the existing four organizations. The code for this is similar to the code we examined in the channel creation stage:

config = fs.readFileSync('./tmp/exportingEntityOrg_update.pb'), 
var signature = client.signChannelConfig(config); 
signatures.push(signature); 

All we need to do now is create an update request and send it to the orderer:

let tx_id = client.newTransactionID(); 
var request = { 
  config: config, 
  signatures : signatures, 
  name : channel_name, 
  orderer : orderer, 
  txId  : tx_id 
}; 
client.updateChannel(request); 
The request structure can contain either a config or an envelope field. The latter has the common.Envelope protobuf format and is a wrapper around the configuration we just created. The Fabric orderer will accept either. Using envelope instead of config is left as an exercise to the reader.

To push the channel configuration update, just run:

node run-upgrade-channel.js 
Please ensure that the original 4-org network from Chapter 5Exposing Network Assets and Transactions is up and running, and that the channel creation step (see middleware/createTradeApp.js for an example) has already been performed.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.110.183