Demonstration of No-System-Channel Setup in Hyperledger Fabric v2.3
Introduction
Besides the ledger snapshot, Fabric v2.3 also introduced a new feature, bringing up application channels without system channel. The process is documented in details in the readthedoc. In this article I am using the configuration and script provided in Test Network and show what is needed to modify in order to bring up such a no-system-channel setup.
Overview
Prior to v2.3, we see two types of channels: system channel and application channel(s). System channel holds the consortium configuration, while all or part of the consortium members are joining various application channels according to the requirements. You may have seen that some configuration updates require the system channel. For example, adding a new organization into the consortium in order to join this organization to a new channel. For details you can see it in my previous article and some behaviour observation in this article.
The flow is like this. First create the genesis block for the system channel and let all orderers boot up with this genesis block. The system channel is now running in all orderers. Then create the genesis block for the application channel through configuration transaction. Finally join peers to the application channel. All orderers by default will also see this application channel.
There are many reasons shown in the readthedoc not to use system channel any more when building a fabric network. Application channel is good enough in daily use. In v2.3, the setup without system channel is introduced and this setup will be the direction in futures. In short, the system channel will no longer be needed.
In v2.3, The flow looks more simpler and straightforward. First create the genesis block for the application channel. Then join selected orderers and peers to the application channel.
In summary here is the difference in the flow.
In this article we first observe what we have before by inspecting Test Network. The script in Test Network is not yet modified and therefore we can make observations on how the system channel looks like. Later we will make a demonstration of how to create a fabric setup with no system channel.
Observation Test Network with System Channel
Let us first examine a fabric network with the system channel, which is the only way a fabric network is created prior to v2.3.
We use the script network.sh
to bring up the components (containers).
cd fabric-samples
cd test-network
./network.sh up
We make an observation on the orderer.example.com, in which we see a system channel only (system-channel).
docker exec orderer.example.com ls /var/hyperledger/production/orderer/chains
Now we create an application channel, mychannel, with the network.sh
script. After that we inspect the orderer again.
./network.sh createChanneldocker exec orderer.example.com ls /var/hyperledger/production/orderer/chains
We know everything works fine in Test Network. Therefore we are done with it here and shut down this setup.
./network.sh down
Demonstration of No-System-Channel Setup
As mentioned above, we are leveraging most configurations in the Test Network. The process of this demonstration is
- duplicate the Test Network in another directory
- generate crypto material
- modify both the docker compose file
- bring up components
- add a profile for no-system-channel setup in channel configuration
- create genesis block for our application channel (mychannel)
- join orderer to mychannel
- join peers to mychannel
- test with SACC chaincode
1. Duplicate the Test Network for the demonstration
We duplicate the directory of Test Network test-network
to demo-test-network
. All demonstration happens in demo-test-network.
cd fabric-samples
cp -r test-network demo-test-networkcd demo-test-network
2. Generate crypto material using cryptogen
Leverage the directory structure of test-network and generate crypto material with cryptogen. The result is kept in organizations/ordererOrganizations
and organizations/peerOrganizations
.
Note: the result of using Fabric-CA is to create a similar directory structure. For sake of simplicity cryptogen is used.
// make sure fabric-samples/bin is included in PATH
export PATH=$PATH:${HOME}/fabric-samples/bincryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output="organizations"cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output="organizations"cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output="organizations"
3. Modify docker compose file
Similarly we make a copy of the docker/docker-compose-test-net.yaml
to another file. We act on this file.
cd dockercp docker-compose-test-net.yaml docker-compose-no-system-channel.yaml
The only part we are modifying is orderer.example.com. In summary,
- comment out the use of genesis file and the mapping of genesis file (line 8, 9 and 33)
- set none bootstrap method (line 22)
- add configuration for orderer admin (line 23–28)
- allow orderer joining channel (line 29)
- map the directory of orderer admin to container (line 36)
- add mapping of admin port 7080 for accessing (line 40)
4. Bring up components
docker-compose -f docker/docker-compose-no-system-channel.yaml up -d
When orderer container is running, we can Inspect the channel now configured in the orderer. We see no system channel any more.
docker exec orderer.example.com ls /var/hyperledger/production/orderer/chains
5. Add a profile for no-system-channel setup in channel configuration
The two existing profiles (TwoOrgsOrdererGenesis and TwoOrgsChannel) defined in configtx/configtx.yaml
are for system channel. Here we add a profile SampleAppChannelEtcdRaft.
Profiles: TwoOrgsOrdererGenesis:
…
TwoOrgsChannel:
…
SampleAppChannelEtcdRaft:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
6. Prepare genesis block for mychannel
Instead of creating genesis block for system channel and configuration transaction, here we generate directly the genesis block for application channel (mychannel) with our new profile.
export FABRIC_CFG_PATH=../configcd configtx/
configtxgen -profile SampleAppChannelEtcdRaft -outputBlock mychannel.block -channelID mychannel
Go back to demo-test-network
directory.
cd ..
7. Join orderer to mychannel
Now we are using the new binary osnadmin
to handle the channel joining for the orderer.
First we inspect any channel configuration in the orderer.
osnadmin channel list -o localhost:7080 --ca-file ./organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt --client-cert ./organizations/ordererOrganizations/example.com/users/Admin\@example.com/tls/client.crt --client-key ./organizations/ordererOrganizations/example.com/users/Admin\@example.com/tls/client.key
Now join the orderer to mychannel.
osnadmin channel join --channel-id mychannel --config-block configtx/mychannel.block -o localhost:7080 --ca-file ./organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt --client-cert ./organizations/ordererOrganizations/example.com/users/Admin\@example.com/tls/client.crt --client-key ./organizations/ordererOrganizations/example.com/users/Admin\@example.com/tls/client.key
Now we see mychannel in orderer, while there is still no system channel.
We see similar results while inspecting the orderer.
docker exec orderer.example.com ls /var/hyperledger/production/orderer/chains
Now the orderer is already in mychannel. Peers can now join mychannel.
8. Join peers to mychannel
Prepare two terminals, with proper environment variables set such that commands are issued to peer0.org1.example.com and peer0.org2.example.com, respectively.
// for peer of org1
peer channel join -b configtx/mychannel.block// for peer of org2
peer channel join -b configtx/mychannel.block
9. Test with SACC chaincode
We again leverage network.sh
script which makes our life easier, as it completes the chaincode deployment with the lifecycle chaincode.
./network.sh deployCC -ccn mycc -ccp ../chaincode/sacc -ccl go
We invoke the set function in peer0.org1.example.com. Then check it with the get function in both peers.
In peer0.org1.example.com, set function is invoked and the result is queried properly with get function.
In peer0.org2.example.com we get the same result.
Now our demonstration completes. we can tear down everything.
docker-compose -f docker/docker-compose-no-system-channel.yaml down -v
Summary
In this article I have used Test Network to demonstrate how to build a fabric setup with no system channel. As this will be the direction in the long run, I am expecting the script will be updated in future versions. Nevertheless, hope this article gives you some hints how things are done in this setup.