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); }
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); }
private bool TryGetSpenderSmartCoinsByOutPointNoLock(OutPoint outPoint, out HashSet <SmartCoin> coins) { return(CoinsByOutPoint.TryGetValue(outPoint, out coins)); }