예제 #1
0
        private bool VerifyAccountState()
        {
            switch (Field)
            {
            case "Votes":
                if (Blockchain.Default == null)
                {
                    return(false);
                }
                ECPoint[] pubkeys;
                try
                {
                    pubkeys = Value.AsSerializableArray <ECPoint>((int)Blockchain.MaxValidators);
                }
                catch (FormatException)
                {
                    return(false);
                }
                UInt160      hash    = new UInt160(Key);
                AccountState account = Blockchain.Default.GetAccountState(hash);
                if (account?.IsFrozen != false)
                {
                    return(false);
                }
                if (pubkeys.Length > 0)
                {
                    if (account.GetBalance(Blockchain.GoverningToken.Hash).Equals(Fixed8.Zero))
                    {
                        return(false);
                    }
                    HashSet <ECPoint> sv = new HashSet <ECPoint>(Blockchain.StandbyValidators);
                    DataCache <ECPoint, ValidatorState> validators = Blockchain.Default.GetStates <ECPoint, ValidatorState>();
                    foreach (ECPoint pubkey in pubkeys)
                    {
                        if (!sv.Contains(pubkey) && validators.TryGet(pubkey)?.Registered != true)
                        {
                            return(false);
                        }
                    }
                }
                return(true);

            default:
                return(false);
            }
        }
예제 #2
0
        protected void ProcessAccountStateDescriptor(StateDescriptor descriptor, DataCache <UInt160, AccountState> accounts, DataCache <ECPoint, ValidatorState> validators, MetaDataCache <ValidatorsCountState> validators_count)
        {
            UInt160      hash    = new UInt160(descriptor.Key);
            AccountState account = accounts.GetAndChange(hash, () => new AccountState(hash));

            switch (descriptor.Field)
            {
            case "Votes":
                Fixed8 balance = account.GetBalance(GoverningToken.Hash);
                foreach (ECPoint pubkey in account.Votes)
                {
                    ValidatorState validator = validators.GetAndChange(pubkey);
                    validator.Votes -= balance;
                    if (!validator.Registered && validator.Votes.Equals(Fixed8.Zero))
                    {
                        validators.Delete(pubkey);
                    }
                }
                ECPoint[] votes = descriptor.Value.AsSerializableArray <ECPoint>().Distinct().ToArray();
                if (votes.Length != account.Votes.Length)
                {
                    ValidatorsCountState count_state = validators_count.GetAndChange();
                    if (account.Votes.Length > 0)
                    {
                        count_state.Votes[account.Votes.Length - 1] -= balance;
                    }
                    if (votes.Length > 0)
                    {
                        count_state.Votes[votes.Length - 1] += balance;
                    }
                }
                account.Votes = votes;
                foreach (ECPoint pubkey in account.Votes)
                {
                    validators.GetAndChange(pubkey, () => new ValidatorState(pubkey)).Votes += balance;
                }
                break;
            }
        }