Neo consensus mechanism from a programmer's perspective | Neo Column

Neo consensus mechanism from a programmer's perspective | Neo Column

Get the list of members

Neo network nodes are divided into two types, one is consensus node and the other is ordinary node. Compared with ordinary nodes, consensus nodes will participate in the consensus process and have the opportunity to become the speaker to preside over the generation of new blocks.

Next, I will introduce how to register a councillor through Neo's server through source code analysis. In the source code, the Reset method in ConsensusContext.cs is called at the beginning of each round of consensus. When resetting the consensus, Blockchain.Default.GetValidators() is called to obtain the councillor list. Follow the GetValidators() source code:

Source code location:

neo/Implementations/BlockChains/LevelDB/LevelDBBlockChain.cs

It is found that the internal GetValidators(IEnumerable<Transaction> others) method is called here. Let's look at this internal GetValidators method:

Source code location:

neo/Core/BlockChain.cs

I deleted all the code in the first foreach loop, because the others parameter passed in is obviously 0, so the code in the loop body will not have a chance to execute at all. The return value of this method is result, and its value data comes from two sources. The first is pubkeys. Pubkeys comes from the councillor information in the local cache. This information is saved when synchronizing the blockchain, that is, as long as the consensus node starts to access the blockchain network for block synchronization, the councillor information will be obtained. If the councillor information is not cached or the cached councillor information is lost, the built-in default councillor list will be used for consensus, and then the councillor information will be cached during the consensus process. The second way to use the built-in default councillor list is to directly read the data in the configuration file protocol.json into the StandbyValidators field.

Next, we will mainly introduce the first approach. The second line of the GetValidators method calls GetStates, and the type of the passed class is ValidatorState. This method is located in the LevelDBBlockChain.cs file. The complete code is as follows:

Source code location:

neo/Implementations/BlockChains/LevelDB/LevelDBBlockChain.cs

You can see that the councillor data is read directly from the leveldb database. That is, before reading the data, you need to create/open the database first. For this part of the operation, you can refer to the neo-cli project. This project passes the database address in the OnStart method of the MainService class. Of course, this is just to get the councillor information from the database. The work of storing the councillor information in the database is mainly done by the Persist(Block block) method in the LevelDBBlockChain.cs file. This method receives a block type as a parameter, and its main task is to parse and save the synchronized block information. The key code involving councillor information is as follows:

Source code location:

neo/Implementations/BlockChains/LevelDB/LevelDBBlockChain.cs/Persist

The obtained congressman account is added to the database cache by calling the GetAndChange method.

Determine the Speaker


The consensus node starts participating in the consensus by calling the Start method in the ConsensusService class. In the Start method, first register for event notifications such as message reception and data storage, and then call InitializeConsensus to start the consensus, receiving an integer parameter called "view number". When the incoming view number is 0, a new round of consensus needs to reset the consensus state. The code for resetting the consensus state is as follows:

Source code location:

neo/Consenus/ConsensusContext.cs

I added detailed comments in the code. The algorithm for determining the speaker is the current block height + 1 minus the current view number, and the result is modulo the current number of members. The result is the speaker's subscript. The member's own number is his position in the list of members. Because the order of this position is based on the weight of each member, in theory, the number of each member is consistent in all consensus nodes. In the consensus node, in addition to determining the speaker when the consensus is reset, the speaker is also re-determined every time the local view is updated:

Source code location:

neo/Consensus/ConsensusContex.cs

Speaker initiates consensus


After the speaker updates the view number, if the current time from the last time a new block was written exceeds the scheduled interval between each round of consensus (15s), a new round of consensus will be started immediately. Otherwise, the consensus will be initiated after the interval. The time control code is as follows:

Source code location:

neo/Consensus/ConsencusService.cs/InitializeConsensus

The function for the speaker to conduct consensus is OnTimeout, which is executed regularly by a timer. The following is the core code for the speaker to initiate consensus:

Source code location:

neo/Consencus/ConsensusService.cs/OnTimeOut

The speaker generates a new Header for the local transaction and signs it, then sends a PrepareRequest to broadcast this Header to the members in the network.

Members of Parliament Participate in Consensus


After receiving the PrepareRequest broadcast, the MP will trigger the OnPrepareReceived method:

Source code location:

neo/Consensus/ConsensusService.cs

