Contents

New Year, New Fablo webp image

Good news, everybody! At the beginning of January, we released a new version of Fablo. Here's a rough overview on what happened in the Fablo world recently.

This article was written in collaboration with Piotr Hejwowski, private blockchain architect and co-creator of Fablo.

News

  • In December, we joined Hyperledger Labs! Our new repo is https://github.com/hyperledger-labs/fablo, however, GitHub supports redirections from the old one.
  • As you might have noticed, we decided to skip few version numbers and from 0.3.0, we went directly to 1.0.0. We felt it’s about time for that - Fablo is packed with useful features.

Features overview

The latest versions of Fablo (0.3.0 and 1.0.0) come with a few handy features that might make your private blockchain solutions development even easier. Our major improvements include:

  • Hooks (v0.3.0, @dzikowski)
  • Orderer groups and orderer sharding (v0.3.0, @Hejwo)
  • Config file reorganization (v0.3.0, @Hejwo)
  • Connection profiles generation (v1.0.0, @gzhk)
  • Blockchain Explorer support (v1.0.0, @gzhk)
  • Network snapshots (v1.0.0, @dzikowski)

We also fixed some bugs, like the lack of support for CouchDB on new MacBooks with M1 processors.

Remember that you can find a complete list of features in the release notes.

Install and upgrade instructions

The simplest way to install the newest stable version of Fablo for a single project scope is:

curl -Lf https://github.com/softwaremill/fablo/releases/download/1.0.0/fablo.sh -o ./fablo && chmod +x ./fablo

If you already use older versions of Fablo, just type ./fablo use 1.0.0. Do not forget to update the $schema path in your current Fablo config files.

You might also be interested in:

Hooks (v0.3.0)

This is a simple but very useful feature. Hooks in Fablo are Bash commands to be executed after a specific event. Right now, Fablo supports only one kind of hook: postGenerate. It will be executed after the network config is generated, so after the ./fablo generate command. If you prefer using ./fablo up, don’t worry - in such a case, a hook will be executed after generating network files and before starting up the network.

You can use the postGenerate hook to change files generated by Fablo. For instance, you can change default MaxMessageCount, providing in Fablo config file:

"hooks": { "postGenerate": "perl -i -pe 's/MaxMessageCount: 10/MaxMessageCount: 1/g' \"./fablo-target/fabric-config/configtx.yaml\"" }

Or you can change permissions and roles by altering default Profiles and ACLs. You can also change ports in the generated Docker compose file. Making those changes might not be simple since you need to use terminal utils, but it is finally possible.

Generated Hooks are saved in the fablo-target/hooks directory.

Orderer groups and orderer sharding (v0.3.0)

Another feature that we’ve added might look inconspicuously at first glance, but it's really powerful. The orderer type is now changed to orderers and it’s a list. It also requires the mandatory field groupName. Channel was enriched with an optional field ordererGroup. What does it all mean?

Well, by default, we have orderers centralized in one organization and having groupName set to group1, but nothing stops us from adding more order groups or from distributing them among many organizations and for assigning channels to different groups.

We’ll be explaining it in depth in a separate article, but here are some examples that might intrigue you :)

One Orderer group distributed among two organizations:

  "orgs": [
    {
      "organization": {
        "name": "Org1",
        "domain": "org1.example.com"
      },
      "peer": { … },
      "orderers": [
        {
          "groupName": "group1",
          "type": "raft",
          "instances": 3
        }
      ]
    },
    {
      "organization": {
        "name": "Org2",
        "domain": "org2.example.com"
      },
      "peer": { … },
      "orderers": [
        {
          "groupName": "group1",
          "type": "raft",
          "instances": 3
        }
      ]
    }
  ]

The network above will have one group of orderers (named “group1”) with six nodes in total.

In this scenario, each organization hosts some part of orderers. Both organizations have equal rights and responsibilities in the network. Since there is only one group, every channel by default will be handled by that group, so you don’t need to pass the ordererGroup param to the channel.

Two separated orderer groups in one organization

