private bool VerifyAccountState(UInt256 ChainHash) { switch (Field) { case "Votes": BlockchainBase chain = BlockchainBase.GetBlockchain(ChainHash); if (chain == null) { return(false); } ECPoint[] pubkeys; try { pubkeys = Value.AsSerializableArray <ECPoint>((int)BlockchainBase.MaxValidators); } catch (FormatException) { return(false); } UInt160 hash = new UInt160(Key); AccountState account = chain.GetAccountState(hash); if (account?.IsFrozen != false) { return(false); } if (pubkeys.Length > 0) { if (account.GetBalance(BlockchainBase.GetStaticAttr().GoverningToken.Hash).Equals(Fixed8.Zero)) { return(false); } HashSet <ECPoint> sv = new HashSet <ECPoint>(chain.StandbyValidators); DataCache <ECPoint, ValidatorState> validators = chain.GetStates <ECPoint, ValidatorState>(); foreach (ECPoint pubkey in pubkeys) { if (!sv.Contains(pubkey) && validators.TryGet(pubkey)?.Registered != true) { return(false); } } } return(true); default: return(false); } }
protected void ProcessAccountStateDescriptor(StateDescriptor descriptor, DataCache <UInt160, AccountState> accounts, DataCache <ECPoint, ValidatorState> validators, MetaDataCache <ValidatorsCountState> validators_count) { TR.Enter(); 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; } TR.Exit(); }