IBM HyperLedger fabric overview

IBM HyperLedger fabric overview

In my opinion, Bitcoin is the real-life V for Vendetta. Of course, the reality is a more cruel world government. This game concerns human civilization, politics, social attributes, economy and human rights.

IBM Hyperledger is also called fabric. You can think of it as a super ledger maintained by the whole society. There is no central authority holding power. Every transaction you make is open and secure to the whole network, and the credit is witnessed by the whole society. Its relationship with Bitcoin is that you can use fabric to build an application called Bitcoin to help you change the world.

The vision is so awesome, and it seems to be just what we want to change the world. However, we are always naive in front of the cruel reality and the world. Blockchain needs to build its grand blueprint step by step. At least there is no case of using it in industrial production and national economy.

Fabric originated from IBM. The original intention was to serve industrial production. IBM made 44,000 lines of code open source, which is a great contribution. It gives us the opportunity to explore the principles of blockchain so closely. But after all, IBM is based on its own interests and the interests of its customers. It is not doing this public welfare without purpose. When we look at fabric, we must have a prudent mindset: blockchain does not have to be like this. What is the most essential non-technical difference between it and Bitcoin? Let's first take a general look at the key terms of fabric (because some words are more accurate in English, I will not translate them).

1. Terminology

  • Transaction它一条request,用来在ledger上执行一个function,这个function是用chaincode来实现的

  • Transactor发出transaction的实体,比如它可能是一个客户端应用

  • Ledger Legder可以理解为一串经过加密的block链条,每一个block包含着transactions和当前world state等信息

  • World State world state是一组变量的集合,包含着transactions的执行结果

  • Chaincode这是一段应用层面的代码(又叫smart contract,智能合约),它存储在ledger上,作为transaction的一部分。也就是说chaincode来运行transaction,然后运行结果可能会修改world state

  • 参与者之一,它是一种在网络里负责执行一致性协议、确认交易和维护账本的计算机节点

  • Nonvalidating Peer它相当于一个代理节点,用来连接transactor和邻近的VP(Validating Peer)节点。一个NVP节点不会去执行transactions但是回去验证它们。同时它也会承担起事件流server和提供REST services的角色

  • Permissioned Ledger这是一个要求每一个实体和节点都要成为网络成员的blockchain网络,所有匿名节点都不被允许连接

  • Privacy用来保护和隐蔽chain transactors的身份,当网络成员要检查交易时,如果没有特权的话,是无法追踪到交易的transactor

  • 这个特性使得交易内容不是对所有人可见,只开放给利益相关者

  • Auditability:将blockchain用于商业用途需要遵守规则,方便监管者调查交易记录


2. Architecture

There are three core logics of the architecture: Membership, Blockchain and Chaincode.

2.1 Membership Services

This service is used to manage node identity, privacy, confidentiality and auditability. In a non-permissioned blockchain network, participants do not require authorization, and all nodes are treated the same and can submit a transaction and store these transactions in blocks. The Membership Service is to transform a non-permissioned blockchain network into a permissioned blockchain network, relying on Public Key Infrastructure (PKI), decentralization and consistency.

2.2 Blockchain Services

Blockchain services use a P2P protocol built on HTTP/2 to manage distributed ledgers. Provide the most efficient hashing algorithm to maintain a copy of the world state. Take a pluggable approach to set consensus protocols according to specific needs, such as PBFT, Raft, PoW, PoS, etc.

2.3 Chaincode Services

Chaincode services will provide a safe and lightweight sandbox operation mode to execute chaincode logic on VP nodes. Here, a container environment is used, and the base images in it are all signature-verified secure images, including the OS layer and the language, runtime, and SDK layer for developing chaincode. Currently, Go, Jave, and Nodejs development languages ​​are supported.

2.4 Events

In the blockchain network, VP nodes and chaincodes will send events to trigger some monitoring actions. For example, chaincode is user code, which can generate user events.

2.5 API and CLI

Provides REST APIs that allow registering users, querying the blockchain, and sending transactions. Some chaincode-specific APIs can be used to execute transactions and query transaction results. For developers, CLI can be used to quickly test chaincode or query transaction status.


3. Topology The topology of distributed networks is very worth studying. In this world, there are many participants, different roles, different interest groups, and various situations. The handling of various situations symbolizes the rules and laws in the distributed network. There is no order without rules. In the blockchain network, there are Membership services, VP nodes, NVP nodes, and one or more applications. They form a chain, and then there will be multiple chains, each of which has its own security requirements and operational requirements.

