internal override async ContractTask PostPersist(ApplicationEngine engine) { // Distribute VALT for committee int m = engine.ProtocolSettings.CommitteeMembersCount; int n = engine.ProtocolSettings.ValidatorsCount; int index = (int)(engine.PersistingBlock.Index % (uint)m); var valtPerBlock = GetValtPerBlock(engine.Snapshot); var committee = GetCommitteeFromCache(engine.Snapshot); var pubkey = committee.ElementAt(index).PublicKey; var account = Contract.CreateSignatureRedeemScript(pubkey).ToScriptHash(); await VALT.Mint(engine, account, valtPerBlock *CommitteeRewardRatio / 100, false); // Record the cumulative reward of the voters of committee if (ShouldRefreshCommittee(engine.PersistingBlock.Index, m)) { BigInteger voterRewardOfEachCommittee = valtPerBlock * VoterRewardRatio * 100000000L * m / (m + n) / 100; // Zoom in 100000000 times, and the final calculation should be divided 100000000L for (index = 0; index < committee.Count; index++) { var member = committee.ElementAt(index); var factor = index < n ? 2 : 1; // The `voter` rewards of validator will double than other committee's if (member.Votes > 0) { BigInteger voterSumRewardPerVauth = factor * voterRewardOfEachCommittee / member.Votes; StorageKey voterRewardKey = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(member.PublicKey).AddBigEndian(engine.PersistingBlock.Index + 1); byte[] border = CreateStorageKey(Prefix_VoterRewardPerCommittee).Add(member.PublicKey).ToArray(); (_, var item) = engine.Snapshot.FindRange(voterRewardKey.ToArray(), border, SeekDirection.Backward).FirstOrDefault(); voterSumRewardPerVauth += (item ?? BigInteger.Zero); engine.Snapshot.Add(voterRewardKey, new StorageItem(voterSumRewardPerVauth)); } } } }
private async ContractTask DistributeValt(ApplicationEngine engine, UInt160 account, VauthAccountState state) { // PersistingBlock is null when running under the debugger if (engine.PersistingBlock is null) { return; } BigInteger valt = CalculateBonus(engine.Snapshot, state.VoteTo, state.Balance, state.BalanceHeight, engine.PersistingBlock.Index); state.BalanceHeight = engine.PersistingBlock.Index; await VALT.Mint(engine, account, valt, true); }