At the heart of the Unity Consensus are the staking and stake delegation mechanisms, which are responsible for managing staker registrations and stake updates. In this article, I will walk you through the design considerations we’ve made and the implementation details. The source code is available at https://github.com/aionnetwork/protocol_contracts.
NOTE: This article is an overview of the current state of the Unity Protocol Contracts, which are still in their infancy stage and are constantly evolving.
Any Proof-of-Stake(PoS) based system needs a way of managing the stake state, i.e. the registered staker list and the amount of stake of each staker at any time. This piece of information decides the eligibility of a staker to produce a PoS block, and has to be agreed on by the whole network.
The stake management is traditionally implemented within the client (software that a node uses to connect to the network), using purpose-specific transaction types, with the utilization of databases or data storages. This is mainly due to the lack of programming capability above the protocol. The consequence of such a design is to make the protocol itself heavy and fat. As a result, it’s very difficult to implement such a system, given that there might be multiple clients in different programming languages.
In the Unity Consensus, we implement the staking and stake delegation mechanisms in AVM smart contracts. Such a design choice gives us two advantages:
First, let’s take a look at the staker registry contract, which is the endpoint to all users for participating in staking. A staker needs to be registered in this contract before it can produce a valid PoS block. A coin-holder can vote/unvote for a registered staker and even transfer stake between two stakers.
The internal structure of the staker registry is shown in the picture below. One staker registry is associated with a collection of registered stakers, pending unvotes and pending transfers. To understand the state/lifecycle of coins, I refer readers to the Section 2.4 of the Unity Engineering Specs. A copy of the coin state transition diagram is also attached below.
The staker registry contract is privileged, in a sense that the kernel depends on it for deciding the validity of a PoS block. Despite being privileged, this contract is designed to be simple and the kernel-contract interaction is limited to just one stateless method call (a stateless method call doesn’t change the state of a smart contract during execution). This method is getEffectiveStake(signingAddress, coinbaseAddress), which returns the effective stake of a block producer.
Anyone can register a staker by calling the registerStaker method of the staker registry, which has the following parameters.
Separating the stake of staker owner from the stake of other voters gives us additional benefits and flexibility. For example, we can then apply self-bond percentage requirement and min self-bond requirement.
Voting is the process of converting liquid coins into stake. To vote for a staker, a coin-holder needs to call the vote(staker) method, with a specific amount of coins being passed along. The coins will be in the custody of the staker registry contract after voting.
To revoke a stake and retrieve the coins, one needs to call the unvote(staker, amount) method, which will cancel the stake, lock it for a pre-defined period of time, i.e.UNVOTE_LOCK_UP_PERIOD, and return a unique PendingUnvote ID, if the request is valid. It’s only after the lock-up period that the user can really get its coins back, by calling the finalizeUnvote(id)method.
The staker registry also allows a voter to transfer stake from one staker to another. This allows voters to swap stake between block producers without going through an unvote-and-vote process, which would involve the unvote lockup period.
To transfer stake, one needs to call the transferStake(from, to, amount)method, which returns a PendingTransfer ID upon valid request. The user needs to call the finalizeTransfer(id) method to complete the stake transfer, after another lock-up period, i.e. TRANSFER_LOCK_UP_PERIOD.
While the staker registry is easy to interact with, many coin-holders would prefer to delegate their stake to a pool rather than to maintain a node and stake on their own. We call this group of people delegators. A pool receives stake from and re-distribute the block rewards to its delegators.
In the Unity Consensus, a decentralized stake delegation system, as in PoolRegistry smart contract, is designed and implemented. This is made possible by the following conditions:
Unlike staker registry, the pool registry is un-privileged and implemented purely based on the existing framework provided by AVM. An architectural view of the design is shown below.
At the very front is the PoolRegistry, which is the endpoint for all pool owners and delegators. For each registered pool, the registry maintains a PoolState , which is associated with one PoolCoinbase, one PoolCustodianand one PoolRewardsManager.
To register a pool, the owner needs to go through the following steps:
After these two steps, the pool can start accepting stakes from delegators, including the pool owner itself. As long as the min self-bond stake requirement is satisfied, the pool owner can use the signing key to produce blocks and earn block rewards.
An interesting implementation detail is that the registerPool method is convoluted. It creates a staker in the staker registry, instantiates a PoolCoinbase and aPoolCustodian, and configures the staker properly. This will ensure that all block rewards of the pool go to the pool registry.
To delegate stake to a pool, one just needs to call the delegate(pool)method along with some amount of AION coins to stake. The pool registry uses the received coin to stake in the staker registry.
Two steps are required to cancel a delegation. First, the delegator needs to call the undelegate(pool, amount) method of the pool registry, which will initiate an unvote operation and return a PendingUnvote ID. Second, it has to call the finalizeUnvote(id) method to finalize it after the unvote lock-up period.
Withdrawal is the process of claiming back the block rewards one delegator has earned so far. This is being done by calling the withdraw(pool) method, which will transfer the rewards to the delegator upon a valid request. For how the contract decides the block rewards, check the F1 fee distribution scheme.
Redelegation is the process of delegating to a pool using the earned block rewards from that pool. This is essentially a combination of withdraw and delegate.
Auto-redelegation enables one delegator to allow others to redelegate its block rewards. This is implemented by introducing an auto-redelegation market. If a delegator sets an auto-redelegation rate, then anyone can call the pool registry to auto-redelegate the delegator’s rewards on its behalf. The caller will get a portion of the rewards as incentives based on the auto-redelegation rate.
In case someone is interested in how the coins flow in the delegation system, an overview is provided below (boxes with shadow background are smart contract instances). Intuitively, all delegator’s stake and PoS block rewards are in the custody of the Pool Registry contract; all pool owner’s stake is in the custody of the Pool Custodian contract. If the coins are for delegation, then they flow to the Staker Registry.
Now, you’ve gone through an overview of the Unity staking and stake delegation contracts. If you want to learn more about the details, please read the Unity Engineer Spec or the smart contract source code.
백해연78 15 시간전
Community | 커뮤니티 예의는 지켜주세요 ♥
Community | [crypto cash] 크립토 캐시 그것이 알고싶다.
Community | 상장사 이름을 알려주세요
좋은정보 감사용 추천하고 갑니다 코로나 조심하시고 예수님 믿고 구원 받으세요
Community | [crypto cash] 크립토 캐시 그것이 알고싶다.
토큰뱅크 가입당시 휴대폰의 otp 를, 새로운 휴대폰으로 바꾼후 구글 otp다운로드후 사용 안되나요??? 지금 상황이 가입당시 휴대폰이 아니라서요;;
Community | otp인증
Write a post
Are you sure you want to delete this post?
Are you sure you want to delete this comment?
Purchase has been completed.
닉네임을 설정 후 작성해주세요.