Пример #1
0
 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;
             }
         }
     }
 }
Пример #2
0
        public async Task SaveAsync(string trackerFolderPath)
        {
            await Saving.WaitAsync().ConfigureAwait(false);

            try
            {
                if (TrackedScriptPubKeys.Count > 0 || TrackedTransactions.Count > 0 || MerkleChain.Count > 0)
                {
                    Directory.CreateDirectory(trackerFolderPath);
                }

                if (TrackedScriptPubKeys.Count > 0)
                {
                    File.WriteAllLines(
                        Path.Combine(trackerFolderPath, TrackedScriptPubKeysFileName),
                        TrackedScriptPubKeys.Select(x => x.ToString()));
                }

                if (TrackedTransactions.Count > 0)
                {
                    File.WriteAllLines(
                        Path.Combine(trackerFolderPath, TrackedTransactionsFileName),
                        TrackedTransactions
                        .Select(x => $"{x.Transaction.ToHex()}:{x.Height}"));
                }

                if (MerkleChain.Count > 0)
                {
                    var path = Path.Combine(trackerFolderPath, MerkleChainFileName);

                    if (File.Exists(path))
                    {
                        const string backupName = MerkleChainFileName + "_backup";
                        var          backupPath = Path.Combine(trackerFolderPath, backupName);
                        File.Copy(path, backupPath, overwrite: true);
                        File.Delete(path);
                    }

                    using (FileStream stream = File.OpenWrite(path))
                    {
                        var toFile = MerkleChain.First().ToBytes();
                        await stream.WriteAsync(toFile, 0, toFile.Length).ConfigureAwait(false);

                        foreach (var block in MerkleChain.Skip(1))
                        {
                            await stream.WriteAsync(blockSep, 0, blockSep.Length).ConfigureAwait(false);

                            var blockBytes = block.ToBytes();
                            await stream.WriteAsync(blockBytes, 0, blockBytes.Length).ConfigureAwait(false);
                        }
                    }
                }
            }
            finally
            {
                Saving.Release();
            }
        }
Пример #3
0
        public async Task LoadAsync(string trackerFolderPath)
        {
            await Saving.WaitAsync().ConfigureAwait(false);

            try
            {
                if (!Directory.Exists(trackerFolderPath))
                {
                    throw new DirectoryNotFoundException($"No Blockchain found at {trackerFolderPath}");
                }

                var tspb = Path.Combine(trackerFolderPath, TrackedScriptPubKeysFileName);
                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(trackerFolderPath, TrackedTransactionsFileName);
                if (File.Exists(tt) && new FileInfo(tt).Length != 0)
                {
                    foreach (var line in File.ReadAllLines(tt))
                    {
                        var pieces = line.Split(':');
                        //ProcessTransaction(new SmartTransaction(new Transaction(pieces[0]), new Height(pieces[1])));
                    }
                }

                var pbc = Path.Combine(trackerFolderPath, MerkleChainFileName);
                if (File.Exists(pbc) && new FileInfo(pbc).Length != 0)
                {
                    foreach (var block in Util.Separate(File.ReadAllBytes(pbc), blockSep))
                    {
                        try
                        {
                            SmartMerkleBlock smartMerkleBlock = SmartMerkleBlock.FromBytes(block);
                            MerkleChain.Add(smartMerkleBlock);
                        }
                        catch (EndOfStreamException)
                        {
                            // Some corruption is fine, the software will self correct and save the right data
                        }
                    }
                    if (MerkleChain.Count != 0)
                    {
                        BestHeight = MerkleChain.Max().Height;
                    }
                }
            }
            finally
            {
                Saving.Release();
            }
        }
Пример #4
0
 public void ReorgOne()
 {
     // remove the last block
     if (MerkleChain.Count != 0)
     {
         if (MerkleChain.TryRemove(MerkleChain.Max()))
         {
             BestHeight = MerkleChain.Max().Height;
         }
     }
 }
Пример #5
0
        public async Task SaveAsync(string trackerFolderPath)
        {
            using (await AsyncLockSaving.LockAsync())
            {
                if (TrackedScriptPubKeys.Count > 0 || TrackedTransactions.Count > 0 || MerkleChain.Count > 0)
                {
                    Directory.CreateDirectory(trackerFolderPath);
                }

                if (TrackedScriptPubKeys.Count > 0)
                {
                    await File.WriteAllLinesAsync(
                        Path.Combine(trackerFolderPath, TrackedScriptPubKeysFileName),
                        TrackedScriptPubKeys.Select(x => x.ToString()));
                }

                if (TrackedTransactions.Count > 0)
                {
                    await File.WriteAllLinesAsync(
                        Path.Combine(trackerFolderPath, TrackedTransactionsFileName),
                        TrackedTransactions
                        .Select(x => $"{x.Transaction.ToHex()}:{x.Height}"));
                }

                if (MerkleChain.Count > 0)
                {
                    var path = Path.Combine(trackerFolderPath, MerkleChainFileName);

                    // remove legacy backup file
                    if (File.Exists(path + "_backup"))
                    {
                        File.Delete(path + "_backup");
                    }

                    using (FileStream stream = File.Open(path, FileMode.Create, FileAccess.Write))
                    {
                        var toFile = MerkleChain.First().ToBytes();
                        await stream.WriteAsync(toFile, 0, toFile.Length);

                        foreach (var block in MerkleChain.Skip(1))
                        {
                            await stream.WriteAsync(BlockSep, 0, BlockSep.Length);

                            var blockBytes = block.ToBytes();
                            await stream.WriteAsync(blockBytes, 0, blockBytes.Length);
                        }
                    }
                }
            }
        }
Пример #6
0
        /// <returns>transactions it processed, empty if not processed any</returns>
        private HashSet <SmartTransaction> ProcessBlock(Height height, Block block)
        {
            var foundTransactions = ProcessTransactions(block.Transactions, height);

            var smartMerkleBlock = new SmartMerkleBlock(height, block, foundTransactions.Select(x => x.GetHash()).ToArray());

            var sameHeights = MerkleChain.Where(x => x.Height == height);

            foreach (var elem in sameHeights)
            {
                MerkleChain.TryRemove(elem);
            }

            MerkleChain.Add(smartMerkleBlock);
            BestHeight = height;

            return(foundTransactions);
        }