예제 #1
0
        public void TestSameBlock()
        {
            var walker = new BlockchainWalker();

            var path = walker.GetBlockchainPath(this.chainedHeaderA2, this.chainedHeaderA2, this.getChainedHeader);

            Assert.AreEqual(this.chainedHeaderA2, path.FromBlock);
            Assert.AreEqual(this.chainedHeaderA2, path.ToBlock);
            Assert.AreEqual(this.chainedHeaderA2, path.LastCommonBlock);

            Assert.AreEqual(0, path.RewindBlocks.Count);
            Assert.AreEqual(0, path.AdvanceBlocks.Count);
        }
예제 #2
0
        public void TestAdvanceFromGenesis()
        {
            var walker = new BlockchainWalker();

            var path = walker.GetBlockchainPath(this.chainedHeader0, this.chainedHeaderA4, this.getChainedHeader);

            Assert.AreEqual(this.chainedHeader0, path.FromBlock);
            Assert.AreEqual(this.chainedHeaderA4, path.ToBlock);
            Assert.AreEqual(this.chainedHeader0, path.LastCommonBlock);

            Assert.AreEqual(0, path.RewindBlocks.Count);

            Assert.AreEqual(4, path.AdvanceBlocks.Count);
            Assert.AreEqual(this.chainedHeader1, path.AdvanceBlocks[0]);
            Assert.AreEqual(this.chainedHeaderA2, path.AdvanceBlocks[1]);
            Assert.AreEqual(this.chainedHeaderA3, path.AdvanceBlocks[2]);
            Assert.AreEqual(this.chainedHeaderA4, path.AdvanceBlocks[3]);
        }
예제 #3
0
        public void TestRewindAndAdvanceToHigher()
        {
            var walker = new BlockchainWalker();

            var path = walker.GetBlockchainPath(this.chainedHeaderA3, this.chainedHeaderB4, this.getChainedHeader);

            Assert.AreEqual(this.chainedHeaderA3, path.FromBlock);
            Assert.AreEqual(this.chainedHeaderB4, path.ToBlock);
            Assert.AreEqual(this.chainedHeader1, path.LastCommonBlock);

            Assert.AreEqual(2, path.RewindBlocks.Count);
            Assert.AreEqual(this.chainedHeaderA3, path.RewindBlocks[0]);
            Assert.AreEqual(this.chainedHeaderA2, path.RewindBlocks[1]);

            Assert.AreEqual(3, path.AdvanceBlocks.Count);
            Assert.AreEqual(this.chainedHeaderB2, path.AdvanceBlocks[0]);
            Assert.AreEqual(this.chainedHeaderB3, path.AdvanceBlocks[1]);
            Assert.AreEqual(this.chainedHeaderB4, path.AdvanceBlocks[2]);
        }
예제 #4
0
        private void UpdateTargetChain()
        {
            using (updatedTracker.TryUpdate(staleAction: NotifyWork))
            {
                try
                {
                    var targetBlockLocal = this.targetBlock;
                    var targetChainLocal = this.targetChain;

                    if (targetBlockLocal != null && targetBlockLocal.Hash != targetChainLocal?.LastBlock.Hash)
                    {
                        var newTargetChain = targetChainLocal?.ToBuilder()
                                             ?? new ChainBuilder(Chain.CreateForGenesisBlock(this.chainParams.GenesisChainedHeader));

                        var deltaBlockPath = new BlockchainWalker().GetBlockchainPath(newTargetChain.LastBlock, targetBlockLocal, blockHash => this.coreStorage.GetChainedHeader(blockHash));

                        foreach (var rewindBlock in deltaBlockPath.RewindBlocks)
                        {
                            newTargetChain.RemoveBlock(rewindBlock);
                        }

                        foreach (var advanceBlock in deltaBlockPath.AdvanceBlocks)
                        {
                            newTargetChain.AddBlock(advanceBlock);
                        }

                        logger.Debug($"Winning chained block {newTargetChain.LastBlock.Hash} at height {newTargetChain.Height}, total work: {newTargetChain.LastBlock.TotalWork:X}");
                        this.targetChain = newTargetChain.ToImmutable();

                        this.OnTargetChainChanged?.Invoke();
                    }
                }
                catch (MissingDataException) { }
                finally
                {
                    inittedEvent.Set();
                }
            }
        }
예제 #5
0
        private void UpdateTargetChain()
        {
            using (updatedTracker.TryUpdate(staleAction: NotifyWork))
            {
                try
                {
                    var targetBlockLocal = this.targetBlock;
                    var targetChainLocal = this.targetChain;

                    if (targetBlockLocal != null && targetBlockLocal.Hash != targetChainLocal?.LastBlock.Hash)
                    {
                        var newTargetChain = targetChainLocal?.ToBuilder()
                            ?? new ChainBuilder(Chain.CreateForGenesisBlock(this.rules.GenesisChainedHeader));

                        var deltaBlockPath = new BlockchainWalker().GetBlockchainPath(newTargetChain.LastBlock, targetBlockLocal, blockHash => this.coreStorage.GetChainedHeader(blockHash));

                        foreach (var rewindBlock in deltaBlockPath.RewindBlocks)
                        {
                            newTargetChain.RemoveBlock(rewindBlock);
                        }

                        foreach (var advanceBlock in deltaBlockPath.AdvanceBlocks)
                        {
                            newTargetChain.AddBlock(advanceBlock);
                        }

                        logger.Debug($"Winning chained block {newTargetChain.LastBlock.Hash} at height {newTargetChain.Height}, total work: {newTargetChain.LastBlock.TotalWork:X}");
                        this.targetChain = newTargetChain.ToImmutable();

                        this.OnTargetChainChanged?.Invoke();
                    }
                }
                catch (MissingDataException) { }
                finally
                {
                    inittedEvent.Set();
                }
            }
        }
예제 #6
0
        public void TestChainMismatch()
        {
            var walker = new BlockchainWalker();

            walker.GetBlockchainPath(this.chainedHeaderA4, this.chainedHeaderX0, this.getChainedHeader);
        }