Staking Manager

Introduction

We are enhancing the VideoCoin Network with a major feature called DPoS (Distributed Proof of Stake) that mitigates the risk of opening up the Network to third party(untrusted) Worker nodes. DPoS prompts the participation of the VideoCoin token holders in securing the Network by selecting and backing the Worker nodes which result in ranking these nodes. This makes the Network dynamic and secure by making all the stakeholders of the Network to actively participate and get rewarded.

DPoS has already successfully been used in several Blockchains such as Cosmos Hub, EoS and Tezos with some variations. It is mostly used to secure the Block producers in these Networks. In VideoCoin we are using this algorithm to ensure the fault-free operation of the Worker nodes.

What is Proof of Stake and why do we need it on VideoCoin network?

The work outsourced to Worker nodes is being verified and rewarded by the Network. A Worker node may fault either a due to compute resources falling below commitment or with an intention to attack Network. Both these issues can be avoided, if the Worker node is required to stake an amount proportionally very high compared to the rewards and it will lose a portion of the amount.

Delegated Proof of Stake and Securing the Network

New Worker nodes joining the network may not have enough VIDs to stake to get the work. Delegated Proof of Stake allows any VID holders to delegate their tokens to a Worker node. These delegations will be rewarded with a portion of the rewards that Worker node receives. It also has an associated risk of losing portion of the delegated amount, if the worker faults. But the overall dynamics of the delegation and associated rewards/losses will result in ranking the worker nodes based on the amount of delegations received. This ranking can be further supplemented with reputation metrics based on the work history and wattage capacity. This creates an environment where worker nodes will be competing for higher ranking in order to receive more work, which in turn results in a secure Network of well behaving worker nodes.

Core Components of VideoCoin DPoS

Staking Manager

VideoCoin Network uses a Staking Manager that maintains an on-chain database of all the Worker Nodes, Delegators and their delegations. This database also maintains information related to worker's capacity and work history that helps in ranking the worker.

A Worker node is required to self-stake some minimum VIDs as well as secure a minimum total stake that can come from other VID holders in the Network called delegators . The Worker also needs to wait a certain amount of period before obtaining the work.

Any VID holders can become delegators and choose a Worker node for delegation. Delegations are bonded to the worker and a certain time period has to elapse while withdrawing the delegation.

Slashing

When a Worker node is faulted, some portion of the the stake(self+delegated) is slashed and transferred to a Network Maintenance pool account. Slashing may occur due to either failure to submit proof-of-transcode, or failed proof-verification. It also may occur due to unavailability of the miner to perform the transcode mining when in bonded state.

Reward Distribution

Worker nodes earn rewards for the work. However, some percentage of the reward amount is distributed to delegators (including self) in proportion to amounts being delegated. Reward amounts can be withdrawn immediately and are not included in slashing.

Worker State

After transcoder registered it can be in one of the four states:

  • BONDING

  • BONDED

  • UNBONDING

  • UNBONDED

Contract variables:

  • transcoderApprovalPeriod. Should pass after registration to enter BONDED state. This time can be used to run tests for transcodeer.

  • unbondingPeriod. After delegator (including transcoder) made withdrawal request this amount of time should pass for request to become withdrawable. During this time funds still can be slashed.

  • minSelfStake. Required funds that transcoder should lock in the contract to become BONDED.

  • minDelegation. Minimum amount of delegated funds that will be accepted.

BONDING

After transcoder registered it should wait for transcoderApprovalPeriod. During this time transcoder can accept delegations from any other delegator, and transcoder must stake minSelfStake funds.

Once two conditions are satisfied transcoder becomes bonded.

If transcoder wishes to withdraw funds while BONDING funds will be transfered immediatly.

BONDED

BONDED transcoder is eligible for work and rewards. In current implementaton transcoder selection is performed offchain, using information stored in staking contract.

If BONDED transcoder wishes to withdraw funds it must wait for unbondingPeriod. If after withdrawal transcoder has less than minSelfStake transcoder enters UNBONDING state.

Also while BONDED - transcoder can be slashed/jailed and become UNBONDED.

UNBONDING

This state is required to prevent transcoder from manipulating stake in such way that will allow to withdraw large part of it without waiting for unbondingPeriod.

Example that was possible before introducing UNBONDING:

  • transcoder BONDED with stake 100 vid (min self stake)

  • transcoder tries to withdraw 1 vid. Withdraw protected with unbondingPeriod. Enters BONDING state.

  • transcoder withdraws the rest (99 vid), while in BONDING state funds trasnferred immediatly.

Transcoder in UNBONDING can be slashed and enter UNBONDED state. If unbondingPeriod passes for requested withdrawal transcoder enters BONDING state.

UNBONDED

In current implementation this state is used exclusively for slashed/jailed transcoders. The only way to leave this state is for the contract owner to unjail transcoder.

In such case transcoder enters BONDING, or BONDED if stake is larger than minSelfStake.

