private void ProcessNewBlock(Block block) { Coin[] changeset; lock (contracts) lock (coins) { foreach (Transaction tx in block.Transactions) { for (ushort index = 0; index < tx.Outputs.Length; index++) { TransactionOutput output = tx.Outputs[index]; if (contracts.ContainsKey(output.ScriptHash)) { TransactionInput key = new TransactionInput { PrevHash = tx.Hash, PrevIndex = index }; if (coins.Contains(key)) { coins[key].State = CoinState.Unspent; } else { coins.Add(new Coin { Input = key, AssetId = output.AssetId, Value = output.Value, ScriptHash = output.ScriptHash, State = CoinState.Unspent }); } } } } foreach (Transaction tx in block.Transactions) { foreach (TransactionInput input in tx.GetAllInputs()) { if (coins.Contains(input)) { if (coins[input].AssetId == Blockchain.AntShare.Hash) { coins[input].State = CoinState.Spent; } else { coins.Remove(input); } } } } foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>()) { foreach (TransactionInput claim in tx.Claims) { if (coins.Contains(claim)) { coins.Remove(claim); } } } current_height++; changeset = coins.GetChangeSet(); OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <TransactionInput>)p).TrackState == TrackState.Deleted)); coins.Commit(); } if (changeset.Length > 0) { BalanceChanged?.Invoke(this, EventArgs.Empty); } }
private void ProcessNewBlock(Block block) { Coin[] changeset; lock (contracts) lock (coins) { foreach (Transaction tx in block.Transactions) { for (ushort index = 0; index < tx.Outputs.Length; index++) { TransactionOutput output = tx.Outputs[index]; AddressState state = CheckAddressState(output.ScriptHash); if (state.HasFlag(AddressState.InWallet)) { CoinReference key = new CoinReference { PrevHash = tx.Hash, PrevIndex = index }; if (coins.Contains(key)) { coins[key].State |= CoinState.Confirmed; } else { coins.Add(new Coin { Reference = key, Output = output, State = CoinState.Confirmed }); } if (state.HasFlag(AddressState.WatchOnly)) { coins[key].State |= CoinState.WatchOnly; } } } } foreach (Transaction tx in block.Transactions) { foreach (CoinReference input in tx.Inputs) { if (coins.Contains(input)) { if (coins[input].Output.AssetId.Equals(Blockchain.SystemShare.Hash)) { coins[input].State |= CoinState.Spent | CoinState.Confirmed; } else { coins.Remove(input); } } } } foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>()) { foreach (CoinReference claim in tx.Claims) { if (coins.Contains(claim)) { coins.Remove(claim); } } } current_height++; changeset = coins.GetChangeSet(); OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Deleted)); coins.Commit(); } if (changeset.Length > 0) { BalanceChanged?.Invoke(this, EventArgs.Empty); } }