Add a Peer to an Organization in Test Network (Hyperledger Fabric v2.2)

KC Tam
8 min readAug 3, 2020

Overview

Test Network comes as a sample network since Fabric v2.0, and in v2.2 we see a more comprehensive set of scripts for flexible channel creation and chaincode deployment. Test Network architecture is very simple, a three-organization network setup, one for ordering service and two for peer organizations. Inside each peer organization we have one peer and an optional CA.

Test Network

While it is good and basic enough for testing channel and chaincode, it does not give us some network architectures for learning or testing purposes. For example, if we wish to take a look at the high availability behaviour inside an organization, we need one more peer. Thanks to the CA option, we can easily add additional peers on the existing network and join it to an existing channel.

Our goal is to add a peer in Org1 in this article.

In this article we will show the steps needed to bring up a new peer for an organization and join it to an existing channel. We will explore what happens when this peer joins a network and when chaincode is installed in this peer.

Examine the Flow in Test Network Script

Test Network script network.sh provides a simple and logical process for bringing up a network, creation of channel and deployment of chaincode. We will examine this script.

Process of Adding a New Peer

Assuming the network is running and application chaincode is deployed for use. We are going to add a peer1.org1.example.com to Org1. The objective is that this new peer will be part of the channel, and able to process chaincode query and endorsement when needed.

The steps we need to walk through are

  • Step 2: generate crypto material for peer1.org1.example.com
  • Step 4: create a docker compose file containing this peer
  • Step 5c: join this new peer to the existing channel
  • Step 6b: install chaincode to that peer

There are two ways to generate crypto material in Test Network: cryptogen and Fabric CA. As we are generating additional material, it is more desirable to use Fabric CA. This is a more standard and operable way to generate new components or new users for an organization. As a result we are using -ca option when bringing up the network, in which Fabric CA servers are brought up.

Besides, step 6c and 6d are not needed. Approving and committing chaincode are done at organization level, not peer level.

Demonstration

Step 0: Preparation

We need a fabric host with Fabric v2.2 installed. For demonstration we also prepare two terminals, one with setting for Org1 (peer0.org1.example.com) and one with setting for Org2 (peer0.org2.example.com).

Terminal for Org1
Terminal for Org2

Step 1: Bring up Test Network

We use script network.sh to bring up the Test Network and mychannel (steps 1–5 in the previous session).

cd fabric-samples/test-network/
./network.sh up createChannel -ca

Total six containers are running:

  • 3 CAs, one for each organization
  • 1 orderer
  • 2 peers, one for Org1 and one for Org2

Step 2: Deploy chaincode SACC

We also use network.sh to deploy sacc (step 6 in previous session).

cd fabric-samples/test-network/
./network.sh up deployCC -ccn mycc -ccp ../chaincode/sacc

After deployment, we take a look on the output of service discovery about endorsement. We see endorsing policy requires both organizations, and each organization has one peer currently. We will see this again after we complete the addition of peer1.org1.example.com.

Output of service discovery after Test Network script is executed.

Step 3: Test chaincode

After deployment we perform an invoke and query from both peers.

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile $ORDERER_CA -C mychannel -n mycc --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 '{"Args":["set","name","Alice"]}'peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

Invoke from Org1

Query from both Org1 and Org2. And we see the same state value for asset name. The network is running well.

Terminal for Org1
Terminal for Org2

Step 4: Generate crypto material for new peer

Use CA of Org1 to generate crypto material for peer1.org1.example.com (step 2 in previous session). Here we largely follow the script ./organizations/fabric-ca/registerEnroll.sh. For a detailed description you can refer to the script file, and read my previous article (second part).

