private void CleanChain(Hash irreversibleBlockHash, long irreversibleBlockHeight) { _taskQueueManager.Enqueue(async() => { // Clean BlockStateSet var discardedBlockHashes = _chainBlockLinkService.GetCachedChainBlockLinks() .Where(b => b.Height <= irreversibleBlockHeight).Select(b => b.BlockHash).ToList(); await _blockchainStateService.RemoveBlockStateSetsAsync(discardedBlockHashes); // Clean chain branch var chain = await _blockchainService.GetChainAsync(); var discardedBranch = await _blockchainService.GetDiscardedBranchAsync(chain); _taskQueueManager.Enqueue( async() => { if (discardedBranch.BranchKeys.Count > 0 || discardedBranch.NotLinkedKeys.Count > 0) { await _blockchainService.CleanChainBranchAsync(discardedBranch); } await _forkCacheService.MergeAndCleanForkCacheAsync(irreversibleBlockHash, irreversibleBlockHeight); }, KernelConstants.UpdateChainQueueName); // Clean transaction block index cache await _transactionBlockIndexService.CleanTransactionBlockIndexCacheAsync(irreversibleBlockHeight); }, KernelConstants.ChainCleaningQueueName); }
public async Task MergeAndCleanForkCacheAsync(Hash irreversibleBlockHash, long irreversibleBlockHeight) { var chainBlockLinks = _chainBlockLinkService.GetCachedChainBlockLinks() .Where(b => b.Height <= irreversibleBlockHeight) .OrderByDescending(b => b.Height).ToList(); var irreversibleLink = chainBlockLinks.FirstOrDefault(b => b.BlockHash == irreversibleBlockHash); var groupedLinks = chainBlockLinks.GroupBy(b => b.Height).ToDictionary(g => g.Key, g => g.ToList()); var deletedBlockIndexes = new List <BlockIndex>(); // delete cache not on best chain while (irreversibleLink != null) { var links = groupedLinks[irreversibleLink.Height].Where(b => b.BlockHash != irreversibleLink.BlockHash) .ToList(); if (links.Count > 0) { foreach (var link in links) { _chainBlockLinkService.RemoveCachedChainBlockLink(link.BlockHash); } var blockHashes = links.Select(b => b.BlockHash).ToArray(); chainBlockLinks.RemoveAll(c => c.BlockHash.IsIn(blockHashes)); deletedBlockIndexes.AddRange(links.Select(l => new BlockIndex { BlockHash = l.BlockHash, BlockHeight = l.Height })); } irreversibleLink = chainBlockLinks.FirstOrDefault(b => b.BlockHash == irreversibleLink.PreviousBlockHash); } await RemoveByBlockHashAsync(deletedBlockIndexes); chainBlockLinks.Reverse(); var blockIndexes = chainBlockLinks.Select(c => new BlockIndex { BlockHash = c.BlockHash, BlockHeight = c.Height }).ToList(); await SetIrreversibleAsync(blockIndexes); foreach (var chainBlockLink in chainBlockLinks) { _chainBlockLinkService.RemoveCachedChainBlockLink(chainBlockLink.BlockHash); } }
private void CleanChain(Hash irreversibleBlockHash, long irreversibleBlockHeight) { _taskQueueManager.Enqueue(async() => { // Clean BlockStateSet var discardedBlockHashes = _chainBlockLinkService.GetCachedChainBlockLinks() .Where(b => b.Height <= irreversibleBlockHeight).Select(b => b.BlockHash).ToList(); await _blockchainStateService.RemoveBlockStateSetsAsync(discardedBlockHashes); // Clean chain branch var chain = await _blockchainService.GetChainAsync(); var discardedBranch = await _blockchainService.GetDiscardedBranchAsync(chain); _taskQueueManager.Enqueue( async() => { if (discardedBranch.BranchKeys.Count > 0 || discardedBranch.NotLinkedKeys.Count > 0) { await _blockchainService.CleanChainBranchAsync(discardedBranch); } await LocalEventBus.PublishAsync(new CleanBlockExecutedDataChangeHeightEventData { IrreversibleBlockHeight = irreversibleBlockHeight }); _chainBlockLinkService.CleanCachedChainBlockLinks(irreversibleBlockHeight); }, KernelConstants.UpdateChainQueueName); // Clean transaction block index cache await _transactionBlockIndexService.UpdateTransactionBlockIndicesByLibHeightAsync(irreversibleBlockHeight); // Clean idle executive _smartContractExecutiveService.CleanIdleExecutive(); }, KernelConstants.ChainCleaningQueueName); }