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.
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.
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).
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/[email protected]/msp export CORE_PEER_ADDRESS=localhost:7051 export PATH=$PATH:$PWD/../bin/ export FABRIC_CFG_PATH=$PWD/../config/ export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CORE_PEER_TLS_ENABLED=true export CORE_PEER_LOCALMSPID="Org2MSP" export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/msp export CORE_PEER_ADDRESS=localhost:9051 export PATH=$PATH:$PWD/../bin/ export FABRIC_CFG_PATH=$PWD/../config/ export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
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.
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.
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.
# Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # version: '2' volumes: peer1.org1.example.com: networks: test: services: peer1.org1.example.com: container_name: peer1.org1.example.com image: hyperledger/fabric-peer:$IMAGE_TAG environment: #Generic peer variables - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock # the following setting starts chaincode containers on the same # bridge network as the peers # https://docs.docker.com/compose/networking/ - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_test - FABRIC_LOGGING_SPEC=INFO #- FABRIC_LOGGING_SPEC=DEBUG - CORE_PEER_TLS_ENABLED=true - CORE_PEER_PROFILE_ENABLED=true - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt # Peer specific variabes - CORE_PEER_ID=peer1.org1.example.com - CORE_PEER_ADDRESS=peer1.org1.example.com:8051 - CORE_PEER_LISTENADDRESS=0.0.0.0:8051 - CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:8052 - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:8052 - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:8051 - CORE_PEER_LOCALMSPID=Org1MSP volumes: - /var/run/:/host/var/run/ - ../organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls - peer1.org1.example.com:/var/hyperledger/production working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: - 8051:8051 networks: - test
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
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
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.
And for sake of completeness, we see the same ledger in peer0.org2.example.com as well.
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"]}'
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.
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.
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.