public void ReorgOne() { UnprocessedBlockBuffer.Clear(); // remove the last block if (MerkleChain.Count != 0) { var bestBlock = MerkleChain.Max(); if (MerkleChain.TryRemove(bestBlock)) { List <SmartTransaction> affectedTxs = TrackedTransactions.Where(x => x.Height == bestBlock.Height).Select(x => x).ToList(); foreach (var tx in affectedTxs) { TrackedTransactions.TryRemove(tx); // add it back as a mempool transaction, it'll drop out anyway TrackedTransactions.TryAdd(new SmartTransaction(tx.Transaction, Height.MemPool)); } if (MerkleChain.Count != 0) { BestHeight = MerkleChain.Max().Height; } else { BestHeight = Height.Unknown; } } } }
private IEnumerable <SmartTransaction> GetNotYetFoundTrackedTransactions() { var notFound = new HashSet <SmartTransaction>(); foreach (var tx in TrackedTransactions.Where(x => !x.Confirmed)) { notFound.Add(tx); } return(notFound); }
/// <summary> /// /// </summary> /// <param name="scriptPubKey"></param> /// <param name="receivedTransactions">int: block height</param> /// <param name="spentTransactions">int: block height</param> /// <returns></returns> public bool TryFindConfirmedTransactions(Script scriptPubKey, out ConcurrentHashSet <SmartTransaction> receivedTransactions, out ConcurrentHashSet <SmartTransaction> spentTransactions) { var found = false; receivedTransactions = new ConcurrentHashSet <SmartTransaction>(); spentTransactions = new ConcurrentHashSet <SmartTransaction>(); foreach (var tx in TrackedTransactions.Where(x => x.Confirmed)) { // if already has that tx continue if (receivedTransactions.Any(x => x.GetHash() == tx.GetHash())) { continue; } foreach (var output in tx.Transaction.Outputs) { if (output.ScriptPubKey.Equals(scriptPubKey)) { receivedTransactions.Add(tx); found = true; } } } if (found) { foreach (var tx in TrackedTransactions.Where(x => x.Confirmed)) { // if already has that tx continue if (spentTransactions.Any(x => x.GetHash() == tx.GetHash())) { continue; } foreach (var input in tx.Transaction.Inputs) { if (receivedTransactions.Select(x => x.GetHash()).Contains(input.PrevOut.Hash)) { spentTransactions.Add(tx); found = true; } } } } return(found); }
/// <returns>if processed it transaction</returns> public bool ProcessTransaction(SmartTransaction transaction) { // 1. If already tracking can we update it? var found = TrackedTransactions.FirstOrDefault(x => x == transaction); if (found != default(SmartTransaction)) { // if in a lower level don't track if (found.Height.Type <= transaction.Height.Type) { return(false); } else { // else update TrackedTransactions.TryRemove(transaction); TrackedTransactions.TryAdd(transaction); return(true); } } // 2. If this transaction arrived to any of our scriptpubkey track it! if (transaction.Transaction.Outputs.Any(output => TrackedScriptPubKeys.Contains(output.ScriptPubKey))) { TrackedTransactions.TryAdd(transaction); return(true); } // 3. If this transaction spends any of our scriptpubkeys track it! if (transaction.Transaction.Inputs.Any(input => TrackedTransactions .Where(ttx => ttx.GetHash() == input.PrevOut.Hash) .Any(ttx => TrackedScriptPubKeys .Contains(ttx.Transaction.Outputs[input.PrevOut.N].ScriptPubKey)))) { TrackedTransactions.TryAdd(transaction); return(true); } // if got so far we are not interested return(false); }