public void Add(int height, Block block) { foreach (var spk in TrackedScriptPubKeys) { TrackIfFindRelatedTransactions(spk, height, block); } FullBlockBuffer.AddOrReplace(height, block); HashSet <uint256> notFoundTransactions = GetNotYetFoundTrackedTransactions(); HashSet <uint256> foundTransactions = new HashSet <uint256>(); foreach (var txid in notFoundTransactions) { if (block.Transactions.Any(x => x.GetHash().Equals(txid))) { foundTransactions.Add(txid); } } MerkleBlock merkleProof = foundTransactions.Count == 0 ? block.Filter() : block.Filter(foundTransactions.ToArray()); var partialBlock = new PartialBlock(height, merkleProof); foreach (var txid in foundTransactions) { foreach (var tx in block.Transactions) { if (tx.GetHash().Equals(txid)) { partialBlock.Transactions.Add(tx); } } } Chain.AddOrReplace(partialBlock.Height, partialBlock); }
/// <summary> Track a transaction </summary> /// <returns>False if not found. When confirms, it starts tracking. If too old you need to resync the chain.</returns> public bool Track(uint256 transactionId) { if (TrackedTransactions.Keys.Contains(transactionId)) { var tracked = TrackedTransactions.First(x => x.Key.Equals(transactionId)); if (tracked.Value == -1) { return(false); } else { return(true); } } TrackedTransactions.AddOrReplace(transactionId, -1); Transaction transaction = null; Block block = null; foreach (var b in FullBlockBuffer.Values) { Transaction tx = b.Transactions.FirstOrDefault(x => transactionId.Equals(x.GetHash())); if (tx != default(Transaction)) { transaction = tx; block = b; break; } } // This warning doesn't make sense: // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (block == null || transaction == null) { return(false); } else { PartialBlock partialBlock = Chain.First(x => block.Header.GetHash().Equals(x.Value.MerkleProof.Header.GetHash())).Value; partialBlock.Transactions.Add(transaction); var transactionHashes = partialBlock.MerkleProof.PartialMerkleTree.GetMatchedTransactions() as HashSet <uint256>; transactionHashes.Add(transaction.GetHash()); partialBlock.MerkleProof = block.Filter(transactionHashes.ToArray()); return(true); } }
public async Task LoadAsync(string partialChainFolderPath) { await Saving.WaitAsync().ConfigureAwait(false); try { if (!Directory.Exists(partialChainFolderPath)) { throw new DirectoryNotFoundException($"No Blockchain found at {partialChainFolderPath}"); } var tspb = Path.Combine(partialChainFolderPath, FilesNames.TrackedScriptPubKeys.ToString()); if (File.Exists(tspb) && new FileInfo(tspb).Length != 0) { foreach (var line in File.ReadAllLines(tspb)) { TrackedScriptPubKeys.Add(new Script(line)); } } var tt = Path.Combine(partialChainFolderPath, FilesNames.TrackedTransactions.ToString()); if (File.Exists(tt) && new FileInfo(tt).Length != 0) { foreach (var line in File.ReadAllLines(tt)) { var pieces = line.Split(':'); TrackedTransactions.TryAdd(new uint256(pieces[0]), int.Parse(pieces[1])); } } var pbc = Path.Combine(partialChainFolderPath, FilesNames.PartialBlockChain.ToString()); if (File.Exists(pbc) && new FileInfo(pbc).Length != 0) { foreach (var block in Help.Separate(File.ReadAllBytes(pbc), blockSep)) { PartialBlock pb = new PartialBlock().FromBytes(block); Chain.TryAdd(pb.Height, pb); } } } finally { Saving.Release(); } }