Beispiel #1
0
        public void CanForkSide()
        {
            PersistantChain side = new PersistantChain(Network.Main);
            PersistantChain main = new PersistantChain(Network.Main);

            AppendBlock(side, main);
            AppendBlock(side, main);
            var common = AppendBlock(side, main);
            var sideb  = AppendBlock(side);
            var mainb1 = AppendBlock(main);
            var mainb2 = AppendBlock(main);
            var mainb3 = AppendBlock(main);

            Assert.Equal(common.HashBlock, side.SetTip(main.Tip).HashBlock);
            Assert.NotNull(side.GetBlock(mainb1.HashBlock));
            Assert.NotNull(side.GetBlock(mainb2.HashBlock));
            Assert.NotNull(side.GetBlock(mainb3.HashBlock));
            Assert.NotNull(side.GetBlock(common.HashBlock));
            Assert.Null(side.GetBlock(sideb.HashBlock));

            Assert.Equal(common.HashBlock, side.SetTip(sideb).HashBlock);
            Assert.Null(side.GetBlock(mainb1.HashBlock));
            Assert.Null(side.GetBlock(mainb2.HashBlock));
            Assert.Null(side.GetBlock(mainb3.HashBlock));
            Assert.NotNull(side.GetBlock(sideb.HashBlock));
        }
