Upgrading Nodes in a Hyperledger Fabric Network: A Step-by-Step Guide

Akkahshh Agarwaal
7 min readAug 30, 2023

Hyperledger Fabric networks, the backbone of enterprise blockchain solutions, require periodic node upgrades to ensure peak performance and security.

Co-author:

This guide breaks down the process, giving you a clear path to successfully upgrade nodes. Let’s dive into the essential steps for upgrading orderer and peer nodes in a Hyperledger Fabric test network.

Prerequisites

In this tutorial, we are going to show you how to upgrade an orderer node and peer node from v2.4.7 to v2.5.2.

The ed result of the upgrade process
  1. Download Fabric samples, docker images, and binaries (v2.4.7).

Run the below command in the Golang Community recommendation for Go projects i.e. $HOME/go/src/github.com/<your_github_userid>

curl -sSL https://bit.ly/2ysbOFE | bash -s -- 2.4.7 1.5.5

Preparing for the upgrade

Now, that we have the docker images and binaries, we can start with bringing up an instance of the test network.

Steps for bringing up an instance of the v2.4.7 test-network
  1. Run an instance of v.2.4.7 test network.

Navigate to the test-network directory in your working directory.

cd $HOME/go/src/github.com/<your_github_userid>/fabric-samples/test-network

Remove any containers or artifacts from any previous runs.

./network.sh down

Bring up the test-network.

This command creates a Fabric network that consists of two peer nodes, one ordering node. No channel is created yet.

./network.sh up

2. Create a channel ‘mychannel’.

This command creates a channel ‘mychannel’ between Org1 and Org2 and joins their peers to the channel.

./network.sh createChannel

3. Deploy chaincode ‘asset-transfer-basic’ on channel ‘mychannel’.

./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

4. Invoke the chaincode.

We will perform transactions on the network by invoking functions in the ‘asset-transfer-basic’ chaincode to create few blocks (i.e. increase the height of the blockchain) so that we can verify that the node (orderer/peer) is able to restore the blocks after the upgrade process is complete.

To invoke the chaincode, we need to set a few environment variables.

Make sure you are operating from the test-network directory.

Add the peer binaries to your CLI path.

export PATH=${PWD}/../bin:$PATH

Set the FABRIC_CFG_PATH to point to the core.yaml file.

export FABRIC_CFG_PATH=$PWD/../config/

Set the environment variables that allow you to operate the peer CLI as Org1.

# Environment variables for Org1
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

Invoke the InitLedger function of the chaincode to put an initial list of assets on the ledger.

# invoking 'InitLedger' function through peer0.org1.example.com
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"InitLedger","Args":[]}'

Change the owner of an asset on the ledger by invoking the TransferAsset function.

# invoking 'TransferAsset' function through peer0.org1.example.com
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"TransferAsset","Args":["asset6","Christopher"]}'

5. Get the current blockchain height.

Execute into peer0.org1.example.com or peer0.org2.example.com container.

# For executing into peer0.org1.example.com
docker exec -it peer0.org1.example.com sh

# For executing into peer0.org2.example.com
docker exec -it peer0.org2.example.com sh

Run the below command to get the blockchain height.

# get the current blockchain height
peer channel getinfo -c mychannel

6. Create the backup folder structure.

As part of the upgrade process, we will ensure the safety of the ledger data and Membership Service Provider (MSP) material, which includes keys and certificates specific to the node. To make this process easier we will create an organised folder structure as shown below.

Ledger and MSP data backup folder structure

Run the following commands to create the basic folder structure.

# creating folder structure for storing orderer MSP data
mkdir -p backup/organizations/ordererOrganizations

# creating folder structure for storing peer MSP data
mkdir -p backup/organizations/peerOrganizations

Upgrading the orderer node

Orderer nodes should be upgraded one at a time.

High-level steps for upgrading an orderer node

Stop the ordering node container.

# stopping the 'orderer.example.com' container
docker stop orderer.example.com

Once it’s down, backup the node’s ledger and MSP data.

The orderer’s ledger data is stored at /var/hyperledger/production/orderer inside the container and it’s MSP material is stored at organizations/ordererOrganizations/example.com inside the test-network directory.

# For backing up the ledger data
# docker cp source_file_path destination_file_path
docker cp orderer.example.com:/var/hyperledger/production/orderer/ backup/orderer/

# For backing up the MSP data
# cp -r source_file_path destination_file_path
cp -r organizations/ordererOrganizations/example.com backup/organizations/ordererOrganizations

Remove the ordering node container.

# removing the 'orderer.example.com' container
docker rm -f orderer.example.com

Update the configuration file.

Inside the test-network/compose/ directory, you will come across a compose-test-net.yamlfile. Within the services section of this file, you’ll find the orderer.example.comservice. To upgrade the orderer node, specific modifications are required in this file.

  1. Change the image tag to 2.5.2
# inside 'test-network/compose/compose-test-net.yaml' file
# modify 'image' field of 'orderer.example.com' service
image: hyperledger/fabric-orderer:2.5.2

2. Modify the volumessection to restore data from the backup.

# inside 'test-network/compose/compose-test-net.yaml' file
# modify 'volumes' section of 'orderer.example.com' service
volumes:
- ../backup/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ../backup/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
- ../backup/orderer:/var/hyperledger/production/orderer

Launch the new ordering node container.

# launching the 'orderer.example.com' service using the 'compose-test-net.yaml' file
# docker-compose -f configuration_file_path up -d service_name
docker-compose -f compose/compose-test-net.yaml up -d orderer.example.com

