I want to add a new orderer to my existing running network. Currently my network is as follows :
docker ps -a
CONTAINER ID I
You can add a new orderer in your RAFT consensus protocol setup by following these steps. It’s a lengthy process so I will also add a script later but for now you can follow these steps. Here, I am using first-network from the fabric samples for starting the network with 5 orderers.
First of all in crypto-config under OrdererOrgs: Specs: create a new hostname for your orderer (using the same domain and name as your other).
Then, run the command cryptogen extend --config=./crypto-config.yaml
NOTE: the 'extend' part so it generates what you need and not regenerate everything.
Now first we will add orderer to the system channel and then when it has all the blocks of the system channel then we will move it into application channel so please make sure you are doing it properly.
Enter into your cli container by using docker exec -it cli bash
and bootstrap it with an active orderer information as you will need the OrdererMSP to sign off this change.
Here are some of the environment variables that you will need to bootstrap cli with orderer:
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp
CORE_PEER_ADDRESS=orderer.example.com:7050
CORE_PEER_LOCALMSPID=OrdererMSP
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
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
CHANNEL_NAME=[system-channel-name]
The next thing is to make sure you have all your binaries working inside your cli container as we will use jq and configtxlator tool here to convert blocks from protobuf to json and back
Fetch the latest config block: peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
Convert to json and trim headers: configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json
open the json file look for "ConsensusType" section and under that heading there should be another tag "consenters". And now you have to add new TLS certs in this section of the latest orderer that you have created above. But here the certs are in Base64 encoded form so first you have to lookout for your tlscert then you have to convert in base64 and then insert it in this section.
In my case the tls cert is here:
crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
Now add it into the section given above in the same manner as others are mentioned like this:
{
"client_tls_cert": "xxxxxxxxxxxx",
"host": "new_orderer.example.com",
"port": 7050,
"server_tls_cert": "xxxxxxxxxxxx"
}
Add the base64 encoded cert instead of xxxxxxxx given above and save the change as modified_config.json
Convert json form step 6 to block configtxlator proto_encode --input config.json --type common.Config --output config.pb
Convert json from step 7 to block configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
Calculate the delta between block in step 8 and 9: configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output orderer_update.pb
change the delta back to json: configtxlator proto_decode --input orderer_update.pb --type common.ConfigUpdate | jq . > orderer_update.json
Now, we have a decoded update file – orderer_update.json – that we need to wrap in an envelope message. This step will give us back the header field that we stripped away earlier. We’ll name this file: orderer_update_in_envelope.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"$CHANNEL_NAME", "type":2}},"data":{"config_update":'$(cat orderer_update.json)'}}}' | jq . > orderer_update_in_envelope.json
configtxlator proto_encode --input orderer_update_in_envelope.json --type common.Envelope --output orderer_update_in_envelope.pb
peer channel update -f orderer_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA
Ensure that the node that will be added is part of the system channel by checking that the config block that was fetched includes the certificate of (soon to be) added node.
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
then, move this config block to the channel-artifacts folder and add the path to this env variable inside orderer’s docker-compose file:
ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
After starting your orderer, you may notice at this point it is connected to the raft and the Steprequests are successful and has your channel and blocks because it is using the same genesis block. What needs to be done though is the network needs to be made aware of the address of this new orderer.
Wait for the Raft node to replicate the blocks from existing nodes for all channels its certificates have been added to. After this step has been completed, the node begins servicing the channel.
Add the endpoint of the newly added Raft node to the channel configuration of the system channel and for that you have to again repeat the whole process of channel update transaction as we have done earlier from (5th to 14th) and the only thing you have to do differently is in the step 7 you have to do this:
Open the json file look for "OrdererAddresses" section and under that heading there should be another tag "addresses". Add the new IP and PORT for the new orderer endpoint in that array. Save the change as modified_config.json and then do the rest as above.
Once your peers get this new block, they now know the address of the new orderer and can contact it.
CHANNEL_NAME=[application-channel-name]
You have to add the same tls certs into the consenters section and then after having replicated blocks of the application channel you can add the orderer’s endpoint in the addresses section and then it will start reflecting all the latest changes that you will make to the application channel.