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); }
public async Task GetTransactionBlockIndexBelowLibTest() { var previousBlockHeader = _kernelTestHelper.BestBranchBlockList.Last().Header; var block1 = _kernelTestHelper.GenerateBlock(previousBlockHeader.Height, HashHelper.ComputeFrom("PreBlockHash1")); var block2 = _kernelTestHelper.GenerateBlock(previousBlockHeader.Height, previousBlockHeader.PreviousBlockHash); var txId = HashHelper.ComputeFrom("Transaction"); var chain = await _blockchainService.GetChainAsync(); await AddBlockAsync(chain, block1); var blockIndex = await _transactionBlockIndexService.GetTransactionBlockIndexAsync(txId); blockIndex.ShouldBeNull(); var blockIndex1 = new BlockIndex { BlockHash = block1.GetHash(), BlockHeight = block1.Height }; await _transactionBlockIndexService.AddBlockIndexAsync(new List <Hash> { txId }, blockIndex1); var blockIndex2 = new BlockIndex { BlockHash = block2.GetHash(), BlockHeight = block2.Height }; await _transactionBlockIndexService.AddBlockIndexAsync(new List <Hash> { txId }, blockIndex2); chain = await _blockchainService.GetChainAsync(); await AddBlockAsync(chain, block2); await SetBestChain(chain, block2); { var existsOnForkBranch = await _transactionBlockIndexService.ValidateTransactionBlockIndexExistsInBranchAsync(txId, block1.GetHash()); Assert.True(existsOnForkBranch); var actualBlockIndexOnBestChain = await _transactionBlockIndexService.GetTransactionBlockIndexAsync(txId); Assert.Equal(blockIndex2, actualBlockIndexOnBestChain); var transactionBlockIndex = await _transactionBlockIndexManager.GetTransactionBlockIndexAsync(txId); transactionBlockIndex.BlockHash.ShouldBe(blockIndex2.BlockHash); transactionBlockIndex.BlockHeight.ShouldBe(blockIndex2.BlockHeight); transactionBlockIndex.PreviousExecutionBlockIndexList.Count.ShouldBe(1); transactionBlockIndex.PreviousExecutionBlockIndexList[0].BlockHash.ShouldBe(blockIndex1.BlockHash); transactionBlockIndex.PreviousExecutionBlockIndexList[0].BlockHeight.ShouldBe(blockIndex1.BlockHeight); _transactionBlockIndexProvider.TryGetTransactionBlockIndex(txId, out var transactionBlockIndexCache) .ShouldBeTrue(); transactionBlockIndexCache.ShouldBe(transactionBlockIndex); } var i = 0; var currentBlock = block2; while (i++ < KernelConstants.ReferenceBlockValidPeriod) { var block = await _kernelTestHelper.AttachBlock(currentBlock.Height, currentBlock.GetHash()); // await AddBlockAsync(chain, block); currentBlock = block; } await SetBestChain(chain, currentBlock); await _blockchainService.SetIrreversibleBlockAsync(chain, currentBlock.Height, currentBlock.GetHash()); await _transactionBlockIndexService.UpdateTransactionBlockIndicesByLibHeightAsync(currentBlock.Height); { _transactionBlockIndexProvider.TryGetTransactionBlockIndex(txId, out _).ShouldBeFalse(); var existsOnForkBranch = await _transactionBlockIndexService.ValidateTransactionBlockIndexExistsInBranchAsync(txId, block1.GetHash()); Assert.False(existsOnForkBranch); var actualBlockIndexOnBestChain = await _transactionBlockIndexService.GetTransactionBlockIndexAsync(txId); Assert.Equal(blockIndex2, actualBlockIndexOnBestChain); var transactionBlockIndex = await _transactionBlockIndexManager.GetTransactionBlockIndexAsync(txId); transactionBlockIndex.BlockHash.ShouldBe(blockIndex2.BlockHash); transactionBlockIndex.BlockHeight.ShouldBe(blockIndex2.BlockHeight); transactionBlockIndex.PreviousExecutionBlockIndexList.Count.ShouldBe(0); } }
public async Task GetTransactionBlockIndexBelowLibTest() { var previousBlockHeader = _kernelTestHelper.BestBranchBlockList.Last().Header; var block1 = _kernelTestHelper.GenerateBlock(previousBlockHeader.Height, Hash.FromString("PreBlockHash1")); var block2 = _kernelTestHelper.GenerateBlock(previousBlockHeader.Height, previousBlockHeader.PreviousBlockHash); var txId = Hash.FromString("Transaction"); var chain = await _blockchainService.GetChainAsync(); await AddBlockAsync(chain, block1); var blockIndex1 = new BlockIndex { BlockHash = block1.GetHash(), BlockHeight = block1.Height }; await _transactionBlockIndexService.AddBlockIndexAsync(new List <Hash> { txId }, blockIndex1); var blockIndex2 = new BlockIndex { BlockHash = block2.GetHash(), BlockHeight = block2.Height }; await _transactionBlockIndexService.AddBlockIndexAsync(new List <Hash> { txId }, blockIndex2); chain = await _blockchainService.GetChainAsync(); await AddBlockAsync(chain, block2); await SetBestChain(chain, block2); { var existsOnForkBranch = await _transactionBlockIndexService.ValidateTransactionBlockIndexExistsInBranchAsync(txId, block1.GetHash()); Assert.True(existsOnForkBranch); } var i = 0; var currentBlock = block2; while (i++ < KernelConstants.ReferenceBlockValidPeriod) { var block = await _kernelTestHelper.AttachBlock(currentBlock.Height, currentBlock.GetHash()); // await AddBlockAsync(chain, block); currentBlock = block; } await SetBestChain(chain, currentBlock); await _blockchainService.SetIrreversibleBlockAsync(chain, currentBlock.Height, currentBlock.GetHash()); await _transactionBlockIndexService.UpdateTransactionBlockIndicesByLibHeightAsync(currentBlock.Height); { var existsOnForkBranch = await _transactionBlockIndexService.ValidateTransactionBlockIndexExistsInBranchAsync(txId, block1.GetHash()); Assert.False(existsOnForkBranch); var actualBlockIndexOnBestChain = await _transactionBlockIndexService.GetTransactionBlockIndexAsync(txId); Assert.Equal(blockIndex2, actualBlockIndexOnBestChain); } }