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

Overview

Test Network comes as a sample network since Fabric v2.0, and in v2.3 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 channels 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:

Our goal is to add a peer in Org1

Demonstration

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 of 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 the 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.

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. Here we largely follow the script ./organizations/fabric-ca/registerEnroll.sh.

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.pem
mkdir -p organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com

fabric-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.pem

cp ${PWD}/organizations/peerOrganizations/org1.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp/config.yaml

fabric-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.pem

cp ${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 the proper host, directory and port modified for peer1.org1.example.com.

Let's start the peer

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.

CORE_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 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 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.

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.

Step 9: Bring down your network.

./network.sh down

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.

Last updated