Hyperledger Fabric — Updating Channel Configs
Introduction
This is a step-by-step tutorial for updating channel configs in Hyperledger Fabric. Those steps are demonstrated using Hyperledger Fabric “Build Your First Network” (BYFN). We use Hyperledger Fabric v1.4.
If you don’t know how to start a BYFN, I will also provide steps in this tutorial, no worry!
Channel in Hyperledger Fabric is a private group in a Blockchain network. And each Blockchain network could contain multiple Channels, where each Channel is independent to other Channels, has its own ledger, and contains (multiple) organisation(s).
Each Channel is independent, thus there is an independent configurations set for each Channel, such as some policies, how many transactions in one block, etc. We would discuss how to update a Channel’s configurations set.
The Steps – Overview
Since steps of updating channel configurations could make people lost easily (there are so many files!), I list the steps overview here:
- Setup a BYFN (our Blockchain network)
- Fetch the current channel configurations for mychannel – output:
config_block.pb
, which is a block file - Transform the
config_block.pb
configurations to an understandable JSON file – output:config.json
- Make a copy of
config.json
tomodified_config.json
, which we will modify it according to what we need to update - Install vim for the modification of JSON file
- Modify configurations in
modified_config.json
- Transform
modified_config.json
to a block file – output:modified_config.pb
- Transform
config.json
to a block file — output:config.pb
- Compute the difference between
modified_config.pb
andconfig.json
– output:diff_config.pb
- Transform the
diff_config.pb
configurations to an understandable JSON file – output:diff_config.json
- Add envelope text in
diff_config.json
— output:diff_config_envelope.json
- Transform
diff_config_envelope.json
to a block file — output:diff_config_envelope.pb
- Sign
diff_config_envelope.pb
as OrdererOrg admin (depending on policy) - Send channel update transaction
Some Q&A:
Q: In step 2, why are those configurations obtained by fetching a block?
A: It is because in Hyperledger Fabric, channel configurations are encoded in Blockchain ledger, they are just information in the Blockchain.
Q: In step 9, why do we need to compute the difference?
A: According to Hyperledger Fabric document, “we are able to forgo the extensive MSP material and modification policy information for Org1 and Org2 because this data is already present within the channel’s genesis block. As such, we only need the delta between the two configurations”.
Q: In step 13, why do we need to sign the config block as OrdererOrg admin?
A: It depends on the policy. For more details about Hyperledger Fabric policy, you might take a look:
(1) https://hyperledger-fabric.readthedocs.io/en/release-1.4/policies.html?highlight=policy
(2) https://medium.com/@reasdom/hyperledger-fabric-damn-implicitmetapolicy-44cc9cc5c472
Step 1 — Setup a BYFN (our Blockchain network)
1.1 Install Prerequisites
We use Hyperledger Fabric v1.4 in this tutorial.
First of all, you could install prerequisites by following the official instructions:
1.2 Switch to the BYFN Directory
Let’s switch to BYFN directory (*supposed that you finish the prerequisite part, you should have all needed files and directories):
cd fabric-samples/first-network
1.3 Bring Up the Network!
There is a script to bring up the network easily, just run it. Thanks, Hyperledger.
./byfn.sh up
After running this script, you might need to wait for a moment…
Also, remember to start Docker, before you run the command above.
*In case you make something wrongly, you can run the following commands to turn down the network, and bring up again (and be careful):
./byfn.sh down
./byfn.sh up
1.4 Access the Cli
There is a cli Docker container created automatically, it is a command line interface to control the nodes.
Let’s get access to the cli:
docker exec -it cli bash
Then, set up environment variables used by some programs:
export CHANNEL_NAME=mychannel
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
You could just copy all of them, then paste to your terminal and press “enter”.
A little bit messy, sorry for that :P.
Step 2 — Fetch the current channel configurations for mychannel — output: config_block.pb, which is a block file
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
Step 3 — Transform the config_block.pb configurations to an understandable JSON file — output: config.json
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json
Step 4 — Make a copy of config.json to modified_config.json, which we will modify it according to what we need to update
cp config.json modified_config.json
Step 5 — Install vim for the modification of JSON file
vim is a famous editing tool in Linux.
sudo apt-get update -y
sudo apt-get install vim -y
Step 6 — Modify configurations in modified_config.json
vim modified_config.json
In this tutorial let’s edit BatchSize, that is about how many transactions in one block (default is 10 txs/block). We are going to modify max_message_count.
- Press “/” to start searching text
- Type “max_message_count”
- Then your cursor should be located at the start of text “max_message_count”
Do you see the texts above?
- Now, Press “i” to enter insert mode in vim (thus we can start editing), after pressing, you should see that there is “-- Insert --” on the left bottom of the terminal
- Locate your cursor on “10” (line 6 above)
- Change it from “10” to “11”:
Notice line 6. Do we have the same texts? We just change the number of transactions per block from 10 to 11.
Tips (optional to this tutorial):
Generally speaking, increasing this number could lead to higher throughput (in TPS, transactions per second), but too much could lead to larger latency. Personally, I use 100 (you might need to adjust “absolute_max_bytes”, “preferre_max_bytes”, some Kafka settings if any, and block release timeout). In case you have very powerful machines, this number could be even larger. I could reach over 2xxx TPS in my load test (GOLang Chaincode with basic getState() and putState() operations, and with LevelDB, v1.4 network).
Remember to perform load/performance test yourself to verify for production case. More details you might take a look: https://arxiv.org/pdf/1805.11390.pdf
- Then, press “esc” to exit insert mode of vim
- Press “shift + :”, type “wq!”, and press “enter”. You should now leave vim and the modification is saved.
Step 7 — Transform modified_config.json to a block file — output: modified_config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
Step 8 — Transform config.json to a block file — output: config.pb
configtxlator proto_encode --input config.json --type common.Config --output config.pb
Step 9 — Compute the difference between modified_config.pb and config.pb — output: diff_config.pb
configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output diff_config.pb
Step 10 — Transform the diff_config.pb configurations to an understandable JSON file — output: diff_config.json
configtxlator proto_decode --input diff_config.pb --type common.ConfigUpdate | jq . > diff_config.json
Step 11 — Add envelope text in diff_config.json — output: diff_config_envelope.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat diff_config.json)'}}}' | jq . > diff_config_envelope.json
Step 12 — Transform diff_config_envelope.json to a block file — output: diff_config_envelope.pb
configtxlator proto_encode --input diff_config_envelope.json --type common.Envelope --output diff_config_envelope.pb
Step 13 — Sign diff_config_envelope.pb as OrdererOrg admin (depending on policy)
In step 1, under “Access the Cli”, our cli is representing Peer0 in Org1 via environment variables.
In this step 13, we are going to switch to OrdererOrg admin to perform the signing, because our policy requires OrdererOrg admin to sign this update transaction.
For details of Hyperledger Fabric policy, please refer to two links provided at the end of section “The Steps — Overview”
export CORE_PEER_ADDRESS=orderer.example.com:7050
export CORE_PEER_LOCALMSPID="OrdererMSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin\@example.com/msp
You could just copy all of them, then paste to your terminal and press “enter”.
A little bit messy (again), sorry for that (again) :P :P.
Now, we do signing:
peer channel signconfigtx -f diff_config_envelope.pb
If you are careful enough, you should observe that the file size of diff_config_envelope.pb before signing is smaller than that after signing.
And it is okay to sign multiple times, let’s try it yourself.
Step 14 — Send channel update transaction
It is time to update the channel!
peer channel update -f diff_config_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA
In fact, this command also performs signing. We still sign it in step 13 because I would like to make the steps explicit and it is also for teaching purpose — in some cases, where the policy requires more than one admin to sign, you might need to use the command in step 13 multiple times before the final signer submits the channel update transaction.
Well, we are done!
Bonus Step 15 — Verify the channel update
How could we know that we have really updated the configurations?
One possible way is to fetch the configuration block again and transform it into JSON file. Finally, we check whether max_message_count is 11.
peer channel fetch config config_block2.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CAconfigtxlator proto_decode --input config_block2.pb --type common.Block | jq .data.data[0].payload.data.config > config2.jsonvim config2.json
Next, I don’t provide further steps to verify, let’s try yourself as a practice.
Thanks! If you like my stories, please follow me for new updates!