Beispiel #1
0
        public void BenchmarkCreateChainFromBlocks()
        {
            BlockStore store     = new BlockStore(@"E:\Bitcoin\blocks\", Network.Main);
            Chain      chain     = null;
            var        fullBuild = Bench(() =>
            {
                chain = store.BuildChain();
            });

            chain.Changes.Rewind();
            var rebuildFromMemory = Bench(() =>
            {
                var chain2 = new Chain(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 #2
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 #3
0
 public Chain(ObjectStream<ChainChange> changes)
 {
     if(changes == null)
         changes = new StreamObjectStream<ChainChange>();
     changes.Rewind();
     _Changes = changes;
     Process();
 }
Beispiel #4
0
 public Account(ObjectStream<AccountEntry> entries)
 {
     if(entries == null)
         entries = new StreamObjectStream<AccountEntry>();
     entries.Rewind();
     _Entries = entries;
     Process();
 }
Beispiel #5
0
 public void CanDownloadChain()
 {
     using (var server = new NodeServer(Network.Main))
     {
         server.RegisterPeerTableRepository(PeerCache);
         CancellationTokenSource          cancel  = new CancellationTokenSource();
         StreamObjectStream <ChainChange> changes = new StreamObjectStream <ChainChange>(new MemoryStream());
         var chain = new Chain(changes);
         server.BuildChain(changes, cancel.Token);
     }
 }
Beispiel #6
0
        public Chain BuildChain(ObjectStream <ChainChange> changes = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (changes == null)
            {
                changes = new StreamObjectStream <ChainChange>();
            }
            var chain = new Chain(Network, changes);
            TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Build chain");

            using (trace.Open())
            {
                using (var pool = CreateNodeSet(3))
                {
                    int height   = pool.GetNodes().Max(o => o.FullVersion.StartHeight);
                    var listener = new PollMessageListener <IncomingMessage>();

                    pool.SendMessage(new GetHeadersPayload()
                    {
                        BlockLocators = chain.Tip.GetLocator()
                    });

                    using (pool.MessageProducer.AddMessageListener(listener))
                    {
                        while (chain.Height != height)
                        {
                            var before  = chain.Tip;
                            var headers = listener.RecieveMessage(cancellationToken).Message.Payload as HeadersPayload;
                            if (headers != null)
                            {
                                foreach (var header in headers.Headers)
                                {
                                    chain.GetOrAdd(header);
                                }
                                if (before.HashBlock != chain.Tip.HashBlock)
                                {
                                    NodeServerTrace.Information("Chain progress : " + chain.Height + "/" + height);
                                    pool.SendMessage(new GetHeadersPayload()
                                    {
                                        BlockLocators = chain.Tip.GetLocator()
                                    });
                                }
                            }
                        }
                    }
                }
            }
            return(chain);
        }
Beispiel #7
0
        public ScannerUser(KeyId keyId, int start, ScannerTester tester)
        {
            var folder = Path.Combine(tester._FolderName, tester.scanner.ToString());

            TestUtils.EnsureNew(folder);

            var chainStream   = new StreamObjectStream <ChainChange>(File.Open(Path.Combine(folder, "Chain"), FileMode.OpenOrCreate));
            var accountStream = new StreamObjectStream <AccountEntry>(File.Open(Path.Combine(folder, "Entries"), FileMode.OpenOrCreate));

            _Id        = keyId;
            _Scanner   = new PubKeyHashScanner(keyId);
            _ScanState = new ScanState(new PubKeyHashScanner(keyId),
                                       new Chain(chainStream),
                                       new Account(accountStream),
                                       start);
            _Tester = tester;
        }
Beispiel #8
0
 public Account(Account copied, ObjectStream<AccountEntry> entries)
 {
     if(entries == null)
         entries = new StreamObjectStream<AccountEntry>();
     _Entries = entries;
     copied.Entries.Rewind();
     entries.Rewind();
     foreach(var entry in copied.Entries.Enumerate())
     {
         if(_NextToProcess < copied._NextToProcess)
         {
             PushAccountEntry(entry);
         }
         else
             entries.WriteNext(entry);
     }
 }
Beispiel #9
0
 public Chain(Chain copied, ObjectStream<ChainChange> changes)
 {
     if(changes == null)
         changes = new StreamObjectStream<ChainChange>();
     AssertEmpty(changes);
     _Changes = changes;
     copied.Changes.Rewind();
     foreach(var change in copied.Changes.Enumerate())
     {
         if(_NextToProcess < copied._NextToProcess)
         {
             ProcessAndRecord(change, null);
         }
         else
         {
             _Changes.WriteNext(change);
         }
     }
 }
Beispiel #10
0
        public void CanBuildChainIncrementally()
        {
            StreamObjectStream <ChainChange> changes = new StreamObjectStream <ChainChange>();
            Chain main = new Chain(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, 6);

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

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

            //1 back track (retour à 3) + height4 + height5 + height6
            AssertLength(changes, 10);

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

            //1 back track (retour à 3) + height4 + height5 + height6 + height7
            current = AppendBlock(current, main);
            AssertHeight(changes, 7);
            AssertLength(changes, 15);
        }
Beispiel #11
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 #12
0
        public void CanBuildChainIncrementally()
        {
            StreamObjectStream<ChainChange> changes = new StreamObjectStream<ChainChange>();
            Chain main = new Chain(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, 6);

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

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

            //1 back track (retour à 3) + height4 + height5 + height6
            AssertLength(changes, 10);

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

            //1 back track (retour à 3) + height4 + height5 + height6 + height7
            current = AppendBlock(current, main);
            AssertHeight(changes, 7);
            AssertLength(changes, 15);
        }
Beispiel #13
0
 public Chain(BlockHeader blockHeader, int height, ObjectStream<ChainChange> changes)
 {
     if(changes == null)
         changes = new StreamObjectStream<ChainChange>();
     AssertEmpty(changes);
     _Changes = changes;
     Initialize(blockHeader, height);
 }
Beispiel #14
0
 public void AssertHeight(StreamObjectStream <ChainChange> changes, int height)
 {
     changes.Rewind();
     Assert.Equal(height, new PersistantChain(changes).Height);
 }
Beispiel #15
0
 private void AssertLength(StreamObjectStream <ChainChange> changes, int count)
 {
     changes.Rewind();
     Assert.Equal(count, changes.Enumerate().Count());
 }
Beispiel #16
0
 private void AssertLength(StreamObjectStream<ChainChange> changes, int count)
 {
     changes.Rewind();
     Assert.Equal(count, changes.Enumerate().Count());
 }
Beispiel #17
0
        public void CanSaveChain()
        {
            var stream = new StreamObjectStream<ChainChange>();
            Chain chain = new Chain(Network.Main, stream);
            AppendBlock(chain);
            AppendBlock(chain);
            var fork = AppendBlock(chain);
            AppendBlock(chain);

            stream.Rewind();

            var chain2 = new Chain(stream);
            Assert.True(chain.SameTip(chain2));

            stream.WriteNext(new ChainChange()
            {
                Add = false,
                HeightOrBackstep = 1
            });
            stream.Rewind();

            var chain3 = new Chain(stream);
            AssertHeight(stream, 3);
            var actualFork = chain3.FindFork(chain);
            Assert.Equal(fork.HashBlock, actualFork.HashBlock);
        }
Beispiel #18
0
 public void AssertHeight(StreamObjectStream<ChainChange> changes, int height)
 {
     changes.Rewind();
     Assert.Equal(height, new Chain(changes).Height);
 }
Beispiel #19
0
        public ScannerUser(KeyId keyId, int start, ScannerTester tester)
        {
            var folder = Path.Combine(tester._FolderName, tester.scanner.ToString());
            TestUtils.EnsureNew(folder);

            var chainStream = new StreamObjectStream<ChainChange>(File.Open(Path.Combine(folder, "Chain"), FileMode.OpenOrCreate));
            var accountStream = new StreamObjectStream<AccountEntry>(File.Open(Path.Combine(folder, "Entries"), FileMode.OpenOrCreate));
            _Id = keyId;
            _Scanner = new PubKeyHashScanner(keyId);
            _ScanState = new ScanState(new PubKeyHashScanner(keyId),
                            new Chain(chainStream),
                            new Account(accountStream),
                            start);
            _Tester = tester;
        }
Beispiel #20
0
 public Chain(BlockHeader blockHeader, int height, ObjectStream<ChainChange> changes)
 {
     if(changes == null)
         changes = new StreamObjectStream<ChainChange>();
     _Changes = changes;
     changes.Rewind();
     if(changes.EOF)
     {
         Initialize(blockHeader, height);
     }
     else
     {
         var first = changes.ReadNext();
         if(first.BlockHeader.GetHash() != blockHeader.GetHash())
         {
             throw new InvalidOperationException("The first block of this stream is different than the expected one at height " + height);
         }
         if(first.HeightOrBackstep != height)
         {
             throw new InvalidOperationException("The first block of this stream has height " + first.HeightOrBackstep + " but expected is " + height);
         }
         changes.Rewind();
         Process();
     }
 }
Beispiel #21
0
 public void CanDownloadChain()
 {
     using(var server = new NodeServer(Network.Main))
     {
         server.RegisterPeerTableRepository(PeerCache);
         CancellationTokenSource cancel = new CancellationTokenSource();
         StreamObjectStream<ChainChange> changes = new StreamObjectStream<ChainChange>(new MemoryStream());
         var chain = new Chain(changes);
         server.BuildChain(changes, cancel.Token);
     }
 }
Beispiel #22
0
        public Chain BuildChain(ObjectStream<ChainChange> changes = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if(changes == null)
                changes = new StreamObjectStream<ChainChange>();
            var chain = new Chain(Network, changes);
            TraceCorrelation trace = new TraceCorrelation(NodeServerTrace.Trace, "Build chain");
            using(trace.Open())
            {
                using(var pool = CreateNodeSet(3))
                {
                    int height = pool.GetNodes().Max(o => o.FullVersion.StartHeight);
                    var listener = new PollMessageListener<IncomingMessage>();

                    pool.SendMessage(new GetHeadersPayload()
                    {
                        BlockLocators = chain.Tip.GetLocator()
                    });

                    using(pool.MessageProducer.AddMessageListener(listener))
                    {
                        while(chain.Height != height)
                        {
                            var before = chain.Tip;
                            var headers = listener.RecieveMessage(cancellationToken).Message.Payload as HeadersPayload;
                            if(headers != null)
                            {
                                foreach(var header in headers.Headers)
                                {
                                    chain.GetOrAdd(header);
                                }
                                if(before.HashBlock != chain.Tip.HashBlock)
                                {
                                    NodeServerTrace.Information("Chain progress : " + chain.Height + "/" + height);
                                    pool.SendMessage(new GetHeadersPayload()
                                    {
                                        BlockLocators = chain.Tip.GetLocator()
                                    });
                                }
                            }
                        }
                    }
                }
            }
            return chain;
        }
Beispiel #23
0
        public Chain CreateSubChain(ChainedBlock from,
            bool fromIncluded,
            ChainedBlock to,
            bool toIncluded,
            ObjectStream<ChainChange> output = null)
        {
            if(output == null)
                output = new StreamObjectStream<ChainChange>();

            var blocks
                =
                to.EnumerateToGenesis()
                .Skip(toIncluded ? 0 : 1)
                .TakeWhile(c => c.HashBlock != from.HashBlock);
            if(fromIncluded)
                blocks = blocks.Concat(new ChainedBlock[] { from });

            var array = blocks.Reverse().ToArray();
            foreach(var b in array)
            {
                output.WriteNext(new ChainChange()
                {
                    Add = true,
                    BlockHeader = b.Header,
                    HeightOrBackstep = (uint)b.Height
                });
            }
            return new Chain(output);
        }