Beispiel #2
0
        public void BenchmarkCreateChainFromBlocks()
        {
            BlockStore      store     = new BlockStore(@"E:\Bitcoin\blocks\", Network.Main);
            PersistantChain chain     = null;
            var             fullBuild = Bench(() =>
            {
                chain = store.BuildChain();
            });

            chain.Changes.Rewind();
            var rebuildFromMemory = Bench(() =>
            {
                var chain2 = new PersistantChain(chain.Changes);
            });

            chain.Changes.Rewind();
            var halfChain = new StreamObjectStream <ChainChange>();

            for (int i = 0; i < 300000; i++)
            {
                halfChain.WriteNext(chain.Changes.ReadNext());
            }

            var halfBuild = Bench(() =>
            {
                var fullChain = store.BuildChain(halfChain);
            });
        }
Beispiel #3
0
        public void CanSaveChain()
        {
            var             stream = new StreamObjectStream <ChainChange>();
            PersistantChain chain  = new PersistantChain(Network.Main, stream);

            AppendBlock(chain);
            AppendBlock(chain);
            var fork = AppendBlock(chain);

            AppendBlock(chain);


            stream.Rewind();

            var chain2 = new PersistantChain(stream);

            Assert.True(chain.SameTip(chain2));

            stream.WriteNext(new ChainChange()
            {
                ChangeType       = ChainChangeType.BackStep,
                HeightOrBackstep = 1
            });
            stream.Rewind();

            var chain3 = new PersistantChain(stream);

            AssertHeight(stream, 3);
            var actualFork = chain3.FindFork(chain);

            Assert.Equal(fork.HashBlock, actualFork.HashBlock);
        }
Beispiel #4
0
        public void CanForkSidePartialChain()
        {
            var             block = TestUtils.CreateFakeBlock();
            PersistantChain side  = new PersistantChain(block.Header, 10, new StreamObjectStream <ChainChange>());
            PersistantChain main  = new PersistantChain(block.Header, 10, new StreamObjectStream <ChainChange>());

            AppendBlock(side, main);
            AppendBlock(side, main);
            var common = AppendBlock(side, main);
            var sideb  = AppendBlock(side);
            var mainb1 = AppendBlock(main);
            var mainb2 = AppendBlock(main);
            var mainb3 = AppendBlock(main);

            Assert.Equal(common.HashBlock, side.SetTip(main.Tip).HashBlock);
            Assert.NotNull(side.GetBlock(mainb1.HashBlock));
            Assert.NotNull(side.GetBlock(mainb2.HashBlock));
            Assert.NotNull(side.GetBlock(mainb3.HashBlock));
            Assert.NotNull(side.GetBlock(common.HashBlock));
            Assert.Null(side.GetBlock(sideb.HashBlock));

            Assert.Equal(common.HashBlock, side.SetTip(sideb).HashBlock);
            Assert.Null(side.GetBlock(mainb1.HashBlock));
            Assert.Null(side.GetBlock(mainb2.HashBlock));
            Assert.Null(side.GetBlock(mainb3.HashBlock));
            Assert.NotNull(side.GetBlock(sideb.HashBlock));
        }
Beispiel #5
0
        public PersistantChain BuildChain(BlockHeader firstBlock, int height)
        {
            PersistantChain chain = new PersistantChain();

            chain.Initialize(firstBlock, height);
            return(BuildChain(chain));
        }
Beispiel #6
0
        public PersistantChain GetChain(uint256 hashStop = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            var             ms    = new MemoryStream();
            PersistantChain chain = new PersistantChain(Network, new StreamObjectStream <ChainChange>(ms));

            SynchronizeChain(chain, hashStop, cancellationToken);
            return(chain);
        }
Beispiel #7
0
        private ChainedBlock AddBlock(PersistantChain chain)
        {
            BlockHeader header = new BlockHeader();

            header.Nonce         = RandomUtils.GetUInt32();
            header.HashPrevBlock = chain.Tip.HashBlock;
            chain.SetTip(header);
            return(chain.GetBlock(header.GetHash()));
        }
Beispiel #8
0
        public static PersistantChain CreateBlockChain(List <Block> blocks)
        {
            PersistantChain chain = new PersistantChain(Network.Main.GetGenesis().Header);

            foreach (var b in blocks)
            {
                b.Header.HashPrevBlock = chain.Tip.Header.GetHash();
                chain.TrySetTip(b.Header);
            }
            return(chain);
        }
Beispiel #9
0
        public void CanBuildPartialChain()
        {
            PersistantChain chain = new PersistantChain(TestUtils.CreateFakeBlock().Header, 10, new StreamObjectStream <ChainChange>());

            AppendBlock(chain);
            AppendBlock(chain);
            AppendBlock(chain);
            var b = AppendBlock(chain);

            Assert.Equal(14, chain.Height);
            Assert.Equal(14, b.Height);
            Assert.Equal(b.HashBlock, chain.Tip.HashBlock);
        }
Beispiel #10
0
        public void CanBuildChain()
        {
            PersistantChain chain = new PersistantChain(Network.Main);

            AppendBlock(chain);
            AppendBlock(chain);
            AppendBlock(chain);
            var b = AppendBlock(chain);

            Assert.Equal(4, chain.Height);
            Assert.Equal(4, b.Height);
            Assert.Equal(b.HashBlock, chain.Tip.HashBlock);
        }
Beispiel #11
0
        public void CanCalculateDifficulty()
        {
            var o         = Network.Main.ProofOfWorkLimit;
            var main      = new PersistantChain(LoadMainChain());
            var histories = File.ReadAllText("data/targethistory.csv").Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var history in histories)
            {
                var height         = int.Parse(history.Split(',')[0]);
                var expectedTarget = new Target(BigInteger.Parse(history.Split(',')[1]));

                var block = main.GetBlock(height).Header;

                Assert.Equal(expectedTarget, block.Bits);
                var target = main.GetWorkRequired(Network.Main, height);
                Assert.Equal(expectedTarget, target);
            }
        }
Beispiel #12
0
        public void CanSaveForkedBlockInChain()
        {
            var chain  = new PersistantChain(Network.Main);
            var common = AppendBlock(chain);
            var fork   = AppendBlock(chain);
            var fork2  = AppendBlock(common, chain);

            Assert.True(chain.Tip == fork);

            var chain2 = chain.Clone();
            var newTip = AppendBlock(fork2, chain);

            Assert.True(chain.Tip == newTip);

            Assert.True(chain2.Tip == fork);
            newTip = AppendBlock(fork2, chain2);
            Assert.True(chain2.Tip == newTip);
        }
