Example #1
0
        /// <summary>
        /// Returns the block with the specified height, searching from <see cref="chainBranchBlockHash"/>. If the height
        /// is in the irreversible section of the chain, it will get the block from the indexed blocks.
        /// </summary>
        /// <param name="chain">the chain to search</param>
        /// <param name="height">the height of the block</param>
        /// <param name="chainBranchBlockHash">the block from which to start the search.</param>
        /// <returns></returns>
        public async Task <Hash> GetBlockHashByHeightAsync(Chain chain, long height, Hash chainBranchBlockHash)
        {
            if (chain.LastIrreversibleBlockHeight >= height)
            {
                // search irreversible section of the chain
                return((await _chainManager.GetChainBlockIndexAsync(height)).BlockHash);
            }

            // TODO: may introduce cache to improve the performance

            var chainBlockLink = await _chainManager.GetChainBlockLinkAsync(chainBranchBlockHash);

            if (chainBlockLink.Height < height)
            {
                return(null);
            }
            while (true)
            {
                if (chainBlockLink.Height == height)
                {
                    return(chainBlockLink.BlockHash);
                }

                chainBranchBlockHash = chainBlockLink.PreviousBlockHash;
                chainBlockLink       = await _chainManager.GetChainBlockLinkAsync(chainBranchBlockHash);

                if (chainBlockLink == null)
                {
                    return(null);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Returns the block with the specified height, searching from <see cref="chainBranchBlockHash"/>. If the height
        /// is in the irreversible section of the chain, it will get the block from the indexed blocks.
        /// </summary>
        /// <param name="chain">the chain to search</param>
        /// <param name="height">the height of the block</param>
        /// <param name="chainBranchBlockHash">the block from which to start the search.</param>
        /// <returns></returns>
        public async Task <Hash> GetBlockHashByHeightAsync(Chain chain, long height, Hash chainBranchBlockHash)
        {
            // 1 2 3 4(lib) 5 6
            // 4 >= height
            // return any(1,2,3,4)

            if (chain.LastIrreversibleBlockHeight >= height)
            {
                // search irreversible section of the chain
                return((await _chainManager.GetChainBlockIndexAsync(height)).BlockHash);
            }

            // Last irreversible block can make the loops in acceptable size, do not need cache

            // 1 2 3 4(lib) 5 6
            // 4 < height
            // return any(5,6)


            var chainBlockLink = await _chainManager.GetChainBlockLinkAsync(chainBranchBlockHash);

            if (chainBlockLink.Height < height)
            {
                Logger.LogWarning(
                    $"Start searching height: {chainBlockLink.Height},target height: {height},cannot get block hash");
                return(null);
            }

            while (true)
            {
                if (chainBlockLink.Height == height)
                {
                    return(chainBlockLink.BlockHash);
                }

                chainBranchBlockHash = chainBlockLink.PreviousBlockHash;
                chainBlockLink       = await _chainManager.GetChainBlockLinkAsync(chainBranchBlockHash);

                if (chainBlockLink == null || chainBlockLink.Height <= chain.LastIrreversibleBlockHeight)
                {
                    return(null);
                }
            }
        }
        public async Task Set_IrreversibleBlock_Test()
        {
            NewIrreversibleBlockFoundEvent eventData = null;

            _eventBus.Subscribe <NewIrreversibleBlockFoundEvent>(d =>
            {
                eventData = d;
                return(Task.CompletedTask);
            });

            var chain = await _fullBlockchainService.GetChainAsync();

            {
                //         LIB height: 7
                //
                //             Height: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14
                //        Best Branch: a -> b -> c -> d -> e -> f -> g -> h -> i -> j  -> k
                //     Longest Branch:                                   (h)-> l -> m  -> n  -> o  -> p
                //        Fork Branch:                    (e)-> q -> r -> s -> t -> u
                //    Unlinked Branch:                                              v  -> w  -> x  -> y  -> z
                await _fullBlockchainService.SetIrreversibleBlockAsync(chain, _kernelTestHelper.BestBranchBlockList[6]
                                                                       .Height, _kernelTestHelper.BestBranchBlockList[6].GetHash());

                chain = await _fullBlockchainService.GetChainAsync();

                chain.LastIrreversibleBlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].GetHash());
                chain.LastIrreversibleBlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].Height);

                eventData.ShouldNotBeNull();
                eventData.BlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].GetHash());
                eventData.BlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].Height);
                eventData.PreviousIrreversibleBlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[4].GetHash());
                eventData.PreviousIrreversibleBlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[4].Height);

                var blockLink =
                    await _chainManager.GetChainBlockLinkAsync(_kernelTestHelper.BestBranchBlockList[6].GetHash());

                while (blockLink != null)
                {
                    blockLink.IsIrreversibleBlock.ShouldBeTrue();
                    var chainBlockIndex = await _chainManager.GetChainBlockIndexAsync(blockLink.Height);

                    chainBlockIndex.BlockHash.ShouldBe(blockLink.BlockHash);

                    blockLink = await _chainManager.GetChainBlockLinkAsync(blockLink.PreviousBlockHash);
                }
            }

            {
                //         LIB height: 11
                //
                //             Height: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14
                //        Best Branch: a -> b -> c -> d -> e -> f -> g -> h -> i -> j  -> k
                //     Longest Branch: (-)                               (h)-> l -> m  -> n  -> o  -> p
                //        Fork Branch: (-)                (e)-> q -> r -> s -> t -> u
                //    Unlinked Branch:                                             v(-) -> w  -> x  -> y  -> z
                eventData = null;
                await _fullBlockchainService.SetIrreversibleBlockAsync(chain, _kernelTestHelper.BestBranchBlockList[10]
                                                                       .Height, _kernelTestHelper.BestBranchBlockList[10].GetHash());

                chain = await _fullBlockchainService.GetChainAsync();

                chain.LastIrreversibleBlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[10].GetHash());
                chain.LastIrreversibleBlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[10].Height);

                eventData.ShouldNotBeNull();
                eventData.BlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[10].GetHash());
                eventData.BlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[10].Height);
                eventData.PreviousIrreversibleBlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].GetHash());
                eventData.PreviousIrreversibleBlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].Height);

                var blockLink =
                    await _chainManager.GetChainBlockLinkAsync(_kernelTestHelper.BestBranchBlockList[10].GetHash());

                while (blockLink != null)
                {
                    blockLink.IsIrreversibleBlock.ShouldBeTrue();
                    var chainBlockIndex = await _chainManager.GetChainBlockIndexAsync(blockLink.Height);

                    chainBlockIndex.BlockHash.ShouldBe(blockLink.BlockHash);

                    blockLink = await _chainManager.GetChainBlockLinkAsync(blockLink.PreviousBlockHash);
                }
            }

            {
                // Set lib failed
                eventData = null;
                await _fullBlockchainService.SetIrreversibleBlockAsync(chain, _kernelTestHelper.BestBranchBlockList[9]
                                                                       .Height, _kernelTestHelper.BestBranchBlockList[9].GetHash());

                eventData.ShouldBeNull();
            }
        }
