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(); } }
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); } } } } }
public async Task SaveAsync(string partialChainFolderPath) { await Saving.WaitAsync().ConfigureAwait(false); try { if (TrackedScriptPubKeys.Count > 0 || TrackedTransactions.Count > 0 || Chain.Count > 0) { Directory.CreateDirectory(partialChainFolderPath); } if (TrackedScriptPubKeys.Count > 0) { File.WriteAllLines( Path.Combine(partialChainFolderPath, FilesNames.TrackedScriptPubKeys.ToString()), TrackedScriptPubKeys.Select(x => x.ToString())); } if (TrackedTransactions.Count > 0) { File.WriteAllLines( Path.Combine(partialChainFolderPath, FilesNames.TrackedTransactions.ToString()), TrackedTransactions.Select(x => $"{x.Key}:{x.Value}")); } if (Chain.Count > 0) { byte[] toFile = Chain.Values.First().ToBytes(); foreach (var block in Chain.Values.Skip(1)) { toFile = toFile.Concat(blockSep).Concat(block.ToBytes()).ToArray(); } File.WriteAllBytes(Path.Combine(partialChainFolderPath, FilesNames.PartialBlockChain.ToString()), toFile); } } finally { Saving.Release(); } }