private bool VerifyAccountState(Snapshot snapshot) { switch (Field) { case "Votes": ECPoint[] pubkeys; try { pubkeys = Value.AsSerializableArray <ECPoint>((int)Blockchain.MaxValidators); } catch (FormatException) { return(false); } UInt160 hash = new UInt160(Key); AccountState account = snapshot.Accounts.TryGet(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); foreach (ECPoint pubkey in pubkeys) { if (!sv.Contains(pubkey) && snapshot.Validators.TryGet(pubkey)?.Registered != true) { return(false); } } } return(true); default: return(false); } }
internal static void ProcessAccountStateDescriptor(StateDescriptor descriptor, Snapshot snapshot) { UInt160 hash = new UInt160(descriptor.Key); AccountState account = snapshot.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 = snapshot.Validators.GetAndChange(pubkey); validator.Votes -= balance; if (!validator.Registered && validator.Votes.Equals(Fixed8.Zero)) { snapshot.Validators.Delete(pubkey); } } ECPoint[] votes = descriptor.Value.AsSerializableArray <ECPoint>().Distinct().ToArray(); if (votes.Length != account.Votes.Length) { ValidatorsCountState count_state = snapshot.ValidatorsCount.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) { snapshot.Validators.GetAndChange(pubkey, () => new ValidatorState(pubkey)).Votes += balance; } break; } }