3.1 Single VP Node Network

The simplest network contains only one VP node, so the consensus part is omitted.

3.2 Multiple VP Node Networks

A network with multiple VPs and NVPs is valuable and meaningful. NVP nodes share the workload of VP nodes and handle API requests and events.

As for VP nodes, a mesh network is formed between VP nodes to propagate information. An NVP node can be connected to a neighboring VP node if allowed. NVP nodes can be omitted if the application can communicate directly with the VP node.

3.3 Multichain

There will also be situations where there are multiple chains in a network, and the intentions of each chain are different.


4. Protocol

Fabric uses gRPC for P2P communication, which is a two-way stream message transmission. Protocol Buffer is used to serialize the data structure to be transmitted.

4.1 Message

There are four types of messages: Discovery, Transaction, Synchronization and Consensus. Each type of message contains more sub-messages, which are indicated by the payload.

The payload is an opaque byte array that contains some objects, such as Transaction or Response. For example, if type is CHAIN_TRANSACTION, then the payload is a Transaction object.

 message Message {
enum Type {
UNDEFINED = 0;

DISC_HELLO = 1;
DISC_DISCONNECT = 2;
DISC_GET_PEERS = 3;
DISC_PEERS = 4;
DISC_NEWMSG = 5;

CHAIN_STATUS = 6;
        CHAIN_TRANSACTION = 7;
        CHAIN_GET_TRANSACTIONS = 8;
CHAIN_QUERY = 9;

SYNC_GET_BLOCKS = 11;
SYNC_BLOCKS = 12;
        SYNC_BLOCK_ADDED = 13;

        SYNC_STATE_GET_SNAPSHOT = 14;
        SYNC_STATE_SNAPSHOT = 15;
        SYNC_STATE_GET_DELTAS = 16;
        SYNC_STATE_DELTAS = 17;

RESPONSE = 20;
CONSENSUS = 21;
}
Type type = 1;
bytes payload = 2;
    google.protobuf.Timestamp timestamp = 3;
}

4.1.1 Discovery Messages

A newly started node, if CORE_PEER_DISCOVERY_ROOTNODE (ROOTNODE refers to the IP of any other node in the network) is specified, it will start running the discovery protocol. ROOTNODE is the first discovery node, and then all nodes in the entire network are discovered through the ROOTNODE node. The discovery protocol message is DISC_HELLO, and its payload is a HelloMessage object, which also contains the information of the node sending the message:

 message HelloMessage {
  PeerEndpoint peerEndpoint = 1;
uint64 blockNumber = 2;
}
message PeerEndpoint {
PeerID ID = 1;
string address = 2;
enum Type {
UNDEFINED = 0;
VALIDATOR = 1;
NON_VALIDATOR = 2;
}
Type type = 3;
bytes pkiID = 4;
}

message PeerID {
string name = 1;
}

If a node receives a DISC_HELLO message and finds that the block height in it is higher than its current block height, it will immediately send a synchronization protocol to synchronize its status with the entire network (mark: but this synchronization logic does not seem to be implemented at the source code level).

After the newly joined node completes the DISC_HELLO message transmission, it will periodically send DISC_GET_PEERS to discover other nodes that have joined the network. In response to DISC_GET_PEERS, a node will send DISC_PEERS.

4.1.2 Synchronization Messages

The Synchronization protocol starts with the discovery protocol mentioned above. When a node finds that the state of its block is inconsistent with other nodes, it will trigger synchronization. The node will broadcast three types of information: SYNC_GET_BLOCKS, SYNC_STATE_GET_SNAPSHOT or
SYNC_STATE_GET_DELTAS, and correspondingly receives three kinds of information: SYNC_BLOCKS, SYNC_STATE_SNAPSHOT or SYNC_STATE_DELTAS.

The consensus algorithm currently embedded in fabric is pbft.

SYNC_GET_BLOCKS will request a series of consecutive blocks, and the payload in the data structure sent will be a SyncBlockRange object.

 message SyncBlockRange {
uint64 correlationId = 1;
uint64 start = 2;
uint64 end = 3;
}

The receiving node will reply with SYNC_BLOCKS, whose payload is a SyncBlocks object:

 message SyncBlocks {
SyncBlockRange range = 1;
    repeated Block blocks = 2;
}

start and end represent the starting and ending blocks. For example, start=3, end=5 represents block 3,4,5; start=5, end=3 represents block 5,4,3.

SYNC_STATE_GET_SNAPSHOT requests a snapshot of the current world state. The payload of this information is a SyncStateSnapshotRequest object:

 message SyncStateSnapshotRequest {
uint64 correlationId = 1;
}

