Development

GitHub metrics:

Developer activity (from Coinlib.io):

In this article, the team walks you through the Aion Unity Proof-of-Concept (PoC) implementation. If you haven’t heard about Aion Unity, read this “zero-to-hero” blog post.

The PoC comprises of four components:

A stake registry contract which manages the staker registration and handles stake/unstake requests,

A new block structure, along with a set of validation rules, to account for two block types — PoW blocks and PoS blocks,

A staking client, analogous to mining software, that eagerly generates PoS blocks when it is eligible to do so,

An implementation of the difficulty adjustment algorithm and fork choice rule.

The objective of the PoC is to validate the key metrics presented in the Aion Unity paper and to simulate different attack scenarios. The metrics studied include block time, block reward distribution, and orphaned block rate.

The PoC Implementation

Stake Registry Contract

The Stake Registry Contract is the smart contract that manages the staker registration and processes vote/unvote requests (a.k.a. stake/unstake respectively). Any coin-holder with a minimum balance is allowed to register as a staker to participate in Unity consensus. Others can vote or unvote for a registered staker. Liquid coins become locked stake after a vote operation, and return to being liquid after an unvote operation, subject a to lock-up period.

The source code of the stake registry contract is available here. Although the smart contract is written in Solidity, it will later be rewritten in Java, to run on the AVM. Also, the enforcement of minimum registration stake and the unvote lock-up period are not implemented in the PoC.

Extended Block Structure

In Aion Unity, the blockchain structure is a singly linked list of PoW blocks and PoS blocks, with no intervening requirement. To distinguish a PoS block from a PoW block, the team extended the original Aion block structure with additional fields. Specifically,

A sealType field is added to identify the block type;

For a PoW block, the seal field consists of a nonce and an EquiHash solution;

For a PoS block, the seal field consists of a seed and a signature of the block header from the staker.

The team has a new set of validation rules for PoS blocks, as follows:

Validate the block header using the existing PoW validators, but skip the seal field validation. Validate that the seed is a valid ED25519 signature of the seed of the previous PoS block, and recover the signer’s address (let’s call it signer1). Validate that the signature is a valid ED25519 signature of the block header, and recover the signer’s address (let call it signer2). Validate that signer1 and signer2 are equal. Look up the signer’s stake from the state database and compute the PoS block generation delay. Validate that the delay is lesser than or equal to the duration between this PoS block and the previous PoS block.

Staking Client

To generate a PoS block, a staker needs to actively look up its stake and compute the block generation delay. When it’s eligible to generate a block, it creates a block template and signs it.

They call the software that performs this lookup, waiting, and block production a staking client. It needs to be able to:

Manage the staker’s private key,

Check the PoS block generation delay by communicating with a full synced node,

Sign block templates created by the node.

The full PoC implementation of a staking client is available here.

Fork Choice Rule

Aion Unity uses a different choice rule to deal with forks on the network. It always selects the chain with the highest product of total mining difficulty and total staking difficulty. The total mining difficulty is simply the sum of the difficulties of all the PoW blocks on the chain; the total staking difficulty is that of the PoS blocks.

The way the fork choice rule is implemented in the PoC is to keep track of the total mining and staking difficulties of each block. When a new block is imported, either the total mining difficulty or staking difficulty is updated, as appropriate.

Difficulty Adjustment Algorithm

To maintain a targeted block time, the difficulty should be adjusted dynamically as miners and stakers join and leave. The mining/staking difficulty increases if the block time is too small, and decreases if the the block time is too large. Check here for the PoC implementation.

The PoC Results

Key Metrics

To test how the PoC implementation works, the team sets up the following cluster:

8 nodes connected via an intranet;

4 of them are mining (1 Nvidia GPU each);

The other 4 nodes are staking (1000, 2000, 3000, 4000 nAmp respectively).

They let the network run for 2500 blocks, and then calculated the following statistics:

Block time statistics between block #500 and block #2500

Orphaned blocks between block #500 and block #2500

The mining difficulty over time

The staking difficulty over time

Block reward distribution

By analyzing the collected data, the team found that the key metrics for the PoC implementation match what has been presented in the Unity paper:

The average block time is very close to the targeted 10 seconds;

The difficulty adjusts from 1 to the right level within 200 blocks, with the given network configuration;

The number of PoS blocks and PoW blocks are roughly the same;

The block rewards of a miner are proportional to the mining hashrate, while the block rewards of a staker are proportional to the amount of stake.

Network Partition Attack

In this experiment, they assessed the ability of the network to recover from a period of broken connectivity. To test it, the team partitioned a cluster into two groups for a period of time, and then rejoined them.

By observing the weight growths of the chains of the two partitions, they found that both partitions could progress independently. When the connectivity issue was resolved, the network chose the chain with a higher weight. The experiment helped them identify some syncing issues in the kernel implementation, which were fixed.