Example #1
0
        private AddressIndexData GetOrCreateAddressData(Script scriptPubKey)
        {
            byte[] scriptPubKeyBytes = scriptPubKey.ToBytes();

            AddressIndexData addrData = this.addressesIndex.AddressIndexDatas.SingleOrDefault(x => StructuralComparisons.StructuralEqualityComparer.Equals(scriptPubKeyBytes, x.ScriptPubKeyBytes));

            if (addrData == null)
            {
                addrData = new AddressIndexData()
                {
                    ScriptPubKeyBytes = scriptPubKeyBytes,
                    Changes           = new List <AddressBalanceChange>()
                };

                this.addressesIndex.AddressIndexDatas.Add(addrData);
                return(addrData);
            }

            return(addrData);
        }
Example #2
0
        /// <summary>Processes block that was added or removed from consensus chain.</summary>
        private void ProcessBlockAddedOrRemoved(KeyValuePair <bool, ChainedHeaderBlock> item)
        {
            // Make sure it's on top of the tip.
            bool blockAdded = item.Key;

            Block block         = item.Value.Block;
            int   currentHeight = item.Value.ChainedHeader.Height;

            // Process inputs
            var inputs = new List <TxIn>();

            // Collect all inputs excluding coinbases.
            foreach (TxInList inputsCollection in block.Transactions.Where(x => !x.IsCoinBase).Select(x => x.Inputs))
            {
                inputs.AddRange(inputsCollection);
            }

            Transaction[] transactions = this.blockStore.GetTransactionsByIds(inputs.Select(x => x.PrevOut.Hash).ToArray());

            // TODO is it possible that transactions is null because block with requested ID was reorged away already?

            for (int i = 0; i < inputs.Count; i++)
            {
                TxIn currentInput = inputs[i];

                TxOut txOut = transactions[i].Outputs[currentInput.PrevOut.N];

                Money amountSpent = txOut.Value;

                AddressIndexData addrData = this.GetOrCreateAddressData(txOut.ScriptPubKey);

                if (blockAdded)
                {
                    // Record money being spent.
                    addrData.Changes.Add(new AddressBalanceChange()
                    {
                        BalanceChangedHeight = currentHeight,
                        Satoshi   = amountSpent.Satoshi,
                        Deposited = false
                    });
                }
                else
                {
                    // Remove changes.
                    addrData.Changes.RemoveAll(x => x.BalanceChangedHeight == currentHeight);
                }
            }

            // Process outputs.
            foreach (Transaction tx in block.Transactions)
            {
                foreach (TxOut txOut in tx.Outputs)
                {
                    Money amountReceived = txOut.Value;

                    AddressIndexData addrData = this.GetOrCreateAddressData(txOut.ScriptPubKey);

                    if (blockAdded)
                    {
                        // Record money being sent.
                        addrData.Changes.Add(new AddressBalanceChange()
                        {
                            BalanceChangedHeight = currentHeight,
                            Satoshi   = amountReceived.Satoshi,
                            Deposited = true
                        });
                    }
                    else
                    {
                        // Remove changes.
                        addrData.Changes.RemoveAll(x => x.BalanceChangedHeight == currentHeight);
                    }
                }
            }

            this.addressesIndex.TipHash = item.Value.ChainedHeader.HashBlock.ToString();
        }