internal ChainedHeader GetFork(ChainedHeader chainTip)
        {
            if (chainTip == null)
            {
                return(null);
            }

            if (chainTip.Height > this.LastBlockSyncedHeight)
            {
                if (this.LastBlockSyncedHeight < 0)
                {
                    return(null);
                }

                chainTip = chainTip.GetAncestor(this.LastBlockSyncedHeight);
            }

            if (chainTip.Height == this.LastBlockSyncedHeight)
            {
                if (chainTip.HashBlock == uint256.Parse(this.LastBlockSyncedHash))
                {
                    return(chainTip);
                }
                else
                {
                    return(null);
                }
            }

            var blockLocator = new BlockLocator()
            {
                Blocks = this.BlockLocator.Split(',').Select(strHash => uint256.Parse(strHash)).ToList()
            };

            List <int> locatorHeights = ChainedHeaderExt.GetLocatorHeights(this.LastBlockSyncedHeight);

            for (int i = 0; i < locatorHeights.Count; i++)
            {
                if (chainTip.Height > locatorHeights[i])
                {
                    chainTip = chainTip.GetAncestor(locatorHeights[i]);
                }

                if (chainTip.HashBlock == blockLocator.Blocks[i])
                {
                    return(chainTip);
                }
            }

            return(null);
        }
        internal ChainedHeader GetFork(ChainedHeader chainTip)
        {
            if (chainTip == null || this.LastBlockSyncedHeight < 0)
            {
                return(null);
            }

            if (chainTip.Height >= this.LastBlockSyncedHeight)
            {
                ChainedHeader fork = (chainTip.Height == this.LastBlockSyncedHeight) ? chainTip : chainTip.GetAncestor(this.LastBlockSyncedHeight);
                if (fork.HashBlock == uint256.Parse(this.LastBlockSyncedHash))
                {
                    return(fork);
                }
            }

            var blockLocator = new BlockLocator()
            {
                Blocks = this.BlockLocator.Split(',').Select(strHash => uint256.Parse(strHash)).ToList()
            };

            List <int> locatorHeights = ChainedHeaderExt.GetLocatorHeights(this.LastBlockSyncedHeight);

            // Find a locator block at or below the chain tip.
            for (int i = 0; i < locatorHeights.Count; i++)
            {
                if (chainTip.Height < locatorHeights[i])
                {
                    continue;
                }

                chainTip = chainTip.GetAncestor(locatorHeights[i]);

                if (chainTip.HashBlock == blockLocator.Blocks[i])
                {
                    return(chainTip);
                }
            }

            return(null);
        }
        internal bool WalletContainsBlock(ChainedHeader lastBlockSynced)
        {
            if (lastBlockSynced == null)
            {
                return(true);
            }

            if (this.LastBlockSyncedHeight <= lastBlockSynced.Height)
            {
                return(uint256.Parse(this.LastBlockSyncedHash) == lastBlockSynced.HashBlock);
            }

            uint256[] hashes = GetBlockLocatorHashes();
            if (hashes.Length == 0)
            {
                return(false);
            }

            int[] heights = ChainedHeaderExt.GetLocatorHeights(this.LastBlockSyncedHeight).ToArray();

            return(hashes.Select((h, n) => lastBlockSynced.HashBlock == h && lastBlockSynced.Height == heights[n]).Any(e => true));
        }