export PATH=$PATH:${PWD}/../bin
export FABRIC_CA_CLIENT_HOME=${PWD}/organizations/peerOrganizations/org1.example.com/
fabric-ca-client register --caname ca-org1 --id.name peer1 --id.secret peer1pw --id.type peer --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pemmkdir -p organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.comfabric-ca-client enroll -u https://peer1:peer1pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp --csr.hosts peer1.org1.example.com --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pemcp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp/config.yamlfabric-ca-client enroll -u https://peer1:peer1pw@localhost:7054 --caname ca-org1 -M ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls --enrollment.profile tls --csr.hosts peer1.org1.example.com --csr.hosts localhost --tls.certfiles ${PWD}/organizations/fabric-ca/org1/tls-cert.pemcp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/tlscacerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/signcerts/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.crt
cp ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/keystore/* ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.key

Let’s check the directory structure for peer1.org1.example.com. We see the msp/ directory structure, and the three files required in tls/, that is, ca.crt, server.crt and server.key.

Step 5: Create configuration for the new peer and bring up the container

Here is step 4 in the previous session. We keep the docker-compose file inside docker/ directory. The file is adopted from docker-compose-test-net.yaml, with proper host, directory and port modified for peer1.org1.example.com.

docker-compose -f docker/docker-compose-peer1org1.yaml up -d

Step 6: Join the new peer to the existing channel

The container for peer1.org1.example.com is running. It is not part of the channel yet. Here we perform the 5c in the previous session, joining this new peer to mychannel.

We are accessing both peer0.org1.example.com and peer1.org1.example.com with the same terminal for Org1. To specify peer1.org1.example.com, we set the variable CORE_PEER_ADDRESS=localhost:8051 before any peer commands.

First, let’s check the channel both peers of Org1 have joined.

peer channel listCORE_PEER_ADDRESS=localhost:8051 peer channel list
Terminal for Org1 (showing peer0.org1.example.com and peer1.org1.example.com)

We see peer1.org1.example.com has not joined any channel yet.

To join the channel, we need the channel genesis block. It was generated during channel creation when we first executed the ./network.sh script, and the block file is kept in channel-artifacts/mychannel.block.

CORE_PEER_ADDRESS=localhost:8051 peer channel join -b channel-artifacts/mychannel.block

Now we see peer1.org1.example.com has joined mychannel

peer1.org1.example.com now joined mychannel

As we know, peer joining the same channel is holding a copy of ledger. And we see they have the same ledger (same blockchain height and hash). The “missing” blocks have been collected from other peers in the channel.

peer1.org1.example.com now has the same ledger as peer0.org1.example.com

And for sake of completeness, we see the same ledger in peer0.org2.example.com as well.

Same ledger is seen in peer0.org2.example.com

Now all the three peers are in the same channel, and have a common ledger.

Step 7: Install chaincode to that peer

We first check if we can use peer1.org1.example.com in chaincode query.

peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'CORE_PEER_ADDRESS=localhost:8051 peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
chaincode query fails in peer1.org1.example.com as it is not installed yet.

We see that, even though the ledger is already there, we cannot query peer1.org1.example.com. The reason is that a chaincode is not installed on this peer and a chaincode container is not there yet.

Before installing chaincode on the new peer, we first take a look at the chaincode containers. We see two, one for each peer.

And these two chaincode containers are instantiated by two images, one for each peer.

Now we install the chaincode package on peer1.org1.example.com. According to the script, the chaincode package mycc.tar.gz is created and kept in the test-network/ directory.

CORE_PEER_ADDRESS=localhost:8051 peer lifecycle chaincode install mycc.tar.gz

After installation completes, we see a new chaincode container running for this peer, instantiated from a new image.

Chaincode container for peer1.org1.example.com on mycc
Chaincode container image for peer1.org1.example.com on mycc

If we take a look on the service discovery on endorsement, now we have two peers for Org1. Either one is good enough to handle the endorsement for Org1. We will test this in the next step.

Output of service discovery after peer1.org1.example.com is added.

Step 8: Test chaincode using new peer

First we query the state of an existing asset. Now we get back the result from peer1.org1.example.com.

peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'CORE_PEER_ADDRESS=localhost:8051 peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

Then we invoke chaincode function, with peer1.org1.example.com as one endorser for Org1. Remember that the default chaincode endorsement policy is majority, which means one endorsement is needed from both organizations. In this chaincode invocation we specify peer1.org1.example.com for Org1, and peer0.org2.example.com for Org2.

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --cafile $ORDERER_CA -C mychannel -n mycc --peerAddresses localhost:8051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.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 '{"Args":["set","name","Bob"]}'

The chaincode invocation is successful. Now we query the result from all peers.

Summary

Through this exercise we know the steps required to add new peers to a peer organization. It is not complicated once we understand the overall flow. As First Network is no longer in v2.2+, we can use this simple process to set up a multiple-peer environment when needed.

--

--