The correlationId is used by the requesting peer to track the corresponding reply to the message. The peer that receives the message will reply with SYNC_STATE_SNAPSHOT, whose payload is a SyncStateSnapshot object:

 message SyncStateSnapshot {
bytes delta = 1;
uint64 sequence = 2;
uint64 blockNumber = 3;
    SyncStateSnapshotRequest request = 4;
}SYNC_STATE_GET_DELTAS By default, the Ledger will contain 500 transition deltas. delta(j) represents the state transition between block(i) and block(j) (i = j -1).
  • SYNC_STATE_GET_DELTAS By default, the Ledger will contain 500 transition deltas. delta(j) represents the state transition between block(i) and block(j) (i = j -1).

4.1.3 Consensus Messages

The consensus framework will convert the received CHAIN_TRANSACTION into CONSENSUS and then broadcast it to all VP nodes.

4.1.4 Transaction Messages

There are three types of transactions in fabric: Deploy, Invoke and Query. Deploy installs the specified chaincode to the chain, and Invoke and Query call the functions of the deployed chaincode.

4.2 Ledger

Ledger mainly consists of two parts: blockchain and world state. Blockchain is a series of connected blocks used to record historical transactions. World state is a key-value database. When the transaction is executed, the chaincode will store the state in it.

4.2.1 Blockchain

A blockchain is a list of blocks, each containing the hash of the previous block. A block also contains a list of transactions and a hash of the world state after all these transactions are executed.

 message Block {
version = 1;
  google.protobuf.Timestamp timestamp = 2;
bytes transactionsHash = 3;
bytes stateHash = 4;
  bytes previousBlockHash = 5;
  bytes consensusMetadata = 6;
  NonHashData nonHashData = 7;
}

message BlockTransactions {
  repeated transactions = 1;
}

How is the hash of the previous block calculated?

  • Use protocol buffer to serialize block information

  • Use the SHA3 SHAKE256 algorithm to hash the serialized block information into a 512-byte output

In the above data structure, there is a transactionHash, which is the root node of the transaction Merkle tree (using Merkle tree to describe these transactions).

4.2.2 World State

The world state of a peer is the collection of states of all deployed chaincodes. The state of a chaincode is described by a collection of key-value pairs. We expect nodes in the network to have consistent world states, so we will compare them by calculating the crypto-hash of the world state, but this will consume expensive computing power. For this reason, we need to design an efficient calculation method. For example, we can introduce Bucket-tree to implement the organization of the world state.

The key in the world state is represented as {chaincodeID, ckey}. We can describe the key as follows: key = chaincodeID+nil+cKey.

The key-value of the world state will be stored in a hash table, which consists of a predefined number (numBuckets) of buckets. A hash function will define which bucket contains which key. These buckets will serve as leaf nodes of the merkle-tree, and the bucket with the smallest number will serve as the leftmost leaf node of the merkle-tree. The second-to-last layer is constructed by grouping together maxGroupingAtEachLevel (predefined number) leaf nodes from the left to form N groups. A node will be inserted into each group as the parent node of the leaf nodes it contains, thus forming the second-to-last layer. It should be noted that the parent node of the last layer (the inserted node just described) may have fewer than maxGroupingAtEachLevel child nodes. Continue to build higher layers in this way until the root node is built.

For example, {numBuckets=10009 and maxGroupingAtEachLevel=10}, the number of nodes in the tree it forms each time is as follows:

Level Number of nodes
0 1
1 2
2 11
3 101
4 1001
5 10009

4.3 Consensus Framework

The consensus framework consists of three packages: consensus, controller and helper.

  • consensus.Communicator is used to send messages to other VP nodes

  • onsensus.Executor is used to start, execute and rollback transactions, as well as preview and commit

  • The controller specifies the consensus plugin used by the VP node.

  • Helper is used to help consensus plugin interact with the stack, such as maintaining the message handler

There are currently two consensus plugins: pbft and noops.
pbft is an implementation of the PBFT consensus algorithm from Microsoft's paper.
Noops is used for development and testing. It has no consensus mechanism, but it handles all consensus messages. So if you want to develop your own consensus plugin, start with it.


5. Implementation and contribution

Implement SYNC_BLOCK_ADDED handler

One of my colleagues implemented a handler for the SYNC_BLOCK_ADDED message so that in noops consensus mode, when a block is added to the (mined/added) ledger, the NVP node can process the message and store the newly added block in its own ledger.

