public async Task Query_TransactionResult_With_Index()
        {
            var tx = _kernelTestHelper.GenerateTransaction();

            var(block, results) =
                GetNextBlockWithTransactionAndResults(_kernelTestHelper.BestBranchBlockList.Last().Header, new[] { tx });

            var result = results.First();

            // Complete block
            await AddTransactionResultsWithPostMiningAsync(block, new[] { result });

            var transactionBlockIndex = new TransactionBlockIndex()
            {
                BlockHash   = block.GetHash(),
                BlockHeight = block.Height
            };
            await _transacionBlockIndexManager.SetTransactionBlockIndexAsync(tx.GetHash(), transactionBlockIndex);

            var queried = await _transactionResultService.GetTransactionResultAsync(tx.GetHash());

            queried.ShouldBe(result);

            var queried2 = await _transactionResultService.GetTransactionResultAsync(tx.GetHash(), block.GetHash());

            queried2.ShouldBe(result);
        }
        public async Task HandleEventAsync(BestChainFoundEventData eventData)
        {
            foreach (var blockHash in eventData.ExecutedBlocks)
            {
                var block = await _blockchainService.GetBlockByHashAsync(blockHash);

                Logger.LogTrace($"Handle lib for transactions of block {block.Height}");

                var preMiningHash         = block.Header.GetPreMiningHash();
                var transactionBlockIndex = new TransactionBlockIndex()
                {
                    BlockHash   = blockHash,
                    BlockHeight = block.Height
                };
                if (block.Body.TransactionIds.Count == 0)
                {
                    // This will only happen during test environment
                    return;
                }

                var firstTransaction = block.Body.TransactionIds.First();
                var withBlockHash    = await _transactionResultManager.GetTransactionResultAsync(
                    firstTransaction, blockHash);

                var withPreMiningHash = await _transactionResultManager.GetTransactionResultAsync(
                    firstTransaction, preMiningHash);

                if (withBlockHash == null)
                {
                    // TransactionResult is not saved with real BlockHash
                    // Save results with real (post mining) Hash, so that it can be queried with TransactionBlockIndex
                    foreach (var txId in block.Body.TransactionIds)
                    {
                        var result = await _transactionResultManager.GetTransactionResultAsync(txId, preMiningHash);

                        await _transactionResultManager.AddTransactionResultAsync(result, transactionBlockIndex.BlockHash);
                    }
                }

                if (withPreMiningHash != null)
                {
                    // TransactionResult is saved with PreMiningHash
                    // Remove results saved with PreMiningHash, as it will never be queried
                    foreach (var txId in block.Body.TransactionIds)
                    {
                        await _transactionResultManager.RemoveTransactionResultAsync(txId, preMiningHash);
                    }
                }

                // Add TransactionBlockIndex
                foreach (var txId in block.Body.TransactionIds)
                {
                    await _transactionBlockIndexManager.SetTransactionBlockIndexAsync(txId, transactionBlockIndex);
                }
            }
        }
Esempio n. 3
0
        private async Task ClearRedundantBlockIndices(Hash txId, TransactionBlockIndex transactionBlockIndex,
                                                      BlockIndex blockIndex, Chain chain)
        {
            if (blockIndex.BlockHeight > chain.LastIrreversibleBlockHeight ||
                transactionBlockIndex.PreviousExecutionBlockIndexList.Count == 0)
            {
                return;
            }

            transactionBlockIndex.BlockHash   = blockIndex.BlockHash;
            transactionBlockIndex.BlockHeight = blockIndex.BlockHeight;
            transactionBlockIndex.PreviousExecutionBlockIndexList.Clear();

            _transactionBlockIndexProvider.AddTransactionBlockIndex(txId, transactionBlockIndex);
            await _transactionBlockIndexManager.SetTransactionBlockIndexAsync(txId, transactionBlockIndex);
        }
        public async Task HandleEventAsync(NewIrreversibleBlockFoundEvent eventData)
        {
            var blockHash = eventData.BlockHash;

            while (true)
            {
                var block = await _blockchainService.GetBlockByHashAsync(blockHash);

                var preMiningHash         = block.Header.GetPreMiningHash();
                var transactionBlockIndex = new TransactionBlockIndex()
                {
                    BlockHash = blockHash
                };
                if (block.Body.Transactions.Count == 0)
                {
                    // This will only happen during test environment
                    return;
                }

                var firstTransaction = block.Body.Transactions.First();
                var withBlockHash    = await _transactionResultManager.GetTransactionResultAsync(
                    firstTransaction, blockHash);

                var withPreMiningHash = await _transactionResultManager.GetTransactionResultAsync(
                    firstTransaction, preMiningHash);

                if (withBlockHash == null)
                {
                    // TransactionResult is not saved with real BlockHash
                    // Save results with real (post mining) Hash, so that it can be queried with TransactionBlockIndex
                    foreach (var txId in block.Body.Transactions)
                    {
                        var result = await _transactionResultManager.GetTransactionResultAsync(txId, preMiningHash);

                        await _transactionResultManager.AddTransactionResultAsync(result, transactionBlockIndex.BlockHash);
                    }
                }

                if (withPreMiningHash != null)
                {
                    // TransactionResult is saved with PreMiningHash
                    // Remove results saved with PreMiningHash, as it will never be queried
                    foreach (var txId in block.Body.Transactions)
                    {
                        await _transactionResultManager.RemoveTransactionResultAsync(txId, preMiningHash);
                    }
                }

                // Add TransactionBlockIndex
                foreach (var txId in block.Body.Transactions)
                {
                    await _transactionBlockIndexManager.SetTransactionBlockIndexAsync(txId, transactionBlockIndex);
                }

                if (block.Height <= eventData.PreviousIrreversibleBlockHeight)
                {
                    break;
                }

                blockHash = block.Header.PreviousBlockHash;
            }
        }