private StackItem Vote(ApplicationEngine engine, Array args) { UInt160 account = new UInt160(args[0].GetSpan()); ECPoint[] pubkeys = ((Array)args[1]).Select(p => p.GetSpan().AsSerializable <ECPoint>()).ToArray(); if (!InteropService.Runtime.CheckWitnessInternal(engine, account)) { return(false); } StorageKey key_account = CreateAccountKey(account); if (engine.Snapshot.Storages.TryGet(key_account) is null) { return(false); } StorageItem storage_account = engine.Snapshot.Storages.GetAndChange(key_account); AccountState state_account = new AccountState(storage_account.Value); foreach (ECPoint pubkey in state_account.Votes) { StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Validator, pubkey.ToArray())); ValidatorState state_validator = ValidatorState.FromByteArray(storage_validator.Value); state_validator.Votes -= state_account.Balance; storage_validator.Value = state_validator.ToByteArray(); } pubkeys = pubkeys.Distinct().Where(p => engine.Snapshot.Storages.TryGet(CreateStorageKey(Prefix_Validator, p.ToArray())) != null).ToArray(); if (pubkeys.Length != state_account.Votes.Length) { StorageItem storage_count = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_ValidatorsCount), () => new StorageItem { Value = new ValidatorsCountState().ToByteArray() }); ValidatorsCountState state_count = ValidatorsCountState.FromByteArray(storage_count.Value); if (state_account.Votes.Length > 0) { state_count.Votes[state_account.Votes.Length - 1] -= state_account.Balance; } if (pubkeys.Length > 0) { state_count.Votes[pubkeys.Length - 1] += state_account.Balance; } storage_count.Value = state_count.ToByteArray(); } state_account.Votes = pubkeys; storage_account.Value = state_account.ToByteArray(); foreach (ECPoint pubkey in state_account.Votes) { StorageItem storage_validator = engine.Snapshot.Storages.GetAndChange(CreateStorageKey(Prefix_Validator, pubkey.ToArray())); ValidatorState state_validator = ValidatorState.FromByteArray(storage_validator.Value); state_validator.Votes += state_account.Balance; storage_validator.Value = state_validator.ToByteArray(); } return(true); }
public override void Deserialize(BinaryReader reader) { base.Deserialize(reader); int count = (int)reader.ReadVarInt(MaxContentsPerBlock); if (count == 0) { throw new FormatException(); } ConsensusData = reader.ReadSerializable <ConsensusData>(); Transactions = new Transaction[count - 1]; for (int i = 0; i < Transactions.Length; i++) { Transactions[i] = reader.ReadSerializable <Transaction>(); } if (Transactions.Distinct().Count() != Transactions.Length) { throw new FormatException(); } if (CalculateMerkleRoot(ConsensusData.Hash, Transactions.Select(p => p.Hash)) != MerkleRoot) { throw new FormatException(); } }