{
  "orgs": [
    {
      "organization": {
        "name": "Org1",
        "domain": "org1.example.com"
      },
      "peer": { },
      "orderers": [
        {
          "groupName": "production-group",
          "type": "raft",
          "instances": 3
        },
        {
          "groupName": "staging-group",
          "type": "solo",
          "instances": 1
        }
      ]
    }
  ],
  "channels": [
    {
      "name": "production-channel",
      "ordererGroup": "production-group",
      "orgs": [
        { "name": "Org1",  "peers": [ ... ] },
        { "name": "Org2",  "peers": [ ... ] }
      ]
    },
    {
      "name": "staging-channel",
      "ordererGroup": "staging-group",
      "orgs": [
        { "name": "Org1",  "peers": [ ... ] }
      ]
    }
  ]
}

In the example above, we have two different Orderer groups defined.

  • One group can, for example, be responsible for production deployment, so it will have the RAFT consensus type and be distributed among many organizations. We’ve called that group production-group and defined that production-channel should be handled by that group.
  • Since production is a serious thing, some parties may decide to have a staging environment to do testing before deployment. Such tests might be performed in an isolated, down-scaled environment. Thanks to that, the load from the testing system won’t affect production. staging-group with “solo” orderer type is an example of such an environment. It handles staging-channel, which is an internal channel of Org1.

Voilà! You’ve seen the basic use cases of orderer groups and how we can achieve sharding of channels thanks to them. Good news is that in Fablo. we try to be as flexible as possible, so you can mix those cases or create your own ones. Have fun!

You might also be interested in:

Config file reorganization (v0.3.0)

Previous versions had a rootOrg section with Orderer definition at the beginning. We’ve decided to remove it and define everything in the orgs section. From now on, every organization in the config file is equal and can host both peers and some part of orderers. In our opinion, that division is closer to the decentralized nature of Hyperledger Fabric.

Connection profile generation (v1.0.0)

Fablo generates connection profiles for each organization defined in the configuration. You can find them in the fablo-target/fablo-config/connection-profiles directory in JSON and YAML format.

Blockchain Explorer (v1.0.0)

You can now run Blockchain Explorer for given organizations or one global Blockchain Explorer. It is available in two ways.

First, you can enable Blockchain Explorer for given organizations. In this case, you can just provide it as a tool in organization configuration:

  "orgs": [
    {
      "organization": {...},
      "peer": {...},
      "tools": {
        "explorer": true
      }
    },
    ...
  ],

You can also enable one global Explorer for the whole network. You just need to provide it in the global config section:

 "global": {
    "fabricVersion": "2.3.0",
    "tls": false,
    "tools": {
      "explorer": true
    }
  },

Note: Current newest Explorer version does not work with Hyperledger Fabric 2.4 (yet).

You might also be interested in:

Network snapshots (v1.0.0)

Fablo supports saving state snapshot (backup) of the network and restoring it. It saves all network artifacts, certificates, and the data of CA, orderer, and peer nodes. However, the snapshot does not contain the Fablo config file and chaincode source code, since both can be located outside Fablo working directory.

Snapshotting might be useful if you want to keep the current state of a network for future use (for testing, sharing the network state, courses, and so on).

Assume you have a working network with some state. In order to create and restore a snapshot, follow the steps:

  1. Execute ./fablo snapshot /tmp/my-snapshot. It will create a file /tmp/my-snapshot.fablo.tar.gz with the state of the network. It is not required to stop the network before making a snapshot.
  2. Execute ./fablo prune to destroy the current network. If the network was present, Fablo would not be able to restore the new one from backup.
  3. Execute ./fablo restore /tmp/my-snapshot to restore the network.
  4. Execute ./fablo start to start the restored network.

Typically, a snapshot of the network with some data takes less than 1 MB, so it is easy to share.

What’s next?

As you can see, version 1.0.0 offers quite a lot. For next minor versions, we plan to include Prometheus metrics support, a new way of managing channels for HLF >2.3, bug fixes.

Many of you also ask about Kubernetes support or other forms of decentralization. We’re starting our work on that and probably will release it in the 2.0.0 version. Keep your fingers crossed! :)

Contributions are welcome

Fablo is a very useful tool. Recently, at HackYeah hackaton, we even won an award sponsored by The Polish Financial Supervision Authority (UKNF), since Fablo took all the complexity of managing a local Hyperledger Fabric network.

If you want to be a part of Fablo’s journey, feel free to submit an issue, or create a PR. And star us if you find Fablo useful.

Blog Comments powered by Disqus.