Inspect the network

Running the docker ps -acommand will showcase that the orderer node is now active, powered by the upgraded 2.5.2 image.

# inspecting containers after upgrading the 'orderer.example.com' service 
docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
47ce14a02955 hyperledger/fabric-orderer:2.5.2 "orderer" 2 hours ago Up 2 hours 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp orderer.example.com

Once all of the ordering nodes in your network have come up, you can move on to upgrading your peers.

Upgrading the peer node

Peers should, like the ordering nodes, be upgraded one at a time.

High-level steps for upgrading a peer node

Stop the peer node container.

# stopping the 'peer0.org1.example.com' container
docker stop peer0.org1.example.com

Once it’s down, backup the node’s ledger and MSP data.

The peer’s ledger data is stored at /var/hyperledger/production/ inside the container and it’s MSP material is stored at organizations/peerOrganizations/org1.example.com inside the test-network directory.

# For backing up the ledger data
# docker cp source_file_path destination_file_path
docker cp peer0.org1.example.com:/var/hyperledger/production/ backup/peer0.org1/

# For backing up the MSP data
# cp -r source_file_path destination_file_path
cp -r organizations/peerOrganizations/org1.example.com backup/organizations/peerOrganizations

Remove the associated chaincode containers, chaincode images and then the node conatiner itself.

# fetching the CONTAINER ID for the peer0.org1.example.com chaincode container
CC_CONTAINER=$(docker ps -a | grep dev-peer0.org1.example.com | awk '{print $1}')

# removing the chaincode container
docker rm -f $CC_CONTAINER

# fetching the REPOSITORY (image_name) for the peer0.org1.example.com chaincode image
CC_IMAGE=$(docker images | grep dev-peer0.org1.example.com | awk '{print $1}')

# removing the chaincode image
docker rmi -f $CC_IMAGE

# removing the 'peer0.org1.example.com' container
docker rm -f peer0.org1.example.com

Update the configuration file.

Inside the test-network/compose/ directory, you will come across a compose-test-net.yamlfile. Within the services section of this file, you’ll find the peer0.org1.example.comservice. To upgrade the peer node, specific modifications are required in this file.

  1. Change the image tag to 2.5.2
# inside 'test-network/compose/compose-test-net.yaml' file
# modify 'image' field of 'peer0.org1.example.com' service
image: hyperledger/fabric-peer:2.5.2

2. Modify the volumessection to restore data from the backup.

# inside 'test-network/compose/compose-test-net.yaml' file
# modify 'volumes' section of 'peer0.org1.example.com' service
volumes:
- ../backup/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com:/etc/hyperledger/fabric
- ../backup/peer0.org1:/var/hyperledger/production
# the below volumes are taken from 'test-network/compose/docker/docker-compose-test-net.yaml' file
- ./docker/peercfg:/etc/hyperledger/peercfg
- /var/run/docker.sock:/host/var/run/docker.sock

3. Add the below environment variables in the environment section.

# add these in the 'environment' section of 'peer0.org1.example.com' service
# the below environment variables are taken from 'test-network/compose/docker/docker-compose-test-net.yaml' file
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test

Launch the new peer node container.

# launching the 'peer0.org1.example.com' service using the 'compose-test-net.yaml' file
# # docker-compose -f configuration_file_path up -d service_name
docker-compose -f compose/compose-test-net.yaml up -d peer0.org1.example.com

Inspect the network

Running the docker ps -acommand will showcase that the peer node and the chaincode container is now active, powered by the upgraded 2.5.2 image.


# inspecting containers after upgrading the 'peer0.org1.example.com' service
docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a78664c80050 dev-peer0.org1.example.com-basic_1.0-d29562b85321d821cc02fddff4366e54b9bdbfa5d51647b5613141dd4d947b9e-2756d23ff6655c33d7654045117ea6449adee1c867448befb8144c90c1b38f1b "chaincode -peer.add…" 9 seconds ago Up 8 seconds dev-peer0.org1.example.com-basic_1.0-d29562b85321d821cc02fddff4366e54b9bdbfa5d51647b5613141dd4d947b9e
47088eab1e3f hyperledger/fabric-peer:2.5.2 "peer node start" About a minute ago Up About a minute 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:9444->9444/tcp, :::9444->9444/tcp peer0.org1.example.com

Once the peer node in your network has come up, you can move on to upgrading other peers by following the same process.

Verifying the upgrade process

We’ll validate the successful upgrade and ledger data restoration of the peer using a chaincode invoke. Additionally, we’ll ensure that the blockchain height matches the height prior to the upgrade.

How to verify peer upgrade completion

Query the ledger.

We will invoke the GetAllAssets function of the already deployed asset-transfer-basic chaincode to verify that the peer is able to query the ledger.

  1. Set the environment variables that allow you to operate the peer CLI as Org1.
# Environment variables for Org1
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051

2. Invoke the GetAllAssets function to get the list of all assets.

# invoking 'GetAllAssets' function through peer0.org1.example.com
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

Check the blockchain height.

  1. Execute into the peer0.org1.example.com container.
# For executing into peer0.org1.example.com
docker exec -it peer0.org1.example.com sh

2. Run the below command to get the blockchain height and verify that it is equal to the height prior to the upgrade.

# get the current blockchain height
peer channel getinfo -c mychannel

Conclusion

Congratulations, I hope you’ve now gained a clear understanding of the node upgrade process within a Hyperledger Fabric network.

Happy Upgrading! 😃

--

--