loomnetwork / loomchain

Loom DAppChain Engine
Other
166 stars 32 forks source link

Create runtime invariant for checking dpos accounting #1044

Open aupiff opened 5 years ago

aupiff commented 5 years ago

We'll use an invariant like the one suggested by ToB:

currentBalance + state.TotalRewardDistribution + state.TotalReferrerRewards
= initialBalance + currentTotalDelegations

where:
- currentBalance isthecurrentbalanceoftheDPoSv3contract,
- state.TotalRewardDistribution isthetotalrewardspaidtoalldelegators,
- state.TotalReferrerRewards isthetotalrewardspaidtoallreferrers(thisisafield
that we added to the s  tate ),
- initialBalance istheinitialbalanceoftheDPoSv3contract,and
- currentTotalDelegations isthesumofthevaluesofallcurrentdelegations(thisis
a value that we calculate) .

The problem with this invariant is that money can be credited to the dpos contract whenever so the invariant breaks when we top off to be able to satisfy the rewards contributions.

I'm going to start by writing smaller, easy-to-understand invariants related to delegation totals & rewards.

aupiff commented 5 years ago

first useful invariant:

sum(statistic.WhitelistAmount) + sum(delegation.Amount) = sum(statistic.TotalDelegation)

aupiff commented 5 years ago

We can include the invariant check in the existing GetState call & also create a function that is called every BEGIN BLOCK which reports on any broken invariants via error logs. (I'm not sure if halting the chain is the best idea, but that's also an option when a broken invariant is found).

aupiff commented 5 years ago

IF we do want to use REWARDS & CURRENT_DPOS_CONTRACT_BALANCE as part of an invariant in the future, we'll have to register all transfers of tokens to the contract (for rewards payouts) so that this can go into the contract's book-keeping. This can be achieved by approving transfers to DPOS CONTRACT from some rewards fund, and then calling an oracle-only function to take in new funds for rewards. Using such an invariant would require making this change & making reward distribution precise (we store a slight overestimate currently)--this is an involved change and will not be done in the initial release of dposv3.