The callback corresponding to the SYNC_BLOCK_ADDED message is beforeBlockAdded (core/peer/handler.go). The official code is as follows:

 func (d *Handler) beforeBlockAdded(e *fsm.Event) {
    peerLogger.Debugf("Received message: %s", e.Event)
    msg, ok := e.Args[0].(*pb.Message)
if !ok {
        e.Cancel(fmt.Errorf("Received unexpected message type"))
return
}
    // Add the block and any delta state to the ledger
_ = msg
}There is no way to obtain and process the block information here, we need to add the following:
 + if ValidatorEnabled() {
+ e.Cancel(fmt.Errorf("VP shouldn't receive SYNC_BLOCK_ADDED"))
+ return
+ }
    // Add the block and any delta state to the ledger
- _ = msg
+ blockState := &pb.BlockState{}
+ err := proto.Unmarshal(msg.Payload, blockState)
+ if err != nil {
+ e.Cancel(fmt.Errorf("Error unmarshalling BlockState: %s", err))
+ return
+ }
+ coord := d.Coordinator
+ blockHeight := coord.GetBlockchainSize()
+ if blockHeight <= 0 {
+ e.Cancel(fmt.Errorf("No genesis block is made"))
+ return
+ }
+ curBlock, err := coord.GetBlockByNumber(blockHeight -1)
+ if err != nil {
+ e.Cancel(fmt.Errorf("Error fetching block #%d, %s", blockHeight -1, err))
+ return
+ }
+ hash, err := curBlock.GetHash()
+ if err != nil {
+ e.Cancel(fmt.Errorf("Error hashing latest block"))
+ return
+ }
+ if bytes.Compare(hash, blockState.Block.PreviousBlockHash) != 0 {
+ e.Cancel(fmt.Errorf("PreviousBlockHash of received block doesnot match hash of current block"))
+ return
+ }
+ coord.PutBlock(blockHeight, blockState.Block)
+ delta := &statemgmt.StateDelta{}
+ if err := delta.Unmarshal(blockState.StateDelta); nil != err {
+ e.Cancel(fmt.Errorf("Received a corrupt state delta"))
+ return
+ }
+ coord.ApplyStateDelta(msg, delta)
+ if coord.CommitStateDelta(msg) != nil {
+ e.Cancel(fmt.Errorf("Played state forward, hashes matched, but failed to commit, invalidated state"))
+ return
+ }
+ peerLogger.Infof("Blockchain height grows into %d", coord.GetBlockchainSize())

Enable statetransfer for HELLO message

We also found that when an NVP node just joins the network, it will send a DISC_HELLO message, and then receive a DISC_HELLO message containing the blockchain information of that node from other nodes, but the official code does not provide the implementation of NVP synchronizing its own status based on these returned information. When NVP is implementing its own status synchronization in the network, a new block is mined, but NVP cannot add this new block to its own chain. So now there is a tricky situation: when a new NVP node just joins the network, it obtains the blockchain information of other nodes through the HELLO message to start synchronizing its own status, which will definitely take some time to complete, but at the same time, transactions in the network are still continuing, and new blocks will be continuously mined. Although NVP can receive SYNC_BLOCK_ADDED and has a handler to process it, it cannot add the new block information to its own chain at this time because the hash does not match. After all, the NVP node has not completed the initial synchronization.


<<:  Blockchain Credit: The Second Law of Thermodynamics of Transactions

>>:  Fintech startup Revolut raises €7.75 million to enable zero-fee overseas transactions

Recommend

What kind of woman should not be married?

Some women can bring prosperity to the husband an...

What are the special palm lines?

What are the special palm lines? 1. Termination l...

I have never been interested in internet celebrities.

Nowadays, Internet celebrities have become ubiqui...

What is the most blessed face for a girl? This face is the most blessed

1. What is the most blessed facial features for g...

How to tell how many children you will have by looking at your palm lines

In fact, God has already arranged our fortune in ...

Fan-ear facial features

Fan-eared people lose money Characteristics of fa...

Woman with phoenix eyes

Woman with phoenix eyes Women's phoenix eyes ...

What kind of man is most likely to be rich?

Physiognomy: What kind of man is most likely to b...

R3 announces eight core areas of blockchain technology testing

R3 reviewed eight major areas of blockchain resea...

Is it accurate to tell fortune by looking at eyebrows?

Is eyebrow fortune telling accurate? Eyebrows are...

Where do moles that bring good fortune to husbands usually grow?

Everyone hopes to grow old together with the pers...