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++; } }
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)); } }
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()); }
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()); }
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); } }
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); } }
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); } } } }
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()); }
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; } }