////II.增量处理 public void restart(bool opreturnStore) { if (!Directory.Exists(utxoSliceFileLocationPath)) { Console.WriteLine("切片文件保存路径不存在"); } Console.WriteLine("程序正在重启......."); Block_Pooling_Manager_Class bpmc = new Block_Pooling_Manager_Class(); Stopwatch timer = new Stopwatch(); timer.Start(); if (restore_StatusForProgram(bpmc) == true) { timer.Stop(); Console.WriteLine("程序重启成功......."); Console.WriteLine("程序重启用时:" + timer.Elapsed); Block readyBlock; Stopwatch timer1 = new Stopwatch(); timer1.Start(); while ((readyBlock = bpmc.dequeue_FromBlockQueuePooling()) != null) { execute_TransactionsOfOneBlock(readyBlock, opreturnStore); processedBlockAmount++; bool successMark = bpmc.enqueue_ToBlockQueuePooling(); if (!successMark) { //执行结束 Console.WriteLine("执行结束"); break; } if (processedBlockAmount % Configuration_Class.UTXOSliceLength == 0) { sliceFileAmount++; //保存UTXO切片 Console.WriteLine("正在保存第" + (int)(processedBlockAmount / Configuration_Class.UTXOSliceLength) + "个切片状态,请勿现在终止程序.........."); save_SliceFile(utxoSliceFileLocationPath + "\\" + processedBlockAmount + "_" + readyBlock.BlockHeader.BlockTimestamp.ToString("yyyy年MM月dd日HH时mm分ss秒") + ".txt", bpmc, processedBlockAmount, sliceFileAmount); Console.WriteLine("切片保存完成"); if (opreturnStore) { //保存opreturn切片 Console.WriteLine("正在保存第" + (int)(processedBlockAmount / Configuration_Class.UTXOSliceLength) + "个opreturn切片状态,请勿现在终止程序.........."); save_opreturnOutputsFile(opreturnOutputsFileFileLocationPath + "\\" + processedBlockAmount + "_" + readyBlock.BlockHeader.BlockTimestamp.ToString("yyyy年MM月dd日HH时mm分ss秒") + ".txt"); Console.WriteLine("opreturn切片保存完成"); } } if (processedBlockAmount % 100 == 0) { Console.WriteLine("已处理" + processedBlockAmount + "个区块"); Console.WriteLine("相同交易出现次数:" + sameTransactionCount); } } timer1.Stop(); Console.WriteLine("执行结束:" + timer1.Elapsed); } else { Console.WriteLine("程序重启失败......."); } }
////I.初次启动 public void initial_Run(bool opreturnStore) { if (!Directory.Exists(utxoSliceFileLocationPath)) { Directory.CreateDirectory(utxoSliceFileLocationPath); } Console.WriteLine("初次启动........."); //获取创世块 Block genesisBlock = get_GenesisBlock(); //计时 Stopwatch timer = new Stopwatch(); timer.Start(); Block_Pooling_Manager_Class bpmc = new Block_Pooling_Manager_Class(); bpmc.initialize_BlockQueuePooling(genesisBlock); processedBlockAmount = 0; sliceFileAmount = 0; Block readyBlock; while ((readyBlock = bpmc.dequeue_FromBlockQueuePooling()) != null) { execute_TransactionsOfOneBlock(readyBlock, opreturnStore); processedBlockAmount++; bool successMark = bpmc.enqueue_ToBlockQueuePooling(); if (!successMark) { //执行结束 break; } if (processedBlockAmount % Configuration_Class.UTXOSliceLength == 0) { sliceFileAmount++; //保存UTXO切片 Console.WriteLine("正在保存第" + (int)(processedBlockAmount / Configuration_Class.UTXOSliceLength) + "个切片状态,请勿现在终止程序.........."); save_SliceFile(utxoSliceFileLocationPath + "\\" + processedBlockAmount + "_" + readyBlock.BlockHeader.BlockTimestamp.ToString("yyyy年MM月dd日HH时mm分ss秒") + ".txt", bpmc, processedBlockAmount, sliceFileAmount); Console.WriteLine("UTXO切片保存完成"); if (opreturnStore) { //保存opreturn切片 Console.WriteLine("正在保存第" + (int)(processedBlockAmount / Configuration_Class.UTXOSliceLength) + "个opreturn切片状态,请勿现在终止程序.........."); save_opreturnOutputsFile(opreturnOutputsFileFileLocationPath + "\\" + processedBlockAmount + "_" + readyBlock.BlockHeader.BlockTimestamp.ToString("yyyy年MM月dd日HH时mm分ss秒") + ".txt"); Console.WriteLine("opreturn切片保存完成"); } } if (processedBlockAmount % 100 == 0) { Console.WriteLine("已处理" + processedBlockAmount + "个区块"); Console.WriteLine("相同交易出现次数:" + sameTransactionCount); } } timer.Stop(); Console.WriteLine("执行结束:" + timer.Elapsed); }
//5.(修改后重用)恢复队首区块 public Block restore_QueueHeaderBlock(string lastProcessedBlockHash, Block_Pooling_Manager_Class blockPoolingManagerObject) { foreach (Block block in blockPoolingManagerObject.blockReadBlocksFromFile) { if (block != null) { if (block.BlockHeader.PreviousBlockHash.ToString() == lastProcessedBlockHash) { return(block); } } } return(null); }
//4.(修改后重用)统计记录孤块 public void record_OrphanBlock(Block_Pooling_Manager_Class blockPoolingManagerObject) { for (int i = 0; i < blockPoolingManagerObject.blockReadBlocksFromFile.Count; i++) { if (blockPoolingManagerObject.blockReadBlocksFromFile[i] != null) { if (!blockPoolingManagerObject.forkedBlockList.Contains(blockPoolingManagerObject.blockReadBlocksFromFile[i].BlockHeader.BlockHash.ToString())) { if (blockPoolingManagerObject.blockReadBlocksFromFile[i].BlockHeader.BlockTimestamp < blockPoolingManagerObject.lastProcessedBlockElement.BlockHeader.BlockTimestamp) { blockPoolingManagerObject.orphanBlockList.Add(blockPoolingManagerObject.blockReadBlocksFromFile[i].BlockHeader.BlockHash.ToString()); } } } } }
//2.(修改后重用)保存切片状态 public void save_SliceFile(string sliceFilePath, Block_Pooling_Manager_Class blockPoolingManagerObject, int processedBlockAmount, int sliceFileAmount) { if (countOfFileBlock(blockPoolingManagerObject.blockCountOfFile) != blockPoolingManagerObject.blockReadBlocksFromFile.Count) { Console.WriteLine("读取文件总数和区块池文件总数不一致"); } else { record_OrphanBlock(blockPoolingManagerObject); fileStatusList.Clear(); int readBlockPointer = 0; for (int i = 0; i < blockPoolingManagerObject.blockCountOfFile.Count; i++) { string fileName = "blk" + i; int totalBlocks = blockPoolingManagerObject.blockCountOfFile[i]; int unusedBlocks = 0; List <string> unusedBlockHash = new List <string>(); for (int j = 0; j < blockPoolingManagerObject.blockCountOfFile[i]; j++) { if (blockPoolingManagerObject.blockReadBlocksFromFile[readBlockPointer] != null) { unusedBlockHash.Add(blockPoolingManagerObject.blockReadBlocksFromFile[readBlockPointer].BlockHeader.BlockHash.ToString()); unusedBlocks++; } readBlockPointer++; } fileStatusList.Add(new FileStatusItem_Class(fileName, totalBlocks, unusedBlocks, unusedBlockHash)); } SliceFileItem_Class sliceFileItem = new SliceFileItem_Class(fileStatusList, utxoDictionary, blockPoolingManagerObject.forkedBlockList, blockPoolingManagerObject.orphanBlockList, blockPoolingManagerObject.lastProcessedBlockElement.BlockHeader.BlockHash.ToString(), blockPoolingManagerObject.blockReadPointer, blockPoolingManagerObject.currentLoadFileNumber, processedBlockAmount, sliceFileAmount, sameTransactionCount); using (StreamWriter sw = File.CreateText(sliceFilePath)) { JsonSerializer serializer = new JsonSerializer(); serializer.Serialize(sw, sliceFileItem); } } }
//4.(修改后重用)恢复区块池(blockReadBlocksFromFile) public void restore_blockReadBlocksFromFile(SliceFileItem_Class sliceFileItemObject, Block_Pooling_Manager_Class blockPoolingManagerObject) { foreach (FileStatusItem_Class fileStatusItemObject in sliceFileItemObject.fileStatusList) { blockPoolingManagerObject.blockCountOfFile.Add(fileStatusItemObject.totalBlocks); if (fileStatusItemObject.unusedBlocks == 0) { for (int i = 0; i < fileStatusItemObject.totalBlocks; i++) { blockPoolingManagerObject.blockReadBlocksFromFile.Add(null); } } else { List <Block> blocksOfFile = blockfileManagerObject.load_one_blockfile(Configuration_Class.preprocessedBlockFilePath + "\\" + fileStatusItemObject.fileName); foreach (Block block in blocksOfFile) { if (fileStatusItemObject.unusedBlockHash.Contains(block.BlockHeader.BlockHash.ToString())) { blockPoolingManagerObject.blockReadBlocksFromFile.Add(block); } else { blockPoolingManagerObject.blockReadBlocksFromFile.Add(null); } } } } }
//3.(修改后重用)从最近的时间切片恢复程序状态(正在修改.....) public bool restore_StatusForProgram(Block_Pooling_Manager_Class blockPoolingManagerObject) { string recentlySliceFilePath = ""; if (exist_TimeingSlice(Configuration_Class.sliceStateFilePath, out recentlySliceFilePath)) { SliceFileItem_Class sliceFileItemObject = null; //反序列化切片文件 Console.WriteLine("开始提取切片中的数据........."); Stopwatch timer = new Stopwatch(); timer.Start(); try { using (StreamReader sr = File.OpenText(recentlySliceFilePath)) { JsonSerializer jsonSerializer = new JsonSerializer(); sliceFileItemObject = jsonSerializer.Deserialize(sr, typeof(SliceFileItem_Class)) as SliceFileItem_Class; } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("最近的切片状态可能保存不完整或已经损坏。该错误可能是由于在保存切片状态时提前终止程序造成的,或是人为修改了最近的切片状态。"); } timer.Stop(); Console.WriteLine("提取结束........."); Console.WriteLine("反序列化切片用时:" + timer.Elapsed); //恢复区块池 Console.WriteLine("开始恢复区块池........."); Stopwatch timer1 = new Stopwatch(); timer1.Start(); restore_blockReadBlocksFromFile(sliceFileItemObject, blockPoolingManagerObject); timer1.Stop(); Console.WriteLine("恢复区块池用时:" + timer1.Elapsed); //恢复UTXO字典 utxoDictionary = sliceFileItemObject.utxoDictionary; //恢复队列池 Console.WriteLine("开始恢复区块队列........."); Stopwatch timer2 = new Stopwatch(); timer2.Start(); Block queueBlock; if ((queueBlock = restore_QueueHeaderBlock(sliceFileItemObject.lastProcessedBlockHash, blockPoolingManagerObject)) != null) { blockPoolingManagerObject.initialize_BlockQueuePooling(queueBlock); } else { Console.WriteLine("队首区块未找到"); return(false); } timer2.Stop(); Console.WriteLine("恢复区块队列用时:" + timer2.Elapsed); //恢复其它 blockPoolingManagerObject.forkedBlockList = sliceFileItemObject.forkedBlockList; blockPoolingManagerObject.orphanBlockList = sliceFileItemObject.orphanBlockList; blockPoolingManagerObject.blockReadPointer = sliceFileItemObject.blockReadPointer; blockPoolingManagerObject.currentLoadFileNumber = sliceFileItemObject.currentLoadFileNumber; processedBlockAmount = sliceFileItemObject.processedBlockAmount; sliceFileAmount = sliceFileItemObject.sliceFileAmount; sameTransactionCount = sliceFileItemObject.sameTransactionCount; sliceFileItemObject.Dispose(); } else { Console.WriteLine("时间切片不存在"); return(false); } return(true); }