After receiving the consensus request from the speaker, the congressman first uses the speaker's public key to verify the received consensus information. After verification, the speaker's signature is added to the signature list. Then the transaction in the speaker's Header transaction hash list is cached in memory and added to the context.

Here we need to talk about the AddTransaction method that adds transaction information from memory to the context. After each transaction is added, this method will compare whether the number of transactions in the current context is the same as the transaction hash number obtained from the speaker. If they are the same and the account holder's contract address is verified, it will broadcast its own signature to the network. The core code of this part is as follows:

Source code location:

neo/Consensus/ConsensusService.cs/AddTransaction

All members need to synchronize the signatures of each consensus node, so the member node also needs to monitor the responses of other nodes in the network to the speaker's consensus information and record the signature information. After each consensus response is monitored and the received signature information is recorded, the node needs to call the CheckSignatures method to determine whether the currently received signature information is legal. The CheckSignatures code is as follows:

Source code location:

neo/Consensus/ConsensusService.cs

The first thing in the CheckSignatures method is to determine the legitimacy of the current number of signatures. That is, the number of legal signatures obtained must be no less than M. The value of M is obtained in the ConsensusContext class:

The acquisition of this value involves the fault tolerance of the Neo consensus algorithm. The formula is ? = ⌊ (?−1) / 3 ⌋. In other words, as long as more than 2/3 of the consensus nodes in the network are consistent, the result is credible. In other words, as long as the number of signatures obtained is legal, the current node can generate a new block based on the existing information and broadcast it to the network.

View Update


The consensus interval of the Neo network is based on a timed task, rather than mathematically guaranteeing the approximate time of each block generation based on the computing power of the entire network. Each round of consensus is initiated by the currently selected speaker, but what if the currently selected speaker is malicious, if the speaker never initiates consensus or deliberately initiates wrong consensus information, resulting in the inability to complete this round of consensus?

In order to solve this problem, the concept of view was born. When a view life cycle is completed, if consensus has not been reached, the councillors will send a broadcast request to enter the next view cycle and re-elect the speaker. When the number of requests to update the view is greater than 2/3 of the number of councillors, the entire network reaches a consensus to enter the next view cycle and restart the consensus process. The speaker selection algorithm is related to the view number, which ensures that the speaker selected for each round of view will not be the same. The lifetime of a view is t*2^(view_number+1), where t is the default block generation time interval and view_number is the current view number. Councillors enter a view cycle numbered 0 at the beginning of each consensus. If consensus is not reached when the current cycle is completed, the view number is +1 and enters the next view cycle. The code that defines the view lifetime is in the InitializeConsensus method of the ConsensusServer class:

Source code location:

neo/Consensus/ConsensusService.cs/InitializeConsensus

When a round of view cycle is completed, if consensus is not reached, a request to update the view is issued:

Source code location:

neo/Consensus/ConsensusService.cs

Updating the view will increase the current expected view by 1, and broadcast the request to update the view to all councillors. It should be noted that after the current node sends the request to update the view, the current view number of the node does not change, but only the expected view number changes. After receiving the broadcast of the updated view, other councillors will trigger the OnChangeViewReceived method to update their own councillor expected view list.

Source code location:

neo/Consensus/ConsensusService.cs

After each view update request is received, it is necessary to check whether the number of requests currently received is greater than 2/3 of the total number of councillors. If the condition is met, the consensus process is restarted in the new view cycle.


<<:  About the difficulty reduction

>>:  An article to understand the history of mining difficulty adjustment: In 2010, the annual growth rate of difficulty reached 1224363%, and this year it is only 0.82%

Recommend

A mole on a woman's right waist indicates that she is good at financial management

What does a mole on a woman’s right waist mean? A...

Science 04 | The Origin of Bitcoin: Mining

How Bitcoin came about is very simple: either you...

Laughing and cursing about the cryptocurrency circle

The rising price of coins is a headache, and the ...

Are men with pointed chins and monkey cheeks unlucky?

Jianzuihouchai means pointed mouth and thin cheek...

Payment service company Qiwi plans to set up Russia's R3CEV

Rage Comment : Although Russian regulators are co...

Diagram of hanging nose

Hanging Nose Fortune Characteristics of a hanging...

What effect will natural curly hair have on men? No luck with love

Asians generally have straight hair, and only a s...

What does a business-minded person look like?

A person's facial features can tell us a lot ...

What kind of eyes are naturally ambiguous?

What kind of eyes are naturally ambiguous? In thi...