Probably the most popular enterprise blockchain guarantees strong consistency of the state and at the same time promises to perform hundreds of transactions per second. Is this really possible? For a blockchain? Find out how Hyperledger Fabric blockchain let you trust your data.
State in Hyperledger Fabric
The state in Hyperledger Fabric consists of two elements:
- The blockchain, i.e. an immutable log of transactions.
- The world state, i.e. a database with business objects created and updated by those transactions.
The world state is derived from the blockchain and has the form of a key-value store. Chaincodes/smart contracts (i.e. applications executed on the blockchain) do interact with the world state, not the blockchain itself.
What is the strong consistency
If operation B started after operation A successfully completed, then operation B must see the system in the same state as it was on completion of operation A, or a newer state.
Unique transaction flow and centralized ordering service enables Hyperledger Fabric to support a single global ordered history of transactions. Any world state changes are performed on the most recent state. As a consequence Hyperledger Fabric provides this kind of consistency (linearizability).
The transaction flow
Typically blockchains follow the order-execute model of transactions. They use consensus protocols to order transactions first and then apply the transactions sequentially on all peers (see these articles).
In Hyperledger Fabric the model is different and consists of three steps (execute-order-validate):
- Transaction proposal (execute): A smart contract is executed on selected peers. It reads the world state, performs some calculations and proposes the update. The world state and blockchain remains unchanged.
- Ordering (order): The ordering service collects proposed transactions, orders them, and packages them into blocks, ready for distribution. It ensures the global order of transactions in the blockchain.
- Actual transaction (validate): Peers receive new block with ordered transactions and append them to the blockchain. Then they verify if the transactions were executed on proper peers and there are no read/update conflicts that may lead to data inconsistencies. Valid transactions update peers world state.
This approach has some significant advantages over order-execute model. It improves the performance and effectively allows to develop smart contracts in common programming languages (see for example this post). But, what is more important, it guarantees that once a block is appended to the chain, it is final.
Most distributed blockchains, for example Ethereum and Bitcoin, do not have the global ordered history of transactions. The same transaction can be packaged in multiple different blocks that compete to form a chain. The state will eventually be consistent to a high degree of probability, but is still vulnerable to forks. For instance, it is recommended to consider Bitcoin transaction final when it is at least 6 blocks deep in the chain.
In Hyperledger Fabric, once a block is generated by the orderer, it becomes final. There are no alternatives. Thanks to the ordering service there is only one global history of transactions.
The design of public blockchains and its distributed nature effectively makes absolute finality impossible. There are some plans for Ethereum 2.0 to achieve it with blockchain state confirmation by dedicated nodes. However, even in this case the finality is going to happen for transactions that are deep enough in the chain.
This absolute finality of Hyperledger Fabric blockchain is very important for enterprise applications. For a critical data it is far better to immediately have consistent final state, rather than the state that after a given period of time will eventually be consistent to a high degree of probability.
Hyperledger Fabric uses optimistic locking to keep the state consistent in case of concurrent modifications. When the same key is read and saved (or saved several times) within the same block, only the first transaction is going to pass. The latter one(s) will fail with an error indicating concurrency control failure. This is a technical error that comes from application design, not from the business logic. Probably the latter transaction(s) should pass as well.
That introduces a significant complexity to the development of both client application and smart contract.
The client application must handle properly concurrent modifications. It should handle the technical errors properly, since they might have a negative impact on business logic — some transactions might be unintentionally skipped or executed in the wrong order. In some cases the client application should even be aware of what keys of the world state are supposed to be read and updated to avoid concurrent updates.
Consistency over latency
Typically the block may consist of tens or hundreds of transactions and creating the block may take even a few seconds. Besides, the validate phase is last in the transaction flow and only then the world state is changed.
The concurrency control mechanism shows how Hyperledger Fabric prefers consistency over latency. When there are many conflicting updates, the overall performance will dramatically decrease.
If your blockchain application does not require high throughput, you can just go with single-threaded process invoking smart contract once in a block. If you do so, it’s getting interesting. You may try to use a queue on the client side, batch smart contract invocations or redesign the smart contract to avoid concurrent modifications. Since there are many techniques that address this problem, I have described them in separate article series linked below.
Hyperledger Fabric performance is highly related with your smart contract design and the data model beneath.
Yes, it can handle hundreds, maybe even thousands of transactions per second and keep the strong consistency of the state, what is a good fit to your enterprise application. In this case, however, both the smart contract design and client application need a special care of experienced developers.
If you do implement chaincodes/smart contracts in Hyperledger Fabric and you face problems with concurrent modifications, you may be interested in my series about Concurrent smart contracts in Hyperledger Fabric blockchain (part 1, part 2, part 3).