To become a transcoder you need to stake a minimal amount required. Transcoder is bonded if approval period passes and self stake is higher than minimum stake. Transcoders and delegators can withdraw stake after a set amount of time.

API

setSelfMinStake

Setter for minimum self-stake, i.e. bonding treshold.

Input/Output

Data Type

Variable Name

Comment

input

uint256

amount

minimum self stake amount

setApprovalPeriod

Setter for approval period

Input/Output

Data Type

Variable Name

Comment

input

uint256

period

aproval period in seconds

setZone

Setter for trancoder zone.

Input/Output

Data Type

Variable Name

Comment

input

address

addr

transcoder address

input

uint256

zone

zone id

setSlashFundAddress

Can be 0x0

Setter for slash pool address.

Input/Output

Data Type

Variable Name

Comment

input

address

addr

new slash pool address

setCapacity

Setter for trancoder capacity.

Input/Output

Data Type

Variable Name

Comment

input

address

addr

transcoder address

input

uint256

capacity

transcoder capacity in uwatt

registerTranscoder

rate parameter not used for now

Method to register as transcoder.

Input/Output

Data Type

Variable Name

Comment

input

uint256

rate

Percentage of rewards that the transcoder will share with delegators

delegate

Needs to send minimal delegation amount.

Delegate tokens to a transcoder. Transcoders will call this to self-delegate.

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

Transcoder address.

requestUnbonding

Requests get approved immediately if tcoder`s state is BONDING or UNBONDED

Delegator requests stake unbonding. Delegator has to wait for unbondingPeriod before calling withdrawStake() with the returned ID.

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address from which to unbond

input

uint256

amount

amount to unbond

output

uint256

N/A

N/A

withdrawPending

Callable by both tcoders & delegators. Delegators can also withdraw no matter what the tcoder state is if they made an unbonding requested and the wait period passed. If transfer cannot be withdrawn transaction will fail.

Withdraw first pending unbonding request.

withdrawAllPending

Callable by both tcoders & delegators. Delegators can also withdraw no matter what the tcoder state is if they made an unbonding requested and the wait period passed. Silently returns if there are no pending transfers that can be withdrawn.

Withdraw all pending unbonding requests.

pendingWithdrawalsExist

Query state if there are any pending withdrawals ready to be executed.

Input/Output

Data Type

Variable Name

Comment

output

bool

N/A

N/A

withdrawStake

Callable by both tcoders & delegators. Delegators can also withdraw no matter what the tcoder state is if they made an unbonding requested and the wait period passed.

Withdraw stake in transcoder.

Input/Output

Data Type

Variable Name

Comment

input

uint256

unbondingID

ID of unbonding request

output

bool

N/A

N/A

getUnbondingRequest

If the request does not exist all the fields will be 0

Getter for unbonding requests

Input/Output

Data Type

Variable Name

Comment

input

address

delegatorAddr

delegator address

input

uint256

unbondingID

unbonding request ID for which to rebond

output

undefined

N/A

N/A

slash

Callable only by a staking manager. Increments the slash counter for lazy slashing of delegators. Transcoder total stake is slashed when method is called. Actual delegator stake values are updated lazily when withdraw, delegate or unbond are called.

Slash the transcoder stake including it`s delegators.

Input/Output

Data Type

Variable Name

Comment

input

address

addr

transcoder address

output

bool

N/A

N/A

applySlash

Lazy slash for delegators stakes. Callable from anywhere; if conditions are met it will execute. Applied during bonding or unbonding.

Applies slashing.

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

input

address

delegatorAddr

delegator address

getSlashableAmount

Used for lazy slash for delegators stakes and to compute the real bonded value of the stake

Returns ammount that is up for slashing of a delegator`s stake.

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

input

address

delegatorAddr

delegator address

output

uint256

N/A

N/A

jail

Called when slashing

Jail a transcoder.

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

unjail

Unjail a transcoder.

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

getTotalStake

Get total amount staked for a transcoder

Input/Output

Data Type

Variable Name

Comment

input

address

_addr

transcoder address

output

uint256

N/A

N/A

getSelfStake

Get transcoder self-stake

Input/Output

Data Type

Variable Name

Comment

input

address

_addr

transcoder address

output

uint256

N/A

N/A

getDelegatorStake

Get delegator stake in a transcoder

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

input

address

delegAddr

delegator address

output

uint256

N/A

N/A

getTrancoderSlashes

Get number of slashes applied to a transcoder

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

output

uint256

N/A

N/A

transcodersCount

Get number of registered transcoders. *

Input/Output

Data Type

Variable Name

Comment

output

uint256

N/A

N/A

getTranscoderState

Used by miner sleection, slashing, rewards. enum TranscoderState { BONDING, BONDED, UNBONDED }

Get the transcoder state

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

output

undefined

N/A

N/A

isJailed

Gettter for jailed state

Input/Output

Data Type

Variable Name

Comment

input

address

transcoderAddr

transcoder address

output

bool

N/A

N/A