Example #1
0
        public static void CanCalculatePowPosCorrectly()
        {
            var chain = new ConcurrentChain(File.ReadAllBytes(TestDataLocations.BlockHeadersLocation));

            foreach (var block in chain.EnumerateAfter(chain.Genesis))
            {
                Assert.True(block.CheckPowPosAndTarget(Network.Main));
            }
        }
        public IEnumerable <IBlockInfo> GetBlocks()
        {
            var fork    = _chain.FindFork(LastProcessed.GetLocator());
            var headers = _chain
                          .EnumerateAfter(fork).Where(h => h.Height <= ToHeight)
                          .ToList();

            var first = headers.FirstOrDefault();

            if (first == null)
            {
                yield break;
            }

            var height = first.Height;

            if (first.Height == 1)
            {
                var headersWithGenesis = new List <ChainedBlock> {
                    fork
                };
                headers = headersWithGenesis.Concat(headers).ToList();
                height  = 0;
            }

            foreach (var block in _nodeBlocks.GetBlocks(headers.Select(_ => _.HashBlock), CancellationToken))
            {
                var header = _chain.GetBlock(height);

                if (block == null)
                {
                    var storeTip = _nodeBlocks.GetStoreTip();
                    if (storeTip != null)
                    {
                        // Store is caught up with Chain but the block is missing from the store.
                        if (header.Header.BlockTime <= storeTip.Header.BlockTime)
                        {
                            throw new InvalidOperationException($"Chained block not found in store (height = { height }). Re-create the block store.");
                        }
                    }

                    // Allow Store to catch up with Chain.
                    break;
                }

                LastProcessed = header;
                yield return(new BlockInfoModel()
                {
                    Block = block,
                    Hash = header.HashBlock,
                    Height = header.Height
                });

                height++;
            }
        }
Example #3
0
        public void CanCalculatePowCorrectly()
        {
            var chain = new ConcurrentChain(Network.Main);

            EnsureDownloaded("MainChain.dat", "https://aois.blob.core.windows.net/public/MainChain.dat");
            chain.Load(File.ReadAllBytes("MainChain.dat"));
            foreach (ChainedHeader block in chain.EnumerateAfter(chain.Genesis))
            {
                Target thisWork  = block.GetWorkRequired(Network.Main);
                Target thisWork2 = block.Previous.GetNextWorkRequired(Network.Main);
                Assert.Equal(thisWork, thisWork2);
                Assert.True(block.CheckProofOfWorkAndTarget(Network.Main));
            }
        }
Example #4
0
        public void CanEnumerateAfterChainedBlock()
        {
            ConcurrentChain chain = new ConcurrentChain(Network.Main);

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

            Assert.True(chain.EnumerateAfter(a).SequenceEqual(new[] { b, c }));

            var d = AppendBlock(chain);

            var enumerator = chain.EnumerateAfter(b).GetEnumerator();

            enumerator.MoveNext();
            Assert.True(enumerator.Current == c);

            chain.SetTip(b);
            var cc = AppendBlock(chain);
            var dd = AppendBlock(chain);

            Assert.False(enumerator.MoveNext());
        }
Example #5
0
        public void CanEnumerateAfterChainedBlock()
        {
            var chain = new ConcurrentChain(this.network);

            this.AppendBlock(chain);
            ChainedHeader a = this.AppendBlock(chain);
            ChainedHeader b = this.AppendBlock(chain);
            ChainedHeader c = this.AppendBlock(chain);

            Assert.True(chain.EnumerateAfter(a).SequenceEqual(new[] { b, c }));

            ChainedHeader d = this.AppendBlock(chain);

            IEnumerator <ChainedHeader> enumerator = chain.EnumerateAfter(b).GetEnumerator();

            enumerator.MoveNext();
            Assert.True(enumerator.Current == c);

            chain.SetTip(b);
            ChainedHeader cc = this.AppendBlock(chain);
            ChainedHeader dd = this.AppendBlock(chain);

            Assert.False(enumerator.MoveNext());
        }
Example #6
0
        public void CanIterateConcurrentChain()
        {
            ConcurrentChain chain = new ConcurrentChain(Network.Main);

            AppendBlock(chain);
            AppendBlock(chain);
            AppendBlock(chain);
            foreach (var b in chain.EnumerateAfter(chain.Genesis))
            {
                chain.GetBlock(0);
            }

            foreach (var b in chain.ToEnumerable(false))
            {
                chain.GetBlock(0);
            }
        }
Example #7
0
        public void CanIterateConcurrentChain()
        {
            var chain = new ConcurrentChain(this.network);

            this.AppendBlock(chain);
            this.AppendBlock(chain);
            this.AppendBlock(chain);
            foreach (ChainedHeader b in chain.EnumerateAfter(chain.Genesis))
            {
                chain.GetBlock(0);
            }

            foreach (ChainedHeader b in chain.ToEnumerable(false))
            {
                chain.GetBlock(0);
            }
        }
Example #8
0
        void StartScan(object unused)
        {
            var node = AttachedNode;

            if (_RunningPing != null)
            {
                _PlannedScan = true;
                return;
            }
            if (!IsScanning(node))
            {
                if (Monitor.TryEnter(cs))
                {
                    try
                    {
                        if (!IsScanning(node))
                        {
                            GetDataPayload payload = new GetDataPayload();
                            var            fork    = _Chain.FindFork(_CurrentProgress);
                            foreach (var block in _Chain
                                     .EnumerateAfter(fork)
                                     .Where(b => b.Header.BlockTime + TimeSpan.FromHours(5.0) > _SkipBefore)                            //Take 5 more hours, block time might not be right
                                     .Partition(10000)
                                     .FirstOrDefault() ?? new List <ChainedBlock>())
                            {
                                if (block.HashBlock != _LastSeen)
                                {
                                    payload.Inventory.Add(new InventoryVector(InventoryType.MSG_FILTERED_BLOCK, block.HashBlock));
                                    _InFlight.TryAdd(block.HashBlock, block.HashBlock);
                                }
                            }
                            if (payload.Inventory.Count > 0)
                            {
                                node.SendMessageAsync(payload);
                            }
                        }
                    }
                    finally
                    {
                        Monitor.Exit(cs);
                    }
                }
            }
        }
Example #9
0
		public void CanEnumerateAfterChainedBlock()
		{
			ConcurrentChain chain = new ConcurrentChain(Network.Main);
			AppendBlock(chain);
			var a = AppendBlock(chain);
			var b = AppendBlock(chain);
			var c = AppendBlock(chain);

			Assert.True(chain.EnumerateAfter(a).SequenceEqual(new[] { b, c }));

			var d = AppendBlock(chain);

			var enumerator = chain.EnumerateAfter(b).GetEnumerator();
			enumerator.MoveNext();
			Assert.True(enumerator.Current == c);

			chain.SetTip(b);
			var cc = AppendBlock(chain);
			var dd = AppendBlock(chain);

			Assert.False(enumerator.MoveNext());
		}
Example #10
0
        public void Sync()
        {
            _isRunning = true;
            try
            {
                var node = Node.Connect(Network.Main, new IPEndPoint(IPAddress.Parse(_settings.Nodes), 16178));
                // var node = Node.ConnectToLocal(Network.Main);

                //var connectedNodes = _group.ConnectedNodes.ToArray();
                //if (!connectedNodes.Any())
                //{
                //    _logger.Information("Waiting for nodes ... ");
                //    _isRunning = false;
                //    return;
                //}
                _logger.Information("************************************************");
                _logger.Information("Connecting to Node ");
                //_logger.Information($"Total connected nodes {connectedNodes.Length}");
                //var rand = new Random();
                //var node = connectedNodes[rand.Next(connectedNodes.Length)];
                _logger.Information($"Node selected {node.Peer.Endpoint.Address}");
                if (node.IsConnected)
                {
                    node.VersionHandshake();

                    _logger.Information("Connected...");
                    _logger.Information($"Last Seen -->{node.LastSeen}");
                    _logger.Information("Checking chain");
                    if (_chain == null)
                    {
                        _logger.Information("Loading chain from disk...");
                        LoadChain();
                        if (_chain == null)
                        {
                            _logger.Information("No chain found on disk, Syncing chain from node ");
                            _chain = node.GetChain();
                            _logger.Information("Chain sync completed");
                        }
                    }

                    _logger.Information("Retrieving latest block...");
                    var lastDbBlock = _proofService.GetLatestBlock();
                    _logger.Information($"Latest Block {lastDbBlock}");

                    _logger.Information("Synching latest chain...");
                    node.SynchronizeChain(_chain);
                    _lastHeight = _chain.Height;

                    _logger.Information($"Lastest Chain Height: {_lastHeight}");

                    var height = 0;
                    IEnumerable <IEnumerable <uint256> > hashChunks = null;
                    if (lastDbBlock == null)
                    {
                        _logger.Information("Retrieving chained blocks from height 0");
                        hashChunks = _chain.ToEnumerable(false).Select(x => x.HashBlock).Chunk(ChunkSize);
                    }
                    else
                    if (lastDbBlock.Height < _chain.Height)
                    {
                        _logger.Information($"Retrieving chained blocks from height {lastDbBlock.Height}");
                        hashChunks = _chain.EnumerateAfter(new uint256(lastDbBlock.Hash)).Select(x => x.HashBlock).Chunk(ChunkSize);
                        height     = lastDbBlock.Height + 1;
                    }
                    if (hashChunks != null)
                    {
                        _logger.Information($"Total blocks to save {_chain.Height - (lastDbBlock ?? new BlockData()).Height}, hashChunks {hashChunks.LongCount()}");
                        var chunkSize = 0;
                        foreach (var hashChunk in hashChunks)
                        {
                            _logger.Information($"Retrieving chunks from {chunkSize} - {chunkSize + ChunkSize}");
                            var blocks     = node.GetBlocks(hashChunk);
                            var dataBlocks = blocks.Select(x =>
                            {
                                var block    = BlockData.Parse(x);
                                block.Height = height++;
                                return(block);
                            });
                            _proofService.SaveBlocks(dataBlocks);
                            chunkSize += ChunkSize;
                            _logger.Information($"Saved blocks");
                        }
                    }
                    _logger.Information("Finished syncing...");
                    SaveChain();

                    _logger.Information("Disconnecting node....");
                    node.Disconnect();

                    CheckPending();

                    //var indexStore = new IndexedBlockStore(new InMemoryNoSqlRepository(), _blockStore);

                    // CheckAddressTransactions(newBlocks);

                    _logger.Information("************************************************");
                }

                else
                {
                    _logger.Information("Couldn't connect to node");
                }
            }
            catch (System.Exception ex)
            {
                _logger.Information($"Exception while syncing {ex}");
            }
            finally
            {
                _isRunning = false;
            }
        }