Example #4
0
        public async Task Set_IrreversibleBlock_Test()
        {
            var chain = await _fullBlockchainService.GetChainAsync();

            {
                //         LIB height: 7
                //
                //             Height: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14
                //        Best Branch: a -> b -> c -> d -> e -> f -> g -> h -> i -> j  -> k
                //     Longest Branch:                                   (h)-> l -> m  -> n  -> o  -> p
                //        Fork Branch:                    (e)-> q -> r -> s -> t -> u
                //    Unlinked Branch:                                              v  -> w  -> x  -> y  -> z
                await _fullBlockchainService.SetIrreversibleBlockAsync(chain, _kernelTestHelper.BestBranchBlockList[6]
                                                                       .Height, _kernelTestHelper.BestBranchBlockList[6].GetHash());

                chain = await _fullBlockchainService.GetChainAsync();

                chain.LastIrreversibleBlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].GetHash());
                chain.LastIrreversibleBlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[6].Height);

                var blockLink =
                    await _chainManager.GetChainBlockLinkAsync(_kernelTestHelper.BestBranchBlockList[6].GetHash());

                while (blockLink != null)
                {
                    blockLink.IsIrreversibleBlock.ShouldBeTrue();
                    var chainBlockIndex = await _chainManager.GetChainBlockIndexAsync(blockLink.Height);

                    chainBlockIndex.BlockHash.ShouldBe(blockLink.BlockHash);

                    blockLink = await _chainManager.GetChainBlockLinkAsync(blockLink.PreviousBlockHash);
                }
            }

            {
                //         LIB height: 11
                //
                //             Height: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11 -> 12 -> 13 -> 14
                //        Best Branch: a -> b -> c -> d -> e -> f -> g -> h -> i -> j  -> k
                //     Longest Branch: (-)                               (h)-> l -> m  -> n  -> o  -> p
                //        Fork Branch: (-)                (e)-> q -> r -> s -> t -> u
                //    Unlinked Branch:                                             v(-) -> w  -> x  -> y  -> z
                await _fullBlockchainService.SetIrreversibleBlockAsync(chain, _kernelTestHelper.BestBranchBlockList[10]
                                                                       .Height, _kernelTestHelper.BestBranchBlockList[10].GetHash());

                chain = await _fullBlockchainService.GetChainAsync();

                chain.LastIrreversibleBlockHash.ShouldBe(_kernelTestHelper.BestBranchBlockList[10].GetHash());
                chain.LastIrreversibleBlockHeight.ShouldBe(_kernelTestHelper.BestBranchBlockList[10].Height);

                var blockLink =
                    await _chainManager.GetChainBlockLinkAsync(_kernelTestHelper.BestBranchBlockList[10].GetHash());

                while (blockLink != null)
                {
                    blockLink.IsIrreversibleBlock.ShouldBeTrue();
                    var chainBlockIndex = await _chainManager.GetChainBlockIndexAsync(blockLink.Height);

                    chainBlockIndex.BlockHash.ShouldBe(blockLink.BlockHash);

                    blockLink = await _chainManager.GetChainBlockLinkAsync(blockLink.PreviousBlockHash);
                }
            }
        }