Beispiel #13
0
        public void CanBuildConcurrentChain()
        {
            ConcurrentChain cchain = new ConcurrentChain();
            PersistantChain chain  = new PersistantChain(Network.Main);

            Assert.Null(cchain.SetTip(chain.Tip));
            var b0 = cchain.Tip;

            Assert.Equal(cchain.Tip, chain.Tip);

            var b1 = AddBlock(chain);
            var b2 = AddBlock(chain);

            AddBlock(chain);
            AddBlock(chain);
            var b5 = AddBlock(chain);

            Assert.Equal(cchain.SetTip(chain.Tip), b0);
            Assert.Equal(cchain.Tip, chain.Tip);

            Assert.Equal(cchain.GetBlock(5), chain.Tip);
            Assert.Equal(cchain.GetBlock(b5.HashBlock), chain.Tip);

            Assert.Equal(cchain.SetTip(b1), b1);
            Assert.Equal(cchain.GetBlock(b5.HashBlock), null);
            Assert.Equal(cchain.GetBlock(b2.HashBlock), null);

            Assert.Equal(cchain.SetTip(b5), b1);
            Assert.Equal(cchain.GetBlock(b5.HashBlock), chain.Tip);

            chain.SetTip(b2);
            AddBlock(chain);
            AddBlock(chain);
            var b5b = AddBlock(chain);
            var b6b = AddBlock(chain);

            Assert.Equal(cchain.SetTip(b6b), b2);

            Assert.Equal(cchain.GetBlock(b5.HashBlock), null);
            Assert.Equal(cchain.GetBlock(b2.HashBlock), b2);
            Assert.Equal(cchain.GetBlock(6), b6b);
            Assert.Equal(cchain.GetBlock(5), b5b);
        }
Beispiel #14
0
        public void CanForkBackwardPartialChain()
        {
            PersistantChain chain = new PersistantChain(TestUtils.CreateFakeBlock().Header, 10, new StreamObjectStream <ChainChange>());

            AppendBlock(chain);
            AppendBlock(chain);
            var fork = AppendBlock(chain);

            //Test single block back fork
            var last = AppendBlock(chain);

            Assert.Equal(14, chain.Height);
            Assert.Equal(14, last.Height);
            Assert.Equal(last.HashBlock, chain.Tip.HashBlock);
            Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock);
            Assert.Equal(13, chain.Height);
            Assert.Equal(13, fork.Height);
            Assert.Equal(fork.HashBlock, chain.Tip.HashBlock);
            Assert.Null(chain.GetBlock(last.HashBlock));
            Assert.NotNull(chain.GetBlock(fork.HashBlock));

            //Test 3 blocks back fork
            var b1 = AppendBlock(chain);
            var b2 = AppendBlock(chain);

            last = AppendBlock(chain);
            Assert.Equal(16, chain.Height);
            Assert.Equal(16, last.Height);
            Assert.Equal(last.HashBlock, chain.Tip.HashBlock);

            Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock);
            Assert.Equal(13, chain.Height);
            Assert.Equal(13, fork.Height);
            Assert.Equal(fork.HashBlock, chain.Tip.HashBlock);
            Assert.Null(chain.GetBlock(last.HashBlock));
            Assert.Null(chain.GetBlock(b1.HashBlock));
            Assert.Null(chain.GetBlock(b2.HashBlock));

            chain.SetTip(last);
            Assert.Equal(16, chain.Height);
            Assert.Equal(16, last.Height);
            Assert.Equal(last.HashBlock, chain.Tip.HashBlock);
        }
Beispiel #15
0
        public void CanForkBackward()
        {
            PersistantChain chain = new PersistantChain(Network.Main);

            AppendBlock(chain);
            AppendBlock(chain);
            var fork = AppendBlock(chain);

            //Test single block back fork
            var last = AppendBlock(chain);

            Assert.Equal(4, chain.Height);
            Assert.Equal(4, last.Height);
            Assert.Equal(last.HashBlock, chain.Tip.HashBlock);
            Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock);
            Assert.Equal(3, chain.Height);
            Assert.Equal(3, fork.Height);
            Assert.Equal(fork.HashBlock, chain.Tip.HashBlock);
            Assert.Null(chain.GetBlock(last.HashBlock));
            Assert.NotNull(chain.GetBlock(fork.HashBlock));

            //Test 3 blocks back fork
            var b1 = AppendBlock(chain);
            var b2 = AppendBlock(chain);

            last = AppendBlock(chain);
            Assert.Equal(6, chain.Height);
            Assert.Equal(6, last.Height);
            Assert.Equal(last.HashBlock, chain.Tip.HashBlock);

            Assert.Equal(fork.HashBlock, chain.SetTip(fork).HashBlock);
            Assert.Equal(3, chain.Height);
            Assert.Equal(3, fork.Height);
            Assert.Equal(fork.HashBlock, chain.Tip.HashBlock);
            Assert.Null(chain.GetBlock(last.HashBlock));
            Assert.Null(chain.GetBlock(b1.HashBlock));
            Assert.Null(chain.GetBlock(b2.HashBlock));

            chain.SetTip(last);
            Assert.Equal(6, chain.Height);
            Assert.Equal(6, last.Height);
            Assert.Equal(last.HashBlock, chain.Tip.HashBlock);
        }
Beispiel #16
0
        public void CanBuildChainIncrementally()
        {
            StreamObjectStream <ChainChange> changes = new StreamObjectStream <ChainChange>();
            PersistantChain main = new PersistantChain(Network.Main, changes);

            AppendBlock(main);
            AppendBlock(main);
            var forkPoint = AppendBlock(main);

            AssertHeight(changes, 3);
            AssertLength(changes, 4);

            var current = AppendBlock(forkPoint, main);
            var oldFork = AppendBlock(current, main);

            AssertHeight(changes, 5);
            AssertLength(changes, 6);

            current = AppendBlock(forkPoint, main);
            AssertHeight(changes, 5);
            AssertLength(changes, 7);

            current = AppendBlock(current, main);
            AssertHeight(changes, 5);
            AssertLength(changes, 8);

            current = AppendBlock(current, main);
            AssertHeight(changes, 6);

            //1 back track (retour à 3) + 1 set tip
            AssertLength(changes, 10);

            current = AppendBlock(oldFork, main);
            AssertHeight(changes, 6);
            AssertLength(changes, 11);

            //1 back track (retour à 3) + 1 set tip à 7
            current = AppendBlock(current, main);
            AssertHeight(changes, 7);
            AssertLength(changes, 13);
        }
Beispiel #17
0
        public void CanLoadAndSaveConcurrentChain()
        {
            ConcurrentChain cchain = new ConcurrentChain();
            PersistantChain chain  = new PersistantChain(Network.Main);

            AddBlock(chain);
            AddBlock(chain);
            AddBlock(chain);

            cchain.SetTip(chain);

            var bytes = cchain.ToBytes();

            cchain = new ConcurrentChain();
            cchain.Load(bytes);

            Assert.Equal(cchain.Tip, chain.Tip);
            Assert.NotNull(cchain.GetBlock(0));

            cchain = new ConcurrentChain(Network.TestNet);
            cchain.Load(cchain.ToBytes());
            Assert.NotNull(cchain.GetBlock(0));
        }
Beispiel #18
0
        public PersistantChain BuildChain(PersistantChain chain)
        {
            Dictionary <uint256, BlockHeader> headers = new Dictionary <uint256, BlockHeader>();
            HashSet <uint256> inChain = new HashSet <uint256>();

            inChain.Add(chain.GetBlock(chain.StartHeight).HashBlock);
            foreach (var header in Enumerate(true).Select(b => b.Item.Header))
            {
                var hash = header.GetHash();
                headers.Add(hash, header);
            }
            List <uint256> toRemove = new List <uint256>();

            while (headers.Count != 0)
            {
                foreach (var header in headers)
                {
                    if (inChain.Contains(header.Value.HashPrevBlock))
                    {
                        toRemove.Add(header.Key);
                        chain.TrySetTip(header.Value);
                        inChain.Add(header.Key);
                    }
                }
                foreach (var item in toRemove)
                {
                    headers.Remove(item);
                }
                if (toRemove.Count == 0)
                {
                    break;
                }
                toRemove.Clear();
            }
            return(chain);
        }
Beispiel #19
0
        public PersistantChain BuildChain(ObjectStream <ChainChange> changes)
        {
            PersistantChain chain = new PersistantChain(changes);

            return(BuildChain(chain));
        }
Beispiel #20
0
 List <ChainChange> EnumerateFromBeginning(PersistantChain chain)
 {
     chain.Changes.Rewind();
     return(chain.Changes.Enumerate().ToList());
 }