In this article, we’ll see how to update the channel config to include anchor peer for an organization using Hyperledger Fabric v1.4.
Hyperledger Fabric is a modular blockchain framework that acts as a foundation for developing blockchain-based products, solutions, and applications using plug-and-play components that are aimed for use within private enterprises.
In this article, we’ll brush up some basics and then jump into tutorial explaining how to update channel config to configuration of multiple anchor peers. The main steps involved in updating channel config to include peer for an organization using Hyperledger Fabric are;
Peers are a fundamental element of a blockchain network, they host ledgers and smart contracts. The ledger records all the transactions generated by smart contracts. Smart contracts are used to encapsulate the shared processes in a network and ledgers are used to encapsulate the shared information in the network. Blockchain networks are administered by a collection of organizations rather than a single organization. An organisation is an entity that has access to channels and can issue identities to the network participants so that every transaction’s source is clear and identifiable. Organisations can join channels and thus get access to certain ledgers.
An anchor peer is a node in a network that all other peers can discover and communicate with. They are encoded into config update transaction in order to enable communication between peers of different organizations and discover all active participants of the channel. It helps to prevent single point of failures. It allows peers belonging to different members to discover all existing peers on a channel. Here, each member on a channel has an anchor peer or can have multiple anchor peers and thereby prevents single point of failure.
For example, consider we have three organizations in a channel — A, B & C and a single anchor peer — peer0.orgC — defined for organization C. When peer1.orgA (from organization A) contacts peer0.orgC, it will tell peer0.orgC about peer0.orgA. And when at a later time peer1.orgB contacts peer0.orgC, the latter would tell the former about peer0.orgA. From that point forward, organizations A and B would start exchanging membership information directly without any assistance from peer0.orgC. A detailed explanation on anchor peer can be found in the glossary of hyperledger.
Let's talk!
We are using Hyperledger Fabric 1.4 for the setup. You have to download the fabric samples form Hyperledger Fabric official. Move into the first-network
subdirectory within the fabric-samples
directory. It is based on the Building Your First Network (BYFN) tutorial in the fabric-samples
directory.
Run the following command to clean up the previous environment.
./byfn.sh down
Now generate the default BYFN artifacts:
./byfn.sh generate
And launch the network making use of the scripted execution within the CLI container:
./byfn.sh up
To add Org3 into the network, run the following script.
./eyfn.sh up
The above script will generate Org3 crypto material, update and signed the channel config for adding the org3 into the channel (mychannel)
We have to update the configuration of the application channel (mychannel
) autogenerated by BYFN, to include Anchor Peer for ‘Org3’ to the network.
Access the automatically created Docker container cli as :
docker exec -it cli bash
Export the ORDERER_CA
and CHANNEL_NAME
variables:
export 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 export CHANNEL_NAME=mychannel
Export the Org1 environment variables:
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp export CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export CORE_PEER_LOCALMSPID="Org1MSP" export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
We can also execute the following steps to update the anchor peer directly from the Org3 CLI, where the environment variables are set for Org3.
Inside the CLI container, fetch the most recent config block for the channel, using the peer channel fetch
command.
peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA
By default, the peer channel fetch config
the command returns the most recent configuration block for the targeted channel (mychannel)
.
By using the configtxlator
tool, decode the channel configuration block into JSON format. In order to strip away all of the headers, metadata, creator signatures which are irrelevant to the update can be accomplished by means of the jq
tool:
configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json
Note: The update process makes use of the configuration translator tool — configtxlator
. The tool which allows for the conversion between different equivalent data representations/formats (ie., between protobufs and JSON). The tool can also be used to compute a configuration update transaction based on the differences between two channel configurations.
We will be using the jq
tool to append the anchor peer for Org3 configuration definition to the channel’s application groups field in config.json
, and copy the output to modified_anchor_config.json
.
jq '.channel_group.groups.Application.groups.Org3MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org3.example.com","port": 11051}]},"version": "0"}}' config.json > modified_anchor_config.json
Note: Org3MSP in the channel’s application groups field is the name of the org we defined in configtx.yaml file.
We have now two JSON files, one for the current channel configuration, config.json
, and other for the updated channel configuration modified_anchor_config.json
. Next, we need to convert each of these back into protobuf format and calculate the delta between the two configurations.
Translate config.json
back into protobuf format as config.pb.
configtxlator proto_encode --input config.json --type common.Config --output config.pb
Translate the modified_anchor_config.json
into protobuf format as modified_anchor_config.pb
configtxlator proto_encode --input modified_anchor_config.json -- type common.Config --output modified_anchor_config.pb
Calculate the delta between the two protobuf formatted configurations.
configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_anchor_config.pb --output anchor_update.pb
Now that we must wrap it in an envelope message so that it can be properly read & signed by the orderer for the update. To do this we must first convert the protobuf back into a JSON that can be wrapped. By using the configtxlator command convert anchor_update.pb
into anchor_update.json
.
configtxlator proto_decode --input anchor_update.pb --type common.ConfigUpdate | jq . > anchor_update.json
Here we will wrap the update in an envelope message and outputting it to anchor_update_in_envelope.json.
echo '{"payload":{"header":{"channel_header": {"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat anchor_update.json)'}}}' | jq . > anchor_update_in_envelope.json
Now we need to convert the final JSON to a protobuf, so it can be properly signed and submitted to the orderer for the update.
configtxlator proto_encode --input anchor_update_in_envelope.json -- type common.Envelope --output anchor_update_in_envelope.pb
The anchor peer update is an update to Org3 , so we only need the signature of Org3 for the configuration update. If we are in the CLI container, update the environment variables for Org3 as follows.
Export the Org3 environment variables:
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp export CORE_PEER_ADDRESS=peer0.org3.example.com:7051 export CORE_PEER_LOCALMSPID="Org3MSP" export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
We can also do the update from the Org3 CLI container, as it is already using the Org3 identity. Then we can use the peer channel update
command as it will sign off as well as do the update on the channel as the Org3 admin before submitting it to the orderer.
peer channel update -f anchor_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA
The orderer receives the config update request and creates a block with the updated configuration. The peers will also process the configuration update as soon as it receives the block.
Get the block height and confirm the updation process as follows:-
We can confirm the block height before and after the channel update transaction.
peer channel getinfo -c mychannel
In order to avoid a single point of failure, we can have more than one anchor peer per organization. We are using multiple peer array as a configuration update instead of updating it with a single peer array. Assume that we have generated one more peer for Org3 as “peer1.org3.example.com”.
Update the anchor peer array as follows for updating one more anchor peer into the Org3 configuration.
[{"host": "peer0.org3.example.com","port": 11051},{"host": "peer1.org3.example.com","port": 12051}]
The modified_anchor_config.json
is updated as follows.
jq '.channel_group.groups.Application.groups.Org3MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org3.example.com","port": 11051},{"host": "peer1.org3.example.com","port": 12051}]},"version": "0"}}' config.json > modified_anchor_config.json We can define any number of anchor peers per each organization.
Error: got unexpected status: BAD_REQUEST -- error applying config update to existing channel 'mychannel': error authorizing update: error validating DeltaSet: invalid mod_policy for element [Group] /Channel/Application/Org3: mod_policy not set
This error is due to the invalid name for the Org we mentioned in the channel’s application groups field. As mentioned use the name of the org we defined in the config.tx.yaml file.
Error: got unexpected status: BAD_REQUEST -- error applying config update to existing channel 'mychannel': error authorizing update: error validating DeltaSet: policy for [Group] /Channel/Application/Org3MSP not satisfied: signature set did not satisfy policy
Let's talk!
This error occurs due to the invalid signature on the peer channel update
request. Since this is only an update to Org3 we only need to have Org3 sign off on the update. You must confirm the environment variables before the signing process. We have completed the configuration update to define an anchor peer for Org3.
This article was originally published here.