public async Task <BlockIndex> GetTransactionBlockIndexAsync(Hash txId) { var transactionBlockIndex = await _transactionBlockIndexManager.GetTransactionBlockIndexAsync(txId); if (transactionBlockIndex == null) { return(null); } return(await GetBlockIndexAsync(transactionBlockIndex)); }
public async Task <TransactionResult> GetTransactionResultAsync(Hash transactionId) { var transactionBlockIndex = await _transactionBlockIndexManager.GetTransactionBlockIndexAsync(transactionId); var chain = await _blockchainService.GetChainAsync(); if (transactionBlockIndex != null) { var blockHashInBestChain = await _blockchainService.GetBlockHashByHeightAsync(chain, transactionBlockIndex.BlockHeight, chain.BestChainHash); // check whether it is on best chain or a fork branch if (transactionBlockIndex.BlockHash == blockHashInBestChain) { // If TransactionBlockIndex exists, then read the result via TransactionBlockIndex return(await _transactionResultManager.GetTransactionResultAsync(transactionId, transactionBlockIndex.BlockHash)); } } var hash = chain.BestChainHash; var until = chain.LastIrreversibleBlockHeight > Constants.GenesisBlockHeight ? chain.LastIrreversibleBlockHeight - 1 : Constants.GenesisBlockHeight; while (true) { var result = await _transactionResultManager.GetTransactionResultAsync(transactionId, hash); if (result != null) { return(result); } var header = await _blockchainService.GetBlockHeaderByHashAsync(hash); result = await _transactionResultManager.GetTransactionResultAsync(transactionId, header.GetPreMiningHash()); if (result != null) { return(result); } if (header.Height <= until) { // do until 1 block below LIB, in case the TransactionBlockIndex is not already added during // NewIrreversibleBlockFoundEvent handling break; } hash = header.PreviousBlockHash; } return(null); }
public async Task LoadTransactionBlockIndexAsync() { var chain = await _blockchainService.GetChainAsync(); if (chain == null) { return; } var blockHeight = chain.LastIrreversibleBlockHeight; var blockHash = chain.LastIrreversibleBlockHash; while (true) { if (blockHeight < AElfConstants.GenesisBlockHeight || blockHeight + KernelConstants.ReferenceBlockValidPeriod <= chain.LastIrreversibleBlockHeight) { break; } var block = await _blockchainService.GetBlockByHashAsync(blockHash); if (block == null) { return; } foreach (var txId in block.TransactionIds) { var txBlockIndex = await _transactionBlockIndexManager.GetTransactionBlockIndexAsync(txId); _transactionBlockIndexProvider.AddTransactionBlockIndex(txId, txBlockIndex); } blockHash = block.Header.PreviousBlockHash; blockHeight--; } }
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); } }