Exemple #1
0
        private ICoinsView RemoveNoLock(SmartCoin coin)
        {
            var coinsToRemove = DescendantOfAndSelfNoLock(coin);

            foreach (var toRemove in coinsToRemove)
            {
                if (!Coins.Remove(toRemove))
                {
                    SpentCoins.Remove(toRemove);
                }

                var removedCoinOutPoint = toRemove.OutPoint;

                // If we can find it in our outpoint to coins cache.
                if (TryGetSpenderSmartCoinsByOutPointNoLock(removedCoinOutPoint, out var coinsByOutPoint))
                {
                    // Go through all the coins of that cache where the coin is the coin we are wishing to remove.
                    foreach (var coinByOutPoint in coinsByOutPoint.Where(x => x == toRemove))
                    {
                        // Remove the coin from the set, and if the set becomes empty as a consequence remove the key too.
                        if (CoinsByOutPoint[removedCoinOutPoint].Remove(coinByOutPoint) && !CoinsByOutPoint[removedCoinOutPoint].Any())
                        {
                            CoinsByOutPoint.Remove(removedCoinOutPoint);
                        }
                    }
                }
            }
            InvalidateSnapshot = true;
            return(coinsToRemove);
        }
Exemple #2
0
        public bool TryAdd(SmartCoin coin)
        {
            var added = false;

            lock (Lock)
            {
                if (!SpentCoins.Contains(coin))
                {
                    added = Coins.Add(coin);
                    if (added)
                    {
                        if (ClustersByScriptPubKey.TryGetValue(coin.ScriptPubKey, out var cluster))
                        {
                            coin.Cluster = cluster;
                        }
                        else
                        {
                            ClustersByScriptPubKey.Add(coin.ScriptPubKey, coin.Cluster);
                        }

                        foreach (var spentOutPoint in coin.SpentOutputs)
                        {
                            var outPoint   = spentOutPoint;
                            var newCoinSet = new HashSet <SmartCoin> {
                                coin
                            };

                            // If we don't succeed to add a new entry to the dictionary.
                            if (!CoinsByOutPoint.TryAdd(outPoint, newCoinSet))
                            {
                                var previousCoinTxId = CoinsByOutPoint[outPoint].First().TransactionId;

                                // Then check if we're in the same transaction as the previous coins in the dictionary are.
                                if (coin.TransactionId == previousCoinTxId)
                                {
                                    // If we are in the same transaction, then just add it to value set.
                                    CoinsByOutPoint[outPoint].Add(coin);
                                }
                                else
                                {
                                    // If we aren't in the same transaction, then it's a conflict, so replace the old set with the new one.
                                    CoinsByOutPoint[outPoint] = newCoinSet;
                                }
                            }
                        }
                        InvalidateSnapshot = true;
                    }
                }
            }
            return(added);
        }
Exemple #3
0
 private bool TryGetSpenderSmartCoinsByOutPointNoLock(OutPoint outPoint, out HashSet <SmartCoin> coins)
 {
     return(CoinsByOutPoint.TryGetValue(outPoint, out coins));
 }