Exemplo n.º